View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   //
3   //                  ObjectLab is sponsoring QALab
4   //
5   // Based in London, we are world leaders in the design and development
6   // of bespoke applications for the Securities Financing markets.
7   //
8   // <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
9   //           ___  _     _           _   _          _
10  //          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
11  //         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
12  //         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
13  //          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
14  //                   |__/
15  //
16  //                   http://www.ObjectLab.co.uk
17  // ---------------------------------------------------------------------------
18  //
19  //QALab is released under the GNU General Public License.
20  //
21  //QALab: Collects QA Statistics from your build over time.
22  //2005+, ObjectLab Ltd
23  //
24  //This library is free software; you can redistribute it and/or
25  //modify it under the terms of the GNU General Public
26  //License as published by the Free Software Foundation; either
27  //version 2.1 of the License, or (at your option) any later version.
28  //
29  //This library is distributed in the hope that it will be useful,
30  //but WITHOUT ANY WARRANTY; without even the implied warranty of
31  //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
32  //General Public License for more details.
33  //
34  //You should have received a copy of the GNU General Public
35  //License along with this library; if not, write to the Free Software
36  //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      // ~ Static fields/initializers
69      // ------------------------------------------------------------------------
70  
71      /** Default SAX parser. * */
72  //    private static final String DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser";
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      // ~ Instance fields -------------------------------------------------------
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 &lt;= 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         // validate the provided parameters
194         validate();
195 
196         // Display the files being processed
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         // define a sax stuff...
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  *                   ObjectLab is sponsoring QALab
449  *
450  * Based in London, we are world leaders in the design and development
451  * of bespoke applications for the securities financing markets.
452  *
453  * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
454  *           ___  _     _           _   _          _
455  *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
456  *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
457  *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
458  *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
459  *                   |__/
460  *
461  *                     www.ObjectLab.co.uk
462  */