001 /* 002 Copyright (C) 2001 Chr. Clemens Lee <clemens@kclee.com>. 003 004 This file is part of JavaNCSS 005 (http://www.kclee.com/clemens/java/javancss/). 006 007 JavaNCSS is free software; you can redistribute it and/or modify it 008 under the terms of the GNU General Public License as published by the 009 Free Software Foundation; either version 2, or (at your option) any 010 later version. 011 012 JavaNCSS is distributed in the hope that it will be useful, but WITHOUT 013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 015 for more details. 016 017 You should have received a copy of the GNU General Public License 018 along with JavaNCSS; see the file COPYING. If not, write to 019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 020 Boston, MA 02111-1307, USA. */ 021 022 package javancss; 023 024 import java.text.DecimalFormat; 025 import java.text.NumberFormat; 026 import java.util.Iterator; 027 import java.util.List; 028 import java.util.Locale; 029 030 import ccl.util.Util; 031 032 /** 033 * Generates ascii output of Java metrics. 034 * 035 * @author Chr. Clemens Lee <clemens@kclee.com> 036 * , Windows 13 10 line feed feature by John Wilson. 037 * @version $Id: AsciiFormatter.java 121 2009-01-17 22:19:45Z hboutemy $ 038 */ 039 public class AsciiFormatter implements Formatter 040 { 041 private static final int LEN_NR = 3; 042 private static final String NL = System.getProperty( "line.separator" ); 043 044 private final Javancss _javancss; 045 046 private String[] _header = null; 047 private int _length = 0; 048 private int _nr = 0; 049 050 private NumberFormat _pNumberFormat = null; 051 052 private String _formatListHeader( int lines, String[] header ) 053 { 054 _header = header; 055 056 _nr = 0; 057 058 StringBuffer sRetVal = new StringBuffer(); 059 060 _length = Util.itoa( lines ).length(); 061 int spaces = Math.max( 0, _length - LEN_NR ); 062 _length = spaces + LEN_NR; 063 sRetVal.append( Util.multiplyChar(' ', spaces) ); 064 sRetVal.append( "Nr." ); 065 for( int nr = 0; nr < header.length; nr++ ) 066 { 067 sRetVal.append( ' ' ).append( header[ nr ] ); 068 } 069 sRetVal.append( NL ); 070 071 return sRetVal.toString(); 072 } 073 074 private String _formatListLine( String name, int[] value ) 075 { 076 StringBuffer sLine = new StringBuffer(); 077 078 _nr++; 079 sLine.append( Util.paddWithSpace( _nr, _length ) ); 080 for( int index = 0; index < _header.length - 1; index++ ) 081 { 082 sLine.append( ' ' ); 083 sLine.append( Util.paddWithSpace( value[ index ] 084 , _header[ index ].length() ) ); 085 } 086 sLine.append( ' ' ); 087 sLine.append( name ); 088 sLine.append( NL ); 089 090 return sLine.toString(); 091 } 092 093 private double _divide( int divident, int divisor ) 094 { 095 double dRetVal = 0.0; 096 if ( divisor > 0) { 097 dRetVal = Math.round(((double)divident/(double)divisor)*100)/100.0; 098 } 099 100 return dRetVal; 101 } 102 103 private double _divide( long divident, long divisor ) 104 { 105 double dRetVal = 0.0; 106 if ( divisor > 0) { 107 dRetVal = Math.round(((double)divident/(double)divisor)*100)/100.0; 108 } 109 110 return dRetVal; 111 } 112 113 private String _formatPackageMatrix( int packages 114 , int classesSum 115 , int functionsSum 116 , int javadocsSum 117 , int ncssSum ) 118 { 119 ((DecimalFormat)_pNumberFormat).applyPattern( "###0.00" ); 120 int maxItemLength = _pNumberFormat.format(ncssSum).length(); 121 maxItemLength = Math.max(9, maxItemLength); 122 String sRetVal = 123 Util.paddWithSpace( "Packages" , maxItemLength ) + ' ' 124 + Util.paddWithSpace("Classes", maxItemLength) + ' ' 125 + Util.paddWithSpace("Functions", maxItemLength) + ' ' 126 + Util.paddWithSpace("NCSS", maxItemLength) + ' ' 127 + Util.paddWithSpace("Javadocs", maxItemLength) 128 + " | per" + NL 129 130 + Util.multiplyChar( '-', (maxItemLength + 1)*6 + 1 ) + NL 131 + Util.paddWithSpace(_pNumberFormat.format(packages), maxItemLength) + ' ' 132 + Util.paddWithSpace(_pNumberFormat.format(classesSum), maxItemLength) + ' ' 133 + Util.paddWithSpace(_pNumberFormat.format(functionsSum), maxItemLength) + ' ' 134 + Util.paddWithSpace(_pNumberFormat.format(ncssSum), maxItemLength) + ' ' 135 + Util.paddWithSpace(_pNumberFormat.format(javadocsSum), maxItemLength) 136 + " | Project" + NL 137 138 + Util.multiplyChar( ' ', maxItemLength + 1 ) 139 + Util.paddWithSpace( _pNumberFormat.format( _divide( classesSum, packages ) ), maxItemLength ) + ' ' 140 + Util.paddWithSpace( _pNumberFormat.format( _divide( functionsSum, packages ) ), maxItemLength ) + ' ' 141 + Util.paddWithSpace( _pNumberFormat.format( _divide( ncssSum, packages ) ), maxItemLength ) + ' ' 142 + Util.paddWithSpace( _pNumberFormat.format( _divide( javadocsSum, packages ) ), maxItemLength ) 143 + " | Package" + NL 144 145 + Util.multiplyChar( ' ', (maxItemLength + 1)*2 ) 146 + Util.paddWithSpace( _pNumberFormat.format( _divide( functionsSum, classesSum ) ), maxItemLength ) + ' ' 147 + Util.paddWithSpace( _pNumberFormat.format( _divide( ncssSum, classesSum ) ), maxItemLength ) + ' ' 148 + Util.paddWithSpace( _pNumberFormat.format( _divide( javadocsSum, classesSum ) ), maxItemLength ) 149 + " | Class" + NL 150 151 + Util.multiplyChar( ' ', (maxItemLength + 1)*3 ) 152 + Util.paddWithSpace( _pNumberFormat.format( _divide( ncssSum, functionsSum ) ), maxItemLength ) + ' ' 153 + Util.paddWithSpace( _pNumberFormat.format( _divide( javadocsSum, functionsSum ) ), maxItemLength ) 154 + " | Function" + NL; 155 156 ((DecimalFormat)_pNumberFormat).applyPattern( "#,##0.00" ); 157 158 return sRetVal; 159 } 160 161 public AsciiFormatter( Javancss javancss ) 162 { 163 super(); 164 165 _javancss = javancss; 166 167 _pNumberFormat = NumberFormat.getInstance( Locale.US ); 168 ((DecimalFormat)_pNumberFormat).applyPattern( "#,##0.00" ); 169 } 170 171 public String printPackageNcss() 172 { 173 List vPackageMetrics = _javancss.getPackageMetrics(); 174 175 int packages = vPackageMetrics.size(); 176 177 StringBuffer sbRetVal = new StringBuffer( _formatListHeader( packages 178 , new String[] { " Classes" 179 , "Functions" 180 , " NCSS" 181 , " Javadocs" 182 , "Package" } ) ); 183 184 int classesSum = 0; 185 int functionsSum = 0; 186 int javadocsSum = 0; 187 int ncssSum = 0; 188 for( Iterator ePackages = vPackageMetrics.iterator(); ePackages.hasNext(); ) 189 { 190 PackageMetric pPackageMetric = (PackageMetric)ePackages.next(); 191 192 classesSum += pPackageMetric.classes; 193 functionsSum += pPackageMetric.functions; 194 ncssSum += pPackageMetric.ncss; 195 javadocsSum += pPackageMetric.javadocs; 196 sbRetVal.append( _formatListLine( pPackageMetric.name 197 , new int[] { pPackageMetric.classes 198 , pPackageMetric.functions 199 , pPackageMetric.ncss 200 , pPackageMetric.javadocs 201 } ) ); 202 } 203 204 int packagesLength = Util.itoa( packages ).length(); 205 int spaces = Math.max( packagesLength, LEN_NR ) + 1; 206 sbRetVal.append( Util.multiplyChar(' ', spaces ) + 207 "--------- --------- --------- ---------" + NL ); 208 209 sbRetVal.append( Util.multiplyChar(' ', spaces ) 210 + Util.paddWithSpace( classesSum, 9 ) + ' ' 211 + Util.paddWithSpace( functionsSum, 9 ) + ' ' 212 + Util.paddWithSpace( ncssSum, 9 ) + ' ' 213 + Util.paddWithSpace( javadocsSum, 9 ) 214 + " Total" + NL + NL ); 215 216 sbRetVal.append( _formatPackageMatrix( packages 217 , classesSum 218 , functionsSum 219 , javadocsSum 220 , ncssSum ) ); 221 222 return sbRetVal.toString(); 223 } 224 225 private String _formatObjectResume( int objects 226 , long lObjectSum 227 , long lFunctionSum 228 , long lClassesSum 229 , long lJVDCSum ) 230 { 231 double fAverageNcss = _divide( lObjectSum , objects ); 232 double fAverageFuncs = _divide( lFunctionSum, objects ); 233 double fAverageClasses = _divide( lClassesSum , objects ); 234 double fAverageJavadocs = _divide( lJVDCSum , objects ); 235 String sRetVal = "Average Object NCSS: " 236 + Util.paddWithSpace(_pNumberFormat.format(fAverageNcss), 9) + NL 237 + "Average Object Functions: " 238 + Util.paddWithSpace(_pNumberFormat.format(fAverageFuncs), 9) + NL 239 + "Average Object Inner Classes: " 240 + Util.paddWithSpace(_pNumberFormat.format(fAverageClasses), 9) + NL 241 + "Average Object Javadoc Comments: " 242 + Util.paddWithSpace(_pNumberFormat.format(fAverageJavadocs), 9) + NL 243 + "Program NCSS: " 244 + Util.paddWithSpace(_pNumberFormat.format(_javancss.getNcss()), 9) + NL; 245 246 return sRetVal; 247 } 248 249 public String printObjectNcss() { 250 List/*<ObjectMetric>*/ vObjectMetrics = _javancss.getObjectMetrics(); 251 252 StringBuffer sbRetVal = new StringBuffer( _formatListHeader( vObjectMetrics.size() 253 , new String[] { "NCSS" 254 , "Functions" 255 , "Classes" 256 , "Javadocs" 257 , "Class" } ) ); 258 long lFunctionSum = 0; 259 long lClassesSum = 0; 260 long lObjectSum = 0; 261 long lJVDCSum = 0; 262 for( Iterator eClasses = vObjectMetrics.iterator(); eClasses.hasNext(); ) 263 { 264 ObjectMetric classMetric = (ObjectMetric)eClasses.next(); 265 String sClass = classMetric.name; 266 int objectNcss = classMetric.ncss; 267 int functions = classMetric.functions; 268 int classes = classMetric.classes; 269 int jvdcs = classMetric.javadocs; 270 lObjectSum += (long)objectNcss; 271 lFunctionSum += (long)functions; 272 lClassesSum += (long)classes; 273 lJVDCSum += (long)jvdcs; 274 sbRetVal.append( _formatListLine( sClass 275 , new int[] { objectNcss 276 , functions 277 , classes 278 , jvdcs } ) ); 279 } 280 281 sbRetVal.append( _formatObjectResume( vObjectMetrics.size() 282 , lObjectSum 283 , lFunctionSum 284 , lClassesSum 285 , lJVDCSum ) ); 286 287 return sbRetVal.toString(); 288 } 289 290 private String _formatFunctionResume( int functions 291 , long lFunctionSum 292 , long lCCNSum 293 , long lJVDCSum ) 294 { 295 double fAverageNcss = _divide( lFunctionSum, functions ); 296 double fAverageCCN = _divide( lCCNSum , functions ); 297 double fAverageJVDC = _divide( lJVDCSum , functions ); 298 299 String sRetVal = "Average Function NCSS: " 300 + Util.paddWithSpace(_pNumberFormat.format(fAverageNcss), 10) + NL 301 + "Average Function CCN: " 302 + Util.paddWithSpace(_pNumberFormat.format(fAverageCCN), 10) + NL 303 + "Average Function JVDC: " 304 + Util.paddWithSpace(_pNumberFormat.format(fAverageJVDC), 10) + NL 305 + "Program NCSS: " 306 + Util.paddWithSpace(_pNumberFormat.format(_javancss.getNcss()), 10) + NL; 307 308 return sRetVal; 309 } 310 311 public String printFunctionNcss() 312 { 313 StringBuffer sRetVal = new StringBuffer(80000); 314 315 List vFunctionMetrics = _javancss.getFunctionMetrics(); 316 317 sRetVal.append( _formatListHeader( vFunctionMetrics.size() 318 , new String[] { "NCSS" 319 , "CCN" 320 , "JVDC" 321 , "Function" } ) ); 322 323 long lFunctionSum = 0; 324 long lCCNSum = 0; 325 long lJVDCSum = 0; 326 for( Iterator eFunctions = vFunctionMetrics.iterator(); eFunctions.hasNext(); ) 327 { 328 FunctionMetric functionMetric = (FunctionMetric)eFunctions.next(); 329 String sFunction = functionMetric.name; 330 int functionNcss = functionMetric.ncss; 331 int functionCCN = functionMetric.ccn; 332 int functionJVDC = functionMetric.javadocs; 333 334 lFunctionSum += (long)functionNcss; 335 lCCNSum += (long)functionCCN; 336 lJVDCSum += (long)functionJVDC; 337 sRetVal.append( _formatListLine( sFunction 338 , new int[] { functionNcss 339 , functionCCN 340 , functionJVDC } ) ); 341 } 342 343 sRetVal.append( _formatFunctionResume( vFunctionMetrics.size() 344 , lFunctionSum 345 , lCCNSum 346 , lJVDCSum ) ); 347 348 return sRetVal.toString(); 349 } 350 351 public String printJavaNcss() 352 { 353 return "Java NCSS: " + _javancss.getNcss() + NL; 354 } 355 }