1 26 package org.hammurapi.inspectors.metrics; 27 28 29 import java.io.FileInputStream ; 30 import java.io.FileOutputStream ; 31 import java.util.Enumeration ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Properties ; 36 import java.util.Vector ; 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 ; 46 import org.w3c.dom.Element ; 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 64 private IntVector ncssClassList = new IntVector(); 65 66 70 private IntVector ncssFunctionList = new IntVector(); 71 72 76 private Integer functionMaxLoc; 77 78 82 private Integer classMaxLoc; 83 84 88 private Integer classMaxFunction; 89 90 93 private Integer ncssReport; 94 95 96 99 private Integer chartDebugWindow; 100 101 double functionAvg = 0.0; 102 double classAvg = 0.0; 103 104 private Vector packageCodeMetricList = new Vector (); 105 private Vector functionCodeMetricList = new Vector (); 106 private Map types = new HashMap (); 107 private Map packages = new HashMap (); 108 private CodeMetric projectMetric = new CodeMetric(); 109 String projectBaseDir = ""; 110 String 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 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 ) typeDefinition.getFcn(), typeCodeMetric); 147 148 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 [] {classMaxLoc, new Integer (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 184 CodeMetric classCodeMetric = (CodeMetric) types.get((String ) code.getEnclosingType().getFcn()); 185 if(classCodeMetric == null ){ 186 new Exception ( "Can't get CodeMetric Object for " + (String ) 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 [] {functionMaxLoc, new Integer (methodCodeMetrics.getNcss())}); 195 } 196 197 if (this.classMaxFunction!=null && classCodeMetric!=null && classCodeMetric.getFunction() > classMaxFunction.intValue()) { 198 context.reportViolation(code, new Object [] {classMaxFunction, new Integer (classCodeMetric.getFunction())}); 199 } 200 201 } 202 203 private void aggregate() { 204 205 206 Iterator it=types.values().iterator(); 207 while(it.hasNext()) { 208 CodeMetric classCodeMetric = (CodeMetric) it.next(); 209 int last = classCodeMetric.getName().lastIndexOf('.'); 210 String 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 } 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 enumP = projectMetric.getChildren().elements(); 227 while (enumP.hasMoreElements()) { 228 CodeMetric cmP = (CodeMetric) enumP.nextElement(); 229 Enumeration 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 Enumeration 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 path; 252 253 public String getName() { 254 return getContext().getDescriptor().getName(); 255 } 256 257 public String getPath() { 258 return path; 259 } 260 261 public void render(AnnotationContext context) throws HammurapiException { 262 String errorCausingFile = ""; 263 projectMetric.setName ( "Project" ); 264 projectMetric.setDescriptonEntity ( projectMetric.getName() ); 265 266 268 class NcssInspectorRenderer extends AbstractRenderer { 269 NcssInspectorRenderer() { 270 super(new RenderRequest(NcssInspector.this)); 271 } 272 273 public Element render(Document document) throws RenderingException { 274 NcssInspector ncssInspector=(NcssInspector) request.getRenderee(); 275 Element entities=document.createElement("Entities"); 276 Element ncssInspectorElement=document.createElement("SourceCodeMetric"); 277 278 Element classMaxLocE=document.createElement("ClassMaxLoc"); 279 classMaxLocE.setAttribute("number", String.valueOf( classMaxLoc ) ); 280 ncssInspectorElement.appendChild(classMaxLocE); 281 282 Element classMaxFuncE=document.createElement("ClassMaxFunction"); 283 classMaxFuncE.setAttribute("number", String.valueOf( classMaxFunction ) ); 284 ncssInspectorElement.appendChild(classMaxFuncE); 285 286 287 Element funcMaxLocE=document.createElement("FunctionMaxLoc"); 288 funcMaxLocE.setAttribute("number", String.valueOf( functionMaxLoc ) ); 289 ncssInspectorElement.appendChild(funcMaxLocE); 290 291 292 Element functionAverage=document.createElement("FunctionNcssAverage"); 293 ncssInspectorElement.appendChild(functionAverage); 294 functionAverage.setAttribute("number", String.valueOf(functionAvg)); 295 296 297 Element classAverage=document.createElement("ClassNcssAverage"); 298 ncssInspectorElement.appendChild(classAverage); 299 classAverage.setAttribute("number", String.valueOf(classAvg)); 300 301 302 Element jpgClassFileEntry=document.createElement("JpgClassFileEntry"); 303 jpgClassFileEntry.setAttribute("chartFile", String.valueOf( locReport.getJpgClassFileEntry().getPath().toString())); 304 ncssInspectorElement.appendChild(jpgClassFileEntry); 305 306 Element jpgFunctionFileEntry=document.createElement("JpgFunctionFileEntry"); 307 308 jpgFunctionFileEntry.setAttribute("chartFile", String.valueOf( locReport.getJpgFunctionFileEntry().getPath().toString())); 309 ncssInspectorElement.appendChild(jpgFunctionFileEntry); 310 311 Element pmd = ncssInspector.projectMetric.toDom(document); 312 ncssInspectorElement.appendChild(pmd); 313 return ncssInspectorElement; 314 } 315 } 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 327 AnnotationContext.FileEntry fileEntryXml=context.getNextFile(".xml"); 328 try { 329 NcssInspectorRenderer renderer=new NcssInspectorRenderer(); 330 FileOutputStream out=new FileOutputStream (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 (context.getParameter("style").toString()), out); 336 } finally { 337 out.close(); 338 } 339 FileOutputStream outXml=new FileOutputStream (fileEntryXml.getFile()); 341 342 try { 343 errorCausingFile = fileEntryXml.getFile().getAbsolutePath(); 344 renderer.setEmbeddedStyle(false); 346 renderer.render(outXml); 347 351 } finally { 352 outXml.close(); 353 } 354 } catch (Exception e) { 355 throw new HammurapiException("Can't save "+ errorCausingFile +". " +e.getMessage() ); 356 } 357 } 358 public Properties getProperties() { 359 Properties ret=new Properties (); 360 ret.setProperty("left-panel", "yes"); 361 ret.setProperty("target", "NCSS"); 362 return ret; 363 } 364 }); 365 } 366 374 public boolean setParameter(String name, Object value) throws ConfigurationException { 375 if ("function-max-loc".equals(name)) { 376 functionMaxLoc=new Integer (Integer.parseInt(value.toString())); 377 } else if ("class-max-loc".equals(name)) { 378 classMaxLoc=new Integer (Integer.parseInt(value.toString())); 379 } else if ("class-max-function".equals(name)) { 380 classMaxFunction=new Integer (Integer.parseInt(value.toString())); 381 } else if ("chart-debug-window".equals(name)) { 382 chartDebugWindow=new Integer (Integer.parseInt(value.toString())); 383 } else if ("ncss-report".equals(name)) { 384 ncssReport=new Integer (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 |