KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > report > ReportProcessor


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: ReportProcessor.java,v 1.1.1.1.2.2 2004/07/16 23:32:29 vlad_r Exp $
8  */

9 package com.vladium.emma.report;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13
14 import com.vladium.logging.Logger;
15 import com.vladium.util.Files;
16 import com.vladium.util.IConstants;
17 import com.vladium.util.IProperties;
18 import com.vladium.util.Strings;
19 import com.vladium.util.asserts.$assert;
20 import com.vladium.util.exception.Exceptions;
21 import com.vladium.emma.IAppConstants;
22 import com.vladium.emma.IAppErrorCodes;
23 import com.vladium.emma.EMMARuntimeException;
24 import com.vladium.emma.Processor;
25 import com.vladium.emma.data.DataFactory;
26 import com.vladium.emma.data.ICoverageData;
27 import com.vladium.emma.data.IMergeable;
28 import com.vladium.emma.data.IMetaData;
29
30 // ----------------------------------------------------------------------------
31
/*
32  * This class was not meant to be public by design. It is made to to work around
33  * access bugs in reflective invocations.
34  */

35 /**
36  * @author Vlad Roubtsov, (C) 2003
37  */

38 public
39 final class ReportProcessor extends Processor
40                             implements IAppErrorCodes
41 {
42     // public: ................................................................
43

44     public static ReportProcessor create ()
45     {
46         return new ReportProcessor ();
47     }
48     
49     /**
50      *
51      * @param path [null is equivalent to an empty array]
52      */

53     public synchronized final void setDataPath (final String JavaDoc [] path)
54     {
55         if ((path == null) || (path.length == 0))
56             m_dataPath = IConstants.EMPTY_FILE_ARRAY;
57         else
58             m_dataPath = Files.pathToFiles (path, true);
59     }
60     
61     /**
62      * @param path [null is equivalent to no source path]
63      */

64     public synchronized void setSourcePath (final String JavaDoc [] path)
65     {
66         if (path == null)
67             m_sourcePath = null;
68         else
69             m_sourcePath = Files.pathToFiles (path, true); // always canonicalize source path
70
}
71
72     /**
73      *
74      * @param types [may not be null]
75      */

76     public synchronized void setReportTypes (final String JavaDoc [] types)
77     {
78         if (types == null) throw new IllegalArgumentException JavaDoc ("null input: types");
79         
80         final String JavaDoc [] reportTypes = Strings.removeDuplicates (types, true);
81         if (reportTypes.length == 0) throw new IllegalArgumentException JavaDoc ("empty input: types");
82         
83         if ($assert.ENABLED) $assert.ASSERT (reportTypes != null && reportTypes.length > 0);
84         
85         
86         final IReportGenerator [] reportGenerators = new IReportGenerator [reportTypes.length];
87         for (int t = 0; t < reportTypes.length; ++ t)
88         {
89             reportGenerators [t] = AbstractReportGenerator.create (reportTypes [t]);
90         }
91         
92         m_reportGenerators = reportGenerators;
93     }
94     
95     // protected: .............................................................
96

97     
98     protected void validateState ()
99     {
100         super.validateState ();
101         
102         if (m_dataPath == null)
103             throw new IllegalStateException JavaDoc ("data path not set");
104             
105         // [m_sourcePath can be null]
106

107         if ((m_reportGenerators == null) || (m_reportGenerators.length == 0))
108             throw new IllegalStateException JavaDoc ("report types not set");
109         
110         // [m_propertyOverrides can be null]
111
}
112
113     
114     protected void _run (final IProperties toolProperties)
115     {
116         final Logger log = m_log;
117         
118         final boolean verbose = m_log.atVERBOSE ();
119         if (verbose)
120         {
121             log.verbose (IAppConstants.APP_VERBOSE_BUILD_ID);
122             
123             // [assertion: m_dataPath != null]
124
log.verbose ("input data path:");
125             log.verbose ("{");
126             for (int p = 0; p < m_dataPath.length; ++ p)
127             {
128                 final File JavaDoc f = m_dataPath [p];
129                 final String JavaDoc nonexistent = f.exists () ? "" : "{nonexistent} ";
130                 
131                 log.verbose (" " + nonexistent + f.getAbsolutePath ());
132             }
133             log.verbose ("}");
134             
135             
136             if ((m_sourcePath == null) || (m_sourcePath.length == 0))
137             {
138                 log.verbose ("source path not set");
139             }
140             else
141             {
142                 log.verbose ("source path:");
143                 log.verbose ("{");
144                 for (int p = 0; p < m_sourcePath.length; ++ p)
145                 {
146                     final File JavaDoc f = m_sourcePath [p];
147                     final String JavaDoc nonexistent = f.exists () ? "" : "{nonexistent} ";
148                     
149                     log.verbose (" " + nonexistent + f.getAbsolutePath ());
150                 }
151                 log.verbose ("}");
152             }
153         }
154         else
155         {
156             log.info ("processing input files ...");
157         }
158         
159         RuntimeException JavaDoc failure = null;
160         try
161         {
162             final long start = log.atINFO () ? System.currentTimeMillis () : 0;
163             
164             IMetaData mdata = null;
165             ICoverageData cdata = null;
166             
167             // merge all data files:
168
try
169             {
170                 for (int f = 0; f < m_dataPath.length; ++ f)
171                 {
172                     final File JavaDoc dataFile = m_dataPath [f];
173                     if (verbose) log.verbose ("processing input file [" + dataFile.getAbsolutePath () + "] ...");
174                     
175                     final IMergeable [] fileData = DataFactory.load (dataFile);
176                     
177                     final IMetaData _mdata = (IMetaData) fileData [DataFactory.TYPE_METADATA];
178                     if (_mdata != null)
179                     {
180                         if (verbose) log.verbose (" loaded " + _mdata.size () + " metadata entries");
181                         
182                         if (mdata == null)
183                             mdata = _mdata;
184                         else
185                             mdata = (IMetaData) mdata.merge (_mdata); // note: later datapath entries override earlier ones
186
}
187                     
188                     final ICoverageData _cdata = (ICoverageData) fileData [DataFactory.TYPE_COVERAGEDATA];
189                     if (_cdata != null)
190                     {
191                         if (verbose) log.verbose (" loaded " + _cdata.size () + " coverage data entries");
192                         
193                         if (cdata == null)
194                             cdata = _cdata;
195                         else
196                             cdata = (ICoverageData) cdata.merge (_cdata); // note: later datapath entries override earlier ones
197
}
198                     
199                     ++ m_dataFileCount;
200                 }
201                 
202                 if (log.atINFO ())
203                 {
204                     final long end = System.currentTimeMillis ();
205                     
206                     log.info (m_dataFileCount + " file(s) read and merged in " + (end - start) + " ms");
207                 }
208                 
209                 if ((mdata == null) || mdata.isEmpty ())
210                 {
211                     log.warning ("nothing to do: no metadata found in any of the data files");
212                     
213                     return;
214                 }
215                 
216                 if (cdata == null)
217                 {
218                     log.warning ("nothing to do: no runtime coverage data found in any of the data files");
219                     
220                     return;
221                 }
222                 
223                 if (cdata.isEmpty ())
224                 {
225                     log.warning ("no collected coverage data found in any of the data files [all reports will be empty]");
226                 }
227                 
228                 
229                 if (verbose)
230                 {
231                     if (mdata != null)
232                     {
233                         log.verbose (" merged metadata contains " + mdata.size () + " entries");
234                     }
235                     
236                     if (cdata != null)
237                     {
238                         log.verbose (" merged coverage data contains " + cdata.size () + " entries");
239                     }
240                 }
241                                 
242                 SourcePathCache srcpathCache = null;
243                 if (m_sourcePath != null) srcpathCache = new SourcePathCache (m_sourcePath, true); // ignore non-existent source dirs
244

245                 for (int g = 0; g < m_reportGenerators.length; ++ g)
246                 {
247                     final IReportGenerator generator = m_reportGenerators [g];
248                     
249                     try
250                     {
251                         // no shallow copies of 'mdata' or 'cdata' are needed here
252
// because this command never runs in a concurrent situation
253

254                         generator.process (mdata, cdata, srcpathCache, toolProperties);
255                     }
256                     catch (Throwable JavaDoc t)
257                     {
258                         // TODO: handle and continue
259
t.printStackTrace (System.out);
260                         
261                         // TODO: continue here
262
break;
263                     }
264                     finally
265                     {
266                         try { generator.cleanup (); } catch (Throwable JavaDoc ignore) {}
267                     }
268                 }
269             }
270             catch (IOException JavaDoc ioe)
271             {
272                 // TODO: handle
273
ioe.printStackTrace (System.out);
274             }
275         }
276         catch (SecurityException JavaDoc se)
277         {
278             failure = new EMMARuntimeException (SECURITY_RESTRICTION, new String JavaDoc [] {IAppConstants.APP_NAME}, se);
279         }
280         catch (RuntimeException JavaDoc re)
281         {
282             failure = re;
283         }
284         finally
285         {
286             reset ();
287         }
288         
289         if (failure != null)
290         {
291             if (Exceptions.unexpectedFailure (failure, EXPECTED_FAILURES))
292             {
293                 throw new EMMARuntimeException (UNEXPECTED_FAILURE,
294                                                 new Object JavaDoc [] {failure.toString (), IAppConstants.APP_BUG_REPORT_LINK},
295                                                 failure);
296             }
297             else
298                 throw failure;
299         }
300     }
301
302     // package: ...............................................................
303

304     // private: ...............................................................
305

306     
307     private ReportProcessor ()
308     {
309         m_dataPath = IConstants.EMPTY_FILE_ARRAY;
310     }
311     
312     private void reset ()
313     {
314         m_dataFileCount = 0;
315     }
316     
317     
318     // caller-settable state [scoped to this runner instance]:
319

320     private File JavaDoc [] m_dataPath; // required to be non-null for run()
321
private File JavaDoc [] m_sourcePath; // can be null/empty for run()
322
private IReportGenerator [] m_reportGenerators; // required to be non-null for run()
323

324     // internal run()-scoped state:
325

326     private int m_dataFileCount;
327     
328     private static final Class JavaDoc [] EXPECTED_FAILURES; // set in <clinit>
329

330     static
331     {
332         EXPECTED_FAILURES = new Class JavaDoc []
333         {
334             EMMARuntimeException.class,
335             IllegalArgumentException JavaDoc.class,
336             IllegalStateException JavaDoc.class,
337         };
338     }
339
340 } // end of class
341
// ----------------------------------------------------------------------------
Popular Tags