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 1400737 2012-10-21 22:53:48Z 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 = "" )
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     /**
208      * Return an {@link ArtifactsFilter} indicating which artifacts must be filtered out.
209      * 
210      * @return an {@link ArtifactsFilter} indicating which artifacts must be filtered out.
211      */
212     protected abstract ArtifactsFilter getMarkedArtifactFilter();
213 
214     /**
215      * Retrieves dependencies, either direct only or all including transitive.
216      *
217      * @return A HashSet of artifacts
218      * @throws MojoExecutionException
219      */
220     protected Set<Artifact> getResolvedDependencies( boolean stopOnFailure )
221         throws MojoExecutionException
222 
223     {
224         DependencyStatusSets status = getDependencySets( stopOnFailure );
225 
226         return status.getResolvedDependencies();
227     }
228 
229     /**
230      * Method creates filters and filters the projects dependencies. This method
231      * also transforms the dependencies if classifier is set. The dependencies
232      * are filtered in least specific to most specific order
233      *
234      * @param stopOnFailure
235      * @return DependencyStatusSets - Bean of TreeSets that contains information
236      *         on the projects dependencies
237      * @throws MojoExecutionException
238      */
239     protected DependencyStatusSets getDependencySets( boolean stopOnFailure )
240         throws MojoExecutionException
241     {
242         // add filters in well known order, least specific to most specific
243         FilterArtifacts filter = new FilterArtifacts();
244 
245         filter.addFilter( new ProjectTransitivityFilter( project.getDependencyArtifacts(), this.excludeTransitive ) );
246 
247         filter.addFilter( new ScopeFilter( DependencyUtil.cleanToBeTokenizedString( this.includeScope ),
248                                            DependencyUtil.cleanToBeTokenizedString( this.excludeScope ) ) );
249 
250         filter.addFilter( new TypeFilter( DependencyUtil.cleanToBeTokenizedString( this.includeTypes ),
251                                           DependencyUtil.cleanToBeTokenizedString( this.excludeTypes ) ) );
252 
253         filter.addFilter( new ClassifierFilter( DependencyUtil.cleanToBeTokenizedString( this.includeClassifiers ),
254                                                 DependencyUtil.cleanToBeTokenizedString( this.excludeClassifiers ) ) );
255 
256         filter.addFilter( new GroupIdFilter( DependencyUtil.cleanToBeTokenizedString( this.includeGroupIds ),
257                                              DependencyUtil.cleanToBeTokenizedString( this.excludeGroupIds ) ) );
258 
259         filter.addFilter( new ArtifactIdFilter( DependencyUtil.cleanToBeTokenizedString( this.includeArtifactIds ),
260                                                 DependencyUtil.cleanToBeTokenizedString( this.excludeArtifactIds ) ) );
261 
262         // start with all artifacts.
263         @SuppressWarnings( "unchecked" ) Set<Artifact> artifacts = project.getArtifacts();
264 
265         // perform filtering
266         try
267         {
268             artifacts = filter.filter( artifacts );
269         }
270         catch ( ArtifactFilterException e )
271         {
272             throw new MojoExecutionException( e.getMessage(), e );
273         }
274 
275         // transform artifacts if classifier is set
276         DependencyStatusSets status = null;
277         if ( StringUtils.isNotEmpty( classifier ) )
278         {
279             status = getClassifierTranslatedDependencies( artifacts, stopOnFailure );
280         }
281         else
282         {
283             status = filterMarkedDependencies( artifacts );
284         }
285 
286         return status;
287     }
288 
289     /**
290      * Transform artifacts
291      *
292      * @param artifacts
293      * @param stopOnFailure
294      * @return DependencyStatusSets - Bean of TreeSets that contains information
295      *         on the projects dependencies
296      * @throws MojoExecutionException
297      */
298     protected DependencyStatusSets getClassifierTranslatedDependencies( Set<Artifact> artifacts, boolean stopOnFailure )
299         throws MojoExecutionException
300     {
301         Set<Artifact> unResolvedArtifacts = new HashSet<Artifact>();
302         Set<Artifact> resolvedArtifacts = artifacts;
303         DependencyStatusSets status = new DependencyStatusSets();
304 
305         // possibly translate artifacts into a new set of artifacts based on the
306         // classifier and type
307         // if this did something, we need to resolve the new artifacts
308         if ( StringUtils.isNotEmpty( classifier ) )
309         {
310             ArtifactTranslator translator = new ClassifierTypeTranslator( this.classifier, this.type, this.factory );
311             artifacts = translator.translate( artifacts, getLog() );
312 
313             status = filterMarkedDependencies( artifacts );
314 
315             // the unskipped artifacts are in the resolved set.
316             artifacts = status.getResolvedDependencies();
317 
318             // resolve the rest of the artifacts
319             ArtifactsResolver artifactsResolver =
320                 new DefaultArtifactsResolver( this.resolver, this.getLocal(), this.remoteRepos, stopOnFailure );
321             resolvedArtifacts = artifactsResolver.resolve( artifacts, getLog() );
322 
323             // calculate the artifacts not resolved.
324             unResolvedArtifacts.addAll( artifacts );
325             unResolvedArtifacts.removeAll( resolvedArtifacts );
326         }
327 
328         // return a bean of all 3 sets.
329         status.setResolvedDependencies( resolvedArtifacts );
330         status.setUnResolvedDependencies( unResolvedArtifacts );
331 
332         return status;
333     }
334 
335     /**
336      * Filter the marked dependencies
337      *
338      * @param artifacts
339      * @return
340      * @throws MojoExecutionException
341      */
342     protected DependencyStatusSets filterMarkedDependencies( Set<Artifact> artifacts )
343         throws MojoExecutionException
344     {
345         // remove files that have markers already
346         FilterArtifacts filter = new FilterArtifacts();
347         filter.clearFilters();
348         filter.addFilter( getMarkedArtifactFilter() );
349 
350         Set<Artifact> unMarkedArtifacts;
351         try
352         {
353             unMarkedArtifacts = filter.filter( artifacts );
354         }
355         catch ( ArtifactFilterException e )
356         {
357             throw new MojoExecutionException( e.getMessage(), e );
358         }
359 
360         // calculate the skipped artifacts
361         Set<Artifact> skippedArtifacts = new HashSet<Artifact>();
362         skippedArtifacts.addAll( artifacts );
363         skippedArtifacts.removeAll( unMarkedArtifacts );
364 
365         return new DependencyStatusSets( unMarkedArtifacts, null, skippedArtifacts );
366     }
367 
368     /**
369      * @return Returns the markersDirectory.
370      */
371     public File getMarkersDirectory()
372     {
373         return this.markersDirectory;
374     }
375 
376     /**
377      * @param theMarkersDirectory The markersDirectory to set.
378      */
379     public void setMarkersDirectory( File theMarkersDirectory )
380     {
381         this.markersDirectory = theMarkersDirectory;
382     }
383 
384     // TODO: Set marker files.
385 
386     /**
387      * @return true, if the groupId should be prepended to the filename.
388      */
389     public boolean isPrependGroupId()
390     {
391         return prependGroupId;
392     }
393 
394     /**
395      * @param prependGroupId -
396      *                       true if the groupId must be prepended during the copy.
397      */
398     public void setPrependGroupId( boolean prependGroupId )
399     {
400         this.prependGroupId = prependGroupId;
401     }
402 }