1 package org.apache.maven.plugin.dependency;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.artifact.ArtifactUtils;
36 import org.apache.maven.artifact.factory.ArtifactFactory;
37 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
38 import org.apache.maven.artifact.repository.ArtifactRepository;
39 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
40 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
41 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
42 import org.apache.maven.artifact.resolver.ArtifactResolver;
43 import org.apache.maven.artifact.versioning.VersionRange;
44 import org.apache.maven.model.Dependency;
45 import org.apache.maven.plugin.AbstractMojo;
46 import org.apache.maven.plugin.MojoExecutionException;
47 import org.apache.maven.plugin.MojoFailureException;
48 import org.apache.maven.project.MavenProject;
49 import org.codehaus.plexus.util.FileUtils;
50
51
52
53
54
55
56
57
58
59
60
61
62 public class PurgeLocalRepositoryMojo
63 extends AbstractMojo
64 {
65
66 public static final String FILE_FUZZINESS = "file";
67
68 public static final String VERSION_FUZZINESS = "version";
69
70 public static final String ARTIFACT_ID_FUZZINESS = "artifactId";
71
72 public static final String GROUP_ID_FUZZINESS = "groupId";
73
74
75
76
77
78
79
80
81
82 private List projects;
83
84
85
86
87
88
89
90 private List excludes;
91
92
93
94
95
96
97
98
99
100 private String exclude;
101
102
103
104
105
106
107
108
109 private boolean reResolve;
110
111
112
113
114
115
116
117
118 private ArtifactRepository localRepository;
119
120
121
122
123
124
125
126 private ArtifactResolver resolver;
127
128
129
130
131
132
133 private ArtifactMetadataSource source;
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 private String resolutionFuzziness;
151
152
153
154
155
156
157
158 private boolean actTransitively;
159
160
161
162
163
164
165 private ArtifactFactory factory;
166
167
168
169
170
171
172 private boolean verbose;
173
174 public void execute()
175 throws MojoExecutionException, MojoFailureException
176 {
177 List exclusionPatterns = buildExclusionPatternsList();
178
179 for ( Iterator it = projects.iterator(); it.hasNext(); )
180 {
181 MavenProject project = (MavenProject) it.next();
182
183 try
184 {
185 refreshDependenciesForProject( project, exclusionPatterns );
186 }
187 catch ( ArtifactResolutionException e )
188 {
189 MojoFailureException failure = new MojoFailureException( this,
190 "Failed to refresh project dependencies for: "
191 + project.getId(),
192 "Artifact resolution failed for project: "
193 + project.getId() );
194 failure.initCause( e );
195
196 throw failure;
197 }
198 }
199 }
200
201 private List buildExclusionPatternsList()
202 {
203 List patterns = new ArrayList();
204
205 if ( exclude != null )
206 {
207 String[] elements = exclude.split( " ?, ?" );
208
209 patterns.addAll( Arrays.asList( elements ) );
210 }
211 else if ( excludes != null && !excludes.isEmpty() )
212 {
213 patterns.addAll( excludes );
214 }
215
216 return patterns;
217 }
218
219 private Map createArtifactMap( MavenProject project )
220 {
221 Map artifactMap = Collections.EMPTY_MAP;
222
223 List dependencies = project.getDependencies();
224
225 List remoteRepositories = Collections.EMPTY_LIST;
226
227 Set dependencyArtifacts = new HashSet();
228
229 for ( Iterator it = dependencies.iterator(); it.hasNext(); )
230 {
231 Dependency dependency = (Dependency) it.next();
232
233 VersionRange vr = VersionRange.createFromVersion( dependency.getVersion() );
234
235 Artifact artifact = factory.createDependencyArtifact( dependency.getGroupId(), dependency.getArtifactId(),
236 vr, dependency.getType(), dependency.getClassifier(),
237 dependency.getScope() );
238 dependencyArtifacts.add( artifact );
239 }
240
241 if ( actTransitively )
242 {
243 try
244 {
245 ArtifactResolutionResult result = resolver.resolveTransitively( dependencyArtifacts, project
246 .getArtifact(), remoteRepositories, localRepository, source );
247
248 artifactMap = ArtifactUtils.artifactMapByVersionlessId( result.getArtifacts() );
249 }
250 catch ( ArtifactResolutionException e )
251 {
252 verbose( "Skipping: " + e.getArtifactId() + ". It cannot be resolved." );
253 }
254 catch ( ArtifactNotFoundException e )
255 {
256 verbose( "Skipping: " + e.getArtifactId() + ". It cannot be resolved." );
257 }
258 }
259 else
260 {
261 artifactMap = new HashMap();
262 for ( Iterator it = dependencyArtifacts.iterator(); it.hasNext(); )
263 {
264 Artifact artifact = (Artifact) it.next();
265
266 try
267 {
268 resolver.resolve( artifact, remoteRepositories, localRepository );
269
270 artifactMap.put( ArtifactUtils.versionlessKey( artifact ), artifact );
271 }
272 catch ( ArtifactResolutionException e )
273 {
274 verbose( "Skipping: " + e.getArtifactId() + ". It cannot be resolved." );
275 }
276 catch ( ArtifactNotFoundException e )
277 {
278 verbose( "Skipping: " + e.getArtifactId() + ". It cannot be resolved." );
279 }
280 }
281 }
282
283 return artifactMap;
284 }
285
286 private void verbose( String message )
287 {
288 if ( verbose || getLog().isDebugEnabled() )
289 {
290 getLog().info( message );
291 }
292 }
293
294 private void refreshDependenciesForProject( MavenProject project, List exclusionPatterns )
295 throws ArtifactResolutionException, MojoFailureException
296 {
297 Map deps = createArtifactMap( project );
298
299 if ( deps.isEmpty() )
300 {
301 getLog().info( "Nothing to do for project: " + project.getId() );
302 return;
303 }
304
305 if ( !exclusionPatterns.isEmpty() )
306 {
307 for ( Iterator it = exclusionPatterns.iterator(); it.hasNext(); )
308 {
309 String excludedKey = (String) it.next();
310
311 verbose( "Excluding: " + excludedKey + " from refresh operation for project: " + project.getId() );
312
313 deps.remove( excludedKey );
314 }
315 }
316
317 verbose( "Processing dependencies for project: " + project.getId() );
318
319 List missingArtifacts = new ArrayList();
320 for ( Iterator it = deps.entrySet().iterator(); it.hasNext(); )
321 {
322 Map.Entry entry = (Map.Entry) it.next();
323
324 Artifact artifact = (Artifact) entry.getValue();
325
326 verbose( "Processing artifact: " + artifact.getId() );
327
328 File deleteTarget = findDeleteTarget( artifact );
329
330 verbose( "Deleting: " + deleteTarget );
331
332 if ( deleteTarget.isDirectory() )
333 {
334 try
335 {
336 FileUtils.deleteDirectory( deleteTarget );
337 }
338 catch ( IOException e )
339 {
340 throw new MojoFailureException( this, "Cannot delete dependency from the local repository: "
341 + artifact.getId(), "Failed to delete: " + deleteTarget );
342 }
343 }
344 else
345 {
346 deleteTarget.delete();
347 }
348
349 if ( reResolve )
350 {
351 verbose( "Re-resolving." );
352
353 artifact.setResolved( false );
354
355 try
356 {
357 resolver.resolveAlways( artifact, project.getRemoteArtifactRepositories(), localRepository );
358 }
359 catch ( ArtifactResolutionException e )
360 {
361 getLog().debug( e.getMessage() );
362 missingArtifacts.add( artifact );
363 }
364 catch ( ArtifactNotFoundException e )
365 {
366 getLog().debug( e.getMessage() );
367 missingArtifacts.add( artifact );
368 }
369 }
370 }
371
372 if ( missingArtifacts.size() > 0 )
373 {
374 String message = "required artifacts missing:\n";
375 for ( Iterator i = missingArtifacts.iterator(); i.hasNext(); )
376 {
377 Artifact missingArtifact = (Artifact) i.next();
378 message += " " + missingArtifact.getId() + "\n";
379 }
380 message += "\nfor the artifact:";
381
382 throw new ArtifactResolutionException( message, project.getArtifact(), project
383 .getRemoteArtifactRepositories() );
384 }
385
386 }
387
388 private File findDeleteTarget( Artifact artifact )
389 {
390 File deleteTarget = artifact.getFile();
391
392 if ( GROUP_ID_FUZZINESS.equals( resolutionFuzziness ) )
393 {
394
395 deleteTarget = deleteTarget.getParentFile().getParentFile();
396
397
398 deleteTarget = deleteTarget.getParentFile();
399
400 String[] path = localRepository.pathOf( artifact ).split( "\\/" );
401
402
403
404
405 int groupParts = path.length - 4;
406
407 File parent = deleteTarget.getParentFile();
408 int count = 0;
409 while ( count++ < groupParts )
410 {
411
412
413
414
415
416 if ( parent.list().length < 2 )
417 {
418 deleteTarget = parent;
419
420
421 parent = deleteTarget.getParentFile();
422 }
423 else
424 {
425
426
427 break;
428 }
429 }
430
431 }
432 else if ( ARTIFACT_ID_FUZZINESS.equals( resolutionFuzziness ) )
433 {
434
435 deleteTarget = deleteTarget.getParentFile().getParentFile();
436 }
437 else if ( VERSION_FUZZINESS.equals( resolutionFuzziness ) )
438 {
439
440 deleteTarget = deleteTarget.getParentFile();
441 }
442
443
444 return deleteTarget;
445 }
446
447 }