KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > groboutils > codecoverage > v2 > report > XmlSourceReportGenerator2


1 /*
2  * @(#)XmlSourceReportGenerator2.java
3  *
4  * Copyright (C) 2003-2004 Matt Albrecht
5  * groboclown@users.sourceforge.net
6  * http://groboutils.sourceforge.net
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  */

26
27 package net.sourceforge.groboutils.codecoverage.v2.report;
28
29 import java.io.BufferedReader JavaDoc;
30 import java.io.File JavaDoc;
31 import java.io.FileReader JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Set JavaDoc;
39 import java.util.Collection JavaDoc;
40
41 import javax.xml.parsers.DocumentBuilder JavaDoc;
42 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
43
44 import org.w3c.dom.Document JavaDoc;
45 import org.w3c.dom.Element JavaDoc;
46 import org.w3c.dom.Node JavaDoc;
47 import org.w3c.dom.NodeList JavaDoc;
48
49
50 /**
51  * Generates an XML report about a Java source file, containing the source
52  * file's line-by-line source, and the coverage information on that class.
53  * <p>
54  * Unlike the other generators, this class must be instantiated for a
55  * particular coverage report, and will be reused to make each sub-source
56  * file.
57  *
58  * @author Matt Albrecht <a HREF="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
59  * @version $Date: 2004/06/08 20:55:35 $
60  * @since November 26, 2003
61  */

