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 org.apache.maven.plugin.AbstractMojo;
42  import org.apache.maven.plugin.MojoExecutionException;
43  
44  import net.objectlab.qalab.interfaces.QALabExporter;
45  import net.objectlab.qalab.parser.StatMerger;
46  import net.objectlab.qalab.util.TaskLogger;
47  import net.objectlab.qalab.m2.util.Utils;
48  import net.objectlab.qalab.m2.util.Maven2TaskLogger;
49  
50  import org.xml.sax.InputSource;
51  
52  import java.io.File;
53  import java.io.FileInputStream;
54  import java.io.IOException;
55  import java.io.FileNotFoundException;
56  
57  import java.util.Iterator;
58  import java.util.Map;
59  import java.util.Properties;
60  
61  /**
62   * Goal that handles the merge of statistics into qalab.xml.
63   * 
64   * @author <a href="http://www.davesag.com">Dave Sag</a>.
65   * @goal merge
66   * @phase deploy
67   */
68  public class BuildStatMergeMojo extends AbstractMojo {
69  
70      // ~ Instance fields -------------------------------------------------------
71      /**
72       * The file the whose values will be incorporated in the qalab.xml. This
73       * file will have been generated by checkstyle, or pmd etc.
74       * @parameter
75       */
76      private File inputFile = null;
77  
78      /**
79       * The merged properties file. By default this is generated into the root of
80       * the project as it is often checked into source control.
81       * 
82       * @parameter expression="${project.basedir}/qalab.xml"
83       */
84      private File outputFile = null;
85  
86      /**
87       * If true then any debug logging output will be suppressed.
88       * 
89       * @parameter default-value=false
90       */
91      private boolean quiet = false;
92  
93      /**
94       * If true then use ONLY DATE for timestamp (use in conjunction action replace).
95       * 
96       * @parameter default-value=true
97       */
98      private boolean dateOnly = true;
99  
100     /**
101      * The directory where the source code is.
102      * 
103      * @parameter expression="${project.build.sourceDirectory}"
104      */
105     private String srcDir;
106 
107     /**
108      * The fully qualified class name for the handler for the given statistics.
109      * <ul>
110      * The built-in handlers are:
111      * <li>net.objectlab.qalab.parser.CheckstyleStatMerge</li>
112      * <li>net.objectlab.qalab.parser.PMDStatMerge</li>
113      * <li>net.objectlab.qalab.parser.FindBugsStatMerge</li>
114      * <li>net.objectlab.qalab.parser.SimianStatMerge</li>
115      * </ul>
116      * 
117      * @parameter
118      */
119     private String handler;
120 
121     /**
122      * The timestamp for the stats.
123      * 
124      * @parameter
125      */
126     private String mergerTimeStamp;
127 
128     /**
129      * An exporter class name.
130      * 
131      * @parameter default-value="net.objectlab.qalab.exporter.QALabXMLExporter"
132      */
133     private String exporterClassName = "net.objectlab.qalab.exporter.QALabXMLExporter";
134 
135     /**
136      * The properties file to use instead of setting them one by one.
137      * 
138      * @parameter
139      */
140     private File propertiesFile;
141 
142     /**
143      * the loaded properties from the properties file declared above.
144      */
145     private Properties theProperties = null;
146 
147     // ~ Methods
148 
149     /**
150      * Method invoked by the ant framework to execute the action associated with
151      * this task. This will validate the input parameters then merge the
152      * statistics.
153      * 
154      * @throws MojoExecutionException
155      *             if anything goes wrong.
156      */
157     public final void execute() throws MojoExecutionException {
158 
159         theProperties = createOverridingProperties();
160 
161         getLog().info("Starting QALab Merge");
162 
163         // validate the provided parameters
164         if (!validate()) {
165             return;
166         }
167 
168         // Display the files being processed
169         if (!quiet) {
170             getLog().info("QALab Merge:");
171             getLog().info("inputFile='" + getInputFile().getPath());
172             getLog().info("outputFile='" + outputFile.getPath());
173             getLog().info("srcDir='" + srcDir + "', mergerTimeStamp=" + mergerTimeStamp);
174             String proppath = null;
175             if (propertiesFile != null) {
176                 proppath = propertiesFile.getPath();
177             }
178             getLog().info("quiet='" + quiet + "', propertiesFile='" + proppath + "'.");
179             for (final Iterator it = theProperties.entrySet().iterator(); it.hasNext();) {
180 
181                 final Map.Entry entry = (Map.Entry) it.next();
182                 final String key = entry.getKey().toString();
183                 if (key.indexOf("qalab") >= 0) {
184                     getLog().info(key + " = '" + entry.getValue() + "'");
185                 }
186             }
187         }
188 
189         mergeFiles();
190     }
191 
192     /**
193      * Merge the statistics into the qalab.xml.
194      * 
195      * @throws MojoExecutionException
196      *             if anything goes wrong.
197      */
198     private void mergeFiles() throws MojoExecutionException {
199         try {
200             final TaskLogger logger = new Maven2TaskLogger(this);
201 
202             // create the exporter
203             final QALabExporter exporter = (QALabExporter) Class.forName(getExporterClassName()).newInstance();
204 
205             getTheProperties().setProperty("qalab.merge.output.file", getOutputFile().getAbsolutePath());
206 
207             exporter.setQuiet(isQuiet());
208             exporter.setTaskLogger(logger);
209 
210             final StatMerger merger = (StatMerger) Class.forName(getHandler()).newInstance();
211 
212             merger.setQuiet(isQuiet());
213             merger.setSrcDir(getSrcDir());
214             merger.setTaskLogger(logger);
215             merger.setMergerTimeStamp(getMergerTimeStamp(), dateOnly);
216 
217             getTheProperties().setProperty("qalab.merge.output.timestamp", merger.getMergerTimeStamp());
218             getTheProperties().setProperty("qalab.merge.type", merger.getType());
219             exporter.configure(getTheProperties());
220 
221             merger.mergeStats(new InputSource(new FileInputStream(getInputFile())), exporter);
222             getLog().info("Files: " + merger.getFileCount() + " Violations:" + merger.getTotalStatistics());
223 
224             exporter.save();
225         } catch (IllegalAccessException e) {
226             throw new MojoExecutionException(e.toString());
227         } catch (FileNotFoundException e) {
228             throw new MojoExecutionException(e.toString());
229         } catch (IOException e) {
230             throw new MojoExecutionException(e.toString());
231         } catch (ClassNotFoundException e) {
232             throw new MojoExecutionException(e.toString());
233         } catch (InstantiationException e) {
234             throw new MojoExecutionException(e.toString());
235         }
236     }
237 
238     /**
239      * Validates the parameters supplied by maven 2.
240      * 
241      * @throws MojoExecutionException
242      *             if anything goes wrong.
243      */
244     private boolean validate() throws MojoExecutionException {
245         try {
246             Utils.checkFile(getInputFile(), "inputFile");
247             return true;
248         } catch (IOException ioex) {
249             getLog().warn("\n\nQALab ==> The file " + getInputFile().getPath() + " cannot be accessed. SKIPPING....\n\n");
250             // throw new MojoExecutionException(ioex.getMessage(), ioex);
251         }
252         return false;
253     }
254 
255     /**
256      * Create the Properties object based on the arguments specified to the Mojo
257      * in your <code>pom.xml</code> file.
258      * 
259      * @return the properties for property expansion expansion
260      * @throws MojoExecutionException
261      *             if anything goes wrong.
262      */
263     private Properties createOverridingProperties() throws MojoExecutionException {
264 
265         final Properties result = new Properties();
266 
267         // Load the properties file if specified
268         if (propertiesFile != null && propertiesFile.canRead() && propertiesFile.isFile()) {
269             FileInputStream inStream = null;
270             if (!quiet) {
271                 getLog().debug("loading " + propertiesFile);
272             }
273 
274             try {
275                 inStream = new FileInputStream(propertiesFile);
276                 result.load(inStream);
277             } catch (FileNotFoundException fnfex) {
278                 throw new MojoExecutionException("Could not find Properties file '" + propertiesFile + "'", fnfex);
279             } catch (IOException ioex) {
280                 throw new MojoExecutionException("Error loading Properties file '" + propertiesFile + "'", ioex);
281             } finally {
282                 try {
283                     if (inStream != null) {
284                         inStream.close();
285                     }
286                 } catch (IOException ioex) {
287                     throw new MojoExecutionException("Error closing Properties file '" + propertiesFile + "'", ioex);
288                 }
289             }
290         }
291 
292         // override with Maven properties as apropriate.
293         final Map projectContext = getPluginContext();
294 
295         for (final Iterator it = projectContext.entrySet().iterator(); it.hasNext();) {
296 
297             final Map.Entry entry = (Map.Entry) it.next();
298             final String value = String.valueOf(entry.getValue());
299             if (entry.getKey().toString().indexOf("qalab") >= 0) {
300                 getLog().info("Adding " + entry.getKey() + " / " + value);
301             }
302             result.put(entry.getKey(), value);
303         }
304 
305         return result;
306     }
307 
308     public String getExporterClassName() {
309         return exporterClassName;
310     }
311 
312     public void setExporterClassName(String exporterClassName) {
313         this.exporterClassName = exporterClassName;
314     }
315 
316     public String getHandler() {
317         return handler;
318     }
319 
320     public void setHandler(String handler) {
321         this.handler = handler;
322     }
323 
324     public File getInputFile() {
325         return inputFile;
326     }
327 
328     public void setInputFile(File inputFile) {
329         this.inputFile = inputFile;
330     }
331 
332     public String getMergerTimeStamp() {
333         return mergerTimeStamp;
334     }
335 
336     public void setMergerTimeStamp(String mergerTimeStamp) {
337         this.mergerTimeStamp = mergerTimeStamp;
338     }
339 
340     public File getOutputFile() {
341         return outputFile;
342     }
343 
344     public void setOutputFile(File outputFile) {
345         this.outputFile = outputFile;
346     }
347 
348     public File getPropertiesFile() {
349         return propertiesFile;
350     }
351 
352     public void setPropertiesFile(File propertiesFile) {
353         this.propertiesFile = propertiesFile;
354     }
355 
356     public boolean isQuiet() {
357         return quiet;
358     }
359 
360     public void setQuiet(boolean quiet) {
361         this.quiet = quiet;
362     }
363 
364     public String getSrcDir() {
365         return srcDir;
366     }
367 
368     public void setSrcDir(String srcDir) {
369         this.srcDir = srcDir;
370     }
371 
372     public Properties getTheProperties() {
373         return theProperties;
374     }
375 
376     public void setTheProperties(Properties theProperties) {
377         this.theProperties = theProperties;
378     }
379 }
380 /*
381  *                   ObjectLab is sponsoring QALab
382  * 
383  * Based in London, we are world leaders in the design and development 
384  * of bespoke applications for the securities financing markets.
385  * 
386  * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
387  *           ___  _     _           _   _          _
388  *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
389  *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
390  *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
391  *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
392  *                   |__/
393  *
394  *                     www.ObjectLab.co.uk
395  */