View Javadoc

1   package org.apache.maven.plugin.dependency;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
5    * agreements. See the NOTICE file distributed with this work for additional information regarding
6    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance with the License. You may obtain a
8    * copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software distributed under the License
13   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14   * or implied. See the License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  
18  import java.io.File;
19  import java.util.HashSet;
20  import java.util.Set;
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugin.dependency.utils.DependencyStatusSets;
25  import org.apache.maven.plugin.dependency.utils.DependencyUtil;
26  import org.apache.maven.plugin.dependency.utils.resolvers.ArtifactsResolver;
27  import org.apache.maven.plugin.dependency.utils.resolvers.DefaultArtifactsResolver;
28  import org.apache.maven.plugin.dependency.utils.translators.ArtifactTranslator;
29  import org.apache.maven.plugin.dependency.utils.translators.ClassifierTypeTranslator;
30  import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
31  import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
32  import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
33  import org.apache.maven.shared.artifact.filter.collection.ClassifierFilter;
34  import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
35  import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
36  import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter;
37  import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
38  import org.apache.maven.shared.artifact.filter.collection.TypeFilter;
39  import org.codehaus.plexus.util.StringUtils;
40  
41  /**
42   * Class that encapsulates the plugin parameters, and contains methods that
43   * handle dependency filtering
44   *
45   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
46   * @version $Id: AbstractDependencyFilterMojo.java 1085777 2011-03-26 18:13:19Z hboutemy $
47   * @see org.apache.maven.plugin.dependency.AbstractDependencyMojo
48   */
49  public abstract class AbstractDependencyFilterMojo
50      extends AbstractDependencyMojo
51  {
52      /**
53       * If we should exclude transitive dependencies
54       *
55       * @since 2.0
56       * @optional
57       * @parameter expression="${excludeTransitive}" default-value="false"
58       */
59      protected boolean excludeTransitive;
60  
61      /**
62       * Comma Separated list of Types to include. Empty String indicates include
63       * everything (default).
64       *
65       * @since 2.0
66       * @parameter expression="${includeTypes}" default-value=""
67       * @optional
68       */
69      protected String includeTypes;
70  
71      /**
72       * Comma Separated list of Types to exclude. Empty String indicates don't
73       * exclude anything (default).
74       *
75       * @since 2.0
76       * @parameter expression="${excludeTypes}" default-value=""
77       * @optional
78       */
79      protected String excludeTypes;
80  
81      /**
82       * Scope to include. An Empty string indicates all scopes (default).
83       *
84       * @since 2.0
85       * @parameter expression="${includeScope}" default-value=""
86       * @optional
87       */
88      protected String includeScope;
89  
90      /**
91       * Scope to exclude. An Empty string indicates no scopes (default).
92       *
93       * @since 2.0
94       * @parameter expression="${excludeScope}" default-value=""
95       * @optional
96       */
97      protected String excludeScope;
98  
99      /**
100      * Comma Separated list of Classifiers to include. Empty String indicates
101      * include everything (default).
102      *
103      * @since 2.0
104      * @parameter expression="${includeClassifiers}" default-value=""
105      * @optional
106      */
107     protected String includeClassifiers;
108 
109     /**
110      * Comma Separated list of Classifiers to exclude. Empty String indicates
111      * don't exclude anything (default).
112      *
113      * @since 2.0
114      * @parameter expression="${excludeClassifiers}" default-value=""
115      * @optional
116      */
117     protected String excludeClassifiers;
118 
119     /**
120      * Specify classifier to look for. Example: sources
121      *
122      * @optional
123      * @since 2.0
124      * @parameter expression="${classifier}" default-value=""
125      */
126     protected String classifier;
127 
128     /**
129      * Specify type to look for when constructing artifact based on classifier.
130      * Example: java-source,jar,war
131      *
132      * @optional
133      * @since 2.0
134      * @parameter expression="${type}" default-value="java-source"
135      */
136     protected String type;
137 
138     /**
139      * Comma separated list of Artifact names too exclude.
140      *
141      * @since 2.0
142      * @optional
143      * @parameter expression="${excludeArtifactIds}" default-value=""
144      */
145     protected String excludeArtifactIds;
146 
147     /**
148      * Comma separated list of Artifact names to include.
149      *
150      * @since 2.0
151      * @optional
152      * @parameter expression="${includeArtifactIds}" default-value=""
153      */
154     protected String includeArtifactIds;
155 
156     /**
157      * Comma separated list of GroupId Names to exclude.
158      *
159      * @since 2.0
160      * @optional
161      * @parameter expression="${excludeGroupIds}" default-value=""
162      */
163     protected String excludeGroupIds;
164 
165     /**
166      * Comma separated list of GroupIds to include.
167      *
168      * @since 2.0
169      * @optional
170      * @parameter expression="${includeGroupIds}" default-value=""
171      */
172     protected String includeGroupIds;
173 
174     /**
175      * Directory to store flag files
176      *
177      * @parameter expression="${markersDirectory}"
178      *            default-value="${project.build.directory}/dependency-maven-plugin-markers"
179      * @optional
180      * @since 2.0
181      */
182     protected File markersDirectory;
183 
184     /**
185      * Overwrite release artifacts
186      *
187      * @optional
188      * @since 1.0
189      * @parameter expression="${overWriteReleases}" default-value="false"
190      */
191     protected boolean overWriteReleases;
192 
193     /**
194      * Overwrite snapshot artifacts
195      *
196      * @optional
197      * @since 1.0
198      * @parameter expression="${overWriteSnapshots}" default-value="false"
199      */
200     protected boolean overWriteSnapshots;
201 
202     /**
203      * Overwrite artifacts that don't exist or are older than the source.
204      *
205      * @optional
206      * @since 2.0
207      * @parameter expression="${overWriteIfNewer}" default-value="true"
208      */
209     protected boolean overWriteIfNewer;
210     
211     /**
212      * Prepend the groupId during copy.
213      * 
214      * @optional
215      * @since 2.2
216      * @parameter expression="${mdep.prependGroupId}" default-value="false"
217      * @parameter
218      */
219     protected boolean prependGroupId = false;
220 
221     protected abstract ArtifactsFilter getMarkedArtifactFilter();
222 
223     /**
224      * Retrieves dependencies, either direct only or all including transitive.
225      *
226      * @return A HashSet of artifacts
227      * @throws MojoExecutionException
228      */
229     protected Set<Artifact> getResolvedDependencies( boolean stopOnFailure )
230         throws MojoExecutionException
231 
232     {
233         DependencyStatusSets status = getDependencySets( stopOnFailure );
234 
235         return status.getResolvedDependencies();
236     }
237 
238     /**
239      *
240      * Method creates filters and filters the projects dependencies. This method
241      * also transforms the dependencies if classifier is set. The dependencies
242      * are filtered in least specific to most specific order
243      *
244      * @param stopOnFailure
245      * @return DependencyStatusSets - Bean of TreeSets that contains information
246      *         on the projects dependencies
247      * @throws MojoExecutionException
248      */
249     protected DependencyStatusSets getDependencySets( boolean stopOnFailure )
250         throws MojoExecutionException
251     {
252         // add filters in well known order, least specific to most specific
253         FilterArtifacts filter = new FilterArtifacts();
254 
255         filter.addFilter( new ProjectTransitivityFilter( project.getDependencyArtifacts(), this.excludeTransitive ) );
256 
257         filter.addFilter( new ScopeFilter( DependencyUtil.cleanToBeTokenizedString( this.includeScope ),
258                                            DependencyUtil.cleanToBeTokenizedString( this.excludeScope ) ) );
259 
260         filter.addFilter( new TypeFilter( DependencyUtil.cleanToBeTokenizedString( this.includeTypes ),
261                                           DependencyUtil.cleanToBeTokenizedString( this.excludeTypes ) ) );
262 
263         filter.addFilter( new ClassifierFilter( DependencyUtil.cleanToBeTokenizedString( this.includeClassifiers ),
264                                                 DependencyUtil.cleanToBeTokenizedString( this.excludeClassifiers ) ) );
265 
266         filter.addFilter( new GroupIdFilter( DependencyUtil.cleanToBeTokenizedString( this.includeGroupIds ),
267                                              DependencyUtil.cleanToBeTokenizedString( this.excludeGroupIds ) ) );
268 
269         filter.addFilter( new ArtifactIdFilter( DependencyUtil.cleanToBeTokenizedString( this.includeArtifactIds ),
270                                                 DependencyUtil.cleanToBeTokenizedString( this.excludeArtifactIds ) ) );
271 
272         // start with all artifacts.
273         Set<Artifact> artifacts = project.getArtifacts();
274 
275         // perform filtering
276         try
277         {
278             artifacts = filter.filter( artifacts );
279         }
280         catch ( ArtifactFilterException e )
281         {
282             throw new MojoExecutionException( e.getMessage(), e );
283         }
284 
285         // transform artifacts if classifier is set
286         DependencyStatusSets status = null;
287         if ( StringUtils.isNotEmpty( classifier ) )
288         {
289             status = getClassifierTranslatedDependencies( artifacts, stopOnFailure );
290         }
291         else
292         {
293             status = filterMarkedDependencies( artifacts );
294         }
295 
296         return status;
297     }
298 
299     /**
300      *
301      * Transform artifacts
302      *
303      * @param artifacts
304      * @param stopOnFailure
305      * @return DependencyStatusSets - Bean of TreeSets that contains information
306      *         on the projects dependencies
307      * @throws MojoExecutionException
308      */
309     protected DependencyStatusSets getClassifierTranslatedDependencies( Set<Artifact> artifacts, boolean stopOnFailure )
310         throws MojoExecutionException
311     {
312         Set<Artifact> unResolvedArtifacts = new HashSet<Artifact>();
313         Set<Artifact> resolvedArtifacts = artifacts;
314         DependencyStatusSets status = new DependencyStatusSets();
315 
316         // possibly translate artifacts into a new set of artifacts based on the
317         // classifier and type
318         // if this did something, we need to resolve the new artifacts
319         if ( StringUtils.isNotEmpty( classifier ) )
320         {
321             ArtifactTranslator translator = new ClassifierTypeTranslator( this.classifier, this.type, this.factory );
322             artifacts = translator.translate( artifacts, getLog() );
323 
324             status = filterMarkedDependencies( artifacts );
325 
326             // the unskipped artifacts are in the resolved set.
327             artifacts = status.getResolvedDependencies();
328 
329             // resolve the rest of the artifacts
330             ArtifactsResolver artifactsResolver = new DefaultArtifactsResolver( this.resolver, this.getLocal(),
331                                                                                 this.remoteRepos, stopOnFailure );
332             resolvedArtifacts = artifactsResolver.resolve( artifacts, getLog() );
333 
334             // calculate the artifacts not resolved.
335             unResolvedArtifacts.addAll( artifacts );
336             unResolvedArtifacts.removeAll( resolvedArtifacts );
337         }
338 
339         // return a bean of all 3 sets.
340         status.setResolvedDependencies( resolvedArtifacts );
341         status.setUnResolvedDependencies( unResolvedArtifacts );
342 
343         return status;
344     }
345 
346     /**
347      * Filter the marked dependencies
348      *
349      * @param artifacts
350      * @return
351      * @throws MojoExecutionException
352      */
353     protected DependencyStatusSets filterMarkedDependencies( Set<Artifact> artifacts )
354         throws MojoExecutionException
355     {
356         // remove files that have markers already
357         FilterArtifacts filter = new FilterArtifacts();
358         filter.clearFilters();
359         filter.addFilter( getMarkedArtifactFilter() );
360 
361         Set<Artifact> unMarkedArtifacts;
362         try
363         {
364             unMarkedArtifacts = filter.filter( artifacts );
365         }
366         catch ( ArtifactFilterException e )
367         {
368             throw new MojoExecutionException( e.getMessage(), e );
369         }
370 
371         // calculate the skipped artifacts
372         Set<Artifact> skippedArtifacts = new HashSet<Artifact>();
373         skippedArtifacts.addAll( artifacts );
374         skippedArtifacts.removeAll( unMarkedArtifacts );
375 
376         return new DependencyStatusSets( unMarkedArtifacts, null, skippedArtifacts );
377     }
378 
379     /**
380      * @return Returns the markersDirectory.
381      */
382     public File getMarkersDirectory()
383     {
384         return this.markersDirectory;
385     }
386 
387     /**
388      * @param theMarkersDirectory
389      *            The markersDirectory to set.
390      */
391     public void setMarkersDirectory( File theMarkersDirectory )
392     {
393         this.markersDirectory = theMarkersDirectory;
394     }
395 
396     // TODO: Set marker files.
397 
398     /**
399      * @return true, if the groupId should be prepended to the filename. 
400      */
401     public boolean isPrependGroupId()
402     {
403         return prependGroupId;
404     }
405 
406     /**
407      * @param prependGroupId - 
408      *            true if the groupId must be prepended during the copy.
409      */
410     public void setPrependGroupId( boolean prependGroupId )
411     {
412         this.prependGroupId = prependGroupId;
413     }
414 }