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.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.model.Dependency;
31 import org.apache.maven.model.DependencyManagement;
32 import org.apache.maven.model.Exclusion;
33 import org.apache.maven.plugin.AbstractMojo;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.MojoFailureException;
36 import org.apache.maven.project.MavenProject;
37 import org.codehaus.plexus.util.StringUtils;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class AnalyzeDepMgt
56 extends AbstractMojo
57 {
58
59
60
61
62
63
64
65
66
67 private MavenProject project;
68
69
70
71
72
73
74 private boolean failBuild = false;
75
76
77
78
79
80
81 private boolean ignoreDirect = true;
82
83
84
85
86
87
88 public void execute()
89 throws MojoExecutionException, MojoFailureException
90 {
91 boolean result = checkDependencyManagement();
92 if ( result )
93 {
94 if ( this.failBuild )
95
96 {
97 throw new MojoExecutionException( "Found Dependency errors." );
98 }
99 else
100 {
101 getLog().warn( "Potential problems found in Dependency Management " );
102 }
103 }
104 }
105
106
107
108
109
110
111 private boolean checkDependencyManagement()
112 throws MojoExecutionException
113 {
114 boolean foundError = false;
115
116 getLog().info( "Found Resolved Dependency / DependencyManagement mismatches:" );
117
118 List<Dependency> depMgtDependencies = null;
119
120 DependencyManagement depMgt = project.getDependencyManagement();
121 if ( depMgt != null )
122 {
123 depMgtDependencies = depMgt.getDependencies();
124 }
125
126 if ( depMgtDependencies != null && !depMgtDependencies.isEmpty() )
127 {
128
129 Map<String, Dependency> depMgtMap = new HashMap<String, Dependency>();
130 Map<String, Exclusion> exclusions = new HashMap<String, Exclusion>();
131 for ( Dependency depMgtDependency : depMgtDependencies )
132 {
133 depMgtMap.put( depMgtDependency.getManagementKey(), depMgtDependency );
134
135
136 exclusions.putAll( addExclusions( depMgtDependency.getExclusions() ) );
137 }
138
139
140 Set<Artifact> allDependencyArtifacts = new HashSet<Artifact>( project.getArtifacts() );
141
142
143
144 if ( this.ignoreDirect )
145 {
146 getLog().info( "\tIgnoring Direct Dependencies." );
147 Set<Artifact> directDependencies = project.getDependencyArtifacts();
148 allDependencyArtifacts.removeAll( directDependencies );
149 }
150
151
152 List<Artifact> exclusionErrors = getExclusionErrors( exclusions, allDependencyArtifacts );
153 for ( Artifact exclusion : exclusionErrors )
154 {
155 getLog().info(
156 StringUtils.stripEnd( getArtifactManagementKey( exclusion ), ":" )
157 + " was excluded in DepMgt, but version " + exclusion.getVersion()
158 + " has been found in the dependency tree." );
159 foundError = true;
160 }
161
162
163 Map<Artifact, Dependency> mismatch = getMismatch( depMgtMap, allDependencyArtifacts );
164 for ( Map.Entry<Artifact, Dependency> entry : mismatch.entrySet() )
165 {
166 logMismatch( entry.getKey(), entry.getValue() );
167 foundError = true;
168 }
169 if ( !foundError )
170 {
171 getLog().info( " None" );
172 }
173 }
174 else
175 {
176 getLog().info( " Nothing in DepMgt." );
177 }
178
179
180
181 return foundError;
182 }
183
184
185
186
187
188
189
190
191
192
193 public Map<String, Exclusion> addExclusions( List<Exclusion> exclusionList )
194 {
195 Map<String, Exclusion> exclusions = new HashMap<String, Exclusion>();
196 if ( exclusionList != null )
197 {
198 for ( Exclusion exclusion : exclusionList )
199 {
200 exclusions.put( getExclusionKey( exclusion ), exclusion );
201 }
202 }
203 return exclusions;
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217 public List<Artifact> getExclusionErrors( Map<String, Exclusion> exclusions, Set<Artifact> allDependencyArtifacts )
218 {
219 List<Artifact> list = new ArrayList<Artifact>();
220
221 for ( Artifact artifact : allDependencyArtifacts )
222 {
223 if ( exclusions.containsKey( getExclusionKey( artifact ) ) )
224 {
225 list.add( artifact );
226 }
227 }
228
229 return list;
230 }
231
232 public String getExclusionKey( Artifact artifact )
233 {
234 return artifact.getGroupId() + ":" + artifact.getArtifactId();
235 }
236
237 public String getExclusionKey( Exclusion ex )
238 {
239 return ex.getGroupId() + ":" + ex.getArtifactId();
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254 public Map<Artifact, Dependency> getMismatch( Map<String, Dependency> depMgtMap,
255 Set<Artifact> allDependencyArtifacts )
256 {
257 Map<Artifact, Dependency> mismatchMap = new HashMap<Artifact, Dependency>();
258
259 for ( Artifact dependencyArtifact : allDependencyArtifacts )
260 {
261 Dependency depFromDepMgt = depMgtMap.get( getArtifactManagementKey( dependencyArtifact ) );
262 if ( depFromDepMgt != null )
263 {
264
265 dependencyArtifact.isSnapshot();
266
267 if (!depFromDepMgt.getVersion().equals( dependencyArtifact.getBaseVersion()) )
268 {
269 mismatchMap.put( dependencyArtifact, depFromDepMgt );
270 }
271 }
272 }
273 return mismatchMap;
274 }
275
276
277
278
279
280
281
282
283
284
285
286 public void logMismatch( Artifact dependencyArtifact, Dependency dependencyFromDepMgt )
287 throws MojoExecutionException
288 {
289 if ( dependencyArtifact == null || dependencyFromDepMgt == null )
290 {
291 throw new MojoExecutionException( "Invalid params: Artifact:" + dependencyArtifact + " Dependency:"
292 + dependencyFromDepMgt );
293 }
294
295 getLog().info( "\tDependency: " + StringUtils.stripEnd(dependencyFromDepMgt.getManagementKey(),":") );
296 getLog().info( "\t\tDepMgt : " + dependencyFromDepMgt.getVersion() );
297 getLog().info( "\t\tResolved: " + dependencyArtifact.getBaseVersion() );
298 }
299
300
301
302
303
304
305
306
307 public String getArtifactManagementKey( Artifact artifact )
308 {
309 return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getType()
310 + ( ( artifact.getClassifier() != null ) ? ":" + artifact.getClassifier() : "" );
311 }
312
313
314
315
316 public boolean isFailBuild()
317 {
318 return this.failBuild;
319 }
320
321
322
323
324
325 public void setFailBuild( boolean theFailBuild )
326 {
327 this.failBuild = theFailBuild;
328 }
329
330
331
332
333 public MavenProject getProject()
334 {
335 return this.project;
336 }
337
338
339
340
341
342 public void setProject( MavenProject theProject )
343 {
344 this.project = theProject;
345 }
346
347
348
349
350 public boolean isIgnoreDirect()
351 {
352 return this.ignoreDirect;
353 }
354
355
356
357
358
359 public void setIgnoreDirect( boolean theIgnoreDirect )
360 {
361 this.ignoreDirect = theIgnoreDirect;
362 }
363 }