Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BuildStatMergeTask |
|
| 3.2857142857142856;3.286 |
1 | //////////////////////////////////////////////////////////////////////////////// | |
2 | // ObjectLab is sponsoring QALab | |
3 | // | |
4 | // Based in London, we are world leaders in the design and development | |
5 | // of bespoke applications for the Securities Financing markets. | |
6 | // | |
7 | // <a href="http://www.objectlab.co.uk/open">Click here to learn more</a> | |
8 | // ___ _ _ _ _ _ | |
9 | // / _ \| |__ (_) ___ ___| |_| | __ _| |__ | |
10 | // | | | | '_ \| |/ _ \/ __| __| | / _` | '_ \ | |
11 | // | |_| | |_) | | __/ (__| |_| |__| (_| | |_) | | |
12 | // \___/|_.__// |\___|\___|\__|_____\__,_|_.__/ | |
13 | // |__/ | |
14 | // | |
15 | // http://www.ObjectLab.co.uk | |
16 | // --------------------------------------------------------------------------- | |
17 | // | |
18 | //QALab is released under the GNU General Public License. | |
19 | // | |
20 | //QALab: Collects QA Statistics from your build over time. | |
21 | //2005+, ObjectLab Ltd | |
22 | // | |
23 | //This library is free software; you can redistribute it and/or | |
24 | //modify it under the terms of the GNU General Public | |
25 | //License as published by the Free Software Foundation; either | |
26 | //version 2.1 of the License, or (at your option) any later version. | |
27 | // | |
28 | //This library is distributed in the hope that it will be useful, | |
29 | //but WITHOUT ANY WARRANTY; without even the implied warranty of | |
30 | //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31 | //General Public License for more details. | |
32 | // | |
33 | //You should have received a copy of the GNU General Public | |
34 | //License along with this library; if not, write to the Free Software | |
35 | //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
36 | // | |
37 | //////////////////////////////////////////////////////////////////////////////// | |
38 | package net.objectlab.qalab.ant; | |
39 | ||
40 | import net.objectlab.qalab.interfaces.QALabExporter; | |
41 | import net.objectlab.qalab.parser.StatMerger; | |
42 | import net.objectlab.qalab.util.TaskLogger; | |
43 | ||
44 | import org.apache.tools.ant.BuildException; | |
45 | import org.apache.tools.ant.Task; | |
46 | import org.xml.sax.InputSource; | |
47 | ||
48 | import java.io.File; | |
49 | import java.io.FileInputStream; | |
50 | import java.io.FileNotFoundException; | |
51 | import java.io.FileReader; | |
52 | import java.io.IOException; | |
53 | ||
54 | import java.util.Hashtable; | |
55 | import java.util.Iterator; | |
56 | import java.util.Map; | |
57 | import java.util.Properties; | |
58 | ||
59 | /** | |
60 | * The ant task that handles the merger of statistics into qalab.xml. | |
61 | * | |
62 | * @author Benoit Xhenseval | |
63 | * @version $Revision: 187 $ | |
64 | */ | |
65 | 0 | public class BuildStatMergeTask extends Task { |
66 | // ~ Instance fields | |
67 | // ------------------------------------------------------------------------ | |
68 | ||
69 | /** the base properties file. */ | |
70 | 0 | private File inputFile = null; |
71 | ||
72 | /** the merged properties file. */ | |
73 | 0 | private File outputFile = null; |
74 | ||
75 | /** if true, logging output will be suppressed. */ | |
76 | 0 | private boolean quiet = false; |
77 | ||
78 | /** the directory where the source code is. */ | |
79 | private String srcDir; | |
80 | ||
81 | /** the handler for these statistics. */ | |
82 | private String handler; | |
83 | ||
84 | /** a given timestamp for the stats. */ | |
85 | private String mergerTimeStamp; | |
86 | ||
87 | /** exporter class name. */ | |
88 | 0 | private String exporterClassName = "net.objectlab.qalab.exporter.QALabXMLExporter"; |
89 | ||
90 | /** properties file to use instead of setting them one by one. */ | |
91 | private File propertiesFile; | |
92 | ||
93 | /** the loaded properties. */ | |
94 | 0 | private Properties properties = null; |
95 | ||
96 | // ~ Methods | |
97 | // ------------------------------------------------------------------------ | |
98 | ||
99 | /** | |
100 | * Sets the class name for the handler for the given statistics. | |
101 | * | |
102 | * @param theHandler | |
103 | * class name for the handler. | |
104 | */ | |
105 | public final void setHandler(final String theHandler) { | |
106 | 0 | this.handler = theHandler; |
107 | 0 | } |
108 | ||
109 | /** | |
110 | * @return the handler | |
111 | */ | |
112 | private String getHandler() { | |
113 | 0 | return handler; |
114 | } | |
115 | ||
116 | /** | |
117 | * @param sourceDirectory | |
118 | * directory where the source code is. | |
119 | */ | |
120 | public final void setSrcDir(final String sourceDirectory) { | |
121 | 0 | this.srcDir = sourceDirectory; |
122 | 0 | } |
123 | ||
124 | /** | |
125 | * Sets the input file containing the new statistics (checkstyle,etc). | |
126 | * | |
127 | * @param newStatisticsFile | |
128 | * the whose values will be incorporated in the qalab.xml | |
129 | */ | |
130 | public final void setInputFile(final File newStatisticsFile) { | |
131 | 0 | this.inputFile = newStatisticsFile; |
132 | 0 | } |
133 | ||
134 | /** | |
135 | * Set the to output file (typically qalab.xml). | |
136 | * | |
137 | * @param consolidatedFile | |
138 | * the destination file where the statistics are written. The | |
139 | * file may or may not exists. | |
140 | */ | |
141 | public final void setOutputFile(final File consolidatedFile) { | |
142 | 0 | this.outputFile = consolidatedFile; |
143 | 0 | } |
144 | ||
145 | /** | |
146 | * Sets the quiet mode. | |
147 | * | |
148 | * @param noLog | |
149 | * if true, no messages are displayed while merging stats. | |
150 | */ | |
151 | public final void setQuiet(final boolean noLog) { | |
152 | 0 | this.quiet = noLog; |
153 | 0 | } |
154 | ||
155 | /** | |
156 | * Sets the timestamp mode. | |
157 | * | |
158 | * @param timestamp | |
159 | * if present, uses this as timestamp for stats. | |
160 | */ | |
161 | public final void setMergerTimeStamp(final String timestamp) { | |
162 | 0 | this.mergerTimeStamp = timestamp; |
163 | 0 | } |
164 | ||
165 | /** | |
166 | * Method invoked by the ant framework to execute the action associated with | |
167 | * this task. This will validate the input parameters then merge the | |
168 | * statistics. | |
169 | */ | |
170 | public final void execute() { | |
171 | 0 | properties = createOverridingProperties(); |
172 | ||
173 | // validate the provided parameters | |
174 | 0 | validate(); |
175 | ||
176 | // Display the files being processed | |
177 | 0 | if (!quiet) { |
178 | 0 | log("inputFile='" + inputFile.getPath() + "', outputFile='" |
179 | + outputFile.getPath()); | |
180 | 0 | log("srcDir='" + srcDir + "', mergerTimeStamp=" + mergerTimeStamp); |
181 | 0 | log("quiet='" |
182 | + quiet | |
183 | + "', propertiesFile=" | |
184 | + (propertiesFile != null ? propertiesFile.getPath() : null)); | |
185 | 0 | for (Iterator it = properties.entrySet().iterator(); it.hasNext();) { |
186 | 0 | final Map.Entry entry = (Map.Entry) it.next(); |
187 | 0 | final String key = entry.getKey().toString(); |
188 | 0 | if (key.indexOf("qalab") >= 0) { |
189 | 0 | log(key + " = '" + entry.getValue() + "'"); |
190 | } | |
191 | 0 | } |
192 | } | |
193 | ||
194 | 0 | mergeFiles(); |
195 | 0 | } |
196 | ||
197 | /** | |
198 | * Merge the statistics into the qalab.xml. | |
199 | */ | |
200 | private void mergeFiles() { | |
201 | try { | |
202 | 0 | TaskLogger logger = new AntTaskLogger(this); |
203 | ||
204 | // create the exporter | |
205 | 0 | QALabExporter exporter = (QALabExporter) Class.forName( |
206 | getExporterClassName()).newInstance(); | |
207 | ||
208 | 0 | properties.setProperty("qalab.merge.output.file", outputFile |
209 | .getAbsolutePath()); | |
210 | ||
211 | 0 | exporter.setQuiet(quiet); |
212 | 0 | exporter.setTaskLogger(logger); |
213 | ||
214 | 0 | StatMerger merger = (StatMerger) Class.forName(getHandler()) |
215 | .newInstance(); | |
216 | ||
217 | 0 | merger.setQuiet(quiet); |
218 | 0 | merger.setSrcDir(srcDir); |
219 | 0 | merger.setTaskLogger(logger); |
220 | 0 | final String tsOnly = properties |
221 | .getProperty("qalab.merge.timestampdateonly"); | |
222 | 0 | merger.setMergerTimeStamp(mergerTimeStamp, tsOnly != null |
223 | && (tsOnly.equalsIgnoreCase("yes") || tsOnly | |
224 | .equalsIgnoreCase("true"))); | |
225 | ||
226 | 0 | properties.setProperty("qalab.merge.output.timestamp", merger |
227 | .getMergerTimeStamp()); | |
228 | 0 | properties.setProperty("qalab.merge.type", merger.getType()); |
229 | 0 | exporter.configure(properties); |
230 | ||
231 | 0 | merger.mergeStats(new InputSource(new FileReader(inputFile)), |
232 | exporter); | |
233 | 0 | log("Files: " + merger.getFileCount() + " Statistics:" |
234 | + merger.getTotalStatistics()); | |
235 | ||
236 | 0 | exporter.save(); |
237 | 0 | } catch (IllegalAccessException e) { |
238 | 0 | e.printStackTrace(); |
239 | 0 | throw new BuildException(e.toString()); |
240 | 0 | } catch (FileNotFoundException e) { |
241 | 0 | e.printStackTrace(); |
242 | 0 | throw new BuildException(e.toString()); |
243 | 0 | } catch (IOException e) { |
244 | 0 | e.printStackTrace(); |
245 | 0 | throw new BuildException(e.toString()); |
246 | 0 | } catch (ClassNotFoundException e) { |
247 | 0 | e.printStackTrace(); |
248 | 0 | throw new BuildException(e.toString()); |
249 | 0 | } catch (InstantiationException e) { |
250 | 0 | e.printStackTrace(); |
251 | 0 | throw new BuildException(e.toString()); |
252 | 0 | } catch (Exception e) { |
253 | 0 | e.printStackTrace(); |
254 | 0 | throw new BuildException(e.toString()); |
255 | 0 | } |
256 | 0 | } |
257 | ||
258 | /** | |
259 | * Validates the parameters supplied by ant. | |
260 | */ | |
261 | private void validate() { | |
262 | 0 | if (inputFile == null) { |
263 | 0 | throw new BuildException("inputFile is mandatory"); |
264 | } | |
265 | ||
266 | 0 | if (!inputFile.canRead()) { |
267 | 0 | final String message = "Unable to read from " + inputFile + "."; |
268 | ||
269 | 0 | throw new BuildException(message); |
270 | } | |
271 | 0 | } |
272 | ||
273 | /** | |
274 | * @param exporterClass | |
275 | * The exporterClassName to set. | |
276 | */ | |
277 | public final void setExporterClassName(final String exporterClass) { | |
278 | 0 | this.exporterClassName = exporterClass; |
279 | 0 | } |
280 | ||
281 | /** | |
282 | * @return Returns the exporterClassName. | |
283 | */ | |
284 | public final String getExporterClassName() { | |
285 | 0 | if (exporterClassName != null) { |
286 | 0 | return exporterClassName; |
287 | } else { | |
288 | 0 | return properties.getProperty("qalab.merge.exporterclass"); |
289 | } | |
290 | } | |
291 | ||
292 | /** | |
293 | * Sets a properties file for use instead of individually setting them. | |
294 | * | |
295 | * @param aProps | |
296 | * the properties File to use | |
297 | */ | |
298 | public final void setPropertiesFile(final File aProps) { | |
299 | 0 | propertiesFile = aProps; |
300 | 0 | } |
301 | ||
302 | /** | |
303 | * Create the Properties object based on the arguments specified to the ANT | |
304 | * task. | |
305 | * | |
306 | * @return the properties for property expansion expansion | |
307 | */ | |
308 | private Properties createOverridingProperties() { | |
309 | 0 | final Properties retVal = new Properties(); |
310 | ||
311 | // Load the properties file if specified | |
312 | 0 | if (propertiesFile != null && propertiesFile.canRead() |
313 | && propertiesFile.isFile()) { | |
314 | 0 | FileInputStream inStream = null; |
315 | 0 | if (!quiet) { |
316 | 0 | log("loading " + propertiesFile); |
317 | } | |
318 | try { | |
319 | 0 | inStream = new FileInputStream(propertiesFile); |
320 | 0 | retVal.load(inStream); |
321 | 0 | } catch (FileNotFoundException e) { |
322 | 0 | throw new BuildException("Could not find Properties file '" |
323 | + propertiesFile + "'", e, getLocation()); | |
324 | 0 | } catch (IOException e) { |
325 | 0 | throw new BuildException("Error loading Properties file '" |
326 | + propertiesFile + "'", e, getLocation()); | |
327 | } finally { | |
328 | 0 | try { |
329 | 0 | if (inStream != null) { |
330 | 0 | inStream.close(); |
331 | } | |
332 | 0 | } catch (IOException e) { |
333 | 0 | throw new BuildException("Error closing Properties file '" |
334 | + propertiesFile + "'", e, getLocation()); | |
335 | 0 | } |
336 | 0 | } |
337 | } | |
338 | ||
339 | // override with Ant properties like ${basedir} | |
340 | 0 | final Hashtable antProps = this.getProject().getProperties(); |
341 | ||
342 | 0 | for (Iterator it = antProps.entrySet().iterator(); it.hasNext();) { |
343 | 0 | final Map.Entry entry = (Map.Entry) it.next(); |
344 | 0 | final String value = String.valueOf(entry.getValue()); |
345 | 0 | if (!quiet && entry.getKey().toString().indexOf("qalab") >= 0) { |
346 | 0 | log("Adding Prop: " + entry.getKey() + " / [" + value + "]"); |
347 | } | |
348 | 0 | retVal.put(entry.getKey(), value); |
349 | 0 | } |
350 | ||
351 | 0 | return retVal; |
352 | } | |
353 | } | |
354 | /* | |
355 | * ObjectLab is sponsoring QALab | |
356 | * | |
357 | * Based in London, we are world leaders in the design and development | |
358 | * of bespoke applications for the securities financing markets. | |
359 | * | |
360 | * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a> | |
361 | * ___ _ _ _ _ _ | |
362 | * / _ \| |__ (_) ___ ___| |_| | __ _| |__ | |
363 | * | | | | '_ \| |/ _ \/ __| __| | / _` | '_ \ | |
364 | * | |_| | |_) | | __/ (__| |_| |__| (_| | |_) | | |
365 | * \___/|_.__// |\___|\___|\__|_____\__,_|_.__/ | |
366 | * |__/ | |
367 | * | |
368 | * www.ObjectLab.co.uk | |
369 | */ |