Как создать enum из файла свойств в Maven? - PullRequest
6 голосов
/ 09 июня 2010

Оригинальное название было "Как создать enum из файла свойств с помощью ant?"

Я хочу перебрать все свойства и сгенерировать перечислимый класс, который имеет каждое свойство.

Я думаю о написании пользовательского задания, но думаю, мне нужно поместить его в дополнительную банку: |

Я использую Maven, и я хочу сделать это в фазе создания источников.

Ответы [ 2 ]

8 голосов
/ 09 июня 2010

Хотя я в некоторой степени согласен с Питером Тайлмансом , я также был искушен этой проблемой и взломал решение, используя groovy и GMaven-Plugin . EDIT : Самое замечательное в GMaven заключается в том, что вы можете получить непосредственный доступ к объектной модели maven, не создавая плагин, и при этом использовать все возможности Groovy для программирования.

Что я делаю в подобных случаях, так это создаю исходную папку с именем src / main / groovy, которая не является частью реального процесса сборки (и, следовательно, не будет вносить вклад в jar / war и т. Д.). Там я могу поместить исходные файлы groovy, что позволит Eclipse использовать их в качестве исходных папок groovy для автозаполнения и т. Д. Без изменения сборки.

Итак, в этой папке у меня есть три файла: EnumGenerator.groovy, enumTemplate.txt и enum.properties (я сделал это для простоты, вы, вероятно, получите файл свойств откуда-то еще)

Вот они:

EnumGenerator.groovy

import java.util.Arrays;
import java.util.HashMap;
import java.util.TreeMap;
import java.io.File;
import java.util.Properties;

class EnumGenerator{

    public EnumGenerator(
        File targetDir, 
        File propfile,
        File templateFile,
        String pkgName,
        String clsName 
    ) {
        def properties = new Properties();
        properties.load(propfile.newInputStream());
        def bodyText = generateBody( new TreeMap( properties) );
        def enumCode = templateFile.getText();
        def templateMap = [ body:bodyText, packageName:pkgName, className: clsName  ];
        templateMap.each{ key, value -> 
                                enumCode = enumCode.replace( "\${$key}", value ) } 
        writeToFile( enumCode, targetDir, pkgName, clsName )
    }

    void writeToFile( code, dir, pkg, cls ) {
        def parentDir = new File( dir, pkg.replace('.','/') )
        parentDir.mkdirs();
        def enumFile = new File ( parentDir, cls + '.java' )
        enumFile.write(code)
        System.out.println( "Wrote file $enumFile successfully" )
    }

    String generateBody( values ) {

        // create constructor call PROPERTY_KEY("value")
        // from property.key=value
        def body = "";
        values.eachWithIndex{
            key, value, index ->
                body += 
                ( 
                    (index > 0 ? ",\n\t" : "\t")
                    + toConstantCase(key) + '("' + value + '")'
                )   
        }
        body += ";";
        return body;

    }

    String toConstantCase( value ) {
        // split camelCase and dot.notation to CAMEL_CASE and DOT_NOTATION
        return Arrays.asList( 
            value.split( "(?:(?=\\p{Upper})|\\.)" ) 
        ).join('_').toUpperCase();
    }

}

enumTemplate.txt

package ${packageName};

public enum ${className} {

${body}

    private ${className}(String value){
        this.value = value;
    }

    private String value;

    public String getValue(){
        return this.value;
    }

}

enum.properties

simple=value
not.so.simple=secondvalue
propertyWithCamelCase=thirdvalue

Вот конфигурация pom:

<plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <id>create-enum</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <scriptpath>
                    <element>${pom.basedir}/src/main/groovy</element>
                </scriptpath>
                <source>
                    import java.io.File
                    import EnumGenerator

                    File groovyDir = new File( pom.basedir,
                      "src/main/groovy")
                    new EnumGenerator(
                        new File( pom.build.directory,
                          "generated-sources/enums"),
                        new File( groovyDir,
                          "enum.properties"),
                        new File( groovyDir,
                          "enumTemplate.txt"),
                        "com.mycompany.enums",
                        "ServiceProperty" 
                    );

                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

И вот результат:

package com.mycompany.enums;

public enum ServiceProperty {

    NOT_SO_SIMPLE("secondvalue"),
    PROPERTY_WITH_CAMEL_CASE("thirdvalue"),
    SIMPLE("value");

    private ServiceProperty(String value){
        this.value = value;
    }

    private String value;

    public String getValue(){
        return this.value;
    }

}

используя шаблон, вы можете настроить enum в соответствии со своими потребностями. и поскольку gmaven встраивает groovy в maven, вам не нужно ничего устанавливать или изменять конфигурацию сборки.

Единственное, что нужно помнить, это то, что вам нужно будет использовать плагин buildhelper для добавления сгенерированной исходной папки в сборку.

3 голосов
/ 09 июня 2010

Я настоятельно рекомендую вам пересмотреть.

Вы рискуете закончить жесткое кодирование для значений, которые приходят из файлов конфигурации и могут измениться в любой момент.

Я думаю, что небольшой класс обертки вокругHashMap или BidiMap, считывающий файл свойств, принесет почти те же преимущества, и разработчики в дальнейшем не будут пытаться понять, почему они получают ошибки компиляции gazillion из-за небольшого изменения в файле свойств.

Iсделал свою долю генерации кода.Они отлично подходят для синтаксических анализаторов и обработчиков протоколов, но тикают бомбы замедленного действия для каждого другого случая использования, для которого я имел несчастье использовать их.

...