KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > Output


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
24 package org.hammurapi;
25
26 import java.io.File JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.FileNotFoundException JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36
37 import org.apache.tools.ant.BuildException;
38 import org.apache.tools.ant.Project;
39 import org.apache.tools.ant.util.FileUtils;
40 import org.hammurapi.render.dom.CompositeResultsRenderer;
41 import org.hammurapi.render.dom.HammurapiMetricRenderer;
42 import org.hammurapi.render.dom.InspectorDescriptorRenderer;
43 import org.hammurapi.render.dom.InspectorSetRenderer;
44 import org.hammurapi.render.dom.InspectorSummaryRenderer;
45 import org.hammurapi.render.dom.ReportRenderer;
46 import org.hammurapi.render.dom.ReviewResultsRenderer;
47 import org.hammurapi.results.AggregatedResults;
48 import org.hammurapi.results.Annotation;
49 import org.hammurapi.results.AnnotationConfig;
50 import org.hammurapi.results.AnnotationContext;
51 import org.hammurapi.results.CompositeResults;
52 import org.hammurapi.results.InspectorSummary;
53 import org.hammurapi.results.ReportMixer;
54 import org.hammurapi.results.ReviewResults;
55
56 import com.pavelvlasov.config.ConfigurationException;
57 import com.pavelvlasov.metrics.MeasurementCategoryFactory;
58 import com.pavelvlasov.metrics.Metric;
59 import com.pavelvlasov.metrics.TimeIntervalCategory;
60 import com.pavelvlasov.render.RenderRequest;
61 import com.pavelvlasov.render.RenderingException;
62 import com.pavelvlasov.render.dom.AbstractRenderer;
63
64 /**
65  * Outputs review results to XML or HTML.
66  * @ant.element parent="hammurapi" name="output" display-name="Output subelement"
67  * @ant.non-required
68  * @author Pavel Vlasov
69  * @version $Revision: 1.12 $
70  */

71 public class Output implements Listener /*, ReviewUnitFilter*/ {
72     private String JavaDoc dir;
73     private boolean embeddedStyle=true;
74     private String JavaDoc extension=".html";
75     private TaskBase task;
76     
77     public Output(TaskBase task) {
78         this.task=task;
79     }
80     
81     /**
82      * Output directory
83      * @ant.required
84      */

85     public void setDir(String JavaDoc dir) {
86         this.dir=dir;
87     }
88     
89     private Map JavaDoc styleSheets=new HashMap JavaDoc();
90     
91     {
92         styleSheets.put("compilation-unit", new StyleSheetEntry());
93         styleSheets.put("summary", new StyleSheetEntry());
94         styleSheets.put("left-panel", new StyleSheetEntry());
95         styleSheets.put("waived-violations", new StyleSheetEntry());
96         styleSheets.put("package", new StyleSheetEntry());
97         styleSheets.put("inspector-set", new StyleSheetEntry());
98         styleSheets.put("inspector-descriptor", new StyleSheetEntry());
99         styleSheets.put("inspector-summary", new StyleSheetEntry());
100         styleSheets.put("metric-details", new StyleSheetEntry());
101     }
102     
103     public void addConfiguredStyleSheet(StyleSheetEntry styleSheet) {
104         if (styleSheet.getName()==null) {
105             throw new BuildException("Unnamed stylesheet");
106         }
107         
108         StyleSheetEntry existing=(StyleSheetEntry) styleSheets.get(styleSheet.getName());
109         if (existing==null) {
110             throw new BuildException("Invalid stylesheet name: "+styleSheet.getName());
111         }
112         
113         if (styleSheet.getFile()!=null) {
114             existing.setFile(styleSheet.getFile());
115         }
116         
117         if (styleSheet.getUrl()!=null) {
118             existing.setUrl(styleSheet.getUrl());
119         }
120         
121         existing.setParameters(styleSheet.getParameters());
122     }
123         
124     /**
125      * Use embedded stylesheets if no stylesheets has been set explicitly.
126      * Default is true.
127      * @ant.non-required
128      */

129     public void setEmbeddedStyle(boolean embeddedStyle) {
130         this.embeddedStyle=embeddedStyle;
131     }
132     
133     /**
134      * Extension for output files. Defaults to ".html"
135      * @ant.non-required
136      */

137     public void setExtension(String JavaDoc extension) {
138         this.extension=extension;
139     }
140     
141     private File JavaDoc javaDocDir;
142     
143     /**
144      * JavaDoc directory to generate links.
145      * @ant.non-required
146      */

147     public void setJavaDocDir(File JavaDoc javaDocDir) {
148         this.javaDocDir=javaDocDir;
149     }
150     
151     private File JavaDoc getOutDir() throws HammurapiException {
152         File JavaDoc outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
153         if (!outDir.exists()) {
154             throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
155         }
156         
157         if (!outDir.isDirectory()) {
158             throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
159         }
160         
161         return outDir;
162     }
163     
164     private String JavaDoc getFileName(ReviewResults reviewResult) {
165         String JavaDoc packageName=reviewResult.getCompilationUnit().getPackage().getName();
166         String JavaDoc unitName=reviewResult.getName();
167         return "source/"+packageName.replace('.', '/')+'/'+unitName;
168     }
169     
170     private File JavaDoc getFile(ReviewResults reviewResult) throws HammurapiException {
171         return new File JavaDoc(getOutDir(), getFileName(reviewResult)+extension);
172     }
173     
174     private static final Object JavaDoc mkDirSynchronizationMonitor=new Object JavaDoc();
175     
176     public void onReview(ReviewResults reviewResult) throws HammurapiException {
177         if (dir==null) {
178             throw new HammurapiException("dir attribute is mandatory");
179         }
180         
181         final File JavaDoc outFile=getFile(reviewResult);
182         final File JavaDoc outFileParent=outFile.getParentFile();
183         synchronized (mkDirSynchronizationMonitor) {
184             if (!outFileParent.exists()) {
185                 if (!outFileParent.mkdirs()) {
186                     throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath());
187                 }
188             }
189         }
190         
191         String JavaDoc packageName=reviewResult.getCompilationUnit().getPackage().getName();
192         int count=0;
193         for (int i=0; i<packageName.length(); i++) {
194             if ('.'==packageName.charAt(i)) {
195                 count++;
196             }
197         }
198         
199         StringBuffer JavaDoc inspectorsPath=new StringBuffer JavaDoc("../");
200         while (count-->=0) {
201             inspectorsPath.append("../");
202         }
203                        
204         renderAnnotations(reviewResult, outFile);
205         
206         writeUnitDoc(reviewResult, outFile, inspectorsPath.toString(), getJavaDocPath(reviewResult));
207     }
208     
209     /**
210      * @param reviewResult
211      * @param outFile
212      * @throws HammurapiException
213      */

