vendredi 13 septembre 2013

Ajouter un filtre personnalisé au plugin maven resource

Suite au post précédent post Multi encoding avec le plugin resource de Maven, il existe un autre moyen de personnaliser le filtering maven.
Il est possible soit de le substituer, soit de le compléter (ce qui répond aux deux bug maven ressource : https://jira.codehaus.org/browse/MRESOURCES-118 et https://jira.codehaus.org/browse/MRESOURCES-31).

En effet, depuis le version 2.4 du plugin resource, il est possible de spécifier un mavenFilteringHints.
A ce sujet, le site met à disposition la documentation suivante : http://maven.apache.org/plugins/maven-resources-plugin/examples/custom-resource-filters.html
Toutefois, l'exemple est peu parlant.
Nous allons donc voir ici comment créer un filtering personnaliser.

Dans un premier temps, il est nécessaire de créer un projet Maven de type JAR.
Le pom doit être renseigné comme ci-dessous :
<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>fr.emeric.filtering</groupId>
  <artifactId>myFiltering</artifactId>
  <packaging>jar</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>myFiltering Maven Mojo</name>

  <dependencies>
    <dependency>
      <groupId>org.apache.maven.shared</groupId>
      <artifactId>maven-filtering</artifactId>
      <version>1.1</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.plexus</groupId>
        <artifactId>plexus-maven-plugin</artifactId>
        <version>1.3.4</version>
        <executions>
          <execution>
            <goals>
              <goal>descriptor</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

La dépendance maven-filtering est là pour importer l'interface org.apache.maven.shared.filtering.MavenResourcesFiltering et toutes les autres classes nécessaires.
Le plugin plexus-maven-plugin est là lui pour générer les méta-données nécessaire à plexus.

Ensuite, il suffit de créer la classe ci-dessous :
package fr.emeric.filtering.myFiltering;

import java.io.File;
import java.util.Collections;
import java.util.List;

import org.apache.maven.model.Dependency;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.codehaus.plexus.util.FileUtils.FilterWrapper;

/**
 * @plexus.component role="org.apache.maven.shared.filtering.MavenResourcesFiltering" 
 *                   role-hint="myFilter"
 */
public class MyFiltering
    implements MavenResourcesFiltering
{

  public void filterResources(List resources, File outputDirectory,
      MavenProject mavenProject, String encoding,
      List fileFilters, List nonFilteredFileExtensions,
      MavenSession mavenSession) throws MavenFilteringException {    
  }

  public void filterResources(List resources, File outputDirectory,
      String encoding, List filterWrappers,
      File resourcesBaseDirectory, List nonFilteredFileExtensions)
      throws MavenFilteringException {
    
  }

  public List getDefaultNonFilteredFileExtensions() {
    return Collections.EMPTY_LIST;
  }

  public boolean filteredFileExtension(String fileName,
      List userNonFilteredFileExtensions) {
    return true;
  }

  public void filterResources(MavenResourcesExecution mavenResourcesExecution)
      throws MavenFilteringException {
    System.out.println("Hello depuis mon filtering !");
    
    List l = mavenResourcesExecution.getMavenProject().getDependencies() ;
    
    for(Dependency da : l) {
      System.out.println(da.toString());
    }
    
  }    
}

La méthode public void filterResources(MavenResourcesExecution mavenResourcesExecution) est applelée pour faire le filtre.

Il faut bien garder à l'esprit que le filtre personnalisé est appelé après le filtre par défaut de Maven.
C'est à dire que les fichiers ressources sont déjà filtrés quand le code est appelé.
Cela permet donc de rajouter des filtres.
Si vous voulez remplacer le filtre par défaut, il n'y a aucun problème. En effet, l'objet MavenResourcesExecution mavenResourcesExecution est le même que celui donné au filtre par défaut. Il y aura juste deux filtres exécutés, le premier ne servant à rien.

L'exemple ci-dessus montre que le filtre ne fait rien. Il affiche un texte Hello depuis mon filtering ! et la liste des dépendances.

Maintenant que notre classe de filtre est créer, le jar contenant cette classe doit être générée et installée dans le repository maven (pour cette exemple, le repository local est suffisant) :
mvn clean install

A présent, dans un autre projet, où l'on souhaite utiliser ce filtre personnalisé, le plugin maven resource doit être configuré :
<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.6</version>
        <configuration>
          ...
          <dependencies>
            <dependency>
              <groupId>fr.emeric.filtering</groupId>
              <artifactId>myFiltering</artifactId>
              <version>0.0.1-SNAPSHOT </version>
            </dependency>
          </dependencies>
    <mavenFilteringHints>
            <mavenFilteringHint>myFilter</mavenFilteringHint>
          </mavenFilteringHints>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

Le jar produit avec le filtre personnalisé est mis en dépendance du plugin maven resource.
Dans le paramètre mavenFilteringHint, le nom indiqué correspond à l'indication de la java doc role-hint="myFilter".
Voici le résultat lorsque maven s'exécute :
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
Hello depuis mon filtering !
Dependency {groupId=org.apache.maven, artifactId=maven-plugin-api, version=2.0.6, type=jar}
Dependency {groupId=org.apache.maven, artifactId=maven-model, version=3.0.5, type=jar}

Aucun commentaire:

Enregistrer un commentaire