繁体   English   中英

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

[英]How to generate enum from properties file in Maven?

原始标题是“如何使用ant生成属性文件中的枚举?”

我想迭代所有属性并生成包含每个属性的枚举类。

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

即时通讯使用maven,我想在生成源阶段做到这一点。

虽然我有点同意Peter Tilemans ,但我也受到这个问题的诱惑,我使用groovy和GMaven-Plugin破解了一个解决方案。 编辑 :关于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;
    }

}

使用模板,您可以自定义枚举以满足您的需求。 由于gmaven在maven中嵌入groovy,因此您无需安装任何内容或更改构建配置。

唯一要记住的是,您需要使用buildhelper插件将生成的源文件夹添加到构建中。

我强烈建议你重新考虑一下。

您可能会冒险对来自配置文件的值进行硬编码,并且可能随时更改。

我认为围绕HashMap或BidiMap阅读属性文件的一个小包装类将实现几乎相同的好处,开发人员后来不会因为属性文件中的小变化而导致他们获得大量编译错误。

我完成了代码生成。 它们非常适合解析器和协议处理程序,但是对于我不幸使用它们的所有其他用例,它们都在计时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM