You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gb...@apache.org on 2017/07/15 21:57:43 UTC

svn commit: r1802034 - in /maven/plugins/trunk/maven-assembly-plugin/src/site: apt/examples/index.apt apt/examples/single/index.apt apt/examples/single/using-container-descriptor-handlers.apt.vm site.xml

Author: gboue
Date: Sat Jul 15 21:57:42 2017
New Revision: 1802034

URL: http://svn.apache.org/viewvc?rev=1802034&view=rev
Log:
[MASSEMBLY-857] Support for custom resource filters

Document container descriptor handlers in a dedicated page.

Added:
    maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm   (with props)
Modified:
    maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/index.apt
    maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/index.apt
    maven/plugins/trunk/maven-assembly-plugin/src/site/site.xml

Modified: maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/index.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/index.apt?rev=1802034&r1=1802033&r2=1802034&view=diff
==============================================================================
--- maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/index.apt (original)
+++ maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/index.apt Sat Jul 15 21:57:42 2017
@@ -43,6 +43,8 @@ Examples
 
     * {{{./single/using-repositories.html}Using Repositories}}
 
+    * {{{./single/using-container-descriptor-handlers.html}Using Container Descriptor Handlers}}
+
     []
 
   * {{{./multimodule/index.html}Working with Multi-Module Projects}}

Modified: maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/index.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/index.apt?rev=1802034&r1=1802033&r2=1802034&view=diff
==============================================================================
--- maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/index.apt (original)
+++ maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/index.apt Sat Jul 15 21:57:42 2017
@@ -40,3 +40,5 @@ Single Project Examples
   * {{{./using-components.html}Using Component Descriptors}}
 
   * {{{./using-repositories.html}Using Repositories}}
+
+  * {{{./using-container-descriptor-handlers.html}Using Container Descriptor Handlers}}

