KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > report > txt > ReportGenerator


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: ReportGenerator.java,v 1.1.1.1.2.1 2004/07/16 23:32:30 vlad_r Exp $
8  */

9 package com.vladium.emma.report.txt;
10
11 import java.io.BufferedWriter JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.FileOutputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.OutputStreamWriter JavaDoc;
16 import java.io.UnsupportedEncodingException JavaDoc;
17 import java.util.Date JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedList JavaDoc;
20
21 import com.vladium.util.Files;
22 import com.vladium.util.IProperties;
23 import com.vladium.util.asserts.$assert;
24 import com.vladium.emma.IAppConstants;
25 import com.vladium.emma.IAppErrorCodes;
26 import com.vladium.emma.EMMAProperties;
27 import com.vladium.emma.EMMARuntimeException;
28 import com.vladium.emma.data.ICoverageData;
29 import com.vladium.emma.data.IMetaData;
30 import com.vladium.emma.report.AbstractReportGenerator;
31 import com.vladium.emma.report.AllItem;
32 import com.vladium.emma.report.ClassItem;
33 import com.vladium.emma.report.IItem;
34 import com.vladium.emma.report.IItemAttribute;
35 import com.vladium.emma.report.ItemComparator;
36 import com.vladium.emma.report.MethodItem;
37 import com.vladium.emma.report.PackageItem;
38 import com.vladium.emma.report.SourcePathCache;
39 import com.vladium.emma.report.SrcFileItem;
40
41 // ----------------------------------------------------------------------------
42
/**
43  * @author Vlad Roubtsov, (C) 2003
44  */

