1 package org.apache.maven.shared.dependency.analyzer;
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.net.URL;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.LinkedHashMap;
29 import java.util.LinkedHashSet;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.project.MavenProject;
35
36
37
38
39
40
41
42
43 public class DefaultProjectDependencyAnalyzer
44 implements ProjectDependencyAnalyzer
45 {
46
47
48
49
50
51
52
53 private ClassAnalyzer classAnalyzer;
54
55
56
57
58
59
60 private DependencyAnalyzer dependencyAnalyzer;
61
62
63
64
65
66
67 public ProjectDependencyAnalysis analyze( MavenProject project )
68 throws ProjectDependencyAnalyzerException
69 {
70 try
71 {
72 Map artifactClassMap = buildArtifactClassMap( project );
73
74 Set dependencyClasses = buildDependencyClasses( project );
75
76 Set declaredArtifacts = buildDeclaredArtifacts( project );
77
78 Set usedArtifacts = buildUsedArtifacts( artifactClassMap, dependencyClasses );
79
80 Set usedDeclaredArtifacts = new LinkedHashSet( declaredArtifacts );
81 usedDeclaredArtifacts.retainAll( usedArtifacts );
82
83 Set usedUndeclaredArtifacts = new LinkedHashSet( usedArtifacts );
84 usedUndeclaredArtifacts = removeAll( usedUndeclaredArtifacts, declaredArtifacts );
85
86 Set unusedDeclaredArtifacts = new LinkedHashSet( declaredArtifacts );
87 unusedDeclaredArtifacts = removeAll( unusedDeclaredArtifacts, usedArtifacts );
88
89 return new ProjectDependencyAnalysis( usedDeclaredArtifacts, usedUndeclaredArtifacts,
90 unusedDeclaredArtifacts );
91 }
92 catch ( IOException exception )
93 {
94 throw new ProjectDependencyAnalyzerException( "Cannot analyze dependencies", exception );
95 }
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109 private Set removeAll( Set start, Set remove )
110 {
111 Set results = new LinkedHashSet( start.size() );
112 Iterator iter = start.iterator();
113 while ( iter.hasNext() )
114 {
115 Artifact artifact = (Artifact) iter.next();
116 Iterator iter2 = remove.iterator();
117 boolean found = false;
118 while ( iter2.hasNext() )
119 {
120 Artifact artifact2 = (Artifact) iter2.next();
121 if ( artifact.getDependencyConflictId().equals( artifact2.getDependencyConflictId() ) )
122 {
123 found = true;
124 }
125 }
126 if ( !found )
127 {
128 results.add( artifact );
129 }
130 }
131 return results;
132 }
133
134
135
136 private Map buildArtifactClassMap( MavenProject project )
137 throws IOException
138 {
139 Map artifactClassMap = new LinkedHashMap();
140
141 Set dependencyArtifacts = project.getArtifacts();
142
143 for ( Iterator iterator = dependencyArtifacts.iterator(); iterator.hasNext(); )
144 {
145 Artifact artifact = (Artifact) iterator.next();
146
147 File file = artifact.getFile();
148
149 if ( file != null && file.getName().endsWith( ".jar" ) )
150 {
151 URL url = file.toURL();
152
153 Set classes = classAnalyzer.analyze( url );
154
155 artifactClassMap.put( artifact, classes );
156 }
157 }
158
159 return artifactClassMap;
160 }
161
162 private Set buildDependencyClasses( MavenProject project )
163 throws IOException
164 {
165 Set dependencyClasses = new HashSet();
166
167 String outputDirectory = project.getBuild().getOutputDirectory();
168 dependencyClasses.addAll( buildDependencyClasses( outputDirectory ) );
169
170 String testOutputDirectory = project.getBuild().getTestOutputDirectory();
171 dependencyClasses.addAll( buildDependencyClasses( testOutputDirectory ) );
172
173 return dependencyClasses;
174 }
175
176 private Set buildDependencyClasses( String path )
177 throws IOException
178 {
179 URL url = new File( path ).toURI().toURL();
180
181 return dependencyAnalyzer.analyze( url );
182 }
183
184 private Set buildDeclaredArtifacts( MavenProject project )
185 {
186 Set declaredArtifacts = project.getDependencyArtifacts();
187
188 if ( declaredArtifacts == null )
189 {
190 declaredArtifacts = Collections.EMPTY_SET;
191 }
192
193 return declaredArtifacts;
194 }
195
196 private Set buildUsedArtifacts( Map artifactClassMap, Set dependencyClasses )
197 {
198 Set usedArtifacts = new HashSet();
199
200 for ( Iterator dependencyIterator = dependencyClasses.iterator(); dependencyIterator.hasNext(); )
201 {
202 String className = (String) dependencyIterator.next();
203
204 Artifact artifact = findArtifactForClassName( artifactClassMap, className );
205
206 if ( artifact != null )
207 {
208 usedArtifacts.add( artifact );
209 }
210 }
211
212 return usedArtifacts;
213 }
214
215 private Artifact findArtifactForClassName( Map artifactClassMap, String className )
216 {
217 for ( Iterator artifactIterator = artifactClassMap.keySet().iterator(); artifactIterator.hasNext(); )
218 {
219 Artifact artifact = (Artifact) artifactIterator.next();
220
221 Set artifactClassNames = (Set) artifactClassMap.get( artifact );
222
223 if ( artifactClassNames.contains( className ) )
224 {
225 return artifact;
226 }
227 }
228
229 return null;
230 }
231 }