1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.maven.exceptions;
17
18 import java.io.File;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Locale;
22 import java.util.ResourceBundle;
23
24 import org.apache.maven.artifact.DependencyResolutionRequiredException;
25 import org.apache.maven.doxia.sink.Sink;
26 import org.apache.maven.plugin.logging.Log;
27 import org.apache.maven.project.MavenProject;
28 import org.apache.maven.reporting.MavenReportException;
29
30 import de.smartics.exceptions.report.ReportBuilder;
31 import de.smartics.exceptions.report.ReportConfiguration;
32 import de.smartics.exceptions.report.data.InMemoryExceptionCodesReport;
33 import de.smartics.exceptions.report.data.ProjectConfiguration;
34 import de.smartics.exceptions.report.data.ReportProblem;
35 import de.smartics.exceptions.report.generator.ReportGenerator;
36 import de.smartics.exceptions.report.utils.StringFunction;
37 import de.smartics.maven.exceptions.conf.ConfigUtils;
38 import de.smartics.maven.exceptions.conf.DefaultProjectConfiguration;
39 import de.smartics.maven.exceptions.runtime.ProjectClassLoader;
40 import de.smartics.maven.util.PathUtils;
41
42
43
44
45
46
47
48
49
50
51
52 public class ExceptionCodeReport extends AbstractElementReport
53 {
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 private String outputName;
76
77
78
79
80
81
82
83
84
85
86
87
88 private String additionalSources;
89
90
91
92
93
94
95
96 private String sourceEncoding;
97
98
99
100
101
102
103
104 private String sourceVersion;
105
106
107
108
109
110
111
112
113
114 @SuppressWarnings("rawtypes")
115 private ArrayList includes;
116
117
118
119
120
121
122
123
124
125 @SuppressWarnings("rawtypes")
126 private ArrayList excludes;
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 private String reportGenerator;
145
146
147
148
149
150
151
152 private String reportEncoding;
153
154
155
156
157
158
159
160
161 private boolean skip;
162
163
164
165
166
167
168
169
170
171 private boolean addModuleSrcFolders;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 public String getOutputName()
195 {
196 return outputName;
197 }
198
199
200
201 @Override
202 public void executeReport(final Locale locale) throws MavenReportException
203 {
204 if (skip)
205 {
206 final Log log = getLog();
207 if (log.isInfoEnabled())
208 {
209 log.info("Report '" + getName(locale) + "' skipped.");
210 }
211 return;
212 }
213
214 try
215 {
216 final ProjectConfiguration<Sink> projectConfig =
217 createProjectConfiguration(locale);
218 final ReportConfiguration reportConfig =
219 createReportConfiguration(projectConfig);
220
221 final ReportBuilder builder = ReportBuilder.create(reportConfig);
222 final InMemoryExceptionCodesReport report =
223 new InMemoryExceptionCodesReport();
224 builder.reportTo(report);
225
226 if (report.hasProblems())
227 {
228 final String message = toString(report.getProblems());
229 getLog().error(message);
230 throw new MavenReportException(
231 "Problems encountered while generating report.\n"
232 + " Please refer to error log for details.");
233 }
234
235 final ReportGenerator<Sink> generator =
236 projectConfig.getReporterInstance();
237 generator.writeReport(projectConfig, report);
238 }
239 catch (final Exception e)
240 {
241 e.printStackTrace();
242 throw new MavenReportException(
243 "Cannot generate " + getName(locale) + ".", e);
244 }
245 }
246
247 private static String toString(final List<ReportProblem> problems)
248 {
249 final StringBuilder buffer = new StringBuilder(512);
250
251 for (final ReportProblem problem : problems)
252 {
253 buffer.append(problem).append('\n');
254 }
255
256 return buffer.toString();
257 }
258
259 @SuppressWarnings("unchecked")
260 private ProjectConfiguration<Sink> createProjectConfiguration(
261 final Locale locale) throws DependencyResolutionRequiredException
262 {
263 final List<String> classRootDirectoryNames =
264 project.getCompileClasspathElements();
265
266 final List<String> sourceRootDirectoryNames = new ArrayList<String>();
267 sourceRootDirectoryNames.addAll(StringFunction.split(
268 this.additionalSources, ","));
269 addModuleSources(sourceRootDirectoryNames);
270 sourceRootDirectoryNames.addAll(project.getCompileSourceRoots());
271 sourceRootDirectoryNames.addAll(ConfigUtils
272 .discoverSourceJars(classRootDirectoryNames));
273 final List<String> toolClassPath = PathUtils.toClassPath(pluginArtifacts);
274
275 final Log log = getLog();
276 if (log.isDebugEnabled())
277 {
278 log.debug("Tool class path: " + toolClassPath);
279 log.debug("Class roots : " + classRootDirectoryNames);
280 log.debug("Source roots : " + sourceRootDirectoryNames);
281 }
282
283 final DefaultProjectConfiguration.Builder<Sink> builder =
284 new DefaultProjectConfiguration.Builder<Sink>(project.getName());
285
286 builder.setIncludes(includes);
287 builder.setExcludes(excludes);
288 builder.setSourceEncoding(this.sourceEncoding);
289 builder.setSourceVersion(this.sourceVersion);
290 builder.setToolClassPath(toolClassPath);
291 builder.setClassRootDirectoryNames(classRootDirectoryNames);
292 builder.setSourceRootDirectoryNames(sourceRootDirectoryNames);
293 builder.setJavadocDir(javadocDir);
294
295 builder.setReportEncoding(this.reportEncoding);
296 builder.setReporter(this.reportGenerator);
297 builder.setReport(new File(this.outputDirectory.getAbsolutePath(),
298 outputName).getPath());
299
300 final ResourceBundle bundle = getBundle(locale);
301 builder.setBundle(bundle);
302
303 final ProjectConfiguration<Sink> config = builder.build();
304
305 final Sink sink = getSink();
306 final ReportGenerator<Sink> generator = config.getReporterInstance();
307 generator.setOutput(sink);
308
309 return config;
310 }
311
312 private void addModuleSources(final List<String> sourceRootDirectoryNames)
313 {
314 if (!addModuleSrcFolders)
315 {
316 return;
317 }
318
319 final List<MavenProject> projects = session.getProjects();
320 for (final MavenProject current : projects)
321 {
322 if (project.getDependencyArtifacts().contains(current.getArtifact()))
323 {
324 final String sourceDir = current.getBuild().getSourceDirectory();
325 if (new File(sourceDir).exists())
326 {
327 sourceRootDirectoryNames.add(sourceDir);
328 }
329 }
330 }
331 }
332
333 private ReportConfiguration createReportConfiguration(
334 final ProjectConfiguration<Sink> projectConfig)
335 {
336 final ReportConfiguration reportConfig = new ReportConfiguration();
337 reportConfig.setEncoding(this.sourceEncoding);
338 final ProjectClassLoader classLoader =
339 new ProjectClassLoader(Thread.currentThread().getContextClassLoader(),
340 projectConfig.getClassRootDirectoryNames());
341 reportConfig.setProjectClassLoader(classLoader);
342 for (final String name : projectConfig.getSourceRootDirectoryNames())
343 {
344 final File file = new File(name);
345 reportConfig.addSourceTree(file);
346 }
347
348 reportConfig.addIncludes(projectConfig.getIncludes());
349 reportConfig.addExcludes(projectConfig.getExcludes());
350
351 return reportConfig;
352 }
353
354 @Override
355 protected String getBundleName()
356 {
357 return "de/smartics/exceptions/report/ExceptionCodeReportBundle";
358 }
359
360
361
362 }