45 public
46 final class ReportGenerator extends AbstractReportGenerator
47                             implements IAppErrorCodes
48 {
49     // public: ................................................................
50

51     // TODO: this is prototype quality, needs major cleanup
52

53     // IReportGenerator:
54

55     public String JavaDoc getType ()
56     {
57         return TYPE;
58     }
59     
60     public void process (final IMetaData mdata, final ICoverageData cdata,
61                          final SourcePathCache cache, final IProperties properties)
62         throws EMMARuntimeException
63     {
64         initialize (mdata, cdata, cache, properties);
65         
66         long start = 0, end;
67         final boolean trace1 = m_log.atTRACE1 ();
68         
69         if (trace1) start = System.currentTimeMillis ();
70         
71         {
72             m_queue = new LinkedList JavaDoc ();
73             for (m_queue.add (m_view.getRoot ()); ! m_queue.isEmpty (); )
74             {
75                 final IItem head = (IItem) m_queue.removeFirst ();
76                 
77                 head.accept (this, null);
78             }
79             line ();
80             
81             close ();
82         }
83                 
84         if (trace1)
85         {
86             end = System.currentTimeMillis ();
87             
88             m_log.trace1 ("process", "[" + getType () + "] report generated in " + (end - start) + " ms");
89         }
90     }
91     
92     public void cleanup ()
93     {
94         m_queue = null;
95         close ();
96         
97         super.cleanup ();
98     }
99     
100     
101     // IItemVisitor:
102

103     public Object JavaDoc visit (final AllItem item, final Object JavaDoc ctx)
104     {
105         File JavaDoc outFile = m_settings.getOutFile ();
106         if (outFile == null)
107         {
108             outFile = new File JavaDoc ("coverage.txt");
109             m_settings.setOutFile (outFile);
110         }
111         
112         final File JavaDoc fullOutFile = Files.newFile (m_settings.getOutDir (), outFile);
113         
114         m_log.info ("writing [" + getType () + "] report to [" + fullOutFile.getAbsolutePath () + "] ...");
115         
116         openOutFile (fullOutFile, m_settings.getOutEncoding (), true);
117         
118         // build ID stamp:
119
try
120         {
121             final StringBuffer JavaDoc label = new StringBuffer JavaDoc (101);
122             
123             label.append ("[");
124             label.append (IAppConstants.APP_NAME);
125             label.append (" v"); label.append (IAppConstants.APP_VERSION_WITH_BUILD_ID_AND_TAG);
126             label.append (" report, generated ");
127             label.append (new Date JavaDoc (EMMAProperties.getTimeStamp ()));
128             label.append ("]");
129             
130             m_out.write (label.toString ());
131             m_out.newLine ();
132             
133             m_out.flush ();
134         }
135         catch (IOException JavaDoc ioe)
136         {
137             throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
138         }
139         
140         final int [] columns = m_settings.getColumnOrder ();
141          
142         line ();
143                 
144         // [all] coverage summary row:
145
addTitleRow ("OVERALL COVERAGE SUMMARY", 0, 1);
146         {
147             // header row:
148
addHeaderRow (item, columns);
149             
150             // coverage row:
151
addItemRow (item, columns);
152         }
153                 
154         // [all] stats summary table ([all] only):
155
addTitleRow ("OVERALL STATS SUMMARY", 1, 1);
156         {
157             row ("total packages:" + m_separator + item.getChildCount ());
158             row ("total classes:" + m_separator + item.getAggregate (IItem.TOTAL_CLASS_COUNT));
159             row ("total methods:" + m_separator + item.getAggregate (IItem.TOTAL_METHOD_COUNT));
160             
161             if (m_srcView && m_hasSrcFileInfo)
162             {
163                 row ("total executable files:" + m_separator + item.getAggregate (IItem.TOTAL_SRCFILE_COUNT));
164                 
165                 if (m_hasLineNumberInfo)
166                     row ("total executable lines:" + m_separator + item.getAggregate (IItem.TOTAL_LINE_COUNT));
167             }
168         }
169         
170         final boolean deeper = (m_settings.getDepth () > item.getMetadata ().getTypeID ());
171         
172         // render package summary rows:
173
addTitleRow ("COVERAGE BREAKDOWN BY PACKAGE", 1, 1);
174         {
175             boolean headerDone = false;
176             final ItemComparator order = m_typeSortComparators [PackageItem.getTypeMetadata ().getTypeID ()];
177             for (Iterator JavaDoc packages = item.getChildren (order); packages.hasNext (); )
178             {
179                 final IItem pkg = (IItem) packages.next ();
180                 
181                 if (! headerDone)
182                 {
183                     // header row:
184
addHeaderRow (pkg, columns);
185                     headerDone = true;
186                 }
187                 
188                 // coverage row:
189
addItemRow (pkg, columns);
190                 
191                 if (deeper) m_queue.addLast (pkg);
192             }
193         }
194
195         return ctx;
196     }
197     
198     public Object JavaDoc visit (final PackageItem item, final Object JavaDoc ctx)
199     {
200         if (m_verbose) m_log.verbose (" report: processing package [" + item.getName () + "] ...");
201         
202         final int [] columns = m_settings.getColumnOrder ();
203         
204         line ();
205         
206         // coverage summary row:
207
addTitleRow ("COVERAGE SUMMARY FOR PACKAGE [".concat (item.getName ()).concat ("]"), 0, 1);
208         {
209             // header row:
210
addHeaderRow (item, columns);
211             
212             // coverage row:
213
addItemRow (item, columns);
214         }
215         
216         
217         final boolean deeper = (m_settings.getDepth () > item.getMetadata ().getTypeID ());
218                 
219         // render child summary rows:
220

221         final String JavaDoc summaryTitle = m_srcView ? "COVERAGE BREAKDOWN BY SOURCE FILE" : "COVERAGE BREAKDOWN BY CLASS";
222         addTitleRow (summaryTitle, 1, 1);
223         {
224             boolean headerDone = false;
225             final ItemComparator order = m_typeSortComparators [m_srcView ? SrcFileItem.getTypeMetadata ().getTypeID () : ClassItem.getTypeMetadata ().getTypeID ()];
226             for (Iterator JavaDoc srcORclsFiles = item.getChildren (order); srcORclsFiles.hasNext (); )
227             {
228                 final IItem srcORcls = (IItem) srcORclsFiles.next ();
229                 
230                 if (! headerDone)
231                 {
232                     // header row:
233
addHeaderRow (srcORcls, columns);
234                     headerDone = true;
235                 }
236                 
237                 // coverage row:
238
addItemRow (srcORcls, columns);
239                 
240                 if (deeper) m_queue.addLast (srcORcls);
241             }
242         }
243
244         return ctx;
245     }
246
247     public Object JavaDoc visit (final SrcFileItem item, final Object JavaDoc ctx)
248     {
249         final int [] columns = m_settings.getColumnOrder ();
250         
251         line ();
252         
253         // coverage summary row:
254
addTitleRow ("COVERAGE SUMMARY FOR SOURCE FILE [".concat (item.getName ()).concat ("]"), 0, 1);
255         {
256             // header row:
257
addHeaderRow (item, columns);
258             
259             // coverage row:
260
addItemRow (item, columns);
261         }
262         
263         // render child summary rows:
264
addTitleRow ("COVERAGE BREAKDOWN BY CLASS AND METHOD", 1, 1);
265         {
266             boolean headerDone = false;
267             final ItemComparator order = m_typeSortComparators [ClassItem.getTypeMetadata ().getTypeID ()];
268             for (Iterator JavaDoc classes = item.getChildren (order); classes.hasNext (); )
269             {
270                 final IItem cls = (IItem) classes.next ();
271                 
272                 if (! headerDone)
273                 {
274                     // header row:
275
addHeaderRow (cls, columns);
276                     headerDone = true;
277                 }
278                 
279                 // coverage row:
280
//addItemRow (child, columns);
281

282                 addTitleRow ("class [" + cls.getName () + "] methods", 0, 0);
283                 
284                 // TODO: select the right comparator here
285
final ItemComparator order2 = m_typeSortComparators [MethodItem.getTypeMetadata ().getTypeID ()];
286                 for (Iterator JavaDoc methods = cls.getChildren (order2); methods.hasNext (); )
287                 {
288                     final MethodItem method = (MethodItem) methods.next ();
289                     
290                     addItemRow (method, columns);
291                 }
292             }
293         }
294
295         return ctx;
296     }
297     
298     public Object JavaDoc visit (final ClassItem item, final Object JavaDoc ctx)
299     {
300         final int [] columns = m_settings.getColumnOrder ();
301         
302         line ();
303         
304         // coverage summary row:
305
addTitleRow ("COVERAGE SUMMARY FOR CLASS [".concat (item.getName ()).concat ("]"), 0, 1);
306         {
307             // header row:
308
addHeaderRow (item, columns);
309             
310             // coverage row:
311
addItemRow (item, columns);
312         }
313         
314         // render child summary rows:
315
addTitleRow ("COVERAGE BREAKDOWN BY METHOD", 1, 1);
316         {
317             final ItemComparator order = m_typeSortComparators [MethodItem.getTypeMetadata ().getTypeID ()];
318             for (Iterator JavaDoc methods = item.getChildren (order); methods.hasNext (); )
319             {
320                 final IItem method = (IItem) methods.next ();
321                 
322                 // coverage row:
323
addItemRow (method, columns);
324             }
325         }
326
327         return ctx;
328     }
329         
330     // protected: .............................................................
331

332     // package: ...............................................................
333

334     // private: ...............................................................
335

336     
337     private void addTitleRow (final String JavaDoc text, final int hlines, final int flines)
338     {
339         for (int i = 0; i < hlines; ++ i) eol ();
340         row (new StringBuffer JavaDoc (text).append (":"));
341         for (int i = 0; i < flines; ++ i) eol ();
342     }
343     
344     private void addHeaderRow (final IItem item, final int [] columns)
345     {
346         if ($assert.ENABLED)
347         {
348             $assert.ASSERT (item != null, "null input: item");
349             $assert.ASSERT (columns != null, "null input: columns");
350         }
351         
352         // header row:
353
final StringBuffer JavaDoc buf = new StringBuffer JavaDoc ();
354         
355         for (int c = 0, cLimit = columns.length; c < cLimit; ++ c)
356         {
357             final int attrID = columns [c];
358             final IItemAttribute attr = item.getAttribute (attrID, m_settings.getUnitsType ());
359             
360             if (attr != null)
361             {
362                 buf.append ('[');
363                 buf.append (attr.getName ());
364                 buf.append (']');
365             }
366             if (c != cLimit - 1) buf.append (m_separator);
367         }
368         
369         row (buf);
370     }
371     
372     
373     /*
374      * No header row, just data rows.
375      */

376     private void addItemRow (final IItem item, final int [] columns)
377     {
378         if ($assert.ENABLED)
379         {
380             $assert.ASSERT (item != null, "null input: item");
381             $assert.ASSERT (columns != null, "null input: columns");
382         }
383         
384         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc (11); // TODO: reuse a buffer
385

386         for (int c = 0, cLimit = columns.length; c < cLimit; ++ c)
387         {
388             final int attrID = columns [c];
389             final IItemAttribute attr = item.getAttribute (attrID, m_settings.getUnitsType ());
390             
391             if (attr != null)
392             {
393                 boolean fail = (m_metrics [attrID] > 0) && ! attr.passes (item, m_metrics [attrID]);
394                 
395                 if (fail)
396                 {
397                     //buf.append ('(');
398
//buf.append ("! ");
399
attr.format (item, buf);
400                     buf.append ('!');
401                     //buf.append (')');
402
}
403                 else
404                 {
405                     attr.format (item, buf);
406                 }
407             }
408             if (c != cLimit - 1) buf.append (m_separator);
409         }
410         
411         row (buf);
412     }
413     
414     
415     private void row (final StringBuffer JavaDoc str)
416     {
417         if ($assert.ENABLED) $assert.ASSERT (str != null, "str = null");
418         
419         try
420         {
421             m_out.write (str.toString ());
422             m_out.newLine ();
423         }
424         catch (IOException JavaDoc ioe)
425         {
426             throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
427         }
428     }
429     
430     private void row (final String JavaDoc str)
431     {
432         if ($assert.ENABLED) $assert.ASSERT (str != null, "str = null");
433         
434         try
435         {
436             m_out.write (str);
437             m_out.newLine ();
438         }
439         catch (IOException JavaDoc ioe)
440         {
441             throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
442         }
443     }
444     
445     private void line ()
446     {
447         try
448         {
449             m_out.write (LINE);
450             m_out.newLine ();
451         }
452         catch (IOException JavaDoc ioe)
453         {
454             throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
455         }
456     }
457     
458     private void eol ()
459     {
460         try
461         {
462             m_out.newLine ();
463         }
464         catch (IOException JavaDoc ioe)
465         {
466             throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
467         }
468     }
469     
470     private void close ()
471     {
472         if (m_out != null)
473         {
474             try
475             {
476                 m_out.flush ();
477                 m_out.close ();
478             }
479             catch (IOException JavaDoc ioe)
480             {
481                 throw new EMMARuntimeException (IAppErrorCodes.REPORT_IO_FAILURE, ioe);
482             }
483             finally
484             {
485                 m_out = null;
486             }
487         }
488     }
489     
490     private void openOutFile (final File JavaDoc file, final String JavaDoc encoding, final boolean mkdirs)
491     {
492         try
493         {
494             if (mkdirs)
495             {
496                 final File JavaDoc parent = file.getParentFile ();
497                 if (parent != null) parent.mkdirs ();
498             }
499             
500             m_out = new BufferedWriter JavaDoc (new OutputStreamWriter JavaDoc (new FileOutputStream JavaDoc (file), encoding), IO_BUF_SIZE);
501         }
502         catch (UnsupportedEncodingException JavaDoc uee)
503         {
504             // TODO: error code
505
throw new EMMARuntimeException (uee);
506         }
507         // note: in J2SDK 1.3 FileOutputStream constructor's throws clause
508
// was narrowed to FileNotFoundException:
509
catch (IOException JavaDoc fnfe) // FileNotFoundException
510
{
511             // TODO: error code
512
throw new EMMARuntimeException (fnfe);
513         }
514     }
515     
516     
517     private char m_separator = '\t'; // TODO: set this
518

519     private LinkedList JavaDoc /* IITem */ m_queue;
520     private BufferedWriter JavaDoc m_out;
521     
522     private static final String JavaDoc TYPE = "txt";
523     private static final String JavaDoc LINE = "-------------------------------------------------------------------------------";
524     
525     private static final int IO_BUF_SIZE = 32 * 1024;
526
527 } // end of class
528
// ----------------------------------------------------------------------------
Popular Tags