MSHADE-12: Ability to filter contents of the archives added to the shaded jar
git-svn-id: https://svn.apache.org/repos/asf/maven/plugins/trunk@612350 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java b/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
index 99d1099..bec2b97 100644
--- a/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
+++ b/src/main/java/org/apache/maven/plugins/shade/DefaultShader.java
@@ -28,6 +28,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.ArrayList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -35,6 +36,7 @@
import org.apache.maven.plugins.shade.relocation.Relocator;
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
+import org.apache.maven.plugins.shade.filter.Filter;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
import org.objectweb.asm.ClassReader;
@@ -51,8 +53,8 @@
extends AbstractLogEnabled
implements Shader
{
- public void shade( Set jars, File uberJar, List relocators, List resourceTransformers )
- throws IOException
+ public void shade( Set jars, File uberJar, List filters, List relocators, List resourceTransformers )
+ throws IOException
{
Set resources = new HashSet();
@@ -64,6 +66,8 @@
{
File jar = (File) i.next();
+ List jarFilters = getFilters( jar, filters );
+
JarFile jarFile = new JarFile( jar );
for ( Enumeration j = jarFile.entries(); j.hasMoreElements(); )
@@ -74,7 +78,7 @@
String mappedName = remapper.map( name );
InputStream is = jarFile.getInputStream( entry );
- if ( !entry.isDirectory() )
+ if ( !entry.isDirectory() && !isFiltered( jarFilters, name ) )
{
int idx = mappedName.lastIndexOf('/');
if ( idx != -1 )
@@ -125,6 +129,24 @@
IOUtil.close( jos );
}
+ private List getFilters(File jar, List filters)
+ {
+ List list = new ArrayList();
+
+ for ( int i = 0; i < filters.size(); i++ )
+ {
+ Filter filter = (Filter) filters.get( i );
+
+ if ( filter.canFilter( jar ) )
+ {
+ list.add( filter );
+ }
+
+ }
+
+ return list;
+ }
+
private void addDirectory( Set resources, JarOutputStream jos, String name )
throws IOException
{
@@ -184,6 +206,21 @@
}
}
+ private boolean isFiltered( List filters, String name )
+ {
+ for ( int i = 0; i < filters.size(); i++ )
+ {
+ Filter filter = (Filter) filters.get( i );
+
+ if ( filter.isFiltered( name ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
private boolean resourceTransformed( List resourceTransformers, String name, InputStream is )
throws IOException
{
diff --git a/src/main/java/org/apache/maven/plugins/shade/Shader.java b/src/main/java/org/apache/maven/plugins/shade/Shader.java
index 3cff990..864d1ac 100644
--- a/src/main/java/org/apache/maven/plugins/shade/Shader.java
+++ b/src/main/java/org/apache/maven/plugins/shade/Shader.java
@@ -29,9 +29,10 @@
{
String ROLE = Shader.class.getName();
- public void shade( Set jars,
- File uberJar,
- List relocators,
- List resourceTransformers )
+ public void shade(Set jars,
+ File uberJar,
+ List filters,
+ List relocators,
+ List resourceTransformers)
throws IOException;
}
diff --git a/src/main/java/org/apache/maven/plugins/shade/filter/Filter.java b/src/main/java/org/apache/maven/plugins/shade/filter/Filter.java
new file mode 100644
index 0000000..4a305a4
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/shade/filter/Filter.java
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+package org.apache.maven.plugins.shade.filter;
+
+import java.io.File;
+
+/**
+ * @author David Blevins
+ */
+public interface Filter
+{
+ boolean canFilter( File jar );
+
+ boolean isFiltered( String classFile );
+}
diff --git a/src/main/java/org/apache/maven/plugins/shade/filter/SimpleFilter.java b/src/main/java/org/apache/maven/plugins/shade/filter/SimpleFilter.java
new file mode 100644
index 0000000..e0a5513
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/shade/filter/SimpleFilter.java
@@ -0,0 +1,89 @@
+/**
+ * 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.
+ */
+package org.apache.maven.plugins.shade.filter;
+
+import org.codehaus.plexus.util.SelectorUtils;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author David Blevins
+ */
+public class SimpleFilter
+ implements Filter
+{
+ private File jar;
+
+ private Set includes;
+
+ private Set excludes;
+
+ public SimpleFilter( File jar, Set includes, Set excludes )
+ {
+ this.jar = jar;
+ this.includes = includes;
+ this.excludes = excludes;
+ }
+
+ public boolean canFilter( File jar )
+ {
+ return this.jar.equals( jar );
+ }
+
+ public boolean isFiltered( String classFile )
+ {
+
+ return !( isIncluded( classFile ) && !isExcluded( classFile ) );
+ }
+
+ private boolean isIncluded( String classFile )
+ {
+ if ( includes == null || includes.size() == 0 )
+ {
+ return true;
+ }
+
+ return matchPaths( includes, classFile );
+ }
+
+ private boolean isExcluded( String classFile )
+ {
+ if ( excludes == null || excludes.size() == 0 )
+ {
+ return false;
+ }
+
+ return matchPaths( excludes, classFile );
+ }
+
+ private boolean matchPaths( Set patterns, String classFile )
+ {
+ for ( Iterator iterator = patterns.iterator(); iterator.hasNext(); )
+ {
+ String pattern = (String) iterator.next();
+
+ if ( SelectorUtils.matchPath( pattern, classFile ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/shade/mojo/ArchiveFilter.java b/src/main/java/org/apache/maven/plugins/shade/mojo/ArchiveFilter.java
new file mode 100644
index 0000000..d95d595
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/shade/mojo/ArchiveFilter.java
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+package org.apache.maven.plugins.shade.mojo;
+
+import java.util.Set;
+
+/**
+ * @author David Blevins
+ */
+public class ArchiveFilter
+{
+ private String artifact;
+
+ private Set includes;
+
+ private Set excludes;
+
+ public String getArtifact()
+ {
+ return artifact;
+ }
+
+ public Set getIncludes()
+ {
+ return includes;
+ }
+
+ public Set getExcludes()
+ {
+ return excludes;
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java b/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
index 3a642cf..fec4cdf 100644
--- a/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
+++ b/src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
@@ -32,6 +32,8 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
@@ -44,6 +46,7 @@
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.shade.Shader;
+import org.apache.maven.plugins.shade.filter.SimpleFilter;
import org.apache.maven.plugins.shade.pom.PomWriter;
import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
@@ -56,6 +59,7 @@
*
* @author Jason van Zyl
* @author Mauro Talevi
+ * @author David Blevins
* @goal shade
* @phase package
* @requiresDependencyResolution runtime
@@ -132,6 +136,18 @@
*/
private ResourceTransformer[] transformers;
+ /**
+ * Archive Filters to be used. Allows you to specify an artifact in the form of
+ * groupId:artifactId and a set of include/exclude file patterns for filtering which
+ * contents of the archive are added to the shaded jar. From a logical perspective,
+ * includes are processed before excludes, thus it's possible to use an include to
+ * collect a set of files from the archive then use excludes to further reduce the set.
+ * By default, all files are included and no files are excluded.
+ *
+ * @parameter
+ */
+ private ArchiveFilter[] filters;
+
/** @parameter expression="${project.build.directory}" */
private File outputDirectory;
@@ -259,15 +275,17 @@
// Now add our extra resources
try
{
+ List filters = getFilters();
+
List relocators = getRelocators();
List resourceTransformers = getResourceTrasformers();
- shader.shade( artifacts, outputJar, relocators, resourceTransformers );
+ shader.shade( artifacts, outputJar, filters, relocators, resourceTransformers );
if (createSourcesJar)
{
- shader.shade( sourceArtifacts, sourcesJar, relocators, resourceTransformers );
+ shader.shade( artifacts, outputJar, filters, relocators, resourceTransformers );
}
if ( shadedArtifactAttached )
@@ -476,6 +494,46 @@
return Arrays.asList( transformers );
}
+ private List getFilters()
+ {
+ List filters = new ArrayList();
+
+ if ( this.filters == null )
+ {
+ return filters;
+ }
+
+ Map artifacts = new HashMap();
+
+ artifacts.put( getId( project.getArtifact() ), project.getArtifact().getFile() );
+
+ for ( Iterator it = project.getArtifacts().iterator(); it.hasNext(); )
+ {
+ Artifact artifact = (Artifact) it.next();
+
+ artifacts.put( getId( artifact ), artifact.getFile() );
+ }
+
+ for ( int i = 0; i < this.filters.length; i++ )
+ {
+ ArchiveFilter f = this.filters[i];
+
+ File jar = (File) artifacts.get( f.getArtifact() );
+
+ if ( jar == null )
+ {
+ getLog().info( "No artifact matching filter " + f.getArtifact() );
+
+ continue;
+ }
+
+ filters.add( new SimpleFilter( jar, f.getIncludes(), f.getExcludes() ) );
+
+ }
+
+ return filters;
+ }
+
private File shadedArtifactFileWithClassifier()
{
Artifact artifact = project.getArtifact();
diff --git a/src/site/apt/examples.apt b/src/site/apt/examples.apt
index 314ff5e..d081d5a 100644
--- a/src/site/apt/examples.apt
+++ b/src/site/apt/examples.apt
@@ -203,4 +203,119 @@
</build>
...
</project>
++-----
+
+ * Shade Plugin with artifact filtering using includes
+
++-----
+<project>
+ ...
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>junit:junit</artifact>
+ <includes>
+ <include>junit/framework/**</include>
+ <include>org/junit/**</include>
+ </includes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ ...
+</project>
++-----
+
+ * Shade Plugin with artifact filtering using includes and excludes
+
++-----
+<project>
+ ...
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>junit:junit</artifact>
+ <includes>
+ <include>junit/framework/**</include>
+ <include>org/junit/**</include>
+ </includes>
+ <excludes>
+ <exclude>org/junit/experimental/**</include>
+ <exclude>org/junit/runners/**</include>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ ...
+</project>
++-----
+
+ * Shade Plugin with artifact filtering using excludes only
+
++-----
+<project>
+ ...
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>junit:junit</artifact>
+ <excludes>
+ <exclude>junit/textui/**</include>
+ <exclude>junit/runner/**</include>
+ <exclude>junit/extensions/**</include>
+ <exclude>org/junit/experimental/**</include>
+ <exclude>org/junit/runners/**</include>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ ...
+</project>
+-----
\ No newline at end of file
diff --git a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
index a6d7ebe..535ef79 100644
--- a/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java
@@ -80,7 +80,9 @@
resourceTransformers.add( new ComponentsXmlResourceTransformer() );
- s.shade( set, jar, relocators, resourceTransformers );
+ List filters = new ArrayList();
+
+ s.shade( set, jar, filters, relocators, resourceTransformers );
}
}
diff --git a/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java b/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
index f973afc..8bf6722 100644
--- a/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
@@ -71,7 +71,9 @@
resourceTransformers.add( new ComponentsXmlResourceTransformer() );
- s.shade( set, jar, relocators, resourceTransformers );
+ List filters = new ArrayList();
+
+ s.shade( set, jar, filters, relocators, resourceTransformers );
}
}