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