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