KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > inspectors > history > HistoryInspector


1 /*
2  * Hammurapi
3  * Automated Java code review system.
4  * Copyright (C) 2004 Hammurapi Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * URL: http://www.hammurapi.org
21  * e-Mail: support@hammurapi.biz
22  */

23 package org.hammurapi.inspectors.history;
24
25 import java.io.File JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.sql.ResultSet JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.text.MessageFormat JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Properties JavaDoc;
36
37 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
38 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
39 import javax.xml.parsers.ParserConfigurationException JavaDoc;
40 import javax.xml.transform.Transformer JavaDoc;
41 import javax.xml.transform.TransformerConfigurationException JavaDoc;
42 import javax.xml.transform.TransformerException JavaDoc;
43 import javax.xml.transform.TransformerFactory JavaDoc;
44 import javax.xml.transform.dom.DOMSource JavaDoc;
45 import javax.xml.transform.stream.StreamResult JavaDoc;
46 import javax.xml.transform.stream.StreamSource JavaDoc;
47
48 import org.hammurapi.HammurapiException;
49 import org.hammurapi.HammurapiRuntimeException;
50 import org.hammurapi.PersistingInspectorBase;
51 import org.hammurapi.results.AnnotationContext;
52 import org.hammurapi.results.LinkedAnnotation;
53 import org.hammurapi.results.NamedResults;
54 import org.hammurapi.results.ResultsFactory;
55 import org.hammurapi.results.AnnotationContext.FileEntry;
56 import org.hammurapi.results.persistent.jdbc.sql.AggregatedResultsMetricData;
57 import org.hammurapi.results.persistent.jdbc.sql.BasicResultTotal;
58 import org.hammurapi.results.persistent.jdbc.sql.Report;
59 import org.hammurapi.results.persistent.jdbc.sql.ResultsEngine;
60 import org.hammurapi.results.simple.SimpleAggregatedResults;
61 import org.jfree.chart.ChartFactory;
62 import org.jfree.chart.ChartUtilities;
63 import org.jfree.chart.JFreeChart;
64 import org.jfree.chart.plot.PlotOrientation;
65 import org.jfree.data.time.Day;
66 import org.jfree.data.time.TimeSeries;
67 import org.jfree.data.time.TimeSeriesCollection;
68 import org.w3c.dom.Document JavaDoc;
69 import org.w3c.dom.Element JavaDoc;
70
71 import com.pavelvlasov.config.ConfigurationException;
72 import com.pavelvlasov.config.XmlSource;
73 import com.pavelvlasov.convert.CompositeConverter;
74 import com.pavelvlasov.jsel.Repository;
75 import com.pavelvlasov.sql.DataAccessObject;
76 import com.pavelvlasov.sql.SQLProcessor;
77 import com.pavelvlasov.xml.dom.AbstractDomObject;
78 import com.pavelvlasov.xml.dom.DOMUtils;
79
80 /**
81  * @author Pavel Vlasov
82  * @version $Revision: 1.8 $
83  */