Added: maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm?rev=1802034&view=auto
==============================================================================
--- maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm (added)
+++ maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm Sat Jul 15 21:57:42 2017
@@ -0,0 +1,373 @@
+ ------
+  Using Container Descriptor Handlers
+ ------
+  Guillaume Boué
+ ------
+  2017-07-15
+ ------
+
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~   http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Using Container Descriptor Handlers
+
+* Introduction
+
+  Container descriptor handlers can be used to filter dynamically the content
+  of files configured in a descriptor, for example by aggregating multiple files 
+  into a single file, or customizing the content of specific files.
+
+  This example demonstrate the use of <<<\<containerDescriptorHandlers\>>>> in
+  the assembly {{{../../assembly.html}descriptor format}}.
+
+* Built-in container descriptor handlers
+
+  The plugin comes with several handlers already defined.
+  
+    [<<<file-aggregator>>>] This handler matches the files according to the given regular
+    expression <<<filePattern>>>, aggregates their content, and stores the output 
+    in the assembly at the given <<<outputPath>>>. A sample descriptor which matches
+    all <<<file.txt>>> files configured in the assembly and aggregates them, by 
+    appending their content, into a single <<<file.txt>>> located under the base directory
+    of the assembly, is:
+
++-----
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
+  ....
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <handlerName>file-aggregator</handlerName>
+      <configuration>
+        <filePattern>.*/file.txt</filePattern>
+        <outputPath>file.txt</outputPath>
+      </configuration>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+</assembly>
++-----
+
+    [<<<metaInf-services>>>] This handler matches every <<<META-INF/services>>> file and
+    aggregates them into a single <<<META-INF/services>>>. The content of the files
+    are appended together.
+
++-----
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
+  ....
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <handlerName>metaInf-services</handlerName>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+</assembly>
++-----
+
+    [<<<metaInf-spring>>>] This handler is similar to <<<metaInf-services>>>. It matches
+    every file with a name starting with <<<META-INF/spring.>>>.
+
++-----
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
+  ....
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <handlerName>metaInf-spring</handlerName>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+</assembly>
++-----
+
+    [<<<plexus>>>] This handler matches every <<<META-INF/plexus/components.xml>>> file and
+    aggregates them into a single valid <<<META-INF/plexus/components.xml>>>.
+
++-----
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
+  ....
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <handlerName>plexus</handlerName>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+</assembly>
++-----
+
+    []
+
+* Custom container descriptor handlers
+
+  You can create your own container descriptor handler by creating a class implementing 
+  <<<ContainerDescriptorHandler>>>. As an example, let's create a handler that will prepend 
+  a configured comment to every properties file configured in an assembly descriptor. 
+
+  We start by creating a new Maven project named <<<custom-container-descriptor-handler>>>
+  with the following 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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.test</groupId>
+  <artifactId>custom-container-descriptor-handler</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.plugins</groupId>
+      <artifactId>maven-assembly-plugin</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-component-metadata</artifactId>
+        <version>1.7.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-metadata</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
++-----
+
+  This POM declares a dependency on the Assembly Plugin so that we can create
+  our handler, and generates a Plexus configuration file so that it can be
+  found through dependency injection during assembling.
+
+  Implementing <<<ContainerDescriptorHandler>>> requires defining a couple of 
+  methods:
+  
+    [<<<isSelected>>>] Tells whether a given file or directory, configured in the
+    assembly descriptor, should be added to the final assembly. A typical
+    set-up would be to prevent the addition of certain files, and let the
+    handler do its work on them.
+    
+    [<<<getVirtualFiles>>>] Returns the list of file paths, from the root of the assembly,
+    of each file this handler will add.
+    
+    [<<<finalizeArchiveCreation>>>] Callback that is invoked when an assembly is going
+    to be created. This method can be used to add files that resulted from the
+    handler's work on each selected file. <<Cave-at:>> Because of the way archive
+    finalization is performed, we need to loop through each resource in the archive
+    before doing anything.
+    
+    [<<<finalizeArchiveExtraction>>>] Callback that is invoked when an assembly has been
+    extracted into a directory. This method can be used to process files that resulted
+    from the handler's work on each selected file.
+
+    []
+    
+  Our handler that prepends a comment to each properties file could look like the following
+  (using here Java 8 features):
+
++-----
+package com.test;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.maven.plugins.assembly.filter.ContainerDescriptorHandler;
+import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.UnArchiver;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.components.io.fileselectors.FileInfo;
+
+@Component(role = ContainerDescriptorHandler.class, hint = "custom")
+public class MyCustomDescriptorHandler implements ContainerDescriptorHandler {
+
+    private String comment;
+
+    private Map<String, List<String>> catalog = new HashMap<>();
+
+    private boolean excludeOverride = false;
+
+    @Override
+    public void finalizeArchiveCreation(Archiver archiver) throws ArchiverException {
+        archiver.getResources().forEachRemaining(a -> {}); // necessary to prompt the isSelected() call
+
+        for (Map.Entry<String, List<String>> entry : catalog.entrySet())
+        {
+            String name = entry.getKey();
+            String fname = new File(name).getName();
+
+            Path p;
+            try {
+                p = Files.createTempFile("assembly-" + fname, ".tmp");
+            } catch (IOException e) {
+                throw new ArchiverException("Cannot create temporary file to finalize archive creation", e);
+            }
+
+            try (BufferedWriter writer = Files.newBufferedWriter(p, StandardCharsets.ISO_8859_1)) {
+                writer.write("# " + comment);
+                for (String line : entry.getValue()) {
+                    writer.newLine();
+                    writer.write(line);
+                }
+            } catch (IOException e) {
+                throw new ArchiverException("Error adding content of " + fname + " to finalize archive creation", e);
+            }
+
+            File file = p.toFile();
+            file.deleteOnExit();
+            excludeOverride = true;
+            archiver.addFile(file, name);
+            excludeOverride = false;
+        }
+    }
+
+    @Override
+    public void finalizeArchiveExtraction(UnArchiver unarchiver) throws ArchiverException { }
+
+    @Override
+    public List<String> getVirtualFiles() {
+        return new ArrayList<>(catalog.keySet());
+    }
+
+    @Override
+    public boolean isSelected(FileInfo fileInfo) throws IOException {
+        if (excludeOverride) {
+            return true;
+        }
+        String name = AssemblyFileUtils.normalizeFileInfo(fileInfo);
+        if (fileInfo.isFile() && AssemblyFileUtils.isPropertyFile(name)) {
+            catalog.put(name, readLines(fileInfo));
+            return false;
+        }
+        return true;
+    }
+
+    private List<String> readLines(FileInfo fileInfo) throws IOException {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(fileInfo.getContents(), StandardCharsets.ISO_8859_1))) {
+            return reader.lines().collect(Collectors.toList());
+        }
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+}
++-----
+
+  It is a Plexus component, having the <<<ContainerDescriptorHandler>>> role,
+  that is distinguished from the other handlers with its <<<hint>>> of <<<custom>>>.
+
+  It selects each properties file and stores their content into a catalog map,
+  where the key is the name of the file and the value is a list of its lines.
+  Those matched files are not added to the assembly, because the handler needs
+  to process them first. During assembly creation, it creates temporary files
+  whose content are the previously read lines, prepended by a custom comment.
+  They are then added back into the archive with their previous name. Note that
+  this simple handler does not aggregate files with the same name - it could be
+  enhanced to do it. When the temporary files are added to the archive, the 
+  <<<isSelected>>> method is automatically called, hence we need to set a boolean 
+  <<<excludeOverride>>> to <<<true>>> to make sure the catalog processing part is not done.
+
+  The last ingredient is using our custom handler in an assembly descriptor of
+  some Maven project. Suppose there is a <<<src/samples>>> directory in this project,
+  containing an XML file named <<<test.xml>>> and a properties file named 
+  <<<test.properties>>>. With the following descriptor format
+
++-----
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+  <id>dist</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <handlerName>custom</handlerName>
+      <configuration>
+        <comment>A comment</comment>
+      </configuration>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+  <fileSets>
+    <fileSet>
+      <directory>src/samples</directory>
+      <outputDirectory></outputDirectory>
+    </fileSet>
+  </fileSets>
+</assembly>
++-----
+
+  and the following Assembly plugin configuration
+
++-----
+<project>
+  [...]
+  <build>
+    [...]
+    <plugins>
+      [...]
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>${project.version}</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <descriptors>
+                <descriptor>src/assemble/assembly.xml</descriptor>
+              </descriptors>
+            </configuration>
+          </execution>
+        </executions>
+        <dependencies>
+          <dependency>
+            <groupId>com.test</groupId>
+            <artifactId>custom-container-descriptor-handler</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+  [...]
+</project>
++-----
+
+  the resulting assembly would contain both <<<test.xml>>> and <<<test.properties>>>
+  under the base directory, with only the latter starting with <<<# A comment>>>.

Propchange: maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-assembly-plugin/src/site/apt/examples/single/using-container-descriptor-handlers.apt.vm
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/plugins/trunk/maven-assembly-plugin/src/site/site.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/site/site.xml?rev=1802034&r1=1802033&r2=1802034&view=diff
==============================================================================
--- maven/plugins/trunk/maven-assembly-plugin/src/site/site.xml (original)
+++ maven/plugins/trunk/maven-assembly-plugin/src/site/site.xml Sat Jul 15 21:57:42 2017
@@ -53,6 +53,7 @@ under the License.
         <item name="Including/Excluding Artifacts" href="./examples/single/including-and-excluding-artifacts.html"/>
         <item name="Using Component Descriptors" href="./examples/single/using-components.html"/>
         <item name="Using Repositories" href="./examples/single/using-repositories.html"/>
+        <item name="Using Container Descriptor Handlers" href="./examples/single/using-container-descriptor-handlers.html"/>
       </item>
       <item name="Multimodule Projects" collapse="false" href="./examples/multimodule/index.html">
         <item name="Include Module Artifacts" href="./examples/multimodule/module-binary-inclusion-simple.html"/>