Pregunta

Me encontré con un problema sobre cómo versionar un archivo de configuración en formato XML. La forma más fácil es escribir actualizaciones XSLT. Cada versión de la aplicación tiene su propia actualización XSLT. Todos estos archivos de actualización son lo suficientemente pequeños como para ser manejables por el IDE, especialmente su herramienta DIFF .

Dado que el proyecto ya se ha desarrollado como Maven2, la solución lógica de Java era activar estas actualizaciones a través del archivo de compilación de Maven.

Así es como se ve hoy la sección para aplicar un conjunto de actualizaciones:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>xml-maven-plugin</artifactId>
  <executions>
    <execution>
    <phase>compile</phase>
      <goals>
        <goal>transform</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <transformationSets>
      <transformationSet>
        <dir>config/xsltUpdates/input</dir>
        <stylesheet>config/xsltUpdates/update1-8-3.xsl</stylesheet>
        <outputDir>config/xsltUpdates/update1-8-3</outputDir>
      </transformationSet>
      <transformationSet>
         <dir>config/xsltUpdates/update1-8-3</dir>
         <stylesheet>config/xsltUpdates/update1-8-9.xsl</stylesheet>
         <outputDir>config/xsltUpdates/update1-8-9</outputDir>
      </transformationSet>
      <transformationSet>
        <dir>config/xsltUpdates/update1-8-9</dir>
        <stylesheet>config/xsltUpdates/update1-9-0.xsl</stylesheet>
        <outputDir>config/xsltUpdates/update1-9-0</outputDir>
      </transformationSet>
      <transformationSet>
        <dir>config/xsltUpdates/update1-9-0</dir>
        <stylesheet>config/xsltUpdates/update1-10-0.xsl</stylesheet>
        <outputDir>config/xsltUpdates/update1-10-0</outputDir>
      </transformationSet>
      <transformationSet>
        <dir>config/xsltUpdates/update1-10-0</dir>
        <stylesheet>config/xsltUpdates/update1-10-0-1.xsl</stylesheet>
        <outputDir>config/xsltUpdates/update1-10-0-1</outputDir>
      </transformationSet>
      <transformationSet>
        <dir>config/xsltUpdates/update1-10-0-1</dir>
        <stylesheet>config/xsltUpdates/update1-10-0-2.xsl</stylesheet>
        <outputDir>config/xsltUpdates/update1-10-0-2</outputDir>
      </transformationSet>
      <transformationSet>
        <dir>config/xsltUpdates/update1-10-0-2</dir>
        <stylesheet>config/xsltUpdates/updateCurrent.xsl</stylesheet>
        <outputDir>config/xsltUpdates/output</outputDir>
      </transformationSet>
    </transformationSets>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>net.sf.saxon</groupId>
      <artifactId>saxon</artifactId>
      <version>8.7</version>
    </dependency>
  </dependencies>
</plugin>

Me gustaría externalizar la información sobre transformaciónSet en algunas propiedades / importación de archivos xml. Mi archivo pom.xml será más limpio y la información externalizada será más fácil de mantener.

¿Cómo puedo hacer eso?

¿Puedo usar alguna instrucción de control iterativo dentro del archivo de compilación? ¿Hay alguna manera de importar datos de algún archivo externo?

¿Fue útil?

Solución

Algunos complementos le permiten usar descriptores externos (por ejemplo, el maven-assembly-plugin ). Lamentablemente, xml-maven-plugin aún no es uno de ellos.

Una opción es copiar los objetivos relevantes de xml-maven-plugin y calzar el procesamiento de maven-shared-io en el objetivo. He estado tratando de hacer esto yo mismo con el fin de presentar solicitudes contra varios complementos para usar archivos de descriptor y el enfoque de LocatorStrategy para encontrar los descriptores. Aquí hay algo de procesamiento que modificará el complemento xml-maven para permitir el uso de descriptores. Tenga en cuenta que hay poca validación de los archivos involucrados, por lo que es un poco frágil, pero funciona.

1) Cree un nuevo proyecto maven-plugin (digamos llamado xml-ext-maven-plugin) con las siguientes dependencias:

<dependencies>
  <dependency>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>xml-maven-plugin</artifactId>
    <version>1.0-beta-2</version>
  </dependency>
  <dependency>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-2</version>
  </dependency>
</dependencies>

2) Copie los archivos TransformMojo y AbstractXmlMojo .java del complemento xml-maven (necesita el mojo principal para heredar las propiedades de su javadoc).

