View Javadoc
1   /*
2   Copyright (C) 2014 Chr. Clemens Lee <clemens@kclee.com>.
3   
4   This file is part of JavaNCSS
5   (http://javancss.codehaus.org/).
6   
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11  
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  Lesser General Public License for more details.
16  
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA*/
20  
21  package javancss;
22  
23  import java.io.IOException;
24  import java.io.Writer;
25  import java.text.DecimalFormat;
26  import java.text.NumberFormat;
27  import java.util.Date;
28  import java.util.List;
29  import java.util.Locale;
30  
31  /**
32   * Generates XML output of Java metrics.
33   *
34   * @author    Chr. Clemens Lee <clemens@kclee.com>
35   * @version   $Id$
36   */
37  public class XmlFormatter
38      implements Formatter
39  {
40      private final Javancss _javancss;
41  
42      private double _divide( int divident, int divisor )
43      {
44          double dRetVal = 0.0;
45          if ( divisor > 0 )
46          {
47              dRetVal = Math.round( ( (double) divident / (double) divisor ) * 100 ) / 100.0;
48          }
49  
50          return dRetVal;
51      }
52  
53      private double _divide( long divident, long divisor )
54      {
55          double dRetVal = 0.0;
56          if ( divisor > 0 )
57          {
58              dRetVal = Math.round( ( (double) divident / (double) divisor ) * 100 ) / 100.0;
59          }
60  
61          return dRetVal;
62      }
63  
64      private NumberFormat _pNumberFormat = null;
65  
66      private String _formatPackageMatrix( int packages
67                                           , int classesSum
68                                           , int functionsSum
69                                           , int ncssSum
70                                           , int javadocsSum                                // added by SMS
71                                           , int javadocLnSum                                // added by SMS
72                                           , int singleLnSum                                // added by SMS
73                                           , int multiLnSum                )                // added by SMS
74      {
75          //NumberFormat pNumberFormat = new DecimalFormat("#,##0.00");
76  
77          String sRetVal =
78              "    <table>\n"
79              + "      <tr><td>Packages</td><td>Classes</td><td>Functions</td><td>NCSS</td><td>Javadocs</td><td>per</td></tr>\n"
80  
81  
82              + "      <tr><td>"
83              + _pNumberFormat.format( packages )
84              + "</td><td>"
85              + _pNumberFormat.format( classesSum )
86              + "</td><td>"
87              + _pNumberFormat.format( functionsSum )
88              + "</td><td>"
89              + _pNumberFormat.format( ncssSum )
90              + "</td><td>"
91              + _pNumberFormat.format( javadocsSum )
92              + "</td><td>Project</td></tr>\n"
93              + "      <tr><td></td><td>"
94              + _pNumberFormat.format( _divide( classesSum, packages ) )
95              + "</td><td>"
96              + _pNumberFormat.format( _divide( functionsSum, packages ) )
97              + "</td><td>"
98              + _pNumberFormat.format( _divide( ncssSum, packages ) )
99              + "</td><td>"
100             + _pNumberFormat.format( _divide( javadocsSum, packages ) )
101             + "</td><td>Package</td></tr>\n"
102             + "      <tr><td></td><td></td><td>"
103             + _pNumberFormat.format( _divide( functionsSum, classesSum ) )
104             + "</td><td>"
105             + _pNumberFormat.format( _divide( ncssSum, classesSum ) )
106             + "</td><td>"
107             + _pNumberFormat.format( _divide( javadocsSum, classesSum ) )
108             + "</td><td>Class</td></tr>\n"
109             + "      <tr><td></td><td></td><td></td><td>"
110             + _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
111             + "</td><td>"
112             //+ _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
113             + _pNumberFormat.format( _divide( javadocsSum, functionsSum ) )
114             + "</td><td>Function</td></tr>\n"
115             + "    </table>\n";
116         /*
117         String sRetVal =
118             "    <table>\n"
119             + "      <tr><td>Packages</td><td>Classes</td><td>Functions</td><td>NCSS</td>"
120             + "<td>javadocs</td><td>javadocs_lines</td><td>single_comment_lines"
121             + "</td><td>implementation_comment_lines</td><td>per</td></tr>\n"
122             + "      <tr><td>"
123             + _pNumberFormat.format( packages )
124             + "</td><td>"
125             + _pNumberFormat.format( classesSum )
126             + "</td><td>"
127             + _pNumberFormat.format( functionsSum )
128             + "</td><td>"
129             + _pNumberFormat.format( ncssSum )
130                 + "</td><td>"
131             + _pNumberFormat.format( javadocSum )
132                 + "</td><td>"
133             + _pNumberFormat.format( javadocLnSum )
134                 + "</td><td>"
135             + _pNumberFormat.format( singleLnSum )
136                 + "</td><td>"
137             + _pNumberFormat.format( multiLnSum )
138             + "</td><td>Project</td></tr>\n"
139             + "      <tr><td></td><td>"
140             + _pNumberFormat.format( _divide( classesSum, packages ) )
141             + "</td><td>"
142             + _pNumberFormat.format( _divide( functionsSum, packages ) )
143             + "</td><td>"
144             + _pNumberFormat.format( _divide( ncssSum, packages ) )
145                 + "</td><td>"
146             + _pNumberFormat.format( _divide( javadocSum, packages ) )
147                 + "</td><td>"
148             + _pNumberFormat.format( _divide( javadocLnSum, packages ) )
149                 + "</td><td>"
150             + _pNumberFormat.format( _divide( javadocLnSum, packages ) )
151                 + "</td><td>"
152             + _pNumberFormat.format( _divide( multiLnSum, packages ) )
153             + "</td><td>Package</td></tr>\n"
154             + "      <tr><td></td><td></td><td>"
155             + _pNumberFormat.format( _divide( functionsSum, classesSum ) )
156             + "</td><td>"
157             + _pNumberFormat.format( _divide( ncssSum, classesSum ) )
158                 + "</td><td>"
159             + _pNumberFormat.format( _divide( javadocSum, classesSum ) )
160                 + "</td><td>"
161             + _pNumberFormat.format( _divide( javadocLnSum, classesSum ) )
162                 + "</td><td>"
163             + _pNumberFormat.format( _divide( javadocLnSum, classesSum ) )
164                 + "</td><td>"
165             + _pNumberFormat.format( _divide( multiLnSum, classesSum ) )
166             + "</td><td>Class</td></tr>\n"
167             + "      <tr><td></td><td></td><td></td><td>"
168             + _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
169                 + "</td><td>"
170             + _pNumberFormat.format( _divide( javadocSum, functionsSum ) )
171                 + "</td><td>"
172             + _pNumberFormat.format( _divide( javadocLnSum, functionsSum ) )
173                 + "</td><td>"
174             + _pNumberFormat.format( _divide( javadocLnSum, functionsSum ) )
175                 + "</td><td>"
176             + _pNumberFormat.format( _divide( multiLnSum, functionsSum ) )
177             + "</td><td>Function</td></tr>\n"
178             + "    </table>\n";
179         */
180 
181         return sRetVal;
182     }
183 
184     public XmlFormatter( Javancss javancss )
185     {
186         _javancss = javancss;
187 
188         _pNumberFormat = NumberFormat.getInstance( Locale.US );
189         ( (DecimalFormat) _pNumberFormat ).applyPattern( "#,##0.00" );
190     }
191 
192     public void printPackageNcss( Writer w )
193         throws IOException
194     {
195         w.write( "  <packages>\n" );
196         List<PackageMetric> vPackageMetrics = _javancss.getPackageMetrics();
197 
198         int packages = vPackageMetrics.size();
199         int classesSum = 0;
200         int functionsSum = 0;
201         int ncssSum = 0;
202         //added by SMS
203         int javadocSum = 0;
204         int javadocLnSum = 0;
205         int singleLnSum = 0;
206         int multiLnSum = 0;
207         //
208         for ( PackageMetric pPackageMetric : vPackageMetrics )
209         {
210             classesSum += pPackageMetric.classes;
211             functionsSum += pPackageMetric.functions;
212             ncssSum += pPackageMetric.ncss;
213             // added by SMS
214             javadocSum += pPackageMetric.javadocs;
215             javadocLnSum += pPackageMetric.javadocsLn;
216             singleLnSum += pPackageMetric.singleLn;
217             multiLnSum += pPackageMetric.multiLn;
218             //
219             w.write(
220                    "    <package>\n" +
221                    "      <name>" + pPackageMetric.name + "</name>\n" +
222                    "      <classes>" + pPackageMetric.classes + "</classes>\n" +
223                    "      <functions>" + pPackageMetric.functions + "</functions>\n" +
224                    "      <ncss>" + pPackageMetric.ncss + "</ncss>\n" +
225                    "      <javadocs>" + pPackageMetric.javadocs + "</javadocs>\n" +
226                    "      <javadoc_lines>" + pPackageMetric.javadocsLn + "</javadoc_lines>\n" +
227                    "      <single_comment_lines>" + pPackageMetric.singleLn + "</single_comment_lines>\n" +
228                    "      <multi_comment_lines>" + pPackageMetric.multiLn + "</multi_comment_lines>\n" +
229                    "    </package>\n" );
230         }
231 
232         w.write(
233                "    <total>\n" +
234                "      <classes>" + classesSum + "</classes>\n" +
235                "      <functions>" + functionsSum + "</functions>\n" +
236                "      <ncss>" + ncssSum + "</ncss>\n" +
237                "      <javadocs>" + javadocSum + "</javadocs>\n" +
238                "      <javadoc_lines>" + javadocLnSum + "</javadoc_lines>\n" +
239                "      <single_comment_lines>" + singleLnSum + "</single_comment_lines>\n" +
240                "      <multi_comment_lines>" + multiLnSum + "</multi_comment_lines>\n" +
241                "    </total>\n" );
242 
243         w.write( _formatPackageMatrix( packages
244                                          , classesSum
245                                          , functionsSum
246                                          , ncssSum
247                                          , javadocSum                                // added by SMS
248                                          , javadocLnSum                                // added by SMS
249                                          , singleLnSum                                // added by SMS
250                                          , multiLnSum               ) );                // added by SMS
251 
252         w.write( "  </packages>\n" );
253     }
254 
255     private String _formatObjectResume( int objects
256                                         , long lObjectSum
257                                         , long lFunctionSum
258                                         , long lClassesSum
259                                         , long lJVDCSum
260                                         , long lJVDCLSum
261                                         , long lSLSum
262                                         , long lMLSum                )
263     {
264         double fAverageNcss     = _divide( lObjectSum  , objects );
265         double fAverageFuncs    = _divide( lFunctionSum, objects );
266         double fAverageClasses  = _divide( lClassesSum , objects );
267         double fAverageJavadocs = _divide( lJVDCSum    , objects );
268         // added by SMS
269         double fAverageJVDCL 	  = _divide( lJVDCLSum , objects );
270         double fAverageSL         = _divide( lSLSum , objects );
271         double fAverageML         = _divide( lMLSum , objects );
272         //
273         //NumberFormat _pNumberFormat = new DecimalFormat("#,##0.00");
274         String sRetVal =
275             "    <averages>\n" +
276             "      <ncss>" + _pNumberFormat.format( fAverageNcss ) + "</ncss>\n" +
277             "      <functions>" + _pNumberFormat.format( fAverageFuncs ) + "</functions>\n" +
278             "      <classes>" + _pNumberFormat.format( fAverageClasses ) + "</classes>\n" +
279             "      <javadocs>" + _pNumberFormat.format( fAverageJavadocs ) + "</javadocs>\n" +
280             "      <javadocs_lines>" + _pNumberFormat.format( fAverageJVDCL ) + "</javadocs_lines>\n" +
281             "      <single_comment_lines>" + _pNumberFormat.format( fAverageSL ) + "</single_comment_lines>\n" +
282             "      <implementation_comment_lines>" + _pNumberFormat.format( fAverageML ) + "</implementation_comment_lines>\n" +
283             "    </averages>\n" +
284             "    <ncss>" + _pNumberFormat.format( _javancss.getNcss() ) + "</ncss>\n";
285 
286         return sRetVal;
287     }
288 
289     public void printObjectNcss( Writer w )
290         throws IOException
291     {
292         w.write( "  <objects>\n" );
293 
294         List<ObjectMetric> vObjectMetrics = _javancss.getObjectMetrics();
295 
296         long lFunctionSum = 0;
297         long lClassesSum  = 0;
298         long lObjectSum   = 0;
299         long lJVDCSum     = 0;
300 
301         // added by REYNAUD Sebastien (LOGICA)
302         long lJVDCSL	  = 0;
303         long lSinglel	  = 0;
304         long lMultil	  = 0;
305         //
306 
307         for ( ObjectMetric classMetric : vObjectMetrics )
308         {
309             String sClass  = classMetric.name;
310             int objectNcss = classMetric.ncss;
311             int functions  = classMetric.functions;
312             int classes    = classMetric.classes;
313             int jvdcs      = classMetric.javadocs;
314 
315             // added by SMS
316             int jvdcsl     = classMetric.javadocsLn;
317             int singlel    = classMetric.singleLn;
318             int multil     = classMetric.multiLn;
319             //
320             lObjectSum   += objectNcss;
321             lFunctionSum += functions;
322             lClassesSum  += classes;
323             lJVDCSum     += jvdcs;
324 
325             // added by REYNAUD Sebastien (LOGICA)
326             lJVDCSL += jvdcsl;
327             lSinglel += singlel;
328             lMultil += multil;
329             //
330 
331             w.write(
332                 "    <object>\n" +
333                 "      <name>"      + sClass     + "</name>\n"      +
334                 "      <ncss>"      + objectNcss + "</ncss>\n"      +
335                 "      <functions>" + functions  + "</functions>\n" +
336                 "      <classes>"   + classes    + "</classes>\n"   +
337                 "      <javadocs>"  + jvdcs      + "</javadocs>\n"  +
338                 "      <javadocs_lines>" + jvdcsl + "</javadocs_lines>\n" +
339                 "      <single_comment_lines>" + singlel + "</single_comment_lines>\n" +
340                 "      <implementation_comment_lines>" + multil + "</implementation_comment_lines>\n" +
341                 "    </object>\n" );
342         }
343 
344         /* Removed by REYNAUD Sebastien (LOGICA)
345         sbRetVal.append( _formatObjectResume( vObjectMetrics.size()
346                                         , lObjectSum
347                                         , lFunctionSum
348                                         , lClassesSum
349                                         , lJVDCSum
350                                         , _javancss.getJdcl()
351                                         , _javancss.getSl()
352                                         , _javancss.getMl()
353                                         ) );
354 
355 		*/
356 
357         // added by REYNAUD Sebastien (LOGICA)
358         w.write( _formatObjectResume( vObjectMetrics.size()
359                 , lObjectSum
360                 , lFunctionSum
361                 , lClassesSum
362                 , lJVDCSum
363                 , lJVDCSL
364                 , lSinglel
365                 , lMultil
366                 ) );
367         //
368 
369         w.write( "  </objects>\n" );
370     }
371 
372     private String _formatFunctionResume( int functions
373                                           , long lFunctionSum
374                                           , long lCCNSum
375                                           , long lJVDCSum
376                                           , long lJVDCLSum
377                                           , long lSLSum
378                                           , long lMLSum                )
379     {
380         double fAverageNcss = _divide( lFunctionSum, functions );
381         double fAverageCCN  = _divide( lCCNSum     , functions );
382         double fAverageJVDC = _divide( lJVDCSum    , functions );
383 
384         // added by SMS
385         //double fAverageJVDCL = _divide( lJVDCLSum   , functions );
386         //double fAverageSL         = _divide( lSLSum                , functions );
387         //double fAverageML         = _divide( lMLSum                , functions );
388         //
389 
390         //NumberFormat _pNumberFormat = new DecimalFormat("#,##0.00");
391         String sRetVal = "    <function_averages>\n" +
392                        "      <ncss>" + _pNumberFormat.format( fAverageNcss ) + "</ncss>\n" +
393                        "      <ccn>"  + _pNumberFormat.format( fAverageCCN  ) + "</ccn>\n"  +
394                        "      <javadocs>" + _pNumberFormat.format( fAverageJVDC ) + "</javadocs>\n" +
395                        //"      <javadocs_lines>" + _pNumberFormat.format( fAverageJVDCL ) + "</javadocs_lines>\n" +
396                        //"      <single_comment_lines>" + _pNumberFormat.format( fAverageSL ) + "</single_comment_lines>\n" +
397                        //"      <implementation_comment_lines>" + _pNumberFormat.format( fAverageML ) + "</implementation_comment_lines>\n" +
398                        "    </function_averages>\n" +
399                        "    <ncss>" + _pNumberFormat.format( _javancss.getNcss() ) + "</ncss>\n";
400 
401         return sRetVal;
402     }
403 
404     public void printFunctionNcss( Writer w )
405         throws IOException
406     {
407         w.write( "  <functions>\n" );
408 
409         List<FunctionMetric> vFunctionMetrics = _javancss.getFunctionMetrics();
410 
411         long lFunctionSum = 0;
412         long lCCNSum      = 0;
413         long lJVDCSum     = 0;
414         for ( FunctionMetric functionMetric : vFunctionMetrics )
415         {
416             String sFunction = functionMetric.name;
417             int functionNcss = functionMetric.ncss;
418             int functionCCN  = functionMetric.ccn;
419             int functionJVDC = functionMetric.javadocs;
420 
421             // added by SMS
422             //int functionJVDCL        = ((Integer)vSingleFunctionMetrics.elementAt(FCT_JVDC_LINES)).intValue();
423             //int functionSL                = ((Integer)vSingleFunctionMetrics.elementAt(FCT_SINGLE_LINES)).intValue();
424             //int functionML                = ((Integer)vSingleFunctionMetrics.elementAt(FCT_MULTI_LINES)).intValue();
425             //
426 
427             lFunctionSum += functionNcss;
428             lCCNSum      += functionCCN;
429             lJVDCSum     += functionJVDC;
430             w.write(
431                            "    <function>\n" +
432                            "      <name>" + sFunction + "</name>\n" +
433                            "      <ncss>" + functionNcss + "</ncss>\n" +
434                            "      <ccn>"  + functionCCN  + "</ccn>\n"  +
435                            "      <javadocs>" + functionJVDC + "</javadocs>\n" +
436                            //"      <javadocs_lines>" + functionJVDCL + "</javadocs_lines>\n" +
437                            //"      <single_comment_lines>" + functionSL + "</single_comment_lines>\n" +
438                            //"      <implementation_comment_lines>" + functionML + "</implementation_comment_lines>\n" +
439                            "    </function>\n" );
440         }
441 
442         w.write( _formatFunctionResume( vFunctionMetrics.size()
443                                                , lFunctionSum
444                                                , lCCNSum
445                                                , lJVDCSum
446                                                , _javancss.getJdcl()
447                                                , _javancss.getSl()
448                                                , _javancss.getMl()
449                                                ) );
450 
451         w.write( "  </functions>\n" );
452     }
453 
454     public void printJavaNcss( Writer w )
455         throws IOException
456     {
457         w.write( "  <ncss>" + _javancss.getNcss() + "</ncss>\n"
458                //+
459                //"  <javadocs>" + _javancss.getJvdc() + "</javadocs>\n" +
460                //"  <javadocs_lines>" + _javancss.getJdcl() + "</javadocs_lines>\n" +
461                //"  <single_comment_lines>" + _javancss.getSl() + "</single_comment_lines>\n" +
462                //"  <implementation_comment_lines>" + _javancss.getSl() + "</implementation_comment_lines>\n";
463                );
464     }
465 
466     public void printStart( Writer w )
467         throws IOException
468     {
469         w.write( "<?xml version=\"1.0\"?>\n" );
470         w.write( "<javancss>\n" );
471         w.write( String.format( "  <date>%tF</date>\n", new Date() ) );
472         w.write( String.format( "  <time>%tT</time>\n", new Date() ) );
473     }
474 
475     public void printEnd( Writer w )
476         throws IOException
477     {
478         w.write( "</javancss>\n" );
479     }
480 }