62 public class XmlSourceReportGenerator2 implements IXmlSourceReportConst
63 {
64     private static final org.apache.log4j.Logger LOG =
65         org.apache.log4j.Logger.getLogger( XmlCombinedReportGenerator.class );
66     
67     
68     private SourceNodeMap sourceNodeMap = new SourceNodeMap();
69     private Node JavaDoc moduleTypesNode;
70     
71     private static class SourceNodes
72     {
73         public List JavaDoc coverNodes = new LinkedList JavaDoc();
74         public Map JavaDoc uncoveredMarkNodesByLine = new HashMap JavaDoc();
75         public List JavaDoc noLine = new LinkedList JavaDoc();
76         
77         public void addCoverNode( Element JavaDoc e )
78         {
79             // we're going to move the marks out of
80
this.coverNodes.add( e );
81             NodeList JavaDoc nl = e.getElementsByTagName( T_MARK );
82             for (int i = 0; i < nl.getLength(); ++i)
83             {
84                 Node JavaDoc node = nl.item(i);
85                 if (node instanceof Element JavaDoc)
86                 {
87                     Element JavaDoc me = (Element JavaDoc)node;
88                     if (!"true".equals( me.getAttribute( A_COVERED ) ))
89                     {
90                         Element JavaDoc methodNode = (Element JavaDoc)me.getParentNode();
91                         me.setAttribute( A_METHODSIGNATURE,
92                             methodNode.getAttribute( A_METHODSIGNATURE ) );
93                         me.setAttribute( A_METHODSIGNATURE_REAL,
94                             methodNode.getAttribute( A_METHODSIGNATURE_REAL ) );
95                         String JavaDoc line = me.getAttribute( A_SOURCELINE );
96                         List JavaDoc marks;
97                         if ("-1".equals( line ))
98                         {
99                             marks = this.noLine;
100                         }
101                         else
102                         {
103                             marks = (List JavaDoc)this.uncoveredMarkNodesByLine.
104                                 get( line );
105                             if (marks == null)
106                             {
107                                 marks = new LinkedList JavaDoc();
108                                 this.uncoveredMarkNodesByLine.put( line, marks );
109                             }
110                         }
111                         marks.add( me );
112                     }
113                 }
114             }
115         }
116         
117         
118         public void copyClassCoverInto( Element JavaDoc rootEl, Document JavaDoc doc )
119         {
120             copyNodesInto( this.coverNodes, rootEl, doc );
121         }
122         
123         
124         public int getNoLineMarkCount()
125         {
126             return this.noLine.size();
127         }
128         
129         
130         public void copyMarksInto( int lineNo, Element JavaDoc rootEl, Document JavaDoc doc )
131         {
132             List JavaDoc marks;
133             if (lineNo < 0)
134             {
135                 marks = this.noLine;
136             }
137             else
138             {
139                 marks = (List JavaDoc)this.uncoveredMarkNodesByLine.get(
140                     Integer.toString( lineNo ) );
141             }
142             copyNodesInto( marks, rootEl, doc );
143         }
144         
145         
146         public boolean copyAllMarksInto( Element JavaDoc rootEl, Document JavaDoc doc )
147         {
148             boolean added = false;
149             Iterator JavaDoc iter = this.uncoveredMarkNodesByLine.keySet().iterator();
150             while (iter.hasNext())
151             {
152                 added = copyNodesInto( (List JavaDoc)this.uncoveredMarkNodesByLine.
153                     get( iter.next() ), rootEl, doc );
154             }
155             return added;
156         }
157         
158         
159         private boolean copyNodesInto( Collection JavaDoc src, Element JavaDoc rootEl, Document JavaDoc doc )
160         {
161             boolean added =false;
162             if (src != null)
163             {
164                 Iterator JavaDoc iter = src.iterator();
165                 while (iter.hasNext())
166                 {
167                     added = true;
168                     rootEl.appendChild( copyNode( (Node JavaDoc)iter.next(), doc ) );
169                 }
170             }
171             return added;
172         }
173     }
174     
175     private static class SourceNodeMap
176     {
177         private Map JavaDoc sourceFileMap = new HashMap JavaDoc();
178         public void addClassCoverageNode( Node JavaDoc n )
179         {
180             if (n instanceof Element JavaDoc)
181             {
182                 Element JavaDoc e = (Element JavaDoc)n;
183                 String JavaDoc name = getSourceName( e );
184                 SourceNodes sn = getSource( name );
185                 if (sn == null)
186                 {
187                     sn = new SourceNodes();
188                     this.sourceFileMap.put( name, sn );
189                 }
190                 sn.addCoverNode( e );
191             }
192         }
193         
194         public SourceNodes getSource( String JavaDoc name )
195         {
196             return (SourceNodes)this.sourceFileMap.get( name );
197         }
198         
199         public String JavaDoc[] getSourceNames()
200         {
201             Set JavaDoc keys = this.sourceFileMap.keySet();
202             return (String JavaDoc[])keys.toArray( new String JavaDoc[ keys.size() ] );
203         }
204     }
205     
206     public XmlSourceReportGenerator2( Document JavaDoc coverageReport )
207     {
208         if (coverageReport == null)
209         {
210             throw new IllegalArgumentException JavaDoc( "No null args" );
211         }
212         
213         NodeList JavaDoc list = coverageReport.getDocumentElement().
214             getElementsByTagName( T_CLASSCOVERAGE );
215         for (int i = 0; i < list.getLength(); ++i)
216         {
217             this.sourceNodeMap.addClassCoverageNode( list.item(i) );
218         }
219         
220         this.moduleTypesNode = coverageReport.getDocumentElement().
221             getElementsByTagName( "moduletypes" ).item(0);
222     }
223     
224     
225     public String JavaDoc[] getSourceNames()
226     {
227         return this.sourceNodeMap.getSourceNames();
228     }
229     
230     
231     /**
232      * Sends the generated report using the given module
233      * and data set.
234      *
235      * @return the root element generated.
236      */

237     public Document JavaDoc createXML( String JavaDoc srcName, File JavaDoc srcFile )
238             throws IOException JavaDoc
239     {
240         SourceNodes coverageNodes = this.sourceNodeMap.getSource( srcName );
241         if (coverageNodes == null)
242         {
243             throw new IllegalArgumentException JavaDoc( "No such source: "+
244                 srcName );
245         }
246         
247         // this is a bit slower, but it conserves some memory resources.
248
DocumentBuilder JavaDoc docBuilder = getDocumentBuilder();
249         Document JavaDoc doc = docBuilder.newDocument();
250         Element JavaDoc rootEl = doc.createElement( T_JAVACOVERAGE );
251         doc.appendChild( rootEl );
252         rootEl.setAttribute( A_JAVACLASS, srcName );
253         rootEl.appendChild( copyNode( this.moduleTypesNode, doc ) );
254         
255         parseSourceFile( srcFile, rootEl, doc, coverageNodes );
256         coverageNodes.copyClassCoverInto( rootEl, doc );
257         
258         return doc;
259     }
260     
261     
262     protected void parseSourceFile( File JavaDoc src, Element JavaDoc parent, Document JavaDoc doc,
263             SourceNodes sourceNode )
264             throws IOException JavaDoc
265     {
266         // everyone needs this.
267
Element JavaDoc nolineEl = null;
268         if (sourceNode.getNoLineMarkCount() > 0)
269         {
270             nolineEl = doc.createElement( T_NO_LINE );
271             sourceNode.copyMarksInto( -1, nolineEl, doc );
272         }
273         
274         // If the file doesn't exist, don't fail. Just put it in the report.
275
if (src == null || !src.exists() || !src.isFile())
276         {
277             Element JavaDoc nosrcEl = doc.createElement( T_NO_SOURCE );
278             parent.appendChild( nosrcEl );
279             
280             // System.out.println( "No source file" );
281
if (nolineEl != null)
282             {
283                 nosrcEl.appendChild( nolineEl );
284                 nolineEl.setAttribute( A_INDEX, Integer.toString( -1 ) );
285                 nolineEl.setAttribute( A_SRC, "Could not find source file." );
286             }
287             
288             Element JavaDoc nsmEl = doc.createElement( T_NO_SOURCE_MARKS );
289             if (sourceNode.copyAllMarksInto( nsmEl, doc ))
290             {
291                 nosrcEl.appendChild( nsmEl );
292             }
293             
294             return;
295         }
296         
297         // else, parse the source file.
298
Element JavaDoc srcEl = doc.createElement( T_SOURCE );
299         parent.appendChild( srcEl );
300         if (nolineEl != null)
301         {
302             srcEl.appendChild( nolineEl );
303         }
304         
305         
306         BufferedReader JavaDoc in = new BufferedReader JavaDoc( new FileReader JavaDoc( src ) );
307         try
308         {
309             int lineNo = 0;
310             for (String JavaDoc line = in.readLine();
311                     line != null;
312                     line = in.readLine())
313             {
314                 ++lineNo;
315                 
316                 // should color-code the line according to Java syntax.
317
// But, we can't guarantee that the source is Java! It
318
// might be NetRexx or any number of other source types.
319
Element JavaDoc lineEl = doc.createElement( T_LINE );
320                 srcEl.appendChild( lineEl );
321                 
322                 lineEl.setAttribute( A_INDEX, Integer.toString( lineNo ) );
323                 lineEl.setAttribute( A_SRC, line );
324                 
325                 sourceNode.copyMarksInto( lineNo, lineEl, doc );
326             }
327         }
328         finally
329         {
330             if (in != null)
331             {
332                 in.close();
333             }
334         }
335     }
336     
337     
338     protected static Node JavaDoc copyNode( Node JavaDoc el, Document JavaDoc doc )
339     {
340         return doc.importNode( el, true );
341     }
342     
343     
344     
345     //------------------------------------------------------------------------
346
// Private methods
347

348     
349     private static DocumentBuilder JavaDoc getDocumentBuilder()
350     {
351         try
352         {
353             return DocumentBuilderFactory.newInstance().newDocumentBuilder();
354         }
355         catch (Exception JavaDoc exc)
356         {
357             throw new ExceptionInInitializerError JavaDoc(exc);
358         }
359     }
360     
361     
362     private static String JavaDoc getSourceName( Element JavaDoc coverageEl )
363     {
364         String JavaDoc pkg = coverageEl.getAttribute( A_PACKAGE );
365         String JavaDoc src = coverageEl.getAttribute( A_SOURCEFILE );
366         return makeSourceName( pkg, src );
367     }
368     
369     
370     private static String JavaDoc makeSourceName( String JavaDoc pkg, String JavaDoc srcFile )
371     {
372         if (pkg == null || pkg.length() <= 0)
373         {
374             return srcFile;
375         }
376         pkg = pkg.replace( '.', File.separatorChar );
377         return pkg + File.separatorChar + srcFile;
378     }
379 }
380
381
Popular Tags