3) Agregue una propiedad descriptores a TransformMojo:

/**
 * A list of descriptor files to obtain the transformation sets from
 * 
 * @parameter
 */
private String[] descriptors;

4) modifique el método execute () para leer los descriptores de transformSets

public void execute() throws MojoExecutionException, MojoFailureException {
    //insert at start of method to resolve transformationSets fronm descriptors
    if (descriptors != null && descriptors.length > 0) {
        transformationSets = readDescriptors(descriptors);
    }

    ...

5) Implemente readDescriptors () para permitirle ubicar descriptores en el classpath o dentro del proyecto (el procesamiento del lector se elimina en gran medida del DefaultAssemblyReader del complemento de ensamblaje). Tenga en cuenta que hay poca validación en esta implementación, un complemento adecuado verificaría si se establecen valores, etc.

private TransformationSet[] readDescriptors(String[] descriptors)
        throws MojoExecutionException {

    List descriptorSets = new ArrayList();
    // add all the existing transformationSets
    if (transformationSets != null && transformationSets.length != 0) {
        descriptorSets.addAll(Arrays.asList(transformationSets));
    }

    for (int i = 0; i < descriptors.length; i++) {
        getLog().info(
                "Reading transformation descriptor: " + descriptors[i]);

        Location location = getLocation(descriptors[i]);

        Reader reader = null;
        try {
            reader = new InputStreamReader(location.getInputStream(),
                    "UTF-8");

            Xpp3Dom dom = Xpp3DomBuilder.build(reader);

            descriptorSets.addAll(parseTransformationSets(dom));
        } catch (IOException e) {
            throw new MojoExecutionException(
                    "Error reading transformation descriptor: "
                            + descriptors[i], e);
        } catch (XmlPullParserException e) {
            throw new MojoExecutionException(
                    "Error parsing transformation descriptor: "
                            + descriptors[i], e);
        } finally {
            IOUtil.close(reader);
        }
    }

    return (TransformationSet[]) descriptorSets
            .toArray(new TransformationSet[descriptorSets.size()]);
}

/**
 * Create transformationSets from the Xpp3Dom.
 * TODO use plexus utilities to resolve these elegantly?
 */
private List parseTransformationSets(Xpp3Dom dom) {
    // TODO validation of the input files!
    Xpp3Dom[] setDoms = dom.getChildren("transformationSet");

    List sets = new ArrayList();
    for (int i = 0; i < setDoms.length; i++) {
        TransformationSet set = new TransformationSet();
        set.setDir(new File(setDoms[i].getChild("dir").getValue()));
        set.setStylesheet(new File(setDoms[i].getChild("stylesheet")
                .getValue()));

        Xpp3Dom outDom = setDoms[i].getChild("outputDir");

        if (outDom != null) {
            set.setOutputDir(new File(outDom.getValue()));
        }

        sets.add(set);
    }
    return sets;
}

6) Implemente getLocation () para usar varias estrategias para descubrir el archivo como ruta relativa, url o desde classpath.

private Location getLocation(String path) {
    List strategies = new ArrayList();
    strategies.add(new RelativeFileLocatorStrategy(getBasedir()));
    strategies.add(new ClasspathResourceLocatorStrategy());
    strategies.add(new FileLocatorStrategy());
    strategies.add(new URLLocatorStrategy());

    List refStrategies = new ArrayList();
    refStrategies.add(classpathStrategy);

    Locator locator = new Locator();

    locator.setStrategies(strategies);

    Location location = locator.resolve(path);
    return location;
}

7) Reemplazar asAbsoluteFile () para resolver archivos utilizando la estrategia de localización (también nos permite definir los archivos xsl en el proyecto del descriptor).

protected File asAbsoluteFile(File f) {
    String path = f.getPath();

    // ensure we're getting a path in the form that URL can handle
    if (path != null) {
        path = path.replaceAll("\\\\", "/");
    }
    Location location = getLocation(path);

    if (location == null) {
        //can't find the file, let the parent implementation have a try
        return super.asAbsoluteFile(f);
    }
    try {
        return location.getFile();
    } catch (IOException e) {
        throw new RuntimeException("unable to read file " + f.getPath(), e);
    }
}

8) Instale el complemento en su repositorio.

9) Cree un nuevo proyecto maven para alojar sus conjuntos de transformación (digamos llamado xml-ext-test-descriptor). el proceso es el mismo que para los descriptores compartidos del conjunto de complementos, es decir, crear un proyecto, agregar algunos archivos xml en src / main / resources e instalar el proyecto. Los archivos xml tienen la forma de la configuración estándar de transformSets. Por ejemplo, ponga un par de transformaciones en src / main / resources / transformations1.xml:

