Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Dependencies |
|
| 4.8;4,8 |
1 | package org.apache.maven.report.projectinfo.dependencies; | |
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 org.apache.maven.artifact.Artifact; | |
23 | import org.apache.maven.artifact.ArtifactUtils; | |
24 | import org.apache.maven.project.MavenProject; | |
25 | import org.apache.maven.shared.dependency.tree.DependencyNode; | |
26 | import org.apache.maven.shared.jar.JarAnalyzer; | |
27 | import org.apache.maven.shared.jar.JarData; | |
28 | import org.apache.maven.shared.jar.classes.JarClassesAnalysis; | |
29 | ||
30 | import java.io.IOException; | |
31 | import java.util.ArrayList; | |
32 | import java.util.HashMap; | |
33 | import java.util.Iterator; | |
34 | import java.util.List; | |
35 | import java.util.Map; | |
36 | ||
37 | /** | |
38 | * @version $Id: Dependencies.java 675813 2008-07-11 00:05:39Z vsiveton $ | |
39 | * @since 2.1 | |
40 | */ | |
41 | public class Dependencies | |
42 | { | |
43 | private final MavenProject project; | |
44 | ||
45 | private final DependencyNode dependencyTreeNode; | |
46 | ||
47 | private final JarClassesAnalysis classesAnalyzer; | |
48 | ||
49 | /** | |
50 | * @since 2.1 | |
51 | */ | |
52 | private List projectDependencies; | |
53 | ||
54 | /** | |
55 | * @since 2.1 | |
56 | */ | |
57 | private List projectTransitiveDependencies; | |
58 | ||
59 | /** | |
60 | * @since 2.1 | |
61 | */ | |
62 | private List allDependencies; | |
63 | ||
64 | /** | |
65 | * @since 2.1 | |
66 | */ | |
67 | private Map dependenciesByScope; | |
68 | ||
69 | /** | |
70 | * @since 2.1 | |
71 | */ | |
72 | private Map transitiveDependenciesByScope; | |
73 | ||
74 | /** | |
75 | * @since 2.1 | |
76 | */ | |
77 | private Map dependencyDetails; | |
78 | ||
79 | /** | |
80 | * Default constructor | |
81 | * | |
82 | * @param project | |
83 | * @param dependencyTreeNode | |
84 | * @param classesAnalyzer | |
85 | */ | |
86 | public Dependencies( MavenProject project, DependencyNode dependencyTreeNode, JarClassesAnalysis classesAnalyzer ) | |
87 | 1 | { |
88 | 1 | this.project = project; |
89 | 1 | this.dependencyTreeNode = dependencyTreeNode; |
90 | 1 | this.classesAnalyzer = classesAnalyzer; |
91 | ||
92 | /* | |
93 | * Workaround to ensure proper File objects in the Artifacts from the ReportResolutionListener | |
94 | */ | |
95 | 1 | Map projectMap = new HashMap(); |
96 | 1 | Iterator it = project.getArtifacts().iterator(); |
97 | 1 | while ( it.hasNext() ) |
98 | { | |
99 | 0 | Artifact artifact = (Artifact) it.next(); |
100 | 0 | projectMap.put( ArtifactUtils.versionlessKey( artifact ), artifact ); |
101 | 0 | } |
102 | ||
103 | 1 | mapArtifactFiles( dependencyTreeNode, projectMap ); |
104 | 1 | } |
105 | ||
106 | /** | |
107 | * Getter for the project | |
108 | * | |
109 | * @return the project | |
110 | */ | |
111 | public MavenProject getProject() | |
112 | { | |
113 | 0 | return project; |
114 | } | |
115 | ||
116 | /** | |
117 | * @return <code>true</code> if getProjectDependencies() is not empty, <code>false</code> otherwise. | |
118 | */ | |
119 | public boolean hasDependencies() | |
120 | { | |
121 | 1 | return ( getProjectDependencies() != null ) && ( !getProjectDependencies().isEmpty() ); |
122 | } | |
123 | ||
124 | /** | |
125 | * @return a list of <code>Artifact</code> from the project. | |
126 | */ | |
127 | public List getProjectDependencies() | |
128 | { | |
129 | 4 | if ( projectDependencies != null ) |
130 | { | |
131 | 3 | return projectDependencies; |
132 | } | |
133 | ||
134 | 1 | projectDependencies = new ArrayList(); |
135 | 1 | for ( Iterator i = dependencyTreeNode.getChildren().iterator(); i.hasNext(); ) |
136 | { | |
137 | 1 | DependencyNode dependencyNode = (DependencyNode) i.next(); |
138 | ||
139 | 1 | projectDependencies.add( dependencyNode.getArtifact() ); |
140 | 1 | } |
141 | ||
142 | 1 | return projectDependencies; |
143 | } | |
144 | ||
145 | /** | |
146 | * @return a list of transitive <code>Artifact</code> from the project. | |
147 | */ | |
148 | public List getTransitiveDependencies() | |
149 | { | |
150 | 1 | if ( projectTransitiveDependencies != null ) |
151 | { | |
152 | 0 | return projectTransitiveDependencies; |
153 | } | |
154 | ||
155 | 1 | projectTransitiveDependencies = new ArrayList( getAllDependencies() ); |
156 | 1 | projectTransitiveDependencies.removeAll( getProjectDependencies() ); |
157 | ||
158 | 1 | return projectTransitiveDependencies; |
159 | } | |
160 | ||
161 | /** | |
162 | * @return a list of included <code>Artifact</code> returned by the dependency tree. | |
163 | */ | |
164 | public List getAllDependencies() | |
165 | { | |
166 | 2 | if ( allDependencies != null ) |
167 | { | |
168 | 1 | return allDependencies; |
169 | } | |
170 | ||
171 | 1 | allDependencies = new ArrayList(); |
172 | 1 | for ( Iterator i = dependencyTreeNode.getChildren().iterator(); i.hasNext(); ) |
173 | { | |
174 | 1 | DependencyNode dependencyNode = (DependencyNode) i.next(); |
175 | ||
176 | 1 | if ( dependencyNode.getState() != DependencyNode.INCLUDED ) |
177 | { | |
178 | 0 | continue; |
179 | } | |
180 | ||
181 | 1 | if ( dependencyNode.getArtifact().getGroupId().equals( project.getGroupId() ) |
182 | && dependencyNode.getArtifact().getArtifactId().equals( project.getArtifactId() ) | |
183 | && dependencyNode.getArtifact().getVersion().equals( project.getVersion() ) ) | |
184 | { | |
185 | 0 | continue; |
186 | } | |
187 | ||
188 | 1 | if ( !allDependencies.contains( dependencyNode.getArtifact() ) ) |
189 | { | |
190 | 1 | allDependencies.add( dependencyNode.getArtifact() ); |
191 | } | |
192 | 1 | getAllDependencies( dependencyNode ); |
193 | 1 | } |
194 | ||
195 | 1 | return allDependencies; |
196 | } | |
197 | ||
198 | /** | |
199 | * @param isTransitively <code>true</code> to return transitive dependencies, <code>false</code> otherwise. | |
200 | * @return a map with supported scopes as key and a list of <code>Artifact</code> as values. | |
201 | * @see Artifact#SCOPE_COMPILE | |
202 | * @see Artifact#SCOPE_PROVIDED | |
203 | * @see Artifact#SCOPE_RUNTIME | |
204 | * @see Artifact#SCOPE_SYSTEM | |
205 | * @see Artifact#SCOPE_TEST | |
206 | */ | |
207 | public Map getDependenciesByScope( boolean isTransitively ) | |
208 | { | |
209 | 2 | if ( isTransitively ) |
210 | { | |
211 | 1 | if ( transitiveDependenciesByScope != null ) |
212 | { | |
213 | 0 | return transitiveDependenciesByScope; |
214 | } | |
215 | ||
216 | 1 | transitiveDependenciesByScope = new HashMap(); |
217 | 1 | for ( Iterator i = getTransitiveDependencies().iterator(); i.hasNext(); ) |
218 | { | |
219 | 0 | Artifact artifact = (Artifact) i.next(); |
220 | ||
221 | 0 | List multiValue = (List) transitiveDependenciesByScope.get( artifact.getScope() ); |
222 | 0 | if ( multiValue == null ) |
223 | { | |
224 | 0 | multiValue = new ArrayList(); |
225 | } | |
226 | ||
227 | 0 | if ( !multiValue.contains( artifact ) ) |
228 | { | |
229 | 0 | multiValue.add( artifact ); |
230 | } | |
231 | 0 | transitiveDependenciesByScope.put( artifact.getScope(), multiValue ); |
232 | 0 | } |
233 | ||
234 | 1 | return transitiveDependenciesByScope; |
235 | } | |
236 | ||
237 | 1 | if ( dependenciesByScope != null ) |
238 | { | |
239 | 0 | return dependenciesByScope; |
240 | } | |
241 | ||
242 | 1 | dependenciesByScope = new HashMap(); |
243 | 1 | for ( Iterator i = getProjectDependencies().iterator(); i.hasNext(); ) |
244 | { | |
245 | 1 | Artifact artifact = (Artifact) i.next(); |
246 | ||
247 | 1 | List multiValue = (List) dependenciesByScope.get( artifact.getScope() ); |
248 | 1 | if ( multiValue == null ) |
249 | { | |
250 | 1 | multiValue = new ArrayList(); |
251 | } | |
252 | ||
253 | 1 | if ( !multiValue.contains( artifact ) ) |
254 | { | |
255 | 1 | multiValue.add( artifact ); |
256 | } | |
257 | 1 | dependenciesByScope.put( artifact.getScope(), multiValue ); |
258 | 1 | } |
259 | ||
260 | 1 | return dependenciesByScope; |
261 | } | |
262 | ||
263 | /** | |
264 | * @param artifact | |
265 | * @return the jardata object from the artifact | |
266 | * @throws IOException if any | |
267 | */ | |
268 | public JarData getJarDependencyDetails( Artifact artifact ) | |
269 | throws IOException | |
270 | { | |
271 | 0 | if ( dependencyDetails == null ) |
272 | { | |
273 | 0 | dependencyDetails = new HashMap(); |
274 | } | |
275 | ||
276 | 0 | JarData old = (JarData) dependencyDetails.get( artifact.getId() ); |
277 | 0 | if ( dependencyDetails.get( artifact.getId() ) != null ) |
278 | { | |
279 | 0 | return old; |
280 | } | |
281 | ||
282 | 0 | JarAnalyzer jarAnalyzer = new JarAnalyzer( artifact.getFile() ); |
283 | try | |
284 | { | |
285 | 0 | classesAnalyzer.analyze( jarAnalyzer ); |
286 | } | |
287 | finally | |
288 | { | |
289 | 0 | jarAnalyzer.closeQuietly(); |
290 | 0 | } |
291 | ||
292 | 0 | dependencyDetails.put( artifact.getId(), jarAnalyzer.getJarData() ); |
293 | ||
294 | 0 | return jarAnalyzer.getJarData(); |
295 | } | |
296 | ||
297 | // ---------------------------------------------------------------------- | |
298 | // Private methods | |
299 | // ---------------------------------------------------------------------- | |
300 | ||
301 | private void mapArtifactFiles( DependencyNode node, Map projectMap ) | |
302 | { | |
303 | 2 | List childs = node.getChildren(); |
304 | 2 | if ( ( childs == null ) || childs.isEmpty() ) |
305 | { | |
306 | 1 | return; |
307 | } | |
308 | ||
309 | 1 | Iterator it = childs.iterator(); |
310 | 2 | while ( it.hasNext() ) |
311 | { | |
312 | 1 | DependencyNode anode = (DependencyNode) it.next(); |
313 | 1 | String key = ArtifactUtils.versionlessKey( anode.getArtifact() ); |
314 | 1 | Artifact projartifact = (Artifact) projectMap.get( key ); |
315 | 1 | if ( projartifact != null ) |
316 | { | |
317 | 0 | anode.getArtifact().setFile( projartifact.getFile() ); |
318 | } | |
319 | ||
320 | 1 | mapArtifactFiles( anode, projectMap ); |
321 | 1 | } |
322 | 1 | } |
323 | ||
324 | /** | |
325 | * Recursive method to get all dependencies from a given <code>dependencyNode</code> | |
326 | * | |
327 | * @param dependencyNode not null | |
328 | */ | |
329 | private void getAllDependencies( DependencyNode dependencyNode ) | |
330 | { | |
331 | 1 | if ( dependencyNode == null || dependencyNode.getChildren() == null ) |
332 | { | |
333 | 0 | if ( !allDependencies.contains( dependencyNode.getArtifact() ) ) |
334 | { | |
335 | 0 | allDependencies.add( dependencyNode.getArtifact() ); |
336 | } | |
337 | 0 | return; |
338 | } | |
339 | ||
340 | 1 | for ( Iterator i = dependencyNode.getChildren().iterator(); i.hasNext(); ) |
341 | { | |
342 | 0 | DependencyNode subdependencyNode = (DependencyNode) i.next(); |
343 | ||
344 | 0 | if ( subdependencyNode.getState() != DependencyNode.INCLUDED ) |
345 | { | |
346 | 0 | continue; |
347 | } | |
348 | ||
349 | 0 | if ( subdependencyNode.getArtifact().getGroupId().equals( project.getGroupId() ) |
350 | && subdependencyNode.getArtifact().getArtifactId().equals( project.getArtifactId() ) | |
351 | && subdependencyNode.getArtifact().getVersion().equals( project.getVersion() ) ) | |
352 | { | |
353 | 0 | continue; |
354 | } | |
355 | ||
356 | 0 | if ( !allDependencies.contains( subdependencyNode.getArtifact() ) ) |
357 | { | |
358 | 0 | allDependencies.add( subdependencyNode.getArtifact() ); |
359 | } | |
360 | 0 | getAllDependencies( subdependencyNode ); |
361 | 0 | } |
362 | 1 | } |
363 | } |