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 }