<transformationSets>
  <transformationSet>
    <!--the config directory is in the root of the project -->
    <dir>config/xsltUpdates/input</dir>
    <!-- the stylesheet can be in the descriptor project-->
    <stylesheet>/stylesheets/update1-8-3.xsl</stylesheet>       
    <outputDir>config/xsltUpdates/update1-8-3</outputDir>
  </transformationSet>
  <transformationSet>
     <dir>config/xsltUpdates/update1-8-3</dir>
     <stylesheet>/stylesheets/update1-8-9.xsl</stylesheet>
     <outputDir>config/xsltUpdates/update1-8-9</outputDir>
  </transformationSet>
</transformationSets>

10) Coloque sus archivos xsl en el proyecto del descriptor, p. src / main / resources / stylesheets / update1-8-3.xsl

11) Configure el nuevo complemento en su proyecto para hacer referencia al proyecto del descriptor como una dependencia y al archivo xml como un descriptor:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>xml-maven-plugin</artifactId>
  <executions>
    <execution>
      <phase>compile</phase>
      <goals>
        <goal>transform</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>name.seller.rich</groupId>
      <artifactId>xml-ext-test-descriptor</artifactId>
      <version>0.0.1</version>
    </dependency>
  </dependencies>
  <configuration>
   <descriptors>
     <!-- will be resolved from xml-ext-test-descriptor -->
     <descriptor>/transformationSet1.xml</descriptor>
   </descriptors>
 </plugin>

Si todos los pasos anteriores funcionaron, cuando se ejecute, el complemento personalizado resolverá transformSet1.xml y sus archivos xsl de la dependencia xml-ext-test-descriptor y los procesará normalmente.

Otros consejos

Puede haber otras formas de hacer esto, pero podría tener un pluginManagement sección en un pom padre.

  

pluginManagement: es un elemento que se ve a lo largo de los complementos laterales. La administración de complementos contiene elementos de complementos de la misma manera, excepto que, en lugar de configurar la información de complementos para esta compilación de proyecto en particular, está destinada a configurar compilaciones de proyectos que heredan de esta. Sin embargo, esto solo configura complementos a los que realmente se hace referencia dentro del elemento de complementos en los elementos secundarios. Los hijos tienen todo el derecho de anular las definiciones de administración de complementos.

Por ejemplo:

POM del proyecto principal (necesita ejecutar mvn install para asegurarse de que este sea visible para su proyecto secundario)

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.nkl</groupId>
  <artifactId>parent</artifactId>
  <packaging>pom</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>xml-maven-plugin</artifactId>
          <executions>
            <execution>
              <phase>compile</phase>
              <goals>
                <goal>transform</goal>
              </goals>
            </execution>
          </executions>
          <configuration>
            <transformationSets>
              <transformationSet>
                <dir>config/xsltUpdates/input</dir>
                <stylesheet>config/xsltUpdates/update1-8-3.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-8-3</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-8-3</dir>
                <stylesheet>config/xsltUpdates/update1-8-9.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-8-9</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-8-9</dir>
                <stylesheet>config/xsltUpdates/update1-9-0.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-9-0</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-9-0</dir>
                <stylesheet>config/xsltUpdates/update1-10-0.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-10-0</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-10-0</dir>
                <stylesheet>config/xsltUpdates/update1-10-0-1.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-10-0-1</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-10-0-1</dir>
                <stylesheet>config/xsltUpdates/update1-10-0-2.xsl</stylesheet>
                <outputDir>config/xsltUpdates/update1-10-0-2</outputDir>
              </transformationSet>
              <transformationSet>
                <dir>config/xsltUpdates/update1-10-0-2</dir>
                <stylesheet>config/xsltUpdates/updateCurrent.xsl</stylesheet>
                <outputDir>config/xsltUpdates/output</outputDir>
              </transformationSet>
            </transformationSets>
          </configuration>
          <dependencies>
            <dependency>
              <groupId>net.sf.saxon</groupId>
              <artifactId>saxon</artifactId>
              <version>8.7</version>
            </dependency>
          </dependencies>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Proyecto hijo POM

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/maven-v4_0_0.xsd">
  <parent>
    <artifactId>parent</artifactId>
    <groupId>org.nkl</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.nkl</groupId>
  <artifactId>child</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>xml-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top