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;
20
21 import javax.inject.Inject;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.MalformedURLException;
26 import java.util.List;
27 import java.util.Locale;
28
29 import org.apache.maven.artifact.repository.ArtifactRepository;
30 import org.apache.maven.doxia.sink.Sink;
31 import org.apache.maven.doxia.tools.SiteTool;
32 import org.apache.maven.model.DistributionManagement;
33 import org.apache.maven.model.Site;
34 import org.apache.maven.plugin.logging.Log;
35 import org.apache.maven.plugins.annotations.Mojo;
36 import org.apache.maven.project.DefaultProjectBuildingRequest;
37 import org.apache.maven.project.MavenProject;
38 import org.apache.maven.project.ProjectBuilder;
39 import org.apache.maven.project.ProjectBuildingException;
40 import org.apache.maven.project.ProjectBuildingRequest;
41 import org.apache.maven.reporting.MavenReportException;
42 import org.apache.maven.repository.RepositorySystem;
43 import org.codehaus.plexus.i18n.I18N;
44
45
46
47
48
49
50
51 @Mojo(name = "modules")
52 public class ModulesReport extends AbstractProjectInfoReport {
53
54 @Inject
55 public ModulesReport(RepositorySystem repositorySystem, I18N i18n, ProjectBuilder projectBuilder) {
56 super(repositorySystem, i18n, projectBuilder);
57 }
58
59
60
61
62
63 @Override
64 public boolean canGenerateReport() throws MavenReportException {
65 boolean result = super.canGenerateReport();
66 if (result && skipEmptyReport) {
67 result = !isEmpty(getProject().getModel().getModules());
68 }
69
70 return result;
71 }
72
73 @Override
74 public void executeReport(Locale locale) {
75 new ModulesRenderer(
76 getSink(),
77 getProject(),
78 getReactorProjects(),
79 projectBuilder,
80 getSession().getProjectBuildingRequest(),
81 getSession().getLocalRepository(),
82 getI18N(locale),
83 locale,
84 getLog(),
85 siteTool)
86 .render();
87 }
88
89
90 public String getOutputName() {
91 return "modules";
92 }
93
94 @Override
95 protected String getI18Nsection() {
96 return "modules";
97 }
98
99
100
101
102
103
104
105
106 static class ModulesRenderer extends AbstractProjectInfoRenderer {
107
108 protected final Log log;
109
110 protected MavenProject project;
111
112 protected List<MavenProject> reactorProjects;
113
114 protected ProjectBuilder projectBuilder;
115
116 protected ProjectBuildingRequest buildingRequest;
117
118 protected ArtifactRepository localRepository;
119
120 protected SiteTool siteTool;
121
122 ModulesRenderer(
123 Sink sink,
124 MavenProject project,
125 List<MavenProject> reactorProjects,
126 ProjectBuilder projectBuilder,
127 ProjectBuildingRequest buildingRequest,
128 ArtifactRepository localRepository,
129 I18N i18n,
130 Locale locale,
131 Log log,
132 SiteTool siteTool) {
133 super(sink, i18n, locale);
134
135 this.project = project;
136 this.reactorProjects = reactorProjects;
137 this.projectBuilder = projectBuilder;
138 this.buildingRequest = buildingRequest;
139 this.localRepository = localRepository;
140 this.siteTool = siteTool;
141 this.log = log;
142 }
143
144 @Override
145 protected String getI18Nsection() {
146 return "modules";
147 }
148
149 @Override
150 protected void renderBody() {
151 List<String> modules = project.getModel().getModules();
152
153 if (modules == null || modules.isEmpty()) {
154 startSection(getTitle());
155
156 paragraph(getI18nString("nolist"));
157
158 endSection();
159
160 return;
161 }
162
163 startSection(getTitle());
164
165 paragraph(getI18nString("intro"));
166
167 startTable();
168
169 String name = getI18nString("header.name");
170 String description = getI18nString("header.description");
171 tableHeader(new String[] {name, description});
172
173 final String baseUrl = getDistMgmntSiteUrl(project);
174
175 ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(this.buildingRequest);
176 buildingRequest.setLocalRepository(localRepository);
177 buildingRequest.setProcessPlugins(false);
178
179 for (String module : modules) {
180 MavenProject moduleProject = getModuleFromReactor(project, reactorProjects, module);
181
182 if (moduleProject == null) {
183 log.warn("Module " + module + " not found in reactor: loading locally");
184
185 File f = new File(project.getBasedir(), module + "/pom.xml");
186 if (f.exists()) {
187 try {
188 moduleProject =
189 projectBuilder.build(f, buildingRequest).getProject();
190 } catch (ProjectBuildingException e) {
191 throw new IllegalStateException("Unable to read local module POM", e);
192 }
193 } else {
194 moduleProject = new MavenProject();
195 moduleProject.setName(module);
196 moduleProject.setDistributionManagement(new DistributionManagement());
197 moduleProject.getDistributionManagement().setSite(new Site());
198 moduleProject.getDistributionManagement().getSite().setUrl(module);
199 }
200 }
201 final String moduleName =
202 (moduleProject.getName() == null) ? moduleProject.getArtifactId() : moduleProject.getName();
203 final String moduleHref =
204 getRelativeLink(baseUrl, getDistMgmntSiteUrl(moduleProject), moduleProject.getArtifactId());
205
206 tableRow(new String[] {linkedName(moduleName, moduleHref), moduleProject.getDescription()});
207 }
208
209 endTable();
210
211 endSection();
212 }
213
214 private MavenProject getModuleFromReactor(
215 MavenProject project, List<MavenProject> reactorProjects, String module) {
216
217 if (reactorProjects == null) {
218 return null;
219 }
220 try {
221 File moduleBasedir = new File(project.getBasedir(), module).getCanonicalFile();
222
223 for (MavenProject reactorProject : reactorProjects) {
224 if (moduleBasedir.equals(reactorProject.getBasedir())) {
225 return reactorProject;
226 }
227 }
228 } catch (IOException e) {
229 log.error("Error while populating modules menu: " + e.getMessage(), e);
230 }
231
232 return null;
233 }
234
235
236
237
238
239
240
241 private static String getDistMgmntSiteUrl(MavenProject project) {
242 return getDistMgmntSiteUrl(project.getDistributionManagement());
243 }
244
245 private static String getDistMgmntSiteUrl(DistributionManagement distMgmnt) {
246 if (distMgmnt != null
247 && distMgmnt.getSite() != null
248 && distMgmnt.getSite().getUrl() != null) {
249 return urlEncode(distMgmnt.getSite().getUrl());
250 }
251
252 return null;
253 }
254
255 private static String urlEncode(final String url) {
256 if (url == null) {
257 return null;
258 }
259
260 try {
261 return new File(url).toURI().toURL().toExternalForm();
262 } catch (MalformedURLException ex) {
263 return url;
264 }
265 }
266
267
268 private String getRelativeLink(String baseUrl, String href, String defaultHref) {
269 String selectedHref = href;
270
271 if (selectedHref == null) {
272 selectedHref = defaultHref;
273 }
274
275 if (baseUrl != null) {
276 selectedHref = siteTool.getRelativePath(selectedHref, baseUrl);
277 }
278
279 if (selectedHref.endsWith("/")) {
280 selectedHref = selectedHref.concat("index.html");
281 } else {
282 selectedHref = selectedHref.concat("/index.html");
283 }
284
285 return selectedHref;
286 }
287
288 private String linkedName(String name, String link) {
289 return "{" + name + ", ./" + link + "}";
290 }
291 }
292 }