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.Calendar;
027    import java.util.Iterator;
028    import java.util.List;
029    import java.util.Locale;
030    
031    import ccl.util.Util;
032    
033    /**
034     * Generates XML output of Java metrics.
035     *
036     * @author    Chr. Clemens Lee <clemens@kclee.com>
037     * @version   $Id: XmlFormatter.java 121 2009-01-17 22:19:45Z hboutemy $
038     */
039    public class XmlFormatter implements Formatter
040    {
041        private final Javancss _javancss;
042    
043        private double _divide( int divident, int divisor )
044        {
045            double dRetVal = 0.0;
046            if ( divisor > 0) {
047                dRetVal = Math.round(((double)divident/(double)divisor)*100)/100.0;
048            }
049    
050            return dRetVal;
051        }
052    
053        private double _divide( long divident, long divisor )
054        {
055            double dRetVal = 0.0;
056            if ( divisor > 0) {
057                dRetVal = Math.round(((double)divident/(double)divisor)*100)/100.0;
058            }
059    
060            return dRetVal;
061        }
062    
063        private NumberFormat _pNumberFormat = null;
064    
065        private String _formatPackageMatrix( int packages
066                                             , int classesSum
067                                             , int functionsSum
068                                             , int ncssSum
069                                             , int javadocsSum                                // added by SMS
070                                             , int javadocLnSum                                // added by SMS
071                                             , int singleLnSum                                // added by SMS
072                                             , int multiLnSum                )                // added by SMS
073        {
074            //NumberFormat pNumberFormat = new DecimalFormat("#,##0.00");
075    
076            String sRetVal =
077                "    <table>\n"
078                + "      <tr><td>Packages</td><td>Classes</td><td>Functions</td><td>NCSS</td><td>Javadocs</td><td>per</td></tr>\n"
079    
080    
081                + "      <tr><td>"
082                + _pNumberFormat.format( packages )
083                + "</td><td>"
084                + _pNumberFormat.format( classesSum )
085                + "</td><td>"
086                + _pNumberFormat.format( functionsSum )
087                + "</td><td>"
088                + _pNumberFormat.format( ncssSum )
089                + "</td><td>"
090                + _pNumberFormat.format( javadocsSum )
091                + "</td><td>Project</td></tr>\n"
092                + "      <tr><td></td><td>"
093                + _pNumberFormat.format( _divide( classesSum, packages ) )
094                + "</td><td>"
095                + _pNumberFormat.format( _divide( functionsSum, packages ) )
096                + "</td><td>"
097                + _pNumberFormat.format( _divide( ncssSum, packages ) )
098                + "</td><td>"
099                + _pNumberFormat.format( _divide( javadocsSum, packages ) )
100                + "</td><td>Package</td></tr>\n"
101                + "      <tr><td></td><td></td><td>"
102                + _pNumberFormat.format( _divide( functionsSum, classesSum ) )
103                + "</td><td>"
104                + _pNumberFormat.format( _divide( ncssSum, classesSum ) )
105                + "</td><td>"
106                + _pNumberFormat.format( _divide( javadocsSum, classesSum ) )
107                + "</td><td>Class</td></tr>\n"
108                + "      <tr><td></td><td></td><td></td><td>"
109                + _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
110                + "</td><td>"
111                //+ _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
112                + _pNumberFormat.format( _divide( javadocsSum, functionsSum ) )
113                + "</td><td>Function</td></tr>\n"
114                + "    </table>\n";
115            /*
116            String sRetVal =
117                "    <table>\n"
118                + "      <tr><td>Packages</td><td>Classes</td><td>Functions</td><td>NCSS</td>"
119                + "<td>javadocs</td><td>javadocs_lines</td><td>single_comment_lines"
120                + "</td><td>implementation_comment_lines</td><td>per</td></tr>\n"
121                + "      <tr><td>"
122                + _pNumberFormat.format( packages )
123                + "</td><td>"
124                + _pNumberFormat.format( classesSum )
125                + "</td><td>"
126                + _pNumberFormat.format( functionsSum )
127                + "</td><td>"
128                + _pNumberFormat.format( ncssSum )
129                    + "</td><td>"
130                + _pNumberFormat.format( javadocSum )
131                    + "</td><td>"
132                + _pNumberFormat.format( javadocLnSum )
133                    + "</td><td>"
134                + _pNumberFormat.format( singleLnSum )
135                    + "</td><td>"
136                + _pNumberFormat.format( multiLnSum )
137                + "</td><td>Project</td></tr>\n"
138                + "      <tr><td></td><td>"
139                + _pNumberFormat.format( _divide( classesSum, packages ) )
140                + "</td><td>"
141                + _pNumberFormat.format( _divide( functionsSum, packages ) )
142                + "</td><td>"
143                + _pNumberFormat.format( _divide( ncssSum, packages ) )
144                    + "</td><td>"
145                + _pNumberFormat.format( _divide( javadocSum, packages ) )
146                    + "</td><td>"
147                + _pNumberFormat.format( _divide( javadocLnSum, packages ) )
148                    + "</td><td>"
149                + _pNumberFormat.format( _divide( javadocLnSum, packages ) )
150                    + "</td><td>"
151                + _pNumberFormat.format( _divide( multiLnSum, packages ) )
152                + "</td><td>Package</td></tr>\n"
153                + "      <tr><td></td><td></td><td>"
154                + _pNumberFormat.format( _divide( functionsSum, classesSum ) )
155                + "</td><td>"
156                + _pNumberFormat.format( _divide( ncssSum, classesSum ) )
157                    + "</td><td>"
158                + _pNumberFormat.format( _divide( javadocSum, classesSum ) )
159                    + "</td><td>"
160                + _pNumberFormat.format( _divide( javadocLnSum, classesSum ) )
161                    + "</td><td>"
162                + _pNumberFormat.format( _divide( javadocLnSum, classesSum ) )
163                    + "</td><td>"
164                + _pNumberFormat.format( _divide( multiLnSum, classesSum ) )
165                + "</td><td>Class</td></tr>\n"
166                + "      <tr><td></td><td></td><td></td><td>"
167                + _pNumberFormat.format( _divide( ncssSum, functionsSum ) )
168                    + "</td><td>"
169                + _pNumberFormat.format( _divide( javadocSum, functionsSum ) )
170                    + "</td><td>"
171                + _pNumberFormat.format( _divide( javadocLnSum, functionsSum ) )
172                    + "</td><td>"
173                + _pNumberFormat.format( _divide( javadocLnSum, functionsSum ) )
174                    + "</td><td>"
175                + _pNumberFormat.format( _divide( multiLnSum, functionsSum ) )
176                + "</td><td>Function</td></tr>\n"
177                + "    </table>\n";
178            */
179    
180            return sRetVal;
181        }
182    
183        public XmlFormatter( Javancss javancss )
184        {
185            super();
186    
187            _javancss = javancss;
188    
189            _pNumberFormat = NumberFormat.getInstance( Locale.US );
190            ((DecimalFormat)_pNumberFormat).applyPattern( "#,##0.00" );
191        }
192    
193        public String printPackageNcss()
194        {
195            StringBuffer sbRetVal = new StringBuffer( "  <packages>\n" );
196            List 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( Iterator ePackages = vPackageMetrics.iterator(); ePackages.hasNext(); )
209            {
210                PackageMetric pPackageMetric = (PackageMetric)ePackages.next();
211    
212                classesSum += pPackageMetric.classes;
213                functionsSum += pPackageMetric.functions;
214                ncssSum += pPackageMetric.ncss;
215                // added by SMS
216                javadocSum += pPackageMetric.javadocs;
217                javadocLnSum += pPackageMetric.javadocsLn;
218                singleLnSum += pPackageMetric.singleLn;
219                multiLnSum += pPackageMetric.multiLn;
220                //
221                sbRetVal.append(
222                       "    <package>\n" +
223                       "      <name>" + pPackageMetric.name + "</name>\n" +
224                       "      <classes>" + pPackageMetric.classes + "</classes>\n" +
225                       "      <functions>" + pPackageMetric.functions + "</functions>\n" +
226                       "      <ncss>" + pPackageMetric.ncss + "</ncss>\n" +
227                       "      <javadocs>" + pPackageMetric.javadocs + "</javadocs>\n" +
228                       "      <javadoc_lines>" + pPackageMetric.javadocsLn + "</javadoc_lines>\n" +
229                       "      <single_comment_lines>" + pPackageMetric.singleLn + "</single_comment_lines>\n" +
230                       "      <multi_comment_lines>" + pPackageMetric.multiLn + "</multi_comment_lines>\n" +
231                       "    </package>\n" );
232            }
233    
234            sbRetVal.append(
235                   "    <total>\n" +
236                   "      <classes>" + classesSum + "</classes>\n" +
237                   "      <functions>" + functionsSum + "</functions>\n" +
238                   "      <ncss>" + ncssSum + "</ncss>\n" +
239                   "      <javadocs>" + javadocSum + "</javadocs>\n" +
240                   "      <javadoc_lines>" + javadocLnSum + "</javadoc_lines>\n" +
241                   "      <single_comment_lines>" + singleLnSum + "</single_comment_lines>\n" +
242                   "      <multi_comment_lines>" + multiLnSum + "</multi_comment_lines>\n" +
243                   "    </total>\n" );
244    
245            sbRetVal.append( _formatPackageMatrix( packages
246                                             , classesSum
247                                             , functionsSum
248                                             , ncssSum
249                                             , javadocSum                                // added by SMS
250                                             , javadocLnSum                                // added by SMS
251                                             , singleLnSum                                // added by SMS
252                                             , multiLnSum               ) );                // added by SMS
253    
254            sbRetVal.append( "  </packages>\n" );
255    
256            return sbRetVal.toString();
257        }
258    
259        private String _formatObjectResume( int objects
260                                            , long lObjectSum
261                                            , long lFunctionSum
262                                            , long lClassesSum
263                                            , long lJVDCSum
264                                            , long lJVDCLSum
265                                            , long lSLSum
266                                            , long lMLSum                )
267        {
268            double fAverageNcss     = _divide( lObjectSum  , objects );
269            double fAverageFuncs    = _divide( lFunctionSum, objects );
270            double fAverageClasses  = _divide( lClassesSum , objects );
271            double fAverageJavadocs = _divide( lJVDCSum    , objects );
272            // added by SMS
273            //double fAverageJVDCL = _divide( lJVDCLSum   , objects );
274            //double fAverageSL         = _divide( lSLSum                , objects );
275            //double fAverageML         = _divide( lMLSum                , objects );
276            //
277            //NumberFormat _pNumberFormat = new DecimalFormat("#,##0.00");
278            String sRetVal =
279                "    <averages>\n" +
280                "      <ncss>" + _pNumberFormat.format( fAverageNcss ) + "</ncss>\n" +
281                "      <functions>" + _pNumberFormat.format( fAverageFuncs ) + "</functions>\n" +
282                "      <classes>" + _pNumberFormat.format( fAverageClasses ) + "</classes>\n" +
283                "      <javadocs>" + _pNumberFormat.format( fAverageJavadocs ) + "</javadocs>\n" +
284                //"      <javadocs_lines>" + _pNumberFormat.format( fAverageJVDCL ) + "</javadocs_lines>\n" +
285                //"      <single_comment_lines>" + _pNumberFormat.format( fAverageSL ) + "</single_comment_lines>\n" +
286                //"      <implementation_comment_lines>" + _pNumberFormat.format( fAverageML ) + "</implementation_comment_lines>\n" +
287                "    </averages>\n" +
288                "    <ncss>" + _pNumberFormat.format( _javancss.getNcss() ) + "</ncss>\n";
289    
290            return sRetVal;
291        }
292    
293        public String printObjectNcss() {
294            StringBuffer sbRetVal = new StringBuffer( "  <objects>\n" );
295    
296            List/*<ObjectMetric>*/ vObjectMetrics = _javancss.getObjectMetrics();
297    
298            long lFunctionSum = 0;
299            long lClassesSum  = 0;
300            long lObjectSum   = 0;
301            long lJVDCSum     = 0;
302            for( Iterator eClasses = vObjectMetrics.iterator(); eClasses.hasNext(); )
303            {
304                ObjectMetric classMetric = (ObjectMetric)eClasses.next();
305                String sClass = classMetric.name;
306                int objectNcss = classMetric.ncss;
307                int functions  = classMetric.functions;
308                int classes    = classMetric.classes;
309                int jvdcs      = classMetric.javadocs;
310    
311                // added by SMS
312                //int jvdcsl     = ((Integer)vClassMetrics.elementAt(OBJ_JVDC_LINES)).intValue();
313                //int singlel           = ((Integer)vClassMetrics.elementAt(OBJ_SINGLE_LINES)).intValue();
314                //int multil     = ((Integer)vClassMetrics.elementAt(OBJ_MULTI_LINES)).intValue();
315                //
316                lObjectSum   += (long)objectNcss;
317                lFunctionSum += (long)functions;
318                lClassesSum  += (long)classes;
319                lJVDCSum     += (long)jvdcs;
320                sbRetVal.append(
321                    "    <object>\n" +
322                    "      <name>"      + sClass     + "</name>\n"      +
323                    "      <ncss>"      + objectNcss + "</ncss>\n"      +
324                    "      <functions>" + functions  + "</functions>\n" +
325                    "      <classes>"   + classes    + "</classes>\n"   +
326                    "      <javadocs>"  + jvdcs      + "</javadocs>\n"  +
327                    //"      <javadocs_lines>" + jvdcsl + "</javadocs_lines>\n" +
328                    //"      <single_comment_lines>" + singlel + "</single_comment_lines>\n" +
329                    //"      <implementation_comment_lines>" + multil + "</implementation_comment_lines>\n" +
330                    "    </object>\n" );
331            }
332    
333            sbRetVal.append( _formatObjectResume( vObjectMetrics.size()
334                                            , lObjectSum
335                                            , lFunctionSum
336                                            , lClassesSum
337                                            , lJVDCSum
338                                            , _javancss.getJdcl()
339                                            , _javancss.getSl()
340                                            , _javancss.getMl()
341                                            ) );
342    
343            sbRetVal.append( "  </objects>\n" );
344    
345            return sbRetVal.toString();
346        }
347    
348        private String _formatFunctionResume( int functions
349                                              , long lFunctionSum
350                                              , long lCCNSum
351                                              , long lJVDCSum
352                                              , long lJVDCLSum
353                                              , long lSLSum
354                                              , long lMLSum                )
355        {
356            double fAverageNcss = _divide( lFunctionSum, functions );
357            double fAverageCCN  = _divide( lCCNSum     , functions );
358            double fAverageJVDC = _divide( lJVDCSum    , functions );
359    
360            // added by SMS
361            //double fAverageJVDCL = _divide( lJVDCLSum   , functions );
362            //double fAverageSL         = _divide( lSLSum                , functions );
363            //double fAverageML         = _divide( lMLSum                , functions );
364            //
365    
366            //NumberFormat _pNumberFormat = new DecimalFormat("#,##0.00");
367            String sRetVal = "    <function_averages>\n" +
368                           "      <ncss>" + _pNumberFormat.format( fAverageNcss ) + "</ncss>\n" +
369                           "      <ccn>"  + _pNumberFormat.format( fAverageCCN  ) + "</ccn>\n"  +
370                           "      <javadocs>" + _pNumberFormat.format( fAverageJVDC ) + "</javadocs>\n" +
371                           //"      <javadocs_lines>" + _pNumberFormat.format( fAverageJVDCL ) + "</javadocs_lines>\n" +
372                           //"      <single_comment_lines>" + _pNumberFormat.format( fAverageSL ) + "</single_comment_lines>\n" +
373                           //"      <implementation_comment_lines>" + _pNumberFormat.format( fAverageML ) + "</implementation_comment_lines>\n" +
374                           "    </function_averages>\n" +
375                           "    <ncss>" + _pNumberFormat.format( _javancss.getNcss() ) + "</ncss>\n";
376    
377            return sRetVal;
378        }
379    
380        public String printFunctionNcss()
381        {
382            StringBuffer sRetVal = new StringBuffer(80000);
383    
384            sRetVal.append( "  <functions>\n" );
385    
386            List vFunctionMetrics = _javancss.getFunctionMetrics();
387    
388            long lFunctionSum = 0;
389            long lCCNSum      = 0;
390            long lJVDCSum     = 0;
391            for( Iterator eFunctions = vFunctionMetrics.iterator(); eFunctions.hasNext(); )
392            {
393                FunctionMetric functionMetric = (FunctionMetric)eFunctions.next();
394                String sFunction = functionMetric.name;
395                int functionNcss = functionMetric.ncss;
396                int functionCCN  = functionMetric.ccn;
397                int functionJVDC = functionMetric.javadocs;
398    
399                // added by SMS
400                //int functionJVDCL        = ((Integer)vSingleFunctionMetrics.elementAt(FCT_JVDC_LINES)).intValue();
401                //int functionSL                = ((Integer)vSingleFunctionMetrics.elementAt(FCT_SINGLE_LINES)).intValue();
402                //int functionML                = ((Integer)vSingleFunctionMetrics.elementAt(FCT_MULTI_LINES)).intValue();
403                //
404    
405                lFunctionSum += (long)functionNcss;
406                lCCNSum      += (long)functionCCN;
407                lJVDCSum     += (long)functionJVDC;
408                sRetVal.append(
409                               "    <function>\n" +
410                               "      <name>" + sFunction + "</name>\n" +
411                               "      <ncss>" + functionNcss + "</ncss>\n" +
412                               "      <ccn>"  + functionCCN  + "</ccn>\n"  +
413                               "      <javadocs>" + functionJVDC + "</javadocs>\n" +
414                               //"      <javadocs_lines>" + functionJVDCL + "</javadocs_lines>\n" +
415                               //"      <single_comment_lines>" + functionSL + "</single_comment_lines>\n" +
416                               //"      <implementation_comment_lines>" + functionML + "</implementation_comment_lines>\n" +
417                               "    </function>\n" );
418            }
419    
420            sRetVal.append( _formatFunctionResume( vFunctionMetrics.size()
421                                                   , lFunctionSum
422                                                   , lCCNSum
423                                                   , lJVDCSum
424                                                   , _javancss.getJdcl()
425                                                   , _javancss.getSl()
426                                                   , _javancss.getMl()
427                                                   ) );
428    
429            sRetVal.append( "  </functions>\n" );
430    
431            return sRetVal.toString();
432        }
433    
434        public String printJavaNcss() {
435            return        "  <ncss>" + _javancss.getNcss() + "</ncss>\n"
436                   //+
437                   //"  <javadocs>" + _javancss.getJvdc() + "</javadocs>\n" +
438                   //"  <javadocs_lines>" + _javancss.getJdcl() + "</javadocs_lines>\n" +
439                   //"  <single_comment_lines>" + _javancss.getSl() + "</single_comment_lines>\n" +
440                   //"  <implementation_comment_lines>" + _javancss.getSl() + "</implementation_comment_lines>\n";
441                   ;
442        }
443    
444        static public String printStart()
445        {
446            Calendar calendar = Util.getCalendar();
447    
448            return "<?xml version=\"1.0\"?>\n" +
449                   "<javancss>\n" +
450                   "  <date>" + Util.getDate( calendar ) + "</date>\n" +
451                   "  <time>" + Util.getTime( calendar ) + "</time>\n";
452        }
453    
454        static public String printEnd()
455        {
456            return "</javancss>\n";
457        }
458    }