2010-06-09 14 views
6

El título original era "¿Cómo generar enum desde el archivo de propiedades usando hormiga?"¿Cómo generar enum desde el archivo de propiedades en Maven?

Quiero iterar sobre todas las propiedades y generar una clase enum que tenga todas las propiedades.

Estoy pensando en escribir una tarea personalizada, pero creo que tendría que ponerlo en un frasco adicional: |

im usando Maven y quiero hacerlo en la fase generar-fuentes.

+1

en realidad debe editar el título de la pregunta, ya que su entorno es maven y hormiga es solo una opción posible –

+0

Sé que esto es viejo, pero ¿por qué no simplemente tirar los archivos de propiedad y simplemente usar enumeraciones? –

Respuesta

8

Aunque de alguna forma estoy de acuerdo con Peter Tilemans, también me sentí tentado por este problema y pirateé una solución usando groovy y el GMaven-Plugin. EDIT: Lo mejor de GMaven es que puedes acceder directamente al modelo de objetos maven sin crear primero un plugin y aun así tener la potencia de programación completa de groovy.

Lo que hago en casos como este es crear una carpeta fuente llamada src/main/groovy que no es parte del proceso de compilación real (y por lo tanto no contribuirá al jar/war, etc.). Allí puedo poner archivos de origen groovy, lo que permite eclipse para usarlos como carpetas fuente groovy para autocompletar, etc., sin cambiar la compilación.

Así que en esta carpeta que tengo tres archivos: EnumGenerator.groovy, enumTemplate.txt y enum.properties (Hice esto por razones de simplicidad, es probable que obtener el archivo de propiedades de otro lugar)

Aquí están :

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.propiedades

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

Aquí está la configuración 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> 

Y aquí está el resultado:

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

} 

usando la plantilla, puede personalizar la enumeración para satisfacer sus necesidades . y como gmaven incorpora groovy en maven, no tienes que instalar nada o cambiar tu configuración de compilación.

Lo único que debe recordar es que tendrá que usar el complemento buildhelper en add the generated source folder en la compilación.

+0

buena idea, gracias. – IAdapter

+0

+1 por creatividad (otra vez) –

+0

@pascal (veremos más de eso, espero :-)) –

3

Le recomiendo que lo reconsidere.

Se arriesga a terminar con la codificación difícil de los valores que provienen de los archivos de configuración y pueden cambiar en cualquier momento.

creo que un poco de clase envoltura alrededor de un HashMap o BidiMap leer el archivo de propiedades alcanzará los casi los mismos beneficios y los desarrolladores más adelante no va a sacar sus pelos por qué consiguen una compilación tropecientos errores a causa de un pequeño cambio en un archivo de propiedad.

He hecho mi parte de generación de código. Son geniales para los analizadores sintácticos y los manejadores de protocolos, pero están ajustando las bombas de tiempo para casi cualquier otro caso de uso que tuve la mala suerte de usar.

+0

lo usé para los selectores de jQuery para las pruebas. ¿Por qué crees que es una mala idea? si alguien quita el selector, también debe eliminar/actualizar la prueba que está usando eso. Acabo de intercambiar errores de tiempo de ejecución por errores de compilación. además de esta manera puedo escapar fácilmente: en selectores (solo funciona como \\ :). – IAdapter

+0

Creo que tuviste un problema con eso porque no mantuviste las clases generadas bajo el control de fuente, por lo que cuando algo se rompió fue realmente difícil solucionarlo. – IAdapter

+0

Siempre que el código generado sea autocontenido, no es un problema, los problemas comienzan si comienza a codificar en clases que no se generan contra funciones con firmas generadas. Y no, las clases generadas no estaban bajo control de fuente, solo los archivos de los cuales fueron generados, y la generación fue hecha por el sistema de compilación. Podría funcionar si tu código está realmente probado y todos en el equipo de desarrollo y mantenimiento lo saben. En realidad, parece un buen caso de uso: generar código reptil "estúpido" que tiene un uso limitado. –

Cuestiones relacionadas