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       * POM
100      */
101     @Component
102     protected MavenProject project;
103 
104     /**
105      * Contains the full list of projects in the reactor.
106      */
107     @Parameter( defaultValue = "${reactorProjects}" )
108     protected List<MavenProject> reactorProjects;
109 
110     /**
111      * If the plugin should be silent.
112      *
113      * @since 2.0
114      */
115     @Parameter( property = "silent", defaultValue = "false" )
116     public boolean silent;
117 
118     /**
119      * Output absolute filename for resolved artifacts
120      *
121      * @since 2.0
122      */
123     @Parameter( property = "outputAbsoluteArtifactFilename", defaultValue = "false" )
124     protected boolean outputAbsoluteArtifactFilename;
125 
126     private Log log;
127 
128     /**
129      * @return Returns the log.
130      */
131     public Log getLog()
132     {
133         if ( log == null )
134         {
135             if ( silent )
136             {
137                 log = new DependencySilentLog();
138             }
139             else
140             {
141                 log = super.getLog();
142             }
143         }
144 
145         return this.log;
146     }
147 
148     /**
149      * @return Returns the archiverManager.
150      */
151     public ArchiverManager getArchiverManager()
152     {
153         return this.archiverManager;
154     }
155 
156     /**
157      * Does the actual copy of the file and logging.
158      *
159      * @param artifact represents the file to copy.
160      * @param destFile file name of destination file.
161      * @throws MojoExecutionException with a message if an
162      *                                error occurs.
163      */
164     protected void copyFile( File artifact, File destFile )
165         throws MojoExecutionException
166     {
167         Log theLog = this.getLog();
168         try
169         {
170             theLog.info(
171                 "Copying " + ( this.outputAbsoluteArtifactFilename ? artifact.getAbsolutePath() : artifact.getName() )
172                     + " to " + destFile );
173 
174             if ( artifact.isDirectory() )
175             {
176                 // usual case is a future jar packaging, but there are special cases: classifier and other packaging
177                 throw new MojoExecutionException( "Artifact has not been packaged yet. When used on reactor artifact, "
178                     + "copy should be executed after packaging: see MDEP-187." );
179             }
180 
181             FileUtils.copyFile( artifact, destFile );
182         }
183         catch ( IOException e )
184         {
185             throw new MojoExecutionException( "Error copying artifact from " + artifact + " to " + destFile, e );
186         }
187     }
188 
189     protected void unpack( File file, File location )
190         throws MojoExecutionException
191     {
192         unpack( file, location, null, null );
193     }
194 
195     /**
196      * Unpacks the archive file.
197      *
198      * @param file     File to be unpacked.
199      * @param location Location where to put the unpacked files.
200      * @param includes Comma separated list of file patterns to include i.e. <code>**&#47;.xml,
201      *                 **&#47;*.properties</code>
202      * @param excludes Comma separated list of file patterns to exclude i.e. <code>**&#47;*.xml,
203      *                 **&#47;*.properties</code>
204      */
205     protected void unpack( File file, File location, String includes, String excludes )
206         throws MojoExecutionException
207     {
208         try
209         {
210             logUnpack( file, location, includes, excludes );
211 
212             location.mkdirs();
213 
214             if ( file.isDirectory() )
215             {
216                 // usual case is a future jar packaging, but there are special cases: classifier and other packaging
217                 throw new MojoExecutionException( "Artifact has not been packaged yet. When used on reactor artifact, "
218                     + "unpack should be executed after packaging: see MDEP-98." );
219             }
220 
221             UnArchiver unArchiver;
222 
223             unArchiver = archiverManager.getUnArchiver( file );
224 
225             unArchiver.setSourceFile( file );
226 
227             unArchiver.setDestDirectory( location );
228 
229             if ( StringUtils.isNotEmpty( excludes ) || StringUtils.isNotEmpty( includes ) )
230             {
231                 // Create the selectors that will filter
232                 // based on include/exclude parameters
233                 // MDEP-47
234                 IncludeExcludeFileSelector[] selectors =
235                     new IncludeExcludeFileSelector[]{ new IncludeExcludeFileSelector() };
236 
237                 if ( StringUtils.isNotEmpty( excludes ) )
238                 {
239                     selectors[0].setExcludes( excludes.split( "," ) );
240                 }
241 
242                 if ( StringUtils.isNotEmpty( includes ) )
243                 {
244                     selectors[0].setIncludes( includes.split( "," ) );
245                 }
246 
247                 unArchiver.setFileSelectors( selectors );
248             }
249             if ( this.silent )
250             {
251                 silenceUnarchiver( unArchiver );
252             }
253 
254             unArchiver.extract();
255         }
256         catch ( NoSuchArchiverException e )
257         {
258             throw new MojoExecutionException( "Unknown archiver type", e );
259         }
260         catch ( ArchiverException e )
261         {
262             throw new MojoExecutionException(
263                 "Error unpacking file: " + file + " to: " + location + "\r\n" + e.toString(), e );
264         }
265     }
266 
267     private void silenceUnarchiver( UnArchiver unArchiver )
268     {
269         // dangerous but handle any errors. It's the only way to silence the unArchiver.
270         try
271         {
272             Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( "logger", unArchiver.getClass() );
273 
274             field.setAccessible( true );
275 
276             field.set( unArchiver, this.getLog() );
277         }
278         catch ( Exception e )
279         {
280             // was a nice try. Don't bother logging because the log is silent.
281         }
282     }
283 
284     /**
285      * @return Returns the factory.
286      */
287     public ArtifactFactory getFactory()
288     {
289         return this.factory;
290     }
291 
292     /**
293      * @param factory The factory to set.
294      */
295     public void setFactory( ArtifactFactory factory )
296     {
297         this.factory = factory;
298     }
299 
300     /**
301      * @return Returns the project.
302      */
303     public MavenProject getProject()
304     {
305         return this.project;
306     }
307 
308     /**
309      * @return Returns the local.
310      */
311     protected ArtifactRepository getLocal()
312     {
313         return this.local;
314     }
315 
316     /**
317      * @param local The local to set.
318      */
319     public void setLocal( ArtifactRepository local )
320     {
321         this.local = local;
322     }
323 
324     /**
325      * @return Returns the remoteRepos.
326      */
327     public List<ArtifactRepository> getRemoteRepos()
328     {
329         return this.remoteRepos;
330     }
331 
332     /**
333      * @param remoteRepos The remoteRepos to set.
334      */
335     public void setRemoteRepos( List<ArtifactRepository> remoteRepos )
336     {
337         this.remoteRepos = remoteRepos;
338     }
339 
340     /**
341      * @return Returns the resolver.
342      */
343     public org.apache.maven.artifact.resolver.ArtifactResolver getResolver()
344     {
345         return this.resolver;
346     }
347 
348     /**
349      * @param resolver The resolver to set.
350      */
351     public void setResolver( ArtifactResolver resolver )
352     {
353         this.resolver = resolver;
354     }
355 
356     /**
357      * @param archiverManager The archiverManager to set.
358      */
359     public void setArchiverManager( ArchiverManager archiverManager )
360     {
361         this.archiverManager = archiverManager;
362     }
363 
364     /**
365      * @return Returns the artifactCollector.
366      */
367     public ArtifactCollector getArtifactCollector()
368     {
369         return this.artifactCollector;
370     }
371 
372     /**
373      * @param theArtifactCollector The artifactCollector to set.
374      */
375     public void setArtifactCollector( ArtifactCollector theArtifactCollector )
376     {
377         this.artifactCollector = theArtifactCollector;
378     }
379 
380     /**
381      * @return Returns the artifactMetadataSource.
382      */
383     public ArtifactMetadataSource getArtifactMetadataSource()
384     {
385         return this.artifactMetadataSource;
386     }
387 
388     /**
389      * @param theArtifactMetadataSource The artifactMetadataSource to set.
390      */
391     public void setArtifactMetadataSource( ArtifactMetadataSource theArtifactMetadataSource )
392     {
393         this.artifactMetadataSource = theArtifactMetadataSource;
394     }
395 
396     private void logUnpack( File file, File location, String includes, String excludes )
397     {
398         if ( !getLog().isInfoEnabled() )
399         {
400             return;
401         }
402 
403         StringBuffer msg = new StringBuffer();
404         msg.append( "Unpacking " );
405         msg.append( file );
406         msg.append( " to " );
407         msg.append( location );
408 
409         if ( includes != null && excludes != null )
410         {
411             msg.append( " with includes \"" );
412             msg.append( includes );
413             msg.append( "\" and excludes \"" );
414             msg.append( excludes );
415             msg.append( "\"" );
416         }
417         else if ( includes != null )
418         {
419             msg.append( " with includes \"" );
420             msg.append( includes );
421             msg.append( "\"" );
422         }
423         else if ( excludes != null )
424         {
425             msg.append( " with excludes \"" );
426             msg.append( excludes );
427             msg.append( "\"" );
428         }
429 
430         getLog().info( msg.toString() );
431     }
432 }