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