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.StringWriter;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.Set;
27
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.plugin.AbstractMojo;
30 import org.apache.maven.plugin.MojoExecutionException;
31 import org.apache.maven.plugin.MojoFailureException;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis;
34 import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzer;
35 import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzerException;
36 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
37
38
39
40
41
42
43
44
45
46 public abstract class AbstractAnalyzeMojo
47 extends AbstractMojo
48 {
49
50
51
52
53
54
55
56
57
58 private MavenProject project;
59
60
61
62
63
64
65
66
67 private ProjectDependencyAnalyzer analyzer;
68
69
70
71
72
73
74 private boolean failOnWarning;
75
76
77
78
79
80
81 private boolean verbose;
82
83
84
85
86
87
88 private boolean ignoreNonCompile;
89
90
91
92
93
94
95
96 private boolean outputXML;
97
98
99
100
101
102
103
104 private boolean scriptableOutput;
105
106
107
108
109
110
111
112 private String scriptableFlag;
113
114
115
116
117
118
119
120
121 private File baseDir;
122
123
124
125
126
127
128
129
130 private File outputDirectory;
131
132
133
134
135
136
137 public void execute()
138 throws MojoExecutionException, MojoFailureException
139 {
140 if ( "pom".equals( project.getPackaging() ) )
141 {
142 getLog().info( "Skipping pom project" );
143 return;
144 }
145
146 if ( outputDirectory == null || !outputDirectory.exists())
147 {
148 getLog().info( "Skipping project with no build directory" );
149 return;
150 }
151
152 boolean warning = checkDependencies();
153
154 if ( warning && failOnWarning )
155 {
156 throw new MojoExecutionException( "Dependency problems found" );
157 }
158 }
159
160
161
162 private boolean checkDependencies()
163 throws MojoExecutionException
164 {
165 ProjectDependencyAnalysis analysis;
166 try
167 {
168 analysis = analyzer.analyze( project );
169 }
170 catch ( ProjectDependencyAnalyzerException exception )
171 {
172 throw new MojoExecutionException( "Cannot analyze dependencies", exception );
173 }
174
175 Set usedDeclared = analysis.getUsedDeclaredArtifacts();
176 Set usedUndeclared = analysis.getUsedUndeclaredArtifacts();
177 Set unusedDeclared = analysis.getUnusedDeclaredArtifacts();
178
179 if ( ignoreNonCompile )
180 {
181 Set filteredUnusedDeclared = new HashSet( unusedDeclared );
182 Iterator iter = filteredUnusedDeclared.iterator();
183 while ( iter.hasNext() )
184 {
185 Artifact artifact = (Artifact) iter.next();
186 if ( !artifact.getScope().equals( Artifact.SCOPE_COMPILE ) )
187 {
188 iter.remove();
189 }
190 }
191 unusedDeclared = filteredUnusedDeclared;
192 }
193
194 if ( ( !verbose || usedDeclared.isEmpty() ) && usedUndeclared.isEmpty() && unusedDeclared.isEmpty() )
195 {
196 getLog().info( "No dependency problems found" );
197 return false;
198 }
199
200 if ( verbose && !usedDeclared.isEmpty() )
201 {
202 getLog().info( "Used declared dependencies found:" );
203
204 logArtifacts( analysis.getUsedDeclaredArtifacts(), false );
205 }
206
207 if ( !usedUndeclared.isEmpty() )
208 {
209 getLog().warn( "Used undeclared dependencies found:" );
210
211 logArtifacts( usedUndeclared, true );
212 }
213
214 if ( !unusedDeclared.isEmpty() )
215 {
216 getLog().warn( "Unused declared dependencies found:" );
217
218 logArtifacts( unusedDeclared, true );
219 }
220
221 if ( outputXML )
222 {
223 writeDependencyXML( usedUndeclared );
224 }
225
226 if ( scriptableOutput )
227 {
228 writeScriptableOutput( usedUndeclared );
229 }
230
231 return !usedUndeclared.isEmpty() || !unusedDeclared.isEmpty();
232 }
233
234 private void logArtifacts( Set artifacts, boolean warn )
235 {
236 if ( artifacts.isEmpty() )
237 {
238 getLog().info( " None" );
239 }
240 else
241 {
242 for ( Iterator iterator = artifacts.iterator(); iterator.hasNext(); )
243 {
244 Artifact artifact = (Artifact) iterator.next();
245
246
247 artifact.isSnapshot();
248
249 if ( warn )
250 {
251 getLog().warn( " " + artifact );
252 }
253 else
254 {
255 getLog().info( " " + artifact );
256 }
257
258 }
259 }
260 }
261
262 private void writeDependencyXML( Set artifacts )
263 {
264 if ( !artifacts.isEmpty() )
265 {
266 getLog().info( "Add the following to your pom to correct the missing dependencies: " );
267
268 StringWriter out = new StringWriter();
269 PrettyPrintXMLWriter writer = new PrettyPrintXMLWriter( out );
270
271 Iterator iter = artifacts.iterator();
272 while ( iter.hasNext() )
273 {
274 Artifact artifact = (Artifact) iter.next();
275
276
277 artifact.isSnapshot();
278
279 writer.startElement( "dependency" );
280 writer.startElement( "groupId" );
281 writer.writeText( artifact.getGroupId() );
282 writer.endElement();
283 writer.startElement( "artifactId" );
284 writer.writeText( artifact.getArtifactId() );
285 writer.endElement();
286 writer.startElement( "version" );
287 writer.writeText( artifact.getBaseVersion() );
288 writer.endElement();
289
290 if ( !Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
291 {
292 writer.startElement( "scope" );
293 writer.writeText( artifact.getScope() );
294 writer.endElement();
295 }
296 writer.endElement();
297 }
298
299 getLog().info( "\n" + out.getBuffer() );
300 }
301 }
302
303 private void writeScriptableOutput( Set artifacts )
304 {
305 if ( !artifacts.isEmpty() )
306 {
307 getLog().info( "Missing dependencies: " );
308 String pomFile = baseDir.getAbsolutePath() + File.separatorChar + "pom.xml";
309 StringBuffer buf = new StringBuffer();
310 Iterator iter = artifacts.iterator();
311 while ( iter.hasNext() )
312 {
313 Artifact artifact = (Artifact) iter.next();
314
315
316 artifact.isSnapshot();
317
318 buf.append( scriptableFlag + ":" + pomFile + ":" + artifact.getDependencyConflictId() + ":"
319 + artifact.getClassifier() + ":" + artifact.getBaseVersion() + ":"
320 + artifact.getScope() + "\n" );
321 }
322 getLog().info( "\n" + buf );
323 }
324 }
325 }