原标题是 “如何使用ant从属性文件生成枚举?”
我想迭代所有属性并生成包含每个属性的枚举类。
我正在考虑编写自定义任务,但我想我需要把它放在额外的jar中:|
我正在使用maven,我想在生成源阶段进行。
答案 0 :(得分:8)
虽然我有点同意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插件add the generated source folder来构建。
答案 1 :(得分:3)
我强烈建议你重新考虑。
您可能会冒险对来自配置文件的值进行硬编码,并且可能随时更改。
我认为围绕HashMap或BidiMap读取属性文件的一个小包装类将实现几乎相同的好处,开发人员稍后将不会理解为什么他们因为一个小的变化而得到大量的编译错误。属性文件。
我完成了代码生成。它们非常适合解析器和协议处理程序,但是对于我不幸使用它们的所有其他用例,它们都在计时器。