View Javadoc

1   package org.apache.maven.plugin.dependency;
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 org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.factory.ArtifactFactory;
24  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
25  import org.apache.maven.artifact.repository.ArtifactRepository;
26  import org.apache.maven.artifact.resolver.ArtifactCollector;
27  import org.apache.maven.artifact.resolver.ArtifactResolver;
28  import org.apache.maven.plugin.AbstractMojo;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.dependency.utils.DependencySilentLog;
31  import org.apache.maven.plugin.logging.Log;
32  import org.apache.maven.plugins.annotations.Component;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.apache.maven.project.MavenProject;
35  import org.codehaus.plexus.archiver.ArchiverException;
36  import org.codehaus.plexus.archiver.UnArchiver;
37  import org.codehaus.plexus.archiver.manager.ArchiverManager;
38  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
39  import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;
40  import org.codehaus.plexus.util.FileUtils;
41  import org.codehaus.plexus.util.ReflectionUtils;
42  import org.codehaus.plexus.util.StringUtils;
43  
44  import java.io.File;
45  import java.io.IOException;
46  import java.lang.reflect.Field;
47  import java.util.List;
48  
49  /**
50   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
51   * @version $Id: AbstractDependencyMojo.java 552528
52   *          2007-07-02 16:12:47Z markh $
53   */
54  public abstract class AbstractDependencyMojo
55      extends AbstractMojo
56  {
57      /**
58       * Used to look up Artifacts in the remote repository.
59       */
60      @Component
61      protected ArtifactFactory factory;
62  
63      /**
64       * Used to look up Artifacts in the remote repository.
65       */
66      @Component
67      protected ArtifactResolver resolver;
68  
69      /**
70       * Artifact collector, needed to resolve dependencies.
71       */
72      @Component( role = ArtifactCollector.class )
73      protected ArtifactCollector artifactCollector;
74  
75      /**
76       *
77       */
78      @Component( role = ArtifactMetadataSource.class, hint = "maven" )
79      protected ArtifactMetadataSource artifactMetadataSource;
80  
81      /**
82       * Location of the local repository.
83       */
84      @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
85      private ArtifactRepository local;
86  
87      /**
88       * List of Remote Repositories used by the resolver
89       */
90      @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
91      protected List<ArtifactRepository> remoteRepos;
92  
93      /**
94       * To look up Archiver/UnArchiver implementations
95       */
96      @Component
97      protected ArchiverManager archiverManager;
98  
99      /**
100      * <p>
101      * will use the jvm chmod, this is available for user and all level group level will be ignored
102      * </p>
103      * <b>since 2.6 is on by default</b>
104      * @since 2.5.1
105      */
106     @Parameter( property = "dependency.useJvmChmod", defaultValue = "true" )
107     protected boolean useJvmChmod;
108 
109     /**
110      * POM
111      */
112     @Component
113     protected MavenProject project;
114 
115     /**
116      * Contains the full list of projects in the reactor.
117      */
118     @Parameter( defaultValue = "${reactorProjects}" )
119     protected List<MavenProject> reactorProjects;
120 
121     /**
122      * If the plugin should be silent.
123      *
124      * @since 2.0
125      */
126     @Parameter( property = "silent", defaultValue = "false" )
127     public boolean silent;
128 
129     /**
130      * Output absolute filename for resolved artifacts
131      *
132      * @since 2.0
133      */
134     @Parameter( property = "outputAbsoluteArtifactFilename", defaultValue = "false" )
135     protected boolean outputAbsoluteArtifactFilename;
136 
137     private Log log;
138 
139     /**
140      * @return Returns the log.
141      */
142     public Log getLog()
143     {
144         if ( log == null )
145         {
146             if ( silent )
147             {
148                 log = new DependencySilentLog();
149             }
150             else
151             {
152                 log = super.getLog();
153             }
154         }
155 
156         return this.log;
157     }
158 
159     /**
160      * @return Returns the archiverManager.
161      */
162     public ArchiverManager getArchiverManager()
163     {
164         return this.archiverManager;
165     }
166 
167     /**
168      * Does the actual copy of the file and logging.
169      *
170      * @param artifact represents the file to copy.
171      * @param destFile file name of destination file.
172      * @throws MojoExecutionException with a message if an
173      *                                error occurs.
174      */
175     protected void copyFile( File artifact, File destFile )
176         throws MojoExecutionException
177     {
178         Log theLog = this.getLog();
179         try
180         {
181             theLog.info(
182                 "Copying " + ( this.outputAbsoluteArtifactFilename ? artifact.getAbsolutePath() : artifact.getName() )
183                     + " to " + destFile );
184 
185             if ( artifact.isDirectory() )
186             {
187                 // usual case is a future jar packaging, but there are special cases: classifier and other packaging
188                 throw new MojoExecutionException( "Artifact has not been packaged yet. When used on reactor artifact, "
189                     + "copy should be executed after packaging: see MDEP-187." );
190             }
191 
192             FileUtils.copyFile( artifact, destFile );
193         }
194         catch ( IOException e )
195         {
196             throw new MojoExecutionException( "Error copying artifact from " + artifact + " to " + destFile, e );
197         }
198     }
199 
200     protected void unpack( Artifact artifact, File location )
201         throws MojoExecutionException
202     {
203         unpack( artifact, location, null, null );
204     }
205 
206     /**
207      * Unpacks the archive file.
208      *
209      * @param file     File to be unpacked.
210      * @param location Location where to put the unpacked files.
211      * @param includes Comma separated list of file patterns to include i.e. <code>**&#47;.xml,
212      *                 **&#47;*.properties</code>
213      * @param excludes Comma separated list of file patterns to exclude i.e. <code>**&#47;*.xml,
214      *                 **&#47;*.properties</code>
215      */
216     protected void unpack( Artifact artifact, File location, String includes, String excludes )
217         throws MojoExecutionException
218     {
219         File file = artifact.getFile(); 
220         try
221         {
222             logUnpack( file, location, includes, excludes );
223 
224             location.mkdirs();
225 
226             if ( file.isDirectory() )
227             {
228                 // usual case is a future jar packaging, but there are special cases: classifier and other packaging
229                 throw new MojoExecutionException( "Artifact has not been packaged yet. When used on reactor artifact, "
230                     + "unpack should be executed after packaging: see MDEP-98." );
231             }
232 
233             UnArchiver unArchiver;
234 
235             try
236             {
237                 unArchiver = archiverManager.getUnArchiver( artifact.getType() );
238                 getLog().debug( "Found unArchiver by type: " + unArchiver );
239             }
240             catch ( NoSuchArchiverException e )
241             {
242                 unArchiver = archiverManager.getUnArchiver( file );
243                 getLog().debug( "Found unArchiver by extension: " + unArchiver );
244             }
245 
246             unArchiver.setUseJvmChmod( useJvmChmod );
247 
248             unArchiver.setSourceFile( file );
249 
250             unArchiver.setDestDirectory( location );
251 
252             if ( StringUtils.isNotEmpty( excludes ) || StringUtils.isNotEmpty( includes ) )
253             {
254                 // Create the selectors that will filter
255                 // based on include/exclude parameters
256                 // MDEP-47
257                 IncludeExcludeFileSelector[] selectors =
258                     new IncludeExcludeFileSelector[]{ new IncludeExcludeFileSelector() };
259 
260                 if ( StringUtils.isNotEmpty( excludes ) )
261                 {
262                     selectors[0].setExcludes( excludes.split( "," ) );
263                 }
264 
265                 if ( StringUtils.isNotEmpty( includes ) )
266                 {
267                     selectors[0].setIncludes( includes.split( "," ) );
268                 }
269 
270                 unArchiver.setFileSelectors( selectors );
271             }
272             if ( this.silent )
273             {
274                 silenceUnarchiver( unArchiver );
275             }
276 
277             unArchiver.extract();
278         }
279         catch ( NoSuchArchiverException e )
280         {
281             throw new MojoExecutionException( "Unknown archiver type", e );
282         }
283         catch ( ArchiverException e )
284         {
285             throw new MojoExecutionException(
286                 "Error unpacking file: " + file + " to: " + location + "\r\n" + e.toString(), e );
287         }
288     }
289 
290     private void silenceUnarchiver( UnArchiver unArchiver )
291     {
292         // dangerous but handle any errors. It's the only way to silence the unArchiver.
293         try
294         {
295             Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( "logger", unArchiver.getClass() );
296 
297             field.setAccessible( true );
298 
299             field.set( unArchiver, this.getLog() );
300         }
301         catch ( Exception e )
302         {
303             // was a nice try. Don't bother logging because the log is silent.
304         }
305     }
306 
307     /**
308      * @return Returns the factory.
309      */
310     public ArtifactFactory getFactory()
311     {
312         return this.factory;
313     }
314 
315     /**
316      * @param factory The factory to set.
317      */
318     public void setFactory( ArtifactFactory factory )
319     {
320         this.factory = factory;
321     }
322 
323     /**
324      * @return Returns the project.
325      */
326     public MavenProject getProject()
327     {
328         return this.project;
329     }
330 
331     /**
332      * @return Returns the local.
333      */
334     protected ArtifactRepository getLocal()
335     {
336         return this.local;
337     }
338 
339     /**
340      * @param local The local to set.
341      */
342     public void setLocal( ArtifactRepository local )
343     {
344         this.local = local;
345     }
346 
347     /**
348      * @return Returns the remoteRepos.
349      */
350     public List<ArtifactRepository> getRemoteRepos()
351     {
352         return this.remoteRepos;
353     }
354 
355     /**
356      * @param remoteRepos The remoteRepos to set.
357      */
358     public void setRemoteRepos( List<ArtifactRepository> remoteRepos )
359     {
360         this.remoteRepos = remoteRepos;
361     }
362 
363     /**
364      * @return Returns the resolver.
365      */
366     public org.apache.maven.artifact.resolver.ArtifactResolver getResolver()
367     {
368         return this.resolver;
369     }
370 
371     /**
372      * @param resolver The resolver to set.
373      */
374     public void setResolver( ArtifactResolver resolver )
375     {
376         this.resolver = resolver;
377     }
378 
379     /**
380      * @param archiverManager The archiverManager to set.
381      */
382     public void setArchiverManager( ArchiverManager archiverManager )
383     {
384         this.archiverManager = archiverManager;
385     }
386 
387     /**
388      * @return Returns the artifactCollector.
389      */
390     public ArtifactCollector getArtifactCollector()
391     {
392         return this.artifactCollector;
393     }
394 
395     /**
396      * @param theArtifactCollector The artifactCollector to set.
397      */
398     public void setArtifactCollector( ArtifactCollector theArtifactCollector )
399     {
400         this.artifactCollector = theArtifactCollector;
401     }
402 
403     /**
404      * @return Returns the artifactMetadataSource.
405      */
406     public ArtifactMetadataSource getArtifactMetadataSource()
407     {
408         return this.artifactMetadataSource;
409     }
410 
411     /**
412      * @param theArtifactMetadataSource The artifactMetadataSource to set.
413      */
414     public void setArtifactMetadataSource( ArtifactMetadataSource theArtifactMetadataSource )
415     {
416         this.artifactMetadataSource = theArtifactMetadataSource;
417     }
418 
419     public boolean isUseJvmChmod()
420     {
421         return useJvmChmod;
422     }
423 
424     public void setUseJvmChmod( boolean useJvmChmod )
425     {
426         this.useJvmChmod = useJvmChmod;
427     }
428 
429     private void logUnpack( File file, File location, String includes, String excludes )
430     {
431         if ( !getLog().isInfoEnabled() )
432         {
433             return;
434         }
435 
436         StringBuilder msg = new StringBuilder();
437         msg.append( "Unpacking " );
438         msg.append( file );
439         msg.append( " to " );
440         msg.append( location );
441 
442         if ( includes != null && excludes != null )
443         {
444             msg.append( " with includes \"" );
445             msg.append( includes );
446             msg.append( "\" and excludes \"" );
447             msg.append( excludes );
448             msg.append( "\"" );
449         }
450         else if ( includes != null )
451         {
452             msg.append( " with includes \"" );
453             msg.append( includes );
454             msg.append( "\"" );
455         }
456         else if ( excludes != null )
457         {
458             msg.append( " with excludes \"" );
459             msg.append( excludes );
460             msg.append( "\"" );
461         }
462 
463         getLog().info( msg.toString() );
464     }
465 }