1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package net.objectlab.qalab.m2;
40
41 import java.io.File;
42 import java.io.FileInputStream;
43 import java.io.FileNotFoundException;
44 import java.io.IOException;
45
46 import javax.xml.parsers.ParserConfigurationException;
47 import javax.xml.parsers.SAXParser;
48 import javax.xml.parsers.SAXParserFactory;
49
50 import net.objectlab.qalab.m2.util.Maven2TaskLogger;
51 import net.objectlab.qalab.m2.util.Utils;
52 import net.objectlab.qalab.parser.BuildStatForChartParser;
53
54 import org.apache.maven.plugin.AbstractMojo;
55 import org.apache.maven.plugin.MojoExecutionException;
56 import org.xml.sax.InputSource;
57 import org.xml.sax.SAXException;
58
59 /**
60 * Goal which generates the QALab BuildStat chart.
61 *
62 * @author <a href="http://www.davesag.com">Dave Sag</a>.
63 * @goal chart
64 * @phase site
65 */
66 public class BuildStatChartMojo extends AbstractMojo {
67
68
69
70
71 /** Default SAX parser. * */
72
73
74 /** Default Chart width. * */
75 private static final int DEFAULT_WIDTH = 750;
76
77 /** Default Chart height. * */
78 private static final int DEFAULT_HEIGHT = 500;
79
80
81
82 /**
83 * The QALab properties file.
84 *
85 * @parameter expression="${project.basedir}/qalab.xml"
86 * @required
87 */
88 private File qalabFile = null;
89
90 /**
91 * The directory to put the chart.
92 *
93 * @parameter expression="${project.reporting.outputDirectory}/qalab"
94 * @required
95 */
96 private File toDir = null;
97
98 /**
99 * If true then any debug logging output will be suppressed.
100 *
101 * @parameter default-value=false
102 */
103 private boolean quiet = false;
104
105 /**
106 * The Chart width.
107 *
108 * @parameter default-value=750
109 */
110 private int width = DEFAULT_WIDTH;
111
112 /**
113 * The Chart height.
114 *
115 * @parameter default-value=500
116 */
117 private int height = DEFAULT_HEIGHT;
118
119 /**
120 * If the movingAverage is <= 0 then there is no moving average, otherwise
121 * it shows the average based on the last n points, where n is the value of
122 * this field.
123 *
124 * @parameter default-value=0
125 */
126 private int movingAverage = 0;
127
128 /**
129 * If true then generate a summary chart only.
130 *
131 * @parameter default-value=false
132 */
133 private boolean summaryOnly = false;
134
135 /**
136 * Statistic type, defaulted to
137 * 'checkstyle,pmd,findbugs,simian,pmd-cpd,cobertura-line,cobertura-branch'.
138 *
139 * @parameter default-value="checkstyle,pmd,findbugs,simian,pmd-cpd,cobertura-line,cobertura-branch"
140 */
141 private String types = "checkstyle,pmd,findbugs,simian,pmd-cpd,cobertura-line,cobertura-branch";
142
143 /**
144 * Statistic type to appear on summary chart, defaulted to
145 * 'checkstyle,pmd,findbugs,simian,pmd-cpd'.
146 *
147 * @parameter default-value="checkstyle,pmd,findbugs,simian,pmd-cpd"
148 */
149 private String summaryTypes = "checkstyle,pmd,findbugs,simian,pmd-cpd";
150
151 /**
152 * File prefix for the charts (e.g. cobertura-) Default empty.
153 *
154 * @parameter default-value=""
155 */
156 private String filePrefix = "";
157
158 /**
159 * X Axis Title
160 *
161 * @parameter default-value="Date"
162 */
163 private String xAxisTitle = "Date";
164
165 /**
166 * Y Axis Title
167 *
168 * @parameter default-value="Violation Count / Coverage Percent"
169 */
170 private String yAxisTitle = "Violation Count / Coverage Percent";
171
172 /**
173 * X Axis Title for Summary
174 *
175 * @parameter default-value="Date"
176 */
177 private String xAxisSummaryTitle = "Date";
178
179 /**
180 * Y Axis Title for Summary
181 *
182 * @parameter default-value="Violation Count"
183 */
184 private String yAxisSummaryTitle = "Violation Count";
185
186 /**
187 * validates the input then generates the charts.
188 *
189 * @throws MojoExecutionException
190 * if anything goes wrong.
191 */
192 public final void execute() throws MojoExecutionException {
193
194 validate();
195
196
197 if (!quiet) {
198 getLog().info("QALab CHARTS ==> qalabFile='" + qalabFile.getPath() + "'");
199 getLog().info("toDir='" + toDir.getPath());
200 getLog().info("width='" + width + "' height='" + height + "' summaryOnly='" + isSummaryOnly() + "'");
201 getLog().info("Types=" + types);
202 getLog().info("Summary Types=" + getSummaryTypes());
203 getLog().info("File Prefix=" + getFilePrefix());
204 }
205
206 generateCharts();
207
208 }
209
210 /**
211 * Generate the charts by creating a SAX parser specialised in finding the
212 * elements of given type and creating charts in a given directory.
213 *
214 * @throws MojoExecutionException
215 * if anything goes wrong.
216 */
217 private void generateCharts() throws MojoExecutionException {
218
219 final BuildStatForChartParser myForChartParser = new BuildStatForChartParser(new Maven2TaskLogger(this));
220
221 myForChartParser.setChartHeight(height);
222 myForChartParser.setChartWidth(width);
223 myForChartParser.setToDir(toDir.getAbsolutePath() + "/");
224 myForChartParser.setMovingAverage(movingAverage);
225 myForChartParser.setSummaryOnly(isSummaryOnly());
226 myForChartParser.setAcceptedStyle(types);
227 myForChartParser.setSummaryStyle(getSummaryTypes());
228 myForChartParser.setQuiet(quiet);
229 myForChartParser.setFilePrefix(getFilePrefix());
230 myForChartParser.setXAxisSummaryTitle(xAxisSummaryTitle);
231 myForChartParser.setXAxisTitle(xAxisTitle);
232 myForChartParser.setYAxisSummaryTitle(yAxisSummaryTitle);
233 myForChartParser.setYAxisTitle(yAxisTitle);
234
235 try {
236 SAXParserFactory factory = SAXParserFactory.newInstance();
237 SAXParser saxParser = factory.newSAXParser();
238
239 if (!quiet) {
240 getLog().info("Parsing " + qalabFile);
241 }
242
243 saxParser.parse(new InputSource(new FileInputStream(qalabFile)), myForChartParser);
244 } catch (SAXException sex) {
245 getLog().error(sex.toString());
246 throw new MojoExecutionException("Error generating charts.", sex);
247 } catch (FileNotFoundException fnfex) {
248 getLog().error(fnfex.toString());
249 throw new MojoExecutionException("Error generating charts.", fnfex);
250 } catch (IOException ioex) {
251 getLog().error(ioex.toString());
252 throw new MojoExecutionException("Error generating charts.", ioex);
253 } catch (ParserConfigurationException e) {
254 getLog().error(e.toString());
255 throw new MojoExecutionException("Error generating charts.", e);
256 }
257 }
258
259 /**
260 * Validates the parameters supplied by maven.
261 *
262 * @throws MojoExecutionException
263 * if anything goes wrong.
264 */
265 private void validate() throws MojoExecutionException {
266 try {
267 Utils.checkFile(qalabFile, "qalabFile");
268 } catch (IOException ioex) {
269 throw new MojoExecutionException(ioex.getMessage(), ioex);
270 }
271
272 if (toDir == null) {
273 throw new MojoExecutionException("toDir is mandatory");
274 }
275
276 if (toDir.exists() && !toDir.isDirectory()) {
277 final String message = "toDir must be a directory (" + toDir + ")";
278 throw new MojoExecutionException(message);
279 }
280
281 if (!toDir.exists()) {
282 if (!quiet) {
283 getLog().debug("Creating directory: " + toDir.toString());
284 }
285
286 toDir.mkdir();
287 }
288 }
289
290 /**
291 * @return the summaryOnly
292 */
293 public boolean isSummaryOnly() {
294 return summaryOnly;
295 }
296
297 /**
298 * @param summaryOnly the summaryOnly to set
299 */
300 public void setSummaryOnly(boolean summaryOnly) {
301 this.summaryOnly = summaryOnly;
302 }
303
304 /**
305 * @return the summaryTypes
306 */
307 public String getSummaryTypes() {
308 return summaryTypes;
309 }
310
311 /**
312 * @param summaryTypes the summaryTypes to set
313 */
314 public void setSummaryTypes(String summaryTypes) {
315 this.summaryTypes = summaryTypes;
316 }
317
318 /**
319 * @return the filePrefix
320 */
321 public String getFilePrefix() {
322 return filePrefix;
323 }
324
325 /**
326 * @param filePrefix the filePrefix to set
327 */
328 public void setFilePrefix(String filePrefix) {
329 this.filePrefix = filePrefix;
330 }
331
332 /**
333 * @return the height
334 */
335 public int getHeight() {
336 return height;
337 }
338
339 /**
340 * @param height the height to set
341 */
342 public void setHeight(int height) {
343 this.height = height;
344 }
345
346 /**
347 * @return the movingAverage
348 */
349 public int getMovingAverage() {
350 return movingAverage;
351 }
352
353 /**
354 * @param movingAverage the movingAverage to set
355 */
356 public void setMovingAverage(int movingAverage) {
357 this.movingAverage = movingAverage;
358 }
359
360 /**
361 * @return the qalabFile
362 */
363 public File getQalabFile() {
364 return qalabFile;
365 }
366
367 /**
368 * @param qalabFile the qalabFile to set
369 */
370 public void setQalabFile(File qalabFile) {
371 this.qalabFile = qalabFile;
372 }
373
374 /**
375 * @return the quiet
376 */
377 public boolean isQuiet() {
378 return quiet;
379 }
380
381 /**
382 * @param quiet the quiet to set
383 */
384 public void setQuiet(boolean quiet) {
385 this.quiet = quiet;
386 }
387
388 /**
389 * @return the toDir
390 */
391 public File getToDir() {
392 return toDir;
393 }
394
395 /**
396 * @param toDir the toDir to set
397 */
398 public void setToDir(File toDir) {
399 this.toDir = toDir;
400 }
401
402 /**
403 * @return the types
404 */
405 public String getTypes() {
406 return types;
407 }
408
409 /**
410 * @param types the types to set
411 */
412 public void setTypes(String types) {
413 this.types = types;
414 }
415
416 /**
417 * @return the width
418 */
419 public int getWidth() {
420 return width;
421 }
422
423 /**
424 * @param width the width to set
425 */
426 public void setWidth(int width) {
427 this.width = width;
428 }
429
430 public void setXAxisSummaryTitle(String xAxisSummaryTitle) {
431 this.xAxisSummaryTitle = xAxisSummaryTitle;
432 }
433
434 public void setXAxisTitle(String xAxisTitle) {
435 this.xAxisTitle = xAxisTitle;
436 }
437
438 public void setYAxisSummaryTitle(String yAxisSummaryTitle) {
439 this.yAxisSummaryTitle = yAxisSummaryTitle;
440 }
441
442 public void setYAxisTitle(String yAxisTitle) {
443 this.yAxisTitle = yAxisTitle;
444 }
445
446 }
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462