1   package org.apache.maven.plugins.shade.mojo;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.lang.reflect.Field;
24  import java.lang.reflect.Method;
25  import java.net.URL;
26  import java.net.URLClassLoader;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.LinkedHashSet;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.DefaultArtifact;
36  import org.apache.maven.artifact.factory.ArtifactFactory;
37  import org.apache.maven.artifact.handler.ArtifactHandler;
38  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
39  import org.apache.maven.artifact.repository.ArtifactRepository;
40  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
41  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
42  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
43  import org.apache.maven.artifact.resolver.ArtifactResolver;
44  import org.apache.maven.artifact.resolver.DefaultArtifactResolver;
45  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
46  import org.apache.maven.artifact.versioning.VersionRange;
47  import org.apache.maven.plugins.shade.Shader;
48  import org.apache.maven.plugins.shade.filter.Filter;
49  import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
50  import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
51  import org.apache.maven.project.MavenProject;
52  import org.codehaus.plexus.PlexusTestCase;
53  
54  /**
55   * @author Jason van Zyl
56   * @author Mauro Talevi
57   */
58  public class ShadeMojoTest
59      extends PlexusTestCase
60  {
61      public void testShaderWithDefaultShadedPattern()
62          throws Exception
63      {
64          shaderWithPattern(null, new File( "target/foo-default.jar" ));
65      }
66  
67      public void testShaderWithCustomShadedPattern()
68          throws Exception
69      {
70          shaderWithPattern("org/shaded/plexus/util", new File( "target/foo-custom.jar" ));
71      }
72  
73      public void testShaderWithExclusions()
74          throws Exception
75      {
76          File jarFile = new File( getBasedir(), "target/unit/foo-bar.jar" );
77  
78          Shader s = (Shader) lookup( Shader.ROLE );
79  
80          Set set = new LinkedHashSet();
81          set.add( new File( getBasedir(), "src/test/jars/test-artifact-1.0-SNAPSHOT.jar" ) );
82  
83          List relocators = new ArrayList();
84          relocators.add( new SimpleRelocator( "org.codehaus.plexus.util", "hidden", null, Arrays.asList( new String[] {
85              "org.codehaus.plexus.util.xml.Xpp3Dom", "org.codehaus.plexus.util.xml.pull.*" } ) ) );
86  
87          List resourceTransformers = new ArrayList();
88  
89          List filters = new ArrayList();
90  
91          s.shade( set, jarFile, filters, relocators, resourceTransformers );
92  
93          ClassLoader cl = new URLClassLoader( new URL[] { jarFile.toURI().toURL() } );
94          Class c = cl.loadClass( "org.apache.maven.plugins.shade.Lib" );
95  
96          Field field = c.getDeclaredField( "CLASS_REALM_PACKAGE_IMPORT" );
97          assertEquals( "org.codehaus.plexus.util.xml.pull", field.get( null ) );
98  
99          Method method = c.getDeclaredMethod( "getClassRealmPackageImport", new Class[0] );
100         assertEquals( "org.codehaus.plexus.util.xml.pull", method.invoke( null, new Object[0] ) );
101     }
102     
103     /**
104      * Tests if a Filter is installed correctly, also if createSourcesJar is set to true.
105      * @throws Exception
106      */
107     public void testShadeWithFilter() throws Exception
108     {
109         ShadeMojo mojo = new ShadeMojo();
110         
111         // set createSourcesJar = true
112         Field createSourcesJar = ShadeMojo.class.getDeclaredField("createSourcesJar");
113         createSourcesJar.setAccessible(true);
114         createSourcesJar.set(mojo, Boolean.TRUE);
115         
116         // configure artifactFactory for mojo
117         ArtifactFactory artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
118         Field artifactFactoryField = ShadeMojo.class.getDeclaredField("artifactFactory");
119         artifactFactoryField.setAccessible(true);
120         artifactFactoryField.set(mojo, artifactFactory);
121         
122         // configure artifactResolver (mocked) for mojo
123         ArtifactResolver mockArtifactResolver = new DefaultArtifactResolver()
124         {
125 
126             public void resolve(Artifact artifact, List remoteRepos,
127                     ArtifactRepository repo)
128                     throws ArtifactResolutionException,
129                     ArtifactNotFoundException
130             {
131                 // artifact is resolved
132                 artifact.setResolved(true);
133                 
134                 // set file
135                 artifact.setFile(new File(artifact.getArtifactId() + "-"
136                         + artifact.getVersion()
137                         + (artifact.getClassifier() != null ? "-" + artifact.getClassifier() : "") 
138                         + ".jar"));
139             }
140 
141         };
142         Field artifactResolverField = ShadeMojo.class.getDeclaredField("artifactResolver");
143         artifactResolverField.setAccessible(true);
144         artifactResolverField.set(mojo, mockArtifactResolver);
145         
146         // create and configure MavenProject
147         MavenProject project = new MavenProject();
148         ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE );
149         Artifact artifact = new DefaultArtifact("org.apache.myfaces.core", "myfaces-impl",
150                 VersionRange.createFromVersion("2.0.1-SNAPSHOT"), "compile", "jar", null, 
151                 artifactHandler);
152         mockArtifactResolver.resolve(artifact, null, null); // setFile and setResolved
153         project.setArtifact(artifact);
154         Field projectField = ShadeMojo.class.getDeclaredField("project");
155         projectField.setAccessible(true);
156         projectField.set(mojo, project);
157         
158         // create and configure the ArchiveFilter
159         ArchiveFilter archiveFilter = new ArchiveFilter();
160         Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField("artifact");
161         archiveFilterArtifact.setAccessible(true);
162         archiveFilterArtifact.set(archiveFilter, "org.apache.myfaces.core:myfaces-impl");
163         
164         // add ArchiveFilter to mojo
165         Field filtersField = ShadeMojo.class.getDeclaredField("filters");
166         filtersField.setAccessible(true);
167         filtersField.set(mojo, new ArchiveFilter[] { archiveFilter });
168         
169         // invoke getFilters()
170         Method getFilters = ShadeMojo.class.getDeclaredMethod("getFilters", new Class[0]);
171         getFilters.setAccessible(true);
172         List filters = (List) getFilters.invoke(mojo, new Object[0]);
173         
174         // assertions - there must be one filter
175         assertEquals(1, filters.size());
176         
177         // the filter must be able to filter the binary and the sources jar
178         Filter filter = (Filter) filters.get(0);
179         assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT.jar"))); // binary jar
180         assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT-sources.jar"))); // sources jar
181     }
182 
183     public void shaderWithPattern(String shadedPattern, File jar)
184         throws Exception
185     {
186         Shader s = (Shader) lookup( Shader.ROLE );
187 
188         Set set = new LinkedHashSet();
189 
190         set.add( new File( getBasedir(), "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
191 
192         set.add( new File( getBasedir(), "src/test/jars/plexus-utils-1.4.1.jar" ) );
193 
194         List relocators = new ArrayList();
195 
196         relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList(
197             new String[]{"org/codehaus/plexus/util/xml/Xpp3Dom", "org/codehaus/plexus/util/xml/pull.*"} ) ) );
198 
199         List resourceTransformers = new ArrayList();
200 
201         resourceTransformers.add( new ComponentsXmlResourceTransformer() );
202 
203         List filters = new ArrayList();
204 
205         s.shade( set, jar, filters, relocators, resourceTransformers );
206     }
207     
208 }