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

问题描述:

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

我想遍历所有属性并生成具有每个属性的枚举类。

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

即时通讯使用maven,我想在生成源阶段。

+1

其实你应该编辑问题的标题,因为你的环境是Maven和蚂蚁仅仅是一种可能的选择 – 2010-06-09 09:32:47

+0

我知道这是旧的,但为什么不干脆扔掉属性文件,只是用枚举? – 2014-09-22 21:50:46

虽然我有点同意Peter Tilemans,但我也被这个问题所诱惑,并且我使用groovy和GMaven-Plugin来砍掉一个解决方案。 编辑:关于GMaven的好处是,您可以直接访问maven对象模型,而无需首先创建插件,并且仍然具有groovy的完整编程能力。

我在这种情况下做的是创建一个名为src/main/groovy的源文件夹,它不是实际构建过程的一部分(因此不会对jar/war等产生影响)。在那里,我可以把groovy的源文件,从而允许日食使用它们作为自动完成等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。性能

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到构建。

+0

很酷的想法,谢谢。 – IAdapter 2010-06-09 10:20:55

+0

+1创造力(再次) – 2010-06-09 10:22:22

+0

@帕斯卡尔(我们会看到更多的,我希望:-)) – 2010-06-09 11:46:43

我强烈建议您重新考虑。

您将面临来自配置文件的硬编码风险,并可能随时改变。

我认为围绕HashMap或BidiMap阅读属性文件的一个包装类将获得几乎相同的好处,开发人员稍后将不会提出他们的头发,他们为什么得到巨大的编译错误是因为属性文件。

我已经完成了我的代码生成。对于解析器和协议处理程序来说,它们是非常棒的,但是对于其他使用情况我不幸使用它们的每个用例都会使用timebombs。

+0

我将它用于测试的jQuery选择器。为什么你认为这是一个坏主意?如果有人删除选择器,则应该删除/更新使用该选择器的测试。我只是将运行时错误交换为编译错误。加上这种方式,我可以很容易地逃避:在选择器(它只能作为\\ :)。 – IAdapter 2010-06-09 08:34:16

+0

我觉得你遇到了问题,因为你没有将生成的类保存在源代码控制之下,所以当某些事情被破坏时,确实很难修复它。 – IAdapter 2010-06-09 09:03:02

+0

只要生成的代码是自包含的,它就不是问题,如果您开始编码的类不是针对具有生成的签名的函数生成的,则问题会开始。不,生成的类不受源代码控制,只有生成它们的文件,并且生成由生成系统完成。 如果你的代码经过了很好的测试,开发和维护团队的每个人都知道它,那么它可能会很好。 实际上它看起来像一个很好的用例:生成具有有限用例的“愚蠢”的可复制代码。 – 2010-06-09 09:20:05