KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > inspectors > metrics > NcssInspector


1 /*
2  * Hammurapi
3  * Automated Java code review system.
4  * Copyright (C) 2004 Johannes Bellert
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.pavelvlasov.com/pv/content/menu.show?id=products.jtaste
21  * e-Mail: Johannes.Bellert@ercgroup.com
22  *
23  * * Created on Mar 23, 2004
24  *
25  */

26 package org.hammurapi.inspectors.metrics;
27
28
29 import java.io.FileInputStream JavaDoc;
30 import java.io.FileOutputStream JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.Vector JavaDoc;
37
38 import org.hammurapi.InspectorBase;
39 import org.hammurapi.HammurapiException;
40 import org.hammurapi.inspectors.metrics.reporting.LocReporter;
41 import org.hammurapi.inspectors.metrics.statistics.DescriptiveStatistic;
42 import org.hammurapi.inspectors.metrics.statistics.IntVector;
43 import org.hammurapi.results.AnnotationContext;
44 import org.hammurapi.results.LinkedAnnotation;
45 import org.w3c.dom.Document JavaDoc;
46 import org.w3c.dom.Element JavaDoc;
47
48 import com.pavelvlasov.config.ConfigurationException;
49 import com.pavelvlasov.config.Parameterizable;
50 import com.pavelvlasov.jsel.Method;
51 import com.pavelvlasov.jsel.Repository;
52 import com.pavelvlasov.jsel.TypeDefinition;
53 import com.pavelvlasov.render.RenderRequest;
54 import com.pavelvlasov.render.RenderingException;
55 import com.pavelvlasov.render.dom.AbstractRenderer;
56 import com.pavelvlasov.review.SourceMarker;
57
58 public class NcssInspector extends InspectorBase implements Parameterizable {
59
60     /**
61      * A sorted distribution list of class NCSS
62      *
63      */

64     private IntVector ncssClassList = new IntVector();
65
66     /**
67      * A sorted distribution list of function NCSS
68      *
69      */

70     private IntVector ncssFunctionList = new IntVector();
71
72     /**
73      * Stores the setting form the configuration for the maximum allowed
74      * NCSS for an implemened method.
75      */

76     private Integer JavaDoc functionMaxLoc;
77
78     /**
79      * Stores the setting form the configuration for the maximum allowed
80      * NCSS for a class.
81      */

82     private Integer JavaDoc classMaxLoc;
83
84     /**
85      * Stores the setting form the configuration for the maximum allowed
86      * NCSS for a class.
87      */

88     private Integer JavaDoc classMaxFunction;
89     
90     /**
91      * if ncssReport == 1, then generate the NCSS metric report
92      */

93     private Integer JavaDoc ncssReport;
94
95
96     /**
97      * You may want to see the Swing Chart for Debug purpose
98      */

99     private Integer JavaDoc chartDebugWindow;
100
101     double functionAvg = 0.0;
102     double classAvg = 0.0;
103
104     private Vector JavaDoc packageCodeMetricList = new Vector JavaDoc();
105     private Vector JavaDoc functionCodeMetricList = new Vector JavaDoc();
106     private Map JavaDoc types = new HashMap JavaDoc();
107     private Map JavaDoc packages = new HashMap JavaDoc();
108     private CodeMetric projectMetric = new CodeMetric();
109     String JavaDoc projectBaseDir = "";
110     String JavaDoc xmlResourceName=this.getClass().getName().replace('.','/')+ "XmlPretty.xsl";
111     LocReporter locReport ;
112
113
114     public void visit(com.pavelvlasov.jsel.Package pkg) {
115         CodeMetric packageCodeMetrics = new CodeMetric();
116         packageCodeMetrics.setDescriptonEntity ("Package");
117         packageCodeMetrics.setName ( pkg.getName() );
118         packages.put(pkg.getName(), packageCodeMetrics);
119
120         int sum = projectMetric.getNcss() +packageCodeMetrics.getNcss();
121         projectMetric.setNcss( sum );
122         sum = projectMetric.getNumber() +1;
123         projectMetric.setNumber( sum );
124
125         projectMetric.getChildren().add( packageCodeMetrics );
126     }
127
128     public void visit(TypeDefinition typeDefinition) {
129         int start = typeDefinition.getAst().getFirstToken().getLine();
130         int end = typeDefinition.getAst().getLastToken().getLine();
131         CodeMetric typeCodeMetric = new CodeMetric();
132         typeCodeMetric.setDescriptonEntity("Class");
133         typeCodeMetric.setName ( typeDefinition.getFcn() );
134
135         // packageName.replace('.','/')+compilationUnit.getName()
136
// System.out.println( "++ " +typeDefinition.getCompilationUnit().getPackage().getName().toString() );
137

138
139
140         typeCodeMetric.source_url= ((SourceMarker) typeDefinition).getSourceURL();
141         typeCodeMetric.source_line= ((SourceMarker) typeDefinition).getLine();
142         typeCodeMetric.source_col= ((SourceMarker) typeDefinition).getColumn();
143
144         typeCodeMetric.setNcss ( end - start);
145
146         types.put((String JavaDoc) typeDefinition.getFcn(), typeCodeMetric);
147
148         // lookup for package
149
CodeMetric packageCodeMetric = (CodeMetric) packages.get( typeDefinition.getCompilationUnit().getPackage().getName() );
150         int sum = packageCodeMetric.getNcss() + typeCodeMetric.getNcss();
151         packageCodeMetric.setNcss( sum );
152
153         packageCodeMetric.setNumber( packageCodeMetric.getNumber() + 1);
154         sum = packageCodeMetric.getFunction() +typeCodeMetric.getFunction();
155         packageCodeMetric.setFunction( sum );
156
157         sum = projectMetric.getFunction() +packageCodeMetric.getFunction();
158         projectMetric.setFunction( sum );
159
160         packageCodeMetric.getChildren().add( typeCodeMetric );
161
162         context.addMetric(typeDefinition, "NCSS Class Inspector", typeCodeMetric.getNcss() );
163         if (this.classMaxLoc!=null && typeCodeMetric.getNcss() > classMaxLoc.intValue()) {
164             context.reportViolation(typeDefinition, new Object JavaDoc[] {classMaxLoc, new Integer JavaDoc(typeCodeMetric.getNcss())});
165         }
166
167     }
168
169     public void visit(Method code) {
170         int start = code.getAst().getFirstToken().getLine();
171         int end = code.getAst().getLastToken().getLine();
172         CodeMetric methodCodeMetrics = new CodeMetric();
173         methodCodeMetrics.setDescriptonEntity ( "MethodImplemented" );
174         methodCodeMetrics.setName( code.getEnclosingType().getFcn() + " >> " + code.getName());
175         
176         methodCodeMetrics.source_url= ((SourceMarker) code).getSourceURL();
177         methodCodeMetrics.source_line= ((SourceMarker) code).getLine();
178         methodCodeMetrics.source_col= ((SourceMarker) code).getColumn();
179
180         methodCodeMetrics.setNcss (end - start);
181
182         // lookup for class
183

184         CodeMetric classCodeMetric = (CodeMetric) types.get((String JavaDoc) code.getEnclosingType().getFcn());
185         if(classCodeMetric == null ){
186              new Exception JavaDoc( "Can't get CodeMetric Object for " + (String JavaDoc) code.getEnclosingType().getFcn());
187         } else {
188         classCodeMetric.setFunction( classCodeMetric.getFunction() +1) ;
189         classCodeMetric.getChildren().add(methodCodeMetrics);
190         context.addMetric(code, "NCSS Method p Class Inspector", classCodeMetric.getFunction());
191         }
192         context.addMetric(code, "NCSS Method Inspector", methodCodeMetrics.getNcss());
193         if (this.functionMaxLoc!=null && methodCodeMetrics.getNcss() > functionMaxLoc.intValue()) {
194             context.reportViolation(code, new Object JavaDoc[] {functionMaxLoc, new Integer JavaDoc(methodCodeMetrics.getNcss())});
195         }
196         
197         if (this.classMaxFunction!=null && classCodeMetric!=null && classCodeMetric.getFunction() > classMaxFunction.intValue()) {
198             context.reportViolation(code, new Object JavaDoc[] {classMaxFunction, new Integer JavaDoc(classCodeMetric.getFunction())});
199         }
200
201     }
202
203     private void aggregate() {
204
205
206         Iterator JavaDoc it=types.values().iterator();
207         while(it.hasNext()) {
208             CodeMetric classCodeMetric = (CodeMetric) it.next();
209             int last = classCodeMetric.getName().lastIndexOf('.');
210             String JavaDoc packg = last==-1 ? "" : classCodeMetric.getName().substring(0,last);
211             CodeMetric packageCodeMetric = (CodeMetric)packages.get(packg);
212             int sum = packageCodeMetric.getFunction() +classCodeMetric.getFunction();
213             packageCodeMetric.setFunction ( sum );
214
215     // this.projectMetric.function += packCm.function;
216
}
217         this.copyDeepCodeMetric();
218         functionAvg = DescriptiveStatistic.mean(ncssFunctionList);
219         classAvg = DescriptiveStatistic.mean(ncssClassList);
220         return;
221     }
222
223
224     private void copyDeepCodeMetric() {
225
226         Enumeration JavaDoc enumP = projectMetric.getChildren().elements();
227         while (enumP.hasMoreElements()) {
228             CodeMetric cmP = (CodeMetric) enumP.nextElement();
229             // Classes
230
Enumeration JavaDoc enumC = cmP.getChildren().elements();
231             while (enumC.hasMoreElements()) {
232                 CodeMetric cmC = (CodeMetric) enumC.nextElement();
233                 this.packageCodeMetricList.add(cmC);
234                 this.ncssClassList.addElement( cmC.getNcss() ) ;
235                 // Functions
236
Enumeration JavaDoc enumF = cmC.getChildren().elements();
237                 while (enumF.hasMoreElements()) {
238                     CodeMetric cmF = (CodeMetric) enumF.nextElement();
239                     this.functionCodeMetricList.add(cmF);
240                     this.ncssFunctionList.addElement( cmF.getNcss() );
241                 }
242             }
243         }
244     }
245
246
247     public void leave(Repository repository) {
248         aggregate();
249
250         context.annotate( new LinkedAnnotation() {
251             private String JavaDoc path;
252
253             public String JavaDoc getName() {
254                 return getContext().getDescriptor().getName();
255             }
256
257             public String JavaDoc getPath() {
258                 return path;
259             }
260
261             public void render(AnnotationContext context) throws HammurapiException {
262                 String JavaDoc errorCausingFile = "";
263                 projectMetric.setName ( "Project" );
264                 projectMetric.setDescriptonEntity ( projectMetric.getName() );
265
266                 // Output images here. See AnnotationTest for details.
267

268                 class NcssInspectorRenderer extends AbstractRenderer {
269                     NcssInspectorRenderer() {
270                         super(new RenderRequest(NcssInspector.this));
271                     }
272
273                     public Element JavaDoc render(Document JavaDoc document) throws RenderingException {
274                         NcssInspector ncssInspector=(NcssInspector) request.getRenderee();
275                         Element JavaDoc entities=document.createElement("Entities");
276                         Element JavaDoc ncssInspectorElement=document.createElement("SourceCodeMetric");
277
278                         Element JavaDoc classMaxLocE=document.createElement("ClassMaxLoc");
279                         classMaxLocE.setAttribute("number", String.valueOf( classMaxLoc ) );
280                         ncssInspectorElement.appendChild(classMaxLocE);
281
282                         Element JavaDoc classMaxFuncE=document.createElement("ClassMaxFunction");
283                         classMaxFuncE.setAttribute("number", String.valueOf( classMaxFunction ) );
284                         ncssInspectorElement.appendChild(classMaxFuncE);
285
286
287                         Element JavaDoc funcMaxLocE=document.createElement("FunctionMaxLoc");
288                         funcMaxLocE.setAttribute("number", String.valueOf( functionMaxLoc ) );
289                         ncssInspectorElement.appendChild(funcMaxLocE);
290
291
292                             Element JavaDoc functionAverage=document.createElement("FunctionNcssAverage");
293                             ncssInspectorElement.appendChild(functionAverage);
294                             functionAverage.setAttribute("number", String.valueOf(functionAvg));
295
296
297                             Element JavaDoc classAverage=document.createElement("ClassNcssAverage");
298                             ncssInspectorElement.appendChild(classAverage);
299                             classAverage.setAttribute("number", String.valueOf(classAvg));
300
301
302                         Element JavaDoc jpgClassFileEntry=document.createElement("JpgClassFileEntry");
303                         jpgClassFileEntry.setAttribute("chartFile", String.valueOf( locReport.getJpgClassFileEntry().getPath().toString()));
304                         ncssInspectorElement.appendChild(jpgClassFileEntry);
305
306                         Element JavaDoc jpgFunctionFileEntry=document.createElement("JpgFunctionFileEntry");
307
308                         jpgFunctionFileEntry.setAttribute("chartFile", String.valueOf( locReport.getJpgFunctionFileEntry().getPath().toString()));
309                         ncssInspectorElement.appendChild(jpgFunctionFileEntry);
310
311                         Element JavaDoc pmd = ncssInspector.projectMetric.toDom(document);
312                         ncssInspectorElement.appendChild(pmd);
313                         return ncssInspectorElement;
314                     }
315                 } //-- end class NcssInspectorRenderer
316

317                 locReport = new LocReporter( context, classMaxLoc, functionMaxLoc, ncssReport, chartDebugWindow );
318                 locReport.setNcssClassList( ncssClassList );
319                 locReport.setNcssFunctionList( ncssFunctionList );
320
321                 locReport.doIt( projectMetric) ;
322
323                 AnnotationContext.FileEntry fileEntry=context.getNextFile(context.getExtension());
324                 path=fileEntry.getPath();
325             // System.out.println( ".> " +this.getPath().toString() );
326

327                 AnnotationContext.FileEntry fileEntryXml=context.getNextFile(".xml");
328                 try {
329                     NcssInspectorRenderer renderer=new NcssInspectorRenderer();
330                     FileOutputStream JavaDoc out=new FileOutputStream JavaDoc(fileEntry.getFile());
331
332                     renderer.setEmbeddedStyle(context.isEmbeddedStyle());
333                     try {
334                         errorCausingFile = fileEntry.getFile().getAbsolutePath();
335                         renderer.render(context.getParameter("style")==null ? null : new FileInputStream JavaDoc(context.getParameter("style").toString()), out);
336                     } finally {
337                         out.close();
338                     }
339                         //-- write a XML file for other XSL usage
340
FileOutputStream JavaDoc outXml=new FileOutputStream JavaDoc(fileEntryXml.getFile());
341
342                     try {
343                         errorCausingFile = fileEntryXml.getFile().getAbsolutePath();
344                         //-- write a XML file for other XSL usage
345
renderer.setEmbeddedStyle(false);
346                         renderer.render(outXml);
347 // renderer.setPrettyPrint( true );
348
// InputStream inStream=getClass().getClassLoader().getResourceAsStream(xmlResourceName);
349
// renderer.render(inStream, outXml);
350

351                     } finally {
352                         outXml.close();
353                     }
354                 } catch (Exception JavaDoc e) {
355                     throw new HammurapiException("Can't save "+ errorCausingFile +". " +e.getMessage() );
356                 }
357             }
358             public Properties JavaDoc getProperties() {
359                 Properties JavaDoc ret=new Properties JavaDoc();
360                 ret.setProperty("left-panel", "yes");
361                 ret.setProperty("target", "NCSS");
362                 return ret;
363             }
364         });
365     }
366        /**
367      * Configures the rule. Reads in the values of the parameters operation-max-complexity and
368      * class-max-complexity.
369      *
370      * @param name the name of the parameter being loaded from Hammurapi configuration
371      * @param value the value of the parameter being loaded from Hammurapi configuration
372      * @exception ConfigurationException in case of a not supported parameter
373      */

374     public boolean setParameter(String JavaDoc name, Object JavaDoc value) throws ConfigurationException {
375         if ("function-max-loc".equals(name)) {
376             functionMaxLoc=new Integer JavaDoc(Integer.parseInt(value.toString()));
377         } else if ("class-max-loc".equals(name)) {
378             classMaxLoc=new Integer JavaDoc(Integer.parseInt(value.toString()));
379         } else if ("class-max-function".equals(name)) {
380             classMaxFunction=new Integer JavaDoc(Integer.parseInt(value.toString()));
381         } else if ("chart-debug-window".equals(name)) {
382             chartDebugWindow=new Integer JavaDoc(Integer.parseInt(value.toString()));
383         } else if ("ncss-report".equals(name)) {
384             ncssReport=new Integer JavaDoc(Integer.parseInt(value.toString()));
385
386         } else {
387             throw new ConfigurationException("Parameter '"+name+"' is not supported");
388         }
389         return true;
390     }
391
392 }
393
394
Popular Tags