1 package org.apache.maven.report.projectinfo.dependencies.renderer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Map;
28
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.artifact.factory.ArtifactFactory;
31 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
32 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
33 import org.apache.maven.artifact.repository.ArtifactRepository;
34 import org.apache.maven.artifact.versioning.ArtifactVersion;
35 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
36 import org.apache.maven.artifact.versioning.VersionRange;
37 import org.apache.maven.doxia.sink.Sink;
38 import org.apache.maven.model.Dependency;
39 import org.apache.maven.model.License;
40 import org.apache.maven.plugin.logging.Log;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.maven.project.MavenProjectBuilder;
43 import org.apache.maven.project.ProjectBuildingException;
44 import org.apache.maven.report.projectinfo.AbstractProjectInfoRenderer;
45 import org.apache.maven.report.projectinfo.ProjectInfoReportUtils;
46 import org.apache.maven.report.projectinfo.dependencies.ManagementDependencies;
47 import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
48 import org.codehaus.plexus.i18n.I18N;
49 import org.codehaus.plexus.util.StringUtils;
50
51
52
53
54
55
56 public class DependencyManagementRenderer
57 extends AbstractProjectInfoRenderer
58 {
59 private final ManagementDependencies dependencies;
60
61 private final Log log;
62
63 private final ArtifactMetadataSource artifactMetadataSource;
64
65 private final ArtifactFactory artifactFactory;
66
67 private final MavenProjectBuilder mavenProjectBuilder;
68
69 private final List<ArtifactRepository> remoteRepositories;
70
71 private final ArtifactRepository localRepository;
72
73 private final RepositoryUtils repoUtils;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public DependencyManagementRenderer( Sink sink, Locale locale, I18N i18n, Log log,
90 ManagementDependencies dependencies,
91 ArtifactMetadataSource artifactMetadataSource,
92 ArtifactFactory artifactFactory, MavenProjectBuilder mavenProjectBuilder,
93 List<ArtifactRepository> remoteRepositories,
94 ArtifactRepository localRepository, RepositoryUtils repoUtils )
95 {
96 super( sink, i18n, locale );
97
98 this.log = log;
99 this.dependencies = dependencies;
100 this.artifactMetadataSource = artifactMetadataSource;
101 this.artifactFactory = artifactFactory;
102 this.mavenProjectBuilder = mavenProjectBuilder;
103 this.remoteRepositories = remoteRepositories;
104 this.localRepository = localRepository;
105 this.repoUtils = repoUtils;
106 }
107
108
109
110
111
112 @Override
113 protected String getI18Nsection()
114 {
115 return "dependencyManagement";
116 }
117
118 @Override
119 public void renderBody()
120 {
121
122
123 if ( !dependencies.hasDependencies() )
124 {
125 startSection( getTitle() );
126
127 paragraph( getI18nString( "nolist" ) );
128
129 endSection();
130
131 return;
132 }
133
134
135 renderSectionProjectDependencies();
136 }
137
138
139
140
141
142 private void renderSectionProjectDependencies()
143 {
144 startSection( getTitle() );
145
146
147 Map<String, List<Dependency>> dependenciesByScope = dependencies.getManagementDependenciesByScope();
148
149 renderDependenciesForAllScopes( dependenciesByScope );
150
151 endSection();
152 }
153
154 private void renderDependenciesForAllScopes( Map<String, List<Dependency>> dependenciesByScope )
155 {
156 renderDependenciesForScope( Artifact.SCOPE_COMPILE, dependenciesByScope.get( Artifact.SCOPE_COMPILE ) );
157 renderDependenciesForScope( Artifact.SCOPE_RUNTIME, dependenciesByScope.get( Artifact.SCOPE_RUNTIME ) );
158 renderDependenciesForScope( Artifact.SCOPE_TEST, dependenciesByScope.get( Artifact.SCOPE_TEST ) );
159 renderDependenciesForScope( Artifact.SCOPE_PROVIDED, dependenciesByScope.get( Artifact.SCOPE_PROVIDED ) );
160 renderDependenciesForScope( Artifact.SCOPE_SYSTEM, dependenciesByScope.get( Artifact.SCOPE_SYSTEM ) );
161 }
162
163 private String[] getDependencyTableHeader( boolean hasClassifier )
164 {
165 String groupId = getI18nString( "column.groupId" );
166 String artifactId = getI18nString( "column.artifactId" );
167 String version = getI18nString( "column.version" );
168 String classifier = getI18nString( "column.classifier" );
169 String type = getI18nString( "column.type" );
170 String license = getI18nString( "column.license" );
171
172 if ( hasClassifier )
173 {
174 return new String[] { groupId, artifactId, version, classifier, type, license };
175 }
176
177 return new String[] { groupId, artifactId, version, type, license };
178 }
179
180 private void renderDependenciesForScope( String scope, List<Dependency> artifacts )
181 {
182 if ( artifacts != null )
183 {
184
185 Collections.sort( artifacts, getDependencyComparator() );
186
187 startSection( scope );
188
189 paragraph( getI18nString( "intro." + scope ) );
190 startTable();
191
192 boolean hasClassifier = false;
193 for ( Dependency dependency : artifacts )
194 {
195 if ( StringUtils.isNotEmpty( dependency.getClassifier() ) )
196 {
197 hasClassifier = true;
198 break;
199 }
200 }
201
202 String[] tableHeader = getDependencyTableHeader( hasClassifier );
203 tableHeader( tableHeader );
204
205 for ( Dependency dependency : artifacts )
206 {
207 tableRow( getDependencyRow( dependency, hasClassifier ) );
208 }
209 endTable();
210
211 endSection();
212 }
213 }
214
215 @SuppressWarnings( "unchecked" )
216 private String[] getDependencyRow( Dependency dependency, boolean hasClassifier )
217 {
218 Artifact artifact =
219 artifactFactory.createProjectArtifact( dependency.getGroupId(), dependency.getArtifactId(),
220 dependency.getVersion() );
221
222 StringBuilder licensesBuffer = new StringBuilder();
223 String url = null;
224 try
225 {
226 VersionRange range = VersionRange.createFromVersionSpec( dependency.getVersion() );
227
228 if ( range.getRecommendedVersion() == null )
229 {
230
231 log.debug( "Resolving range for DependencyManagement on " + artifact.getId() );
232
233 List<ArtifactVersion> versions =
234 artifactMetadataSource.retrieveAvailableVersions( artifact, localRepository, remoteRepositories );
235
236
237 for ( Iterator<ArtifactVersion> iter = versions.iterator(); iter.hasNext(); )
238 {
239 if ( ! range.containsVersion( iter.next() ) )
240 {
241 iter.remove();
242 }
243 }
244
245
246 if ( versions.size() > 0 )
247 {
248 Collections.sort( versions );
249
250 artifact.setVersion( versions.get( versions.size() - 1 ).toString() );
251 log.debug( "DependencyManagement resolved: " + artifact.getId() );
252 }
253 }
254
255 url =
256 ProjectInfoReportUtils.getArtifactUrl( artifactFactory, artifact, mavenProjectBuilder,
257 remoteRepositories, localRepository );
258
259 MavenProject artifactProject = repoUtils.getMavenProjectFromRepository( artifact );
260
261 List<License> licenses = artifactProject.getLicenses();
262 for ( License license : licenses )
263 {
264 String licenseCell = ProjectInfoReportUtils.getArtifactIdCell( license.getName(), license.getUrl() );
265 if ( licensesBuffer.length() > 0 )
266 {
267 licensesBuffer.append( ", " );
268 }
269 licensesBuffer.append( licenseCell );
270 }
271 }
272 catch ( InvalidVersionSpecificationException e )
273 {
274 log.warn( "Unable to parse version for " + artifact.getId(), e );
275 }
276 catch ( ArtifactMetadataRetrievalException e )
277 {
278 log.warn( "Unable to retrieve versions for " + artifact.getId() + " from repository.", e );
279 }
280 catch ( ProjectBuildingException e )
281 {
282 log.warn( "Unable to create Maven project for " + artifact.getId() + " from repository.", e );
283 }
284
285 String artifactIdCell = ProjectInfoReportUtils.getArtifactIdCell( artifact.getArtifactId(), url );
286
287 if ( hasClassifier )
288 {
289 return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
290 dependency.getClassifier(), dependency.getType(), licensesBuffer.toString() };
291 }
292
293 return new String[] { dependency.getGroupId(), artifactIdCell, dependency.getVersion(),
294 dependency.getType(), licensesBuffer.toString() };
295 }
296
297 private Comparator<Dependency> getDependencyComparator()
298 {
299 return new Comparator<Dependency>()
300 {
301 public int compare( Dependency a1, Dependency a2 )
302 {
303 int result = a1.getGroupId().compareTo( a2.getGroupId() );
304 if ( result != 0 )
305 {
306 return result;
307 }
308
309 result = a1.getArtifactId().compareTo( a2.getArtifactId() );
310 if ( result != 0 )
311 {
312 return result;
313 }
314
315 result = a1.getType().compareTo( a2.getType() );
316 if ( result != 0 )
317 {
318 return result;
319 }
320
321 if ( a1.getClassifier() == null )
322 {
323 if ( a2.getClassifier() != null )
324 {
325 return 1;
326 }
327 }
328 else
329 {
330 if ( a2.getClassifier() != null )
331 {
332 result = a1.getClassifier().compareTo( a2.getClassifier() );
333 }
334 else
335 {
336 return -1;
337 }
338 }
339
340 if ( result != 0 )
341 {
342 return result;
343 }
344
345
346 return a1.getVersion().compareTo( a2.getVersion() );
347 }
348 };
349 }
350 }