2009-01-30 8 views
2

J'ai été confronté à un problème de version d'un fichier de configuration au format XML. Le plus simple est d'écrire des mises à jour XSLT. Chaque version de l'application possède sa propre mise à jour XSLT. Tous ces fichiers de mise à jour sont suffisamment petits pour être gérés par l'IDE, en particulier son outil DIFF.Comment externaliser des morceaux de fichier de construction maven?

Étant donné que le projet a déjà été développé en tant que solution logique Java Maven2 était de déclencher ces mises à jour via le fichier de construction maven.

Voici comment la section pour l'application d'une série de mises à jour semble aujourd'hui:

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

Je voudrais extérioriser des informations sur transformationSet dans certains fichier de propriétés/xml import. Mon fichier pom.xml sera plus propre et les informations externalisées seront plus faciles à entretenir.

Comment puis-je faire cela? Puis-je utiliser une instruction de contrôle itérative dans le fichier de construction? Existe-t-il un moyen d'importer des données à partir d'un fichier externe?

Répondre

3

Certains Les plugins vous permettent d'utiliser des descripteurs externes (par exemple le maven-assembly-plugin). Malheureusement, le plugin xml-maven-plugin n'en fait pas encore partie.

Une option consiste à copier les objectifs pertinents du plugin xml-maven-plugin et le chakra du traitement de maven-shared-io dans le but. J'ai cherché à le faire moi-même en vue d'élever des demandes contre divers plugins pour utiliser des fichiers descripteurs et l'approche LocatorStrategy pour trouver les descripteurs. Voici un traitement qui va modifier le xml-maven-plugin pour permettre l'utilisation des descripteurs. Notez qu'il y a peu de validation des fichiers impliqués donc c'est un peu fragile comme ça, mais ça marche.

1) Créer un nouveau projet maven-plugin (dire appelé xml-ext-maven-plugin) avec les dépendances suivantes:

<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) Copiez le TransformMojo et les fichiers du AbstractXmlMojo du xml -maven-plugin (vous avez besoin du mojo parent pour hériter des propriétés de son javadoc).

3) Ajouter un descripteurs logement à TransformMojo:

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

4) modifier la méthode execute() pour lire les descripteurs pour transformationSets

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) Mettre en oeuvre readDescriptors ( pour vous permettre de localiser des descripteurs sur le chemin de classe ou dans le projet (le traitement du lecteur est en grande partie levé à partir du DefaultAssemblyReader du plugin d'assembly). Notez qu'il ya peu de validation dans cette mise en œuvre, un plug-in correct vérifierait si les valeurs sont définies 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) Mettre en œuvre getLocation() utiliser diverses stratégies pour découvrir le fichier soit comme un chemin relatif, url ou du chemin de classe.

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) Remplacer les asAbsoluteFile() pour résoudre les fichiers en utilisant la stratégie de localisation (permet de définir les fichiers xsl dans le projet de descripteur ainsi).

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) Installez le plug-in dans votre référentiel.

9) Créez un nouveau projet maven pour héberger vos transformationSets (par exemple appelé xml-ext-test-descriptor). le processus est le même que pour le shared descriptors de l'assembly-plugin, c'est-à-dire créer un projet, ajouter des fichiers xml sous src/main/resources et installer le projet. Les fichiers xml ont la forme de la configuration standard de transformationSets. Par exemple mettre quelques transformations dans 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) Mettez vos fichiers xsl dans le projet de descripteur, par exemple src/main/resources/stylesheets/update1-8-3.xsl

11) Configurez le nouveau plug-in dans votre projet pour référencer le projet descripteur en tant que dépendance et référence le fichier xml comme descripteur:

<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 toutes les étapes ci-dessus ont fonctionné, une fois exécuté, le plugin personnalisé résoudra transformationSet1.xml et vos fichiers xsl de la dépendance xml-ext-test-descriptor et les traitera comme d'habitude.

1

Il existe peut-être d'autres manières de procéder, mais vous pouvez avoir une section pluginManagement dans un pom parent.

pluginManagement: est un élément qui est vu le long des plugins latéraux. La gestion des plugins contient des éléments de plugin de la même manière, sauf qu'au lieu de configurer les informations de plugin pour cette construction de projet particulière, il est prévu de configurer les builds de projet qui en héritent. Cependant, ceci ne configure que les plugins qui sont réellement référencés dans l'élément plugins des enfants. Les enfants ont le droit de remplacer les définitions de pluginManagement.

Par exemple:

projet parent POM (besoin d'exécuter mvn installer pour y parvenir est visible à votre projet d'enfant)

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

projet enfant 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> 
+0

Pom actuel a déjà un fichier parent. Maven2 n'autorise pas l'héritage multiple. Je peux faire mon pom grand enfant de son parent actuel et ajouter un nouveau parent entre lequel se tiendra des données externalisées ... –

+0

... Le problème est que l'externalisation sera faite hors de la portée du projet que je voudrais éviter –

+0

Désolé je ne pourrais pas être plus aider Boris. – toolkit

Questions connexes