84 public class HistoryInspector extends PersistingInspectorBase {
85     
86     private XmlSource styleConfig;
87
88     public HistoryInspector() {
89         styleConfig=new XmlSource("style", this.getClass(), ".xsl");
90         addConfigurator(styleConfig);
91     }
92     
93     public static class JoinedHistoryImplEx extends JoinedHistoryImpl implements DataAccessObject {
94         private SQLProcessor processor;
95
96         public void toDom(Element JavaDoc holder) {
97             super.toDom(holder);
98             AbstractDomObject.addTextElement(holder, "DPMO", getDPMO());
99             AbstractDomObject.addTextElement(holder, "Sigma", getSigma());
100             
101             try {
102                 String JavaDoc description=new HistoryEngine(processor).getLastDescription(getReportDate());
103                 if (description!=null) {
104                     AbstractDomObject.addTextElement(holder, "Description", description);
105                 }
106             } catch (SQLException JavaDoc e) {
107                 throw new HammurapiRuntimeException(e);
108             }
109         }
110         
111         public String JavaDoc getDPMO() {
112             if (getReviews()==0) {
113                 return "Not available, no reviews";
114             }
115             
116             return String.valueOf((int) (1000000*getViolationLevel()/getReviews())) + (getHasWarnings()>0 ? "*" : "");
117         }
118
119         public String JavaDoc getSigma() {
120             double p=1.0-getViolationLevel()/getReviews();
121             if (getReviews()==0) {
122                 return "No results";
123             } else if (p<=0) {
124                 return "Full incompliance";
125             } else if (p>=1) {
126                 return "Full compliance";
127             } else {
128                 return MessageFormat.format("{0,number,#.###}", new Object JavaDoc[] {new Double JavaDoc(SimpleAggregatedResults.normsinv(p)+1.5)}) + (getHasWarnings()>0 ? "*" : "");
129             }
130         }
131         
132         public JoinedHistoryImplEx() {
133             super();
134         }
135         
136         public JoinedHistoryImplEx(ResultSet JavaDoc rs) throws SQLException JavaDoc {
137             super(rs);
138         }
139
140         public void setSQLProcessor(SQLProcessor sqlProcessor) {
141             this.processor=sqlProcessor;
142         }
143     }
144     
145     private static abstract class TimeChartGenerator {
146         
147         abstract Number JavaDoc getValue(JoinedHistoryImplEx jhie);
148                 
149         TimeSeries createTimeSeries(Collection JavaDoc series, String JavaDoc title) {
150             TimeSeries timeSeries = new TimeSeries(title);
151             Iterator JavaDoc sit=series.iterator();
152             while (sit.hasNext()) {
153                 JoinedHistoryImplEx jhie=(JoinedHistoryImplEx) sit.next();
154                 timeSeries.add(new Day(new Date JavaDoc(jhie.getReportDate().getTime())), getValue(jhie));
155             }
156             return timeSeries;
157         }
158                 
159         void createPngChart(String JavaDoc title, TimeSeries timeSeries, File JavaDoc out) throws IOException JavaDoc {
160             TimeSeriesCollection timeDataset = new TimeSeriesCollection(timeSeries);
161
162             JFreeChart chart = ChartFactory.createTimeSeriesChart(
163                     title, // Title
164
"Time", // X-Axis label
165
timeSeries.getName(), // Y-Axis label
166
timeDataset, // Dataset
167
true, // Show legend
168
true,
169                     true);
170             
171             ChartUtilities.saveChartAsPNG(out, chart, 500, 300 );
172         }
173         
174         void createPngBarChart(String JavaDoc title, TimeSeries timeSeries, File JavaDoc out) throws IOException JavaDoc {
175             TimeSeriesCollection timeDataset = new TimeSeriesCollection(timeSeries);
176
177             JFreeChart chart = ChartFactory.createXYBarChart(
178                     title, // Title
179
"Time", // X-Axis label
180
true,
181                     timeSeries.getName(), // Y-Axis label
182
timeDataset, // Dataset
183
PlotOrientation.VERTICAL,
184                     true, // Show legend
185
true,
186                     true
187                    );
188             
189             //System.out.println(out);
190
ChartUtilities.saveChartAsPNG(out, chart, 500, 300 );
191         }
192         
193     }
194     
195     public void leave(Repository repository) {
196         getContext().annotate(new LinkedAnnotation() {
197             NamedResults summary=ResultsFactory.getThreadResults();
198             FileEntry rootFile;
199
200             public String JavaDoc getName() {
201                 return "History";
202             }
203
204             public void render(AnnotationContext context) throws HammurapiException {
205                 if (ResultsFactory.getInstance() instanceof org.hammurapi.results.persistent.jdbc.ResultsFactory) {
206                     try {
207                         SQLProcessor processor=getContext().getSession().getProcessor();
208                         HistoryEngine historyEngine=new HistoryEngine(processor);
209                         ResultsEngine resultsEngine = new ResultsEngine(processor);
210                         Iterator JavaDoc it=historyEngine.getReportWithoutHistory(summary.getName(), ((org.hammurapi.results.persistent.jdbc.ResultsFactory) ResultsFactory.getInstance()).getReportId()).iterator();
211                         while (it.hasNext()) {
212                             Report report=(Report) it.next();
213                             BasicResultTotal result = resultsEngine.getBasicResultTotal(report.getResultId().intValue());
214                             AggregatedResultsMetricData cr = resultsEngine.getAggregatedResultsMetricData(report.getResultId().intValue(), "Change ratio");
215                             
216                             historyEngine.insertHistory(
217                                     report.getId(),
218                                     result.getCodebase(),
219                                     (Integer JavaDoc) CompositeConverter.getDefaultConverter().convert(result.getMaxSeverity(), Integer JavaDoc.class, false),
220                                     result.getReviews(),
221                                     result.getViolationLevel(),
222                                     result.getViolations(),
223                                     result.getWaivedViolations(),
224                                     (int) result.getHasWarnings(),
225                                     cr==null ? -1 : cr.getTotalValue()/ cr.getMeasurements(),
226                                     result.getCompilationUnits(),
227                                     result.getResultDate(),
228                                     report.getName(),
229                                     report.getDescription(),
230                                     new Long JavaDoc(report.getExecutionTime()==null ? 0 : report.getExecutionTime().longValue()));
231                         }
232                         
233                         Document JavaDoc doc=DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
234                         Element JavaDoc root = doc.createElement("history");
235                         root.setAttribute("title", summary.getName());
236                         doc.appendChild(root);
237                         Collection JavaDoc series=new ArrayList JavaDoc();
238                         DOMUtils.toDom(historyEngine.getJoinedHistory(summary.getName(), series, JoinedHistoryImplEx.class), root);
239                         
240                         // Generate charts here
241
if (series.size()>1) {
242                             generateNodesChart(context, root, series);
243                             generateFilesChart(context, root, series);
244                             generateActivityChart(context, root, series);
245                             generateSigmaChart(context, root, series);
246                             generateDpmoChart(context, root, series);
247                             generateMaxSeverityChart(context, root, series);
248                             generateViolationsChart(context, root, series);
249                             generateReviewsChart(context, root, series);
250                             //generatePerformanceChart(context, root, series);
251
}
252                         
253                         rootFile=context.getNextFile(context.getExtension());
254                         
255                         if (context.getExtension().equalsIgnoreCase(".html")) {
256                             TransformerFactory JavaDoc tFactory = TransformerFactory.newInstance();
257                             InputStream JavaDoc styleStream = styleConfig.getStream();
258                             if (styleStream==null) {
259                                 throw new HammurapiException("Stylesheet cannot be loaded");
260                             }
261                             
262                             Transformer JavaDoc transformer = tFactory.newTransformer(new StreamSource JavaDoc(styleStream));
263
264                             DOMSource JavaDoc domSource = new DOMSource JavaDoc(doc);
265                             transformer.transform(domSource, new StreamResult JavaDoc(rootFile.getFile()));
266                         } else {
267                             DOMUtils.serialize(doc, rootFile.getFile());
268                         }
269                     } catch (ConfigurationException JavaDoc e) {
270                         throw new HammurapiException("Cannot render history annotation, "+e.getMessage(), e);
271                     } catch (IOException JavaDoc e) {
272                         throw new HammurapiException("Cannot render history annotation, "+e.getMessage(), e);
273                     } catch (SQLException JavaDoc e) {
274                         throw new HammurapiException("Cannot process history annotation, "+e.getMessage(), e);
275                     } catch (ParserConfigurationException JavaDoc e) {
276                         throw new HammurapiException("Cannot process history annotation, "+e.getMessage(), e);
277                     } catch (FactoryConfigurationError JavaDoc e) {
278                         throw new HammurapiException("Cannot process history annotation, "+e.getMessage(), e);
279                     } catch (TransformerConfigurationException JavaDoc e) {
280                         throw new HammurapiException("Cannot process history annotation, "+e.getMessage(), e);
281                     } catch (TransformerException JavaDoc e) {
282                         throw new HammurapiException("Cannot process history annotation, "+e.getMessage(), e);
283                     }
284                 }
285             }
286
287             /**
288              * @param context
289              * @param root
290              * @param series
291              * @throws HammurapiException
292              * @throws IOException
293              */

294             private void generateNodesChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
295                 TimeChartGenerator codeBaseChartGenerator=new TimeChartGenerator() {
296                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
297                         return new Long JavaDoc(jhie.getCodebase());
298                     }
299                 };
300                 
301                 FileEntry codeBaseNodesChart=context.getNextFile(".png");
302                 TimeSeries cbtn = codeBaseChartGenerator.createTimeSeries(series, "Nodes");
303                 codeBaseChartGenerator.createPngChart("Codebase history (nodes)", cbtn, codeBaseNodesChart.getFile());
304                 root.setAttribute("nodes-chart", codeBaseNodesChart.getPath());
305             }
306
307             /**
308              * @param context
309              * @param root
310              * @param series
311              * @throws HammurapiException
312              * @throws IOException
313              */

314             private void generateFilesChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
315                 TimeChartGenerator codeBaseChartGenerator=new TimeChartGenerator() {
316                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
317                         return new Long JavaDoc(jhie.getCompilationUnits());
318                     }
319                 };
320                 
321                 FileEntry codeBaseChart=context.getNextFile(".png");
322                 TimeSeries cbtn = codeBaseChartGenerator.createTimeSeries(series, "Files");
323                 codeBaseChartGenerator.createPngChart("Codebase history (files)", cbtn, codeBaseChart.getFile());
324                 root.setAttribute("files-chart", codeBaseChart.getPath());
325             }
326             
327             /**
328              * @param context
329              * @param root
330              * @param series
331              * @throws HammurapiException
332              * @throws IOException
333              */

