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