214     private void renderAnnotations(AggregatedResults reviewResult, final File JavaDoc outFile) throws HammurapiException {
215         Iterator JavaDoc ait=reviewResult.getAnnotations().iterator();
216         while (ait.hasNext()) {
217             final Annotation annotation=(Annotation) ait.next();
218             annotation.render(new AnnotationContext() {
219                 public FileEntry getNextFile(String JavaDoc extension) throws HammurapiException {
220                     try {
221                         final File JavaDoc ret=File.createTempFile(outFile.getName()+"_"+annotation.getName(),extension,outFile.getParentFile());
222                         return new AnnotationContext.FileEntry() {
223                             public File JavaDoc getFile() {
224                                 return ret;
225                             }
226     
227                             public String JavaDoc getPath() {
228                                 return ret.getName();
229                             }
230                         };
231                     } catch (IOException JavaDoc e) {
232                         throw new HammurapiException(e);
233                     }
234                 }
235
236                 public String JavaDoc getExtension() {
237                     return Output.this.getExtension();
238                 }
239
240                 public Object JavaDoc getParameter(String JavaDoc name) throws BuildException {
241                     AnnotationConfig ac=(AnnotationConfig) annotationConfigs.get(annotation.getName());
242                     if (ac==null) {
243                         return null;
244                     }
245                     
246                     return ac.getParameter(name);
247                 }
248
249                 public boolean isEmbeddedStyle() {
250                     return Output.this.isEmbeddedStyle();
251                 }
252             });
253         }
254     }
255
256     private String JavaDoc getRelativePath(String JavaDoc packageName) throws HammurapiException {
257         if (javaDocDir==null) {
258             return null;
259         }
260         
261         try {
262             StringTokenizer JavaDoc ost=new StringTokenizer JavaDoc(getOutDir().getCanonicalPath(), File.separator);
263             StringTokenizer JavaDoc jst=new StringTokenizer JavaDoc(javaDocDir.getCanonicalPath(), File.separator);
264             StringBuffer JavaDoc upPath=new StringBuffer JavaDoc("../");
265             StringBuffer JavaDoc downPath=new StringBuffer JavaDoc();
266             while (ost.hasMoreTokens() && jst.hasMoreTokens()) {
267                 String JavaDoc ot=ost.nextToken();
268                 String JavaDoc jt=jst.nextToken();
269                 if (!ot.equals(jt)) {
270                     upPath.append("../");
271                     downPath.append(jt);
272                     downPath.append("/");
273                     break;
274                 }
275             }
276
277             while (ost.hasMoreTokens()) {
278                 upPath.append("../");
279                 ost.nextToken();
280             }
281
282             while (jst.hasMoreTokens()) {
283                 downPath.append(jst.nextToken());
284                 downPath.append("/");
285             }
286             
287             StringTokenizer JavaDoc pst=new StringTokenizer JavaDoc(packageName, ".");
288             while (pst.hasMoreTokens()) {
289                 upPath.append("../");
290                 downPath.append(pst.nextToken());
291                 downPath.append("/");
292             }
293
294             upPath.append(downPath);
295             return upPath.toString();
296         } catch (IOException JavaDoc e) {
297             return null;
298         }
299     }
300      
301     private String JavaDoc getRelativePath() throws HammurapiException {
302         if (javaDocDir==null) {
303             return null;
304         }
305         
306         try {
307             StringTokenizer JavaDoc ost=new StringTokenizer JavaDoc(getOutDir().getCanonicalPath(), File.separator);
308             StringTokenizer JavaDoc jst=new StringTokenizer JavaDoc(javaDocDir.getCanonicalPath(), File.separator);
309             StringBuffer JavaDoc upPath=new StringBuffer JavaDoc();
310             StringBuffer JavaDoc downPath=new StringBuffer JavaDoc();
311             while (ost.hasMoreTokens() && jst.hasMoreTokens()) {
312                 String JavaDoc ot=ost.nextToken();
313                 String JavaDoc jt=jst.nextToken();
314                 if (!ot.equals(jt)) {
315                     upPath.append("../");
316                     downPath.append(jt);
317                     downPath.append("/");
318                     break;
319                 }
320             }
321
322             while (ost.hasMoreTokens()) {
323                 upPath.append("../");
324                 ost.nextToken();
325             }
326
327             while (jst.hasMoreTokens()) {
328                 downPath.append(jst.nextToken());
329                 downPath.append("/");
330             }
331             
332             upPath.append(downPath);
333             return upPath.toString();
334         } catch (IOException JavaDoc e) {
335             return null;
336         }
337     }
338     
339     /**
340      * @pag:todo Should calculate relative path to JavaDoc dir.
341      */