334             private void generateActivityChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
335                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
336                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
337                         return new Integer JavaDoc((int) (jhie.getChangeRatio() * 100));
338                     }
339                 };
340                 
341                 FileEntry fileEntry=context.getNextFile(".png");
342                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "Activity (%)");
343                 chartGenerator.createPngBarChart("Activity history", cbtn, fileEntry.getFile());
344                 root.setAttribute("activity-chart", fileEntry.getPath());
345             }
346             
347             /**
348              * @param context
349              * @param root
350              * @param series
351              * @throws HammurapiException
352              * @throws IOException
353              */

354             private void generateSigmaChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
355                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
356                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
357                         String JavaDoc sigma=jhie.getSigma();
358                         int idx=sigma.indexOf(' ');
359                         try {
360                             return new Double JavaDoc(idx==-1 ? sigma : sigma.substring(0, idx));
361                         } catch (NumberFormatException JavaDoc e) {
362                             return null;
363                         }
364                     }
365                 };
366                 
367                 FileEntry fileEntry=context.getNextFile(".png");
368                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "Sigma");
369                 chartGenerator.createPngChart("Sigma history", cbtn, fileEntry.getFile());
370                 root.setAttribute("sigma-chart", fileEntry.getPath());
371             }
372             
373             /**
374              * @param context
375              * @param root
376              * @param series
377              * @throws HammurapiException
378              * @throws IOException
379              */

