代码之家  ›  专栏  ›  技术社区  ›  IAdapter

如何从Maven中的属性文件生成enum?

  •  6
  • IAdapter  · 技术社区  · 14 年前

    “如何使用ant从属性文件生成枚举?”

    我正在考虑编写自定义任务,但我想我需要将其放入额外的jar中:|

    2 回复  |  直到 14 年前
        1
  •  8
  •   Community T.Woody    7 年前

    Peter Tilemans ,我也被这个问题所吸引,我用groovy和 GMaven-Plugin 编辑 :GMaven的优点在于,您可以直接访问maven对象模型,而无需先创建插件,而且仍然拥有groovy的全部编程能力。

    在这种情况下,我要做的是创建一个名为src/main/groovy的源文件夹,它不是实际构建过程的一部分(因此不会对jar/war等产生影响)。我可以将groovy源文件放在那里,这样eclipse就可以将它们用作groovy源文件夹,用于自动完成等操作,而无需更改构建。

    因此,在这个文件夹中我有三个文件:EnumGenerator.groovy、enumTemplate.txt和enum.properties(我这样做是为了简单起见,您可能会从其他地方获得属性文件)

    它们在这里:

    枚举生成器.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();
        }
    
    }
    

    枚举模板.txt

    package ${packageName};
    
    public enum ${className} {
    
    ${body}
    
        private ${className}(String value){
            this.value = value;
        }
    
        private String value;
    
        public String getValue(){
            return this.value;
        }
    
    }
    

    枚举属性

    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;
        }
    
    }
    

    使用模板,您可以自定义枚举以满足您的需要。由于gmaven在maven中嵌入了groovy,所以您不必安装任何东西或更改构建配置。

    唯一要记住的是,您需要使用buildhelper插件 add the generated source folder

        2
  •  3
  •   Peter Tillemans    14 年前

    您有可能最终对来自配置文件的值进行硬编码,这些值可能随时更改。

    我认为围绕HashMap或BidiMap读取属性文件的一个小包装类将获得几乎相同的好处,开发人员以后也不会因为属性文件中的一个小更改而发现大量编译错误。

    我已经完成了代码生成的工作。它们非常适合于解析器和协议处理程序,但对于我不幸使用它们的每一个其他用例来说,它们都是定时炸弹。