View Javadoc

1   /*
2   Copyright (C) 2001 Chr. Clemens Lee <clemens@kclee.com>.
3   
4   This file is part of JavaNCSS
5   (http://www.kclee.com/clemens/java/javancss/).
6   
7   JavaNCSS is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2, or (at your option) any
10  later version.
11  
12  JavaNCSS is distributed in the hope that it will be useful, but WITHOUT
13  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  for more details.
16  
17  You should have received a copy of the GNU General Public License
18  along with JavaNCSS; see the file COPYING.  If not, write to
19  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  Boston, MA 02111-1307, USA.  */
21  
22  package javancss;
23  
24  import java.text.DecimalFormat;
25  import java.text.NumberFormat;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Locale;
29  
30  import ccl.util.Util;
31  
32  /**
33   * Generates ascii output of Java metrics.
34   *
35   * @author    Chr. Clemens Lee <clemens@kclee.com>
36   *            , Windows 13 10 line feed feature by John Wilson.
37   * @version   $Id: AsciiFormatter.java 121 2009-01-17 22:19:45Z hboutemy $
38   */
39  public class AsciiFormatter implements Formatter
40  {
41      private static final int LEN_NR = 3;
42      private static final String NL = System.getProperty( "line.separator" );
43  
44      private final Javancss _javancss;
45  
46      private String[] _header = null;
47      private int      _length = 0;
48      private int      _nr     = 0;
49  
50      private NumberFormat _pNumberFormat = null;
51  
52      private String _formatListHeader( int lines, String[] header )
53      {
54          _header = header;
55  
56          _nr = 0;
57  
58          StringBuffer sRetVal = new StringBuffer();
59  
60          _length = Util.itoa( lines ).length();
61          int spaces = Math.max( 0, _length - LEN_NR );
62          _length = spaces + LEN_NR;
63          sRetVal.append( Util.multiplyChar(' ', spaces) );
64          sRetVal.append( "Nr." );
65          for( int nr = 0; nr < header.length; nr++ )
66          {
67              sRetVal.append( ' ' ).append( header[ nr ] );
68          }
69          sRetVal.append( NL );
70  
71          return sRetVal.toString();
72      }
73  
74      private String _formatListLine( String name, int[] value )
75      {
76          StringBuffer sLine = new StringBuffer();
77  
78          _nr++;
79          sLine.append( Util.paddWithSpace( _nr, _length ) );
80          for( int index = 0; index < _header.length - 1; index++ )
81          {
82              sLine.append( ' ' );
83              sLine.append( Util.paddWithSpace( value[ index ]
84                                                , _header[ index ].length() ) );
85          }
86          sLine.append( ' ' );
87          sLine.append( name );
88          sLine.append( NL );
89  
90          return sLine.toString();
91      }
92  
93      private double _divide( int divident, int divisor )
94      {
95          double dRetVal = 0.0;
96          if ( divisor > 0) {
97              dRetVal = Math.round(((double)divident/(double)divisor)*100)/100.0;
98          }
99  
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 }