View Javadoc
1   package org.codehaus.mojo.javancss;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.ResourceBundle;
26  
27  import org.apache.maven.plugin.logging.Log;
28  import org.apache.maven.doxia.sink.Sink;
29  import org.dom4j.Document;
30  import org.dom4j.Node;
31  
32  /**
33   * Generates the javaNcss maven report.
34   *
35   * @author <a href="jeanlaurentATgmail.com">Jean-Laurent de Morlhon</a>
36   * @version $Id$
37   */
38  public class NcssReportGenerator
39      extends AbstractNcssReportGenerator
40  {
41      private String xrefLocation;
42  
43      private int lineThreshold;
44  
45      /**
46       * build a new NcssReportGenerator.
47       *
48       * @param sink the sink which will be used for reporting.
49       * @param bundle the correct RessourceBundle to be used for reporting.
50       * @param log the log to output log with.
51       * @param xrefLocation the location of the xref file.
52       */
53      public NcssReportGenerator( Sink sink, ResourceBundle bundle, Log log, String xrefLocation )
54      {
55          super( sink, bundle, log );
56          this.xrefLocation = xrefLocation;
57      }
58  
59      /**
60       * Generates the JavaNcss reports.
61       *
62       * @param document the javaNcss raw report as an XML document.
63       * @param lineThreshold the maximum number of lines to keep in major reports.
64       */
65      public void doReport( Document document, int lineThreshold )
66      {
67          this.lineThreshold = lineThreshold;
68          // HEADER
69          getSink().head();
70          getSink().title();
71          getSink().text( getString( "report.javancss.title" ) );
72          getSink().title_();
73          getSink().head_();
74          // BODY
75          getSink().body();
76          doIntro( true );
77          // packages
78          startSection( "report.javancss.package.link", "report.javancss.package.title" );
79          doMainPackageAnalysis( document );
80          doTotalPackageAnalysis( document );
81          endSection();
82          // Objects
83          startSection( "report.javancss.object.link", "report.javancss.object.title" );
84          doTopObjectNcss( document );
85          doTopObjectFunctions( document );
86          doObjectAverage( document );
87          endSection();
88          // Functions
89          startSection( "report.javancss.function.link", "report.javancss.function.title" );
90          doFunctionAnalysis( document );
91          doFunctionAverage( document );
92          endSection();
93          // Explanation
94          startSection( "report.javancss.explanation.link", "report.javancss.explanation.title" );
95          doExplanation();
96          endSection();
97          getSink().body_();
98          getSink().close();
99      }
100 
101     private void doMainPackageAnalysis( Document document )
102     {
103         subtitleHelper( getString( "report.javancss.package.text" ) );
104         getSink().table();
105         getSink().tableRow();
106         // HEADER
107         headerCellHelper( getString( "report.javancss.header.package" ) );
108         headerCellHelper( getString( "report.javancss.header.classe" ) );
109         headerCellHelper( getString( "report.javancss.header.function" ) );
110         headerCellHelper( getString( "report.javancss.header.ncss" ) );
111         headerCellHelper( getString( "report.javancss.header.javadoc" ) );
112         headerCellHelper( getString( "report.javancss.header.javadoc_line" ) );
113         headerCellHelper( getString( "report.javancss.header.single_comment" ) );
114         headerCellHelper( getString( "report.javancss.header.multi_comment" ) );
115         getSink().tableRow_();
116         // DATA
117         List<Node> list = document.selectNodes( "//javancss/packages/package" );
118         Collections.<Node>sort( list, new NumericNodeComparator( "ncss" ) );
119         for ( Node node : list )
120         {
121             getSink().tableRow();
122             tableCellHelper( node.valueOf( "name" ) );
123             tableCellHelper( node.valueOf( "classes" ) );
124             tableCellHelper( node.valueOf( "functions" ) );
125             tableCellHelper( node.valueOf( "ncss" ) );
126             tableCellHelper( node.valueOf( "javadocs" ) );
127             tableCellHelper( node.valueOf( "javadoc_lines" ) );
128             tableCellHelper( node.valueOf( "single_comment_lines" ) );
129             tableCellHelper( node.valueOf( "multi_comment_lines" ) );
130             getSink().tableRow_();
131         }
132         getSink().table_();
133     }
134 
135     private void doTotalPackageAnalysis( Document document )
136     {
137         getSink().table();
138         getSink().tableRow();
139         headerCellHelper( getString( "report.javancss.header.classetotal" ) );
140         headerCellHelper( getString( "report.javancss.header.functiontotal" ) );
141         headerCellHelper( getString( "report.javancss.header.ncsstotal" ) );
142         headerCellHelper( getString( "report.javancss.header.javadoc" ) );
143         headerCellHelper( getString( "report.javancss.header.javadoc_line" ) );
144         headerCellHelper( getString( "report.javancss.header.single_comment" ) );
145         headerCellHelper( getString( "report.javancss.header.multi_comment" ) );
146         getSink().tableRow_();
147         Node node = document.selectSingleNode( "//javancss/packages/total" );
148         getSink().tableRow();
149         tableCellHelper( node.valueOf( "classes" ) );
150         tableCellHelper( node.valueOf( "functions" ) );
151         tableCellHelper( node.valueOf( "ncss" ) );
152         tableCellHelper( node.valueOf( "javadocs" ) );
153         tableCellHelper( node.valueOf( "javadoc_lines" ) );
154         tableCellHelper( node.valueOf( "single_comment_lines" ) );
155         tableCellHelper( node.valueOf( "multi_comment_lines" ) );
156         getSink().tableRow_();
157         getSink().table_();
158     }
159 
160     private void doTopObjectNcss( Document document )
161     {
162         subtitleHelper( getString( "report.javancss.top" ) + " " + lineThreshold + " "
163             + getString( "report.javancss.object.byncss" ) );
164         List<Node> nodeList = document.selectNodes( "//javancss/objects/object" );
165         Collections.<Node>sort( nodeList, new NumericNodeComparator( "ncss" ) );
166         doTopObjectGeneric( nodeList );
167     }
168 
169     private void doTopObjectFunctions( Document document )
170     {
171         subtitleHelper( getString( "report.javancss.top" ) + " " + lineThreshold + " "
172             + getString( "report.javancss.object.byfunction" ) );
173         List<Node> nodeList = document.selectNodes( "//javancss/objects/object" );
174         Collections.<Node>sort( nodeList, new NumericNodeComparator( "functions" ) );
175         doTopObjectGeneric( nodeList );
176     }
177 
178     // generic method called by doTopObjectFunctions & doTopObjectNCss
179     private void doTopObjectGeneric( List<Node> nodeList )
180     {
181         getSink().table();
182         getSink().tableRow();
183         headerCellHelper( getString( "report.javancss.header.object" ) );
184         headerCellHelper( getString( "report.javancss.header.ncss" ) );
185         headerCellHelper( getString( "report.javancss.header.function" ) );
186         headerCellHelper( getString( "report.javancss.header.classe" ) );
187         headerCellHelper( getString( "report.javancss.header.javadoc" ) );
188         getSink().tableRow_();
189         Iterator<Node> nodeIterator = nodeList.iterator();
190         int i = 0;
191         while ( nodeIterator.hasNext() && ( i++ < lineThreshold ) )
192         {
193             Node node = nodeIterator.next();
194             getSink().tableRow();
195             getSink().tableCell();
196             jxrLink( node.valueOf( "name" ) );
197             getSink().tableCell_();
198             tableCellHelper( node.valueOf( "ncss" ) );
199             tableCellHelper( node.valueOf( "functions" ) );
200             tableCellHelper( node.valueOf( "classes" ) );
201             tableCellHelper( node.valueOf( "javadocs" ) );
202             getSink().tableRow_();
203         }
204         getSink().table_();
205     }
206 
207     private void doObjectAverage( Document document )
208     {
209         subtitleHelper( getString( "report.javancss.averages" ) );
210         getSink().table();
211         getSink().tableRow();
212         headerCellHelper( getString( "report.javancss.header.ncssaverage" ) );
213         headerCellHelper( getString( "report.javancss.header.programncss" ) );
214         headerCellHelper( getString( "report.javancss.header.classeaverage" ) );
215         headerCellHelper( getString( "report.javancss.header.functionaverage" ) );
216         headerCellHelper( getString( "report.javancss.header.javadocaverage" ) );
217         getSink().tableRow_();
218         Node node = document.selectSingleNode( "//javancss/objects/averages" );
219         String totalNcss = document.selectSingleNode( "//javancss/objects/ncss" ).getText();
220         getSink().tableRow();
221         tableCellHelper( node.valueOf( "ncss" ) );
222         tableCellHelper( totalNcss );
223         tableCellHelper( node.valueOf( "classes" ) );
224         tableCellHelper( node.valueOf( "functions" ) );
225         tableCellHelper( node.valueOf( "javadocs" ) );
226         getSink().tableRow_();
227         getSink().table_();
228     }
229 
230     private void doFunctionAnalysis( Document document )
231     {
232         subtitleHelper( getString( "report.javancss.top" ) + " " + lineThreshold + " "
233             + getString( "report.javancss.function.byncss" ) );
234         getSink().table();
235         getSink().tableRow();
236         headerCellHelper( getString( "report.javancss.header.function" ) );
237         headerCellHelper( getString( "report.javancss.header.ncss" ) );
238         headerCellHelper( getString( "report.javancss.header.ccn" ) );
239         headerCellHelper( getString( "report.javancss.header.javadoc" ) );
240         getSink().tableRow_();
241         List<Node> list = document.selectNodes( "//javancss/functions/function" );
242         Collections.<Node>sort( list, new NumericNodeComparator( "ncss" ) );
243         Iterator<Node> nodeIterator = list.iterator();
244         int i = 0;
245         while ( nodeIterator.hasNext() && ( i++ < lineThreshold ) )
246         {
247             Node node = nodeIterator.next();
248             getSink().tableRow();
249             getSink().tableCell();
250             jxrFunctionLink( node.valueOf( "name" ) );
251             getSink().tableCell_();
252             tableCellHelper( node.valueOf( "ncss" ) );
253             tableCellHelper( node.valueOf( "ccn" ) );
254             tableCellHelper( node.valueOf( "javadocs" ) );
255             getSink().tableRow_();
256         }
257         getSink().table_();
258     }
259 
260     private void doFunctionAverage( Document document )
261     {
262         subtitleHelper( getString( "report.javancss.averages" ) );
263         getSink().table();
264         getSink().tableRow();
265         headerCellHelper( getString( "report.javancss.header.programncss" ) );
266         headerCellHelper( getString( "report.javancss.header.ncssaverage" ) );
267         headerCellHelper( getString( "report.javancss.header.ccnaverage" ) );
268         headerCellHelper( getString( "report.javancss.header.javadocaverage" ) );
269         getSink().tableRow_();
270         Node node = document.selectSingleNode( "//javancss/functions/function_averages" );
271         String totalNcss = document.selectSingleNode( "//javancss/functions/ncss" ).getText();
272         getSink().tableRow();
273         tableCellHelper( totalNcss );
274         tableCellHelper( node.valueOf( "ncss" ) );
275         tableCellHelper( node.valueOf( "ccn" ) );
276         tableCellHelper( node.valueOf( "javadocs" ) );
277         getSink().tableRow_();
278         getSink().table_();
279     }
280 
281     private void doExplanation()
282     {
283         subtitleHelper( getString( "report.javancss.explanation.ncss.title" ) );
284         paragraphHelper( getString( "report.javancss.explanation.ncss.paragraph1" ) );
285         paragraphHelper( getString( "report.javancss.explanation.ncss.paragraph2" ) );
286         getSink().table();
287 
288         getSink().tableRow();
289         headerCellHelper( "" );
290         headerCellHelper( getString( "report.javancss.explanation.ncss.table.examples" ) );
291         getSink().tableRow_();
292 
293         getSink().tableRow();
294         tableCellHelper( getString( "report.javancss.explanation.ncss.table.package" ) );
295         codeCellHelper( "package java.lang;" );
296         getSink().tableRow_();
297 
298         getSink().tableRow();
299         tableCellHelper( getString( "report.javancss.explanation.ncss.table.import" ) );
300         codeCellHelper( "import java.awt.*;" );
301         getSink().tableRow_();
302 
303         getSink().tableRow();
304         tableCellHelper( getString( "report.javancss.explanation.ncss.table.class" ) );
305         getSink().tableCell();
306         getSink().list();
307         codeItemListHelper( "public class Foo {" );
308         codeItemListHelper( "public class Foo extends Bla {" );
309         getSink().list_();
310         getSink().tableCell_();
311         getSink().tableRow_();
312 
313         getSink().tableRow();
314         tableCellHelper( getString( "report.javancss.explanation.ncss.table.interface" ) );
315         codeCellHelper( "public interface Able ; {" );
316         getSink().tableRow_();
317 
318         getSink().tableRow();
319         tableCellHelper( getString( "report.javancss.explanation.ncss.table.field" ) );
320         getSink().tableCell();
321         getSink().list();
322         codeItemListHelper( "int a; " );
323         codeItemListHelper( "int a, b, c = 5, d = 6;" );
324         getSink().list_();
325         getSink().tableCell_();
326         getSink().tableRow_();
327 
328         getSink().tableRow();
329         tableCellHelper( getString( "report.javancss.explanation.ncss.table.method" ) );
330         getSink().tableCell();
331         getSink().list();
332         codeItemListHelper( "public void cry();" );
333         codeItemListHelper( "public void gib() throws DeadException {" );
334         getSink().list_();
335         getSink().tableCell_();
336         getSink().tableRow_();
337 
338         getSink().tableRow();
339         tableCellHelper( getString( "report.javancss.explanation.ncss.table.constructorD" ) );
340         codeCellHelper( "public Foo() {" );
341         getSink().tableRow_();
342 
343         getSink().tableRow();
344         tableCellHelper( getString( "report.javancss.explanation.ncss.table.constructorI" ) );
345         getSink().tableCell();
346         getSink().list();
347         codeItemListHelper( "this();" );
348         codeItemListHelper( "super();" );
349         getSink().list_();
350         getSink().tableCell_();
351         getSink().tableRow_();
352 
353         getSink().tableRow();
354         tableCellHelper( getString( "report.javancss.explanation.ncss.table.statement" ) );
355         getSink().tableCell();
356         getSink().list();
357         codeItemListHelper( "i = 0;" );
358         codeItemListHelper( "if (ok)" );
359         codeItemListHelper( "if (exit) {" );
360         codeItemListHelper( "if (3 == 4);" );
361         codeItemListHelper( "if (4 == 4) { ;" );
362         codeItemListHelper( "} else {" );
363         getSink().list_();
364         getSink().tableCell_();
365         getSink().tableRow_();
366 
367         getSink().tableRow();
368         tableCellHelper( getString( "report.javancss.explanation.ncss.table.label" ) );
369         codeCellHelper( "fine :" );
370         getSink().tableRow_();
371 
372         getSink().table_();
373         paragraphHelper( getString( "report.javancss.explanation.ncss.paragraph3" ) );
374 
375         // CCN Explanation
376         subtitleHelper( getString( "report.javancss.explanation.ccn.title" ) );
377         paragraphHelper( getString( "report.javancss.explanation.ccn.paragraph1" ) );
378         paragraphHelper( getString( "report.javancss.explanation.ccn.paragraph2" ) );
379         getSink().list();
380         codeItemListHelper( "if" );
381         codeItemListHelper( "for" );
382         codeItemListHelper( "while" );
383         codeItemListHelper( "case" );
384         codeItemListHelper( "catch" );
385         getSink().list_();
386         paragraphHelper( getString( "report.javancss.explanation.ccn.paragraph3" ) );
387         getSink().list();
388         codeItemListHelper( "if" );
389         codeItemListHelper( "for" );
390         getSink().list_();
391         paragraphHelper( getString( "report.javancss.explanation.ccn.paragraph4" ) );
392         paragraphHelper( getString( "report.javancss.explanation.ccn.paragraph5" ) );
393     }
394 
395     // sink helper to start a section
396     protected void startSection( String link, String title )
397     {
398         super.startSection( link, title );
399         navigationBar();
400     }
401 
402     protected void jxrLink( String clazz )
403     {
404         if ( xrefLocation != null )
405         {
406             getSink().link( xrefLocation + "/" + clazz.replace( '.', '/' ) + ".html" );
407         }
408         getSink().text( clazz );
409         if ( xrefLocation != null )
410         {
411             getSink().link_();
412         }
413     }
414 
415     protected void jxrFunctionLink( String clazz )
416     {
417         int indexDot = -1;
418         if ( xrefLocation != null )
419         {
420             indexDot = clazz.lastIndexOf( '.' );
421             if ( indexDot != -1 )
422             {
423                 getSink().link( xrefLocation + "/" + clazz.substring( 0, indexDot ).replace( '.', '/' ) + ".html" );
424             }
425         }
426         getSink().text( clazz );
427         if ( xrefLocation != null && indexDot != -1 )
428         {
429             getSink().link_();
430         }
431     }
432 
433 }