380             private void generateDpmoChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
381                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
382                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
383                         String JavaDoc dpmo=jhie.getDPMO();
384                         int idx=dpmo.indexOf(' ');
385                         try {
386                             return new Long JavaDoc(idx==-1 ? dpmo : dpmo.substring(0, idx));
387                         } catch (NumberFormatException JavaDoc e) {
388                             return null;
389                         }
390                     }
391                 };
392                 
393                 FileEntry fileEntry=context.getNextFile(".png");
394                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "DPMO");
395                 chartGenerator.createPngChart("DPMO history", cbtn, fileEntry.getFile());
396                 root.setAttribute("dpmo-chart", fileEntry.getPath());
397             }
398             
399             /**
400              * @param context
401              * @param root
402              * @param series
403              * @throws HammurapiException
404              * @throws IOException
405              */

406             private void generateViolationsChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
407                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
408                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
409                         return new Long JavaDoc(jhie.getViolations());
410                     }
411                 };
412                 
413                 FileEntry fileEntry=context.getNextFile(".png");
414                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "Violations");
415                 chartGenerator.createPngChart("Violations history", cbtn, fileEntry.getFile());
416                 root.setAttribute("violations-chart", fileEntry.getPath());
417             }
418             
419             /**
420              * @param context
421              * @param root
422              * @param series
423              * @throws HammurapiException
424              * @throws IOException
425              */

426             private void generateMaxSeverityChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
427                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
428                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
429                         return new Integer JavaDoc(jhie.getMaxSeverity());
430                     }
431                 };
432                 
433                 FileEntry fileEntry=context.getNextFile(".png");
434                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "Max severity");
435                 chartGenerator.createPngChart("Max severity history", cbtn, fileEntry.getFile());
436                 root.setAttribute("max-severity-chart", fileEntry.getPath());
437             }
438             
439             /**
440              * @param context
441              * @param root
442              * @param series
443              * @throws HammurapiException
444              * @throws IOException
445              */

446             private void generateReviewsChart(AnnotationContext context, Element JavaDoc root, Collection JavaDoc series) throws HammurapiException, IOException JavaDoc {
447                 TimeChartGenerator chartGenerator=new TimeChartGenerator() {
448                     Number JavaDoc getValue(JoinedHistoryImplEx jhie) {
449                         return new Long JavaDoc(jhie.getReviews());
450                     }
451                 };
452                 
453                 FileEntry fileEntry=context.getNextFile(".png");
454                 TimeSeries cbtn = chartGenerator.createTimeSeries(series, "Reviews");
455                 chartGenerator.createPngChart("Reviews history", cbtn, fileEntry.getFile());
456                 root.setAttribute("reviews-chart", fileEntry.getPath());
457             }
458             
459             public Properties JavaDoc getProperties() {
460                 return null;
461             }
462
463             public String JavaDoc getPath() {
464                 return rootFile.getPath();
465             }
466             
467         });
468     }
469 }
470
Popular Tags