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