342     private String JavaDoc getJavaDocPath(ReviewResults ru) throws HammurapiException {
343         if (javaDocDir==null) {
344             return null;
345         }
346         
347         if (!javaDocDir.exists()) {
348             throw new HammurapiException("JavaDoc directory does not exist");
349         }
350         
351         String JavaDoc packageName = ru.getCompilationUnit().getPackage().getName();
352         String JavaDoc path=getRelativePath(packageName);
353         if (path==null) {
354             path=javaDocDir.getAbsolutePath()+'/'+packageName.replace('.', '/')+"/";
355         }
356         
357         return path;
358     }
359     
360     /**
361      * @pag:todo Should calculate relative path to JavaDoc dir.
362      */

363     private String JavaDoc getJavaDocPath(CompositeResults packageResults) throws HammurapiException {
364         if (javaDocDir==null) {
365             return null;
366         }
367         
368         if (!javaDocDir.exists()) {
369             throw new HammurapiException("JavaDoc directory does not exist");
370         }
371         
372         String JavaDoc path=getRelativePath(packageResults.getName());
373         if (path==null) {
374             path=javaDocDir.getAbsolutePath()+'/'+packageResults.getName().replace('.', '/')+'/';
375         }
376         
377         return path+"package-summary.html";
378     }
379     
380     private static TimeIntervalCategory tic=MeasurementCategoryFactory.getTimeIntervalCategory(Output.class);
381     
382     private void render(AbstractRenderer renderer, String JavaDoc styleName, String JavaDoc inspectorsPath, String JavaDoc javaDocPath, File JavaDoc outFile)
383     throws HammurapiException {
384         long start=tic.getTime();
385         File JavaDoc outFileParent=outFile.getParentFile();
386         if (!outFileParent.exists()) {
387             if (!outFileParent.mkdirs()) {
388                 throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath());
389             }
390         }
391         
392         renderer.setEmbeddedStyle(embeddedStyle);
393         
394         StyleSheetEntry sse=(StyleSheetEntry) styleSheets.get(styleName);
395         if (sse==null) {
396             throw new HammurapiException("Stylesheet entry with name '"+styleName +"' not found");
397         }
398         
399         try {
400             sse.setParameters(task.getProject(), renderer);
401         } catch (ConfigurationException ce) {
402             throw new HammurapiException("setParameters() failed", ce);
403         }
404         
405         if (inspectorsPath!=null) {
406             renderer.setParameter("inspectorsPath", inspectorsPath);
407         }
408         
409         if (javaDocPath!=null) {
410             renderer.setParameter("javaDocPath", javaDocPath);
411         }
412         
413         try {
414             if (sse.getFile()==null) {
415                 renderer.render(new FileOutputStream JavaDoc(outFile));
416             } else {
417                 renderer.render(new FileInputStream JavaDoc(sse.getFile()), new FileOutputStream JavaDoc(outFile));
418             }
419         } catch (FileNotFoundException JavaDoc e) {
420             throw new HammurapiException(e.toString(), e);
421         } catch (RenderingException e) {
422             throw new HammurapiException(e.toString(), e);
423         }
424         tic.addInterval("render", start);
425     }
426     
427     private void writeUnitDoc(ReviewResults reviewResult, File JavaDoc outFile, String JavaDoc inspectorsPath, String JavaDoc javaDocPath) throws HammurapiException {
428         task.getProject().log("Writing "+outFile.getAbsolutePath(), Project.MSG_VERBOSE);
429         render(new ReviewResultsRenderer(new RenderRequest(reviewResult)), "compilation-unit", inspectorsPath, javaDocPath, outFile);
430     }
431         
432     public void onSummary(CompositeResults summary, InspectorSet inspectorSet) throws HammurapiException {
433         if (dir==null) {
434             throw new HammurapiException("dir attribute is mandatory");
435         }
436         
437         File JavaDoc outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
438         if (!outDir.exists()) {
439             throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
440         }
441         
442         if (!outDir.isDirectory()) {
443             throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
444         }
445         
446         String JavaDoc javaDocPath=javaDocDir==null ? null : getRelativePath()+"index.html";
447         File JavaDoc summaryFile = new File JavaDoc(outDir, "summary"+extension);
448         renderAnnotations(summary, summaryFile);
449         RenderRequest summaryRenderRequest = new RenderRequest(ReportMixer.mix(summary, task.reviewDescription));
450         render(new ReportRenderer(summaryRenderRequest, null), "summary", null, javaDocPath, summaryFile);
451         render(new CompositeResultsRenderer(summaryRenderRequest, "leftPanel"), "left-panel", null, javaDocPath, new File JavaDoc(outDir, "leftPanel"+extension));
452         render(new CompositeResultsRenderer(summaryRenderRequest, "waivedViolations"), "waived-violations", null, javaDocPath, new File JavaDoc(outDir, "waivedViolations"+extension));
453         render(new InspectorSetRenderer(new RenderRequest(inspectorSet)), "inspector-set", null, null, new File JavaDoc(outDir, "inspectors"+extension));
454
455         Iterator JavaDoc descriptors=inspectorSet.getDescriptors().iterator();
456         while (descriptors.hasNext()) {
457             InspectorDescriptor d =(InspectorDescriptor) descriptors.next();
458             render(new InspectorDescriptorRenderer(new RenderRequest(d)), "inspector-descriptor", null, null, new File JavaDoc(outDir, "inspectors/inspector_" + d.getName() + extension));
459         }
460
461         if (".HTML".equalsIgnoreCase(extension)) {
462             writeFrame(outDir);
463         }
464         
465         Iterator JavaDoc it=summary.getSeveritySummary().values().iterator();
466         while (it.hasNext()) {
467             Iterator JavaDoc iit=((Map JavaDoc) it.next()).values().iterator();
468             while (iit.hasNext()) {
469                 InspectorSummary is=(InspectorSummary) iit.next();
470                 if (is.getLocations()!=null) {
471                     render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", "source/", null, new File JavaDoc(outDir, "summary_"+is.getName()+extension));
472                 }
473             }
474         }
475                
476         it=summary.getMetrics().values().iterator();
477         while (it.hasNext()) {
478             Metric metric = (Metric) it.next();
479             if (metric.getMeasurements()!=null) {
480                 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", "source/", null, new File JavaDoc(outDir, "metric_details_"+metric.getName()+extension));
481             }
482         }
483     }
484     
485     private void writeFrame(File JavaDoc outDir) throws HammurapiException {
486         try {
487             byte[] buf=new byte[4096];
488             String JavaDoc resourceName="/"+getClass().getName().replace('.', '/')+"!report.html";
489             InputStream JavaDoc in=getClass().getResourceAsStream(resourceName);
490             if (in!=null) {
491                 FileOutputStream JavaDoc out=new FileOutputStream JavaDoc(new File JavaDoc(outDir, "report.html"));
492                 int l;
493                 while ((l=in.read(buf))!=-1) {
494                     out.write(buf,0,l);
495                 }
496                 out.close();
497                 in.close();
498             }
499         } catch (IOException JavaDoc e) {
500             throw new HammurapiException("Can't write report.html: "+e);
501         }
502     }
503         
504     public void onPackage(CompositeResults packageResults) throws HammurapiException {
505         if (dir==null) {
506             throw new HammurapiException("dir attribute is mandatory");
507         }
508         
509         File JavaDoc outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
510         if (!outDir.exists()) {
511             throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
512         }
513         
514         if (!outDir.isDirectory()) {
515             throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
516         }
517         
518         String JavaDoc summaryPath="source/"+packageResults.getName().replace('.', '/')+"/.summary";
519         
520         int count=0;
521         for (int i=0; i<summaryPath.length(); i++) {
522             if ('/'==summaryPath.charAt(i)) {
523                 count++;
524             }
525         }
526         
527         StringBuffer JavaDoc inspectorsPath=new StringBuffer JavaDoc();
528         while (count-- > 0) {
529             inspectorsPath.append("../");
530         }
531         
532         File JavaDoc packageSummaryFile = new File JavaDoc(outDir, summaryPath+extension);
533         renderAnnotations(packageResults, packageSummaryFile);
534         render(new CompositeResultsRenderer(new RenderRequest(packageResults), "packageSummary"), "package", inspectorsPath.toString(), getJavaDocPath(packageResults), packageSummaryFile);
535         
536         Iterator JavaDoc it=packageResults.getSeveritySummary().values().iterator();
537         while (it.hasNext()) {
538             Iterator JavaDoc iit=((Map JavaDoc) it.next()).values().iterator();
539             while (iit.hasNext()) {
540                 InspectorSummary is=(InspectorSummary) iit.next();
541                 if (is.getLocations()!=null) {
542                     render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", inspectorsPath.toString()+"source/", null, new File JavaDoc(outDir, summaryPath+"_"+is.getName()+extension));
543                 }
544             }
545         }
546         
547         it=packageResults.getMetrics().values().iterator();
548         while (it.hasNext()) {
549             Metric metric = (Metric) it.next();
550             if (metric.getMeasurements()!=null) {
551                 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", inspectorsPath.toString()+"source/", null, new File JavaDoc(outDir, summaryPath+"_metric_details_"+metric.getName()+extension));
552             }
553         }
554     }
555     
556     private final Map JavaDoc annotationConfigs=new HashMap JavaDoc();
557     
558     /**
559      * Annotation configuration
560      * @ant.non-required
561      * @param annotationConfig
562      */

563     public void addConfiguredAnnotationConfig(AnnotationConfig annotationConfig) {
564         annotationConfigs.put(annotationConfig.getName(), annotationConfig);
565     }
566     /**
567      * @return Returns the extension.
568      */

569     private String JavaDoc getExtension() {
570         return extension;
571     }
572     
573     /**
574      * @return Returns the embeddedStyle.
575      */

576     private boolean isEmbeddedStyle() {
577         return embeddedStyle;
578     }
579     
580     public void onBegin(InspectorSet inspectorSet) throws HammurapiException {
581         File JavaDoc outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
582         if (!outDir.exists()) {
583             if (!outDir.mkdirs()) {
584                 throw new HammurapiException("Output directory cannot be created: "+outDir.getAbsolutePath());
585             }
586         }
587         
588         if (!outDir.isDirectory()) {
589             throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
590         }
591     }
592 }
593
Popular Tags