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.commons.lang.LocaleUtils;
25 import org.apache.commons.lang.StringUtils;
26 import org.apache.maven.artifact.DependencyResolutionRequiredException;
27 import org.apache.maven.plugin.AbstractMojo;
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.plugin.MojoFailureException;
30 import org.apache.maven.plugin.logging.Log;
31 import org.apache.maven.project.MavenProject;
32 import org.apache.maven.reporting.MavenReportException;
33
34 import de.smartics.exceptions.report.ReportBuilder;
35 import de.smartics.exceptions.report.ReportConfiguration;
36 import de.smartics.exceptions.report.data.InMemoryExceptionCodesReport;
37 import de.smartics.exceptions.report.data.ProjectConfiguration;
38 import de.smartics.exceptions.report.data.ReportProblem;
39 import de.smartics.exceptions.report.generator.ReportGenerator;
40 import de.smartics.exceptions.report.utils.StringFunction;
41 import de.smartics.maven.exceptions.conf.ConfigUtils;
42 import de.smartics.maven.exceptions.conf.DefaultProjectConfiguration;
43 import de.smartics.maven.exceptions.runtime.ProjectClassLoader;
44 import de.smartics.maven.io.MojoIoUtils;
45 import de.smartics.maven.util.LoggingUtils;
46 import de.smartics.maven.util.PathUtils;
47
48
49
50
51 public abstract class AbstractSdocCodeMojo extends AbstractMojo
52 {
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 protected MavenProject project;
70
71
72
73
74
75
76
77
78 @SuppressWarnings("rawtypes")
79
80 protected ArrayList pluginArtifacts;
81
82
83
84
85
86
87
88
89 protected boolean skip;
90
91
92
93
94
95
96
97
98
99
100
101 private String logLevel;
102
103
104
105
106
107
108
109
110
111 protected String locale;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 private String additionalSources;
128
129
130
131
132
133
134
135
136 private String sourceEncoding;
137
138
139
140
141
142
143
144
145 private String sourceVersion;
146
147
148
149
150
151
152
153
154
155 @SuppressWarnings("rawtypes")
156 private ArrayList includes;
157
158
159
160
161
162
163
164
165
166 @SuppressWarnings("rawtypes")
167 private ArrayList excludes;
168
169
170
171
172
173
174
175
176
177 private String outputDirectory;
178
179
180
181
182
183
184 protected File output;
185
186
187
188
189
190
191
192
193 private String reportEncoding;
194
195
196
197
198
199
200
201
202
203
204 private String reportGenerator;
205
206
207
208
209
210
211
212
213
214
215 private String codeBundleMapper;
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 public MavenProject getProject()
235 {
236 return project;
237 }
238
239
240
241
242
243
244 public void setProject(final MavenProject project)
245 {
246 this.project = project;
247 }
248
249
250
251
252
253
254 public void execute() throws MojoExecutionException, MojoFailureException
255 {
256 if (skip)
257 {
258 getLog().info("Skipping sdoc exception code collection since skip=true.");
259 return;
260 }
261
262 if (canBuild())
263 {
264 init();
265 final Locale locale = determineLocale();
266
267 try
268 {
269 final ProjectConfiguration<File> projectConfig =
270 createProjectConfiguration(locale, output);
271 final ReportConfiguration reportConfig =
272 createReportConfiguration(projectConfig);
273
274 final ReportBuilder builder = ReportBuilder.create(reportConfig);
275 final InMemoryExceptionCodesReport report =
276 new InMemoryExceptionCodesReport();
277 builder.reportTo(report);
278
279 if (report.hasProblems())
280 {
281 final String message = toString(report.getProblems());
282 getLog().error(message);
283 throw new MavenReportException(
284 "Problems encountered while generating report.\n"
285 + " Please refer to error log for details.");
286 }
287
288 final ReportGenerator<File> generator =
289 projectConfig.getReporterInstance();
290 generator.setOutput(output);
291 generator.writeReport(projectConfig, report);
292
293 handleGeneratedDocuments();
294 }
295 catch (final Exception e)
296 {
297 throw new MojoExecutionException(
298 "Cannot generate code export for projectdoc.", e);
299 }
300 }
301 else
302 {
303 getLog().debug(
304 "Skipping sdoccode since no classes are provided by this project.");
305 }
306 }
307
308 private static String toString(final List<ReportProblem> problems)
309 {
310 final StringBuilder buffer = new StringBuilder(512);
311
312 for (final ReportProblem problem : problems)
313 {
314 buffer.append(problem).append('\n');
315 }
316
317 return buffer.toString();
318 }
319
320
321
322
323
324
325
326 protected abstract void handleGeneratedDocuments()
327 throws MojoExecutionException, MojoFailureException;
328
329 @SuppressWarnings("unchecked")
330
331 private void init() throws MojoExecutionException
332 {
333 LoggingUtils.configureLogger(getLog(), logLevel);
334 if (includes.isEmpty())
335 {
336 includes.add("**");
337 }
338
339 if (StringUtils.isBlank(codeBundleMapper))
340 {
341 throw new IllegalArgumentException(
342 "No code bundle mapper class provided."
343 + " Please specify one by the mojo parameter 'codeBundleMapper'.");
344 }
345
346 this.output = MojoIoUtils.provideMojoDirectory(outputDirectory);
347 }
348
349
350
351
352
353
354
355 private Locale determineLocale()
356 {
357 return StringUtils.isNotBlank(this.locale) ? LocaleUtils
358 .toLocale(this.locale) : Locale.getDefault();
359 }
360
361 @SuppressWarnings("unchecked")
362 private boolean canBuild()
363 {
364 final String packaging = project.getPackaging();
365 return !("pom".equals(packaging) || !PathUtils.exists(project
366 .getCompileSourceRoots()));
367 }
368
369 @SuppressWarnings("unchecked")
370 private ProjectConfiguration<File> createProjectConfiguration(
371 final Locale locale, final File outputDir)
372 throws DependencyResolutionRequiredException
373 {
374 final List<String> classRootDirectoryNames =
375 project.getCompileClasspathElements();
376
377 final List<String> sourceRootDirectoryNames = new ArrayList<String>();
378 sourceRootDirectoryNames.addAll(StringFunction.split(
379 this.additionalSources, ","));
380 sourceRootDirectoryNames.addAll(project.getCompileSourceRoots());
381 sourceRootDirectoryNames.addAll(ConfigUtils
382 .discoverSourceJars(classRootDirectoryNames));
383 final List<String> toolClassPath = PathUtils.toClassPath(pluginArtifacts);
384
385 final Log log = getLog();
386 if (log.isDebugEnabled())
387 {
388 log.debug("Tool class path: " + toolClassPath);
389 log.debug("Class roots : " + classRootDirectoryNames);
390 log.debug("Source roots : " + sourceRootDirectoryNames);
391 }
392
393 final DefaultProjectConfiguration.Builder<File> builder =
394 new DefaultProjectConfiguration.Builder<File>(project.getName());
395
396 builder.setIncludes(includes);
397 builder.setExcludes(excludes);
398 builder.setSourceEncoding(this.sourceEncoding);
399 builder.setSourceVersion(this.sourceVersion);
400 builder.setToolClassPath(toolClassPath);
401 builder.setClassRootDirectoryNames(classRootDirectoryNames);
402 builder.setSourceRootDirectoryNames(sourceRootDirectoryNames);
403 builder.setJavadocDir(null);
404
405 builder.setReportEncoding(this.reportEncoding);
406 builder.setReporter(this.reportGenerator);
407 builder.setReport(outputDir.getAbsolutePath());
408
409 final ResourceBundle bundle = getBundle(locale);
410 builder.setBundle(bundle);
411 builder.setBundleMapperClassName(this.codeBundleMapper);
412
413 final ProjectConfiguration<File> config = builder.build();
414 return config;
415 }
416
417 private ReportConfiguration createReportConfiguration(
418 final ProjectConfiguration<File> projectConfig)
419 {
420 final ReportConfiguration reportConfig = new ReportConfiguration();
421 reportConfig.setEncoding(this.sourceEncoding);
422 final ProjectClassLoader classLoader =
423 new ProjectClassLoader(Thread.currentThread().getContextClassLoader(),
424 projectConfig.getClassRootDirectoryNames());
425 reportConfig.setProjectClassLoader(classLoader);
426 for (final String name : projectConfig.getSourceRootDirectoryNames())
427 {
428 final File file = new File(name);
429 reportConfig.addSourceTree(file);
430 }
431
432 reportConfig.addIncludes(projectConfig.getIncludes());
433 reportConfig.addExcludes(projectConfig.getExcludes());
434
435 return reportConfig;
436 }
437
438 private ResourceBundle getBundle(final Locale locale)
439 {
440 return ResourceBundle.getBundle(getBundleName(), locale, getClass()
441 .getClassLoader());
442 }
443
444 private String getBundleName()
445 {
446 return "de/smartics/maven/exceptions/sdoc/SdocCodeBundle";
447 }
448
449
450
451 }