KickJava   Java API By Example, From Geeks To Geeks.

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


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: SrcFileItem.java,v 1.1.1.1.2.1 2004/06/20 20:07:22 vlad_r Exp $
8  */

9 package com.vladium.emma.report;
10
11 import java.util.Iterator JavaDoc;
12
13 import com.vladium.util.IntObjectMap;
14 import com.vladium.util.asserts.$assert;
15 import com.vladium.emma.data.ClassDescriptor;
16 import com.vladium.emma.data.MethodDescriptor;
17
18 // ----------------------------------------------------------------------------
19
/**
20  * @author Vlad Roubtsov, (C) 2003
21  */

22 public
23 final class SrcFileItem extends Item
24 {
25     // public: ................................................................
26

27     
28     public final class LineCoverageData
29     {
30         public static final int LINE_COVERAGE_ZERO = 0;
31         public static final int LINE_COVERAGE_PARTIAL = 1;
32         public static final int LINE_COVERAGE_COMPLETE = 2;
33         
34         public final int m_coverageStatus;
35         public final int [/* units mode */][/* total, coverage */] m_coverageRatio; // not null in LINE_COVERAGE_PARTIAL status only]
36

37         LineCoverageData (final int coverageStatus, final int [][] coverageRatio)
38         {
39             m_coverageStatus = coverageStatus;
40             m_coverageRatio = coverageRatio;
41         }
42         
43     } // end of nested class
44

45
46     public SrcFileItem (final IItem parent, final String JavaDoc name, final String JavaDoc fullVMName)
47     {
48         super (parent);
49         
50         m_name = name;
51         m_fullVMName = fullVMName;
52     }
53     
54     public String JavaDoc getName ()
55     {
56         return m_name;
57     }
58     
59     public String JavaDoc getFullVMName ()
60     {
61         return m_fullVMName;
62     }
63     
64     public int getFirstLine ()
65     {
66         // TODO: state validation
67

68         if (m_firstLine == 0)
69         {
70             getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation
71
}
72         
73         return m_firstLine;
74     }
75
76     
77     
78     
79     public IntObjectMap /* line_no:int -> LineCoverageData */ getLineCoverage ()
80     {
81         if (m_lineCoverage == null)
82         {
83             getAggregate (TOTAL_LINE_COUNT); // fault line coverage calculation
84
}
85         
86         return m_lineCoverage;
87     }
88     
89         
90     public int getAggregate (final int type)
91     {
92         final int [] aggregates = m_aggregates;
93
94         int value = aggregates [type];
95         
96         if (value < 0)
97         {
98             switch (type)
99             {
100                 case COVERAGE_CLASS_COUNT:
101                 case TOTAL_CLASS_COUNT:
102                 {
103                     aggregates [TOTAL_CLASS_COUNT] = getChildCount ();
104                     
105                     value = 0;
106                     for (Iterator JavaDoc children = getChildren (); children.hasNext (); )
107                     {
108                         // SF BUG 972725: this was incorrectly using 'type' instead
109
// of the COVERAGE_CLASS_COUNT aggregate type, making class
110
// coverage computation dependent on the order of how item
111
// nodes were traversed in report generators
112
value += ((IItem) children.next ()).getAggregate (COVERAGE_CLASS_COUNT);
113                     }
114                     aggregates [COVERAGE_CLASS_COUNT] = value;
115
116                     return aggregates [type];
117                 }
118                 //break;
119

120                 
121                 case TOTAL_SRCFILE_COUNT:
122                 {
123                     return aggregates [TOTAL_SRCFILE_COUNT] = 1;
124                 }
125                 //break;
126

127                 
128                 case COVERAGE_LINE_COUNT:
129                 case TOTAL_LINE_COUNT:
130                 
131                 case COVERAGE_LINE_INSTR:
132                 {
133                     // line aggregate types are special when used on srcfile items:
134
// unlike all others, they do not simply add up when the line
135
// info is available; instead, lines from all classes belonging
136
// to the same srcfile parent are set-merged
137

138                     final IntObjectMap /* line -> int[2] */ fldata = new IntObjectMap ();
139                     
140                     for (Iterator JavaDoc classes = getChildren (); classes.hasNext (); )
141                     {
142                         final ClassItem cls = (ClassItem) classes.next ();
143                     
144                         final boolean [][] ccoverage = cls.getCoverage (); // this can be null
145
final ClassDescriptor clsdesc = cls.getClassDescriptor ();
146                         final MethodDescriptor [] methoddescs = clsdesc.getMethods ();
147                         
148                         for (Iterator JavaDoc methods = cls.getChildren (); methods.hasNext (); )
149                         {
150                             final MethodItem method = (MethodItem) methods.next ();
151                             final int methodID = method.getID ();
152                             
153                             final boolean [] mcoverage = ccoverage == null ? null : ccoverage [methodID];
154                             
155                             final MethodDescriptor methoddesc = methoddescs [methodID];
156                             final int [] mbsizes = methoddesc.getBlockSizes ();
157                             final IntObjectMap mlineMap = methoddesc.getLineMap ();
158                             if ($assert.ENABLED) $assert.ASSERT (mlineMap != null);
159                             
160                             final int [] mlines = mlineMap.keys ();
161                             for (int ml = 0, mlLimit = mlines.length; ml < mlLimit; ++ ml)
162                             {
163                                 final int mline = mlines [ml];
164                                 
165                                 int [] data = (int []) fldata.get (mline);
166                                 if (data == null)
167                                 {
168                                     data = new int [4]; // { totalcount, totalinstr, coveragecount, coverageinstr }
169
fldata.put (mline, data);
170                                 }
171                                 
172                                 final int [] lblocks = (int []) mlineMap.get (mline);
173                                 
174                                 final int bCount = lblocks.length;
175                                 data [0] += bCount;
176                                 
177                                 for (int bID = 0; bID < bCount; ++ bID)
178                                 {
179                                     final int block = lblocks [bID];
180                                     
181                                     final boolean bcovered = mcoverage != null && mcoverage [block];
182                                     final int instr = mbsizes [block];
183                                     
184                                     data [1] += instr;
185                                     if (bcovered)
186                                     {
187                                         ++ data [2];
188                                         data [3] += instr;
189                                     }
190                                 }
191                             }
192                         }
193                     }
194                     
195                     final int lineCount = fldata.size ();
196                     
197                     aggregates [TOTAL_LINE_COUNT] = lineCount;
198                     
199                     int coverageLineCount = 0;
200                     int coverageLineInstr = 0;
201                     
202                     final IntObjectMap /* line_no:int -> LineCoverageData */ lineCoverage = new IntObjectMap (lineCount);
203                     int firstLine = Integer.MAX_VALUE;
204                     
205                     final int [] clines = fldata.keys ();
206                     
207                     for (int cl = 0; cl < lineCount; ++ cl)
208                     {
209                         final int cline = clines [cl];
210                         final int [] data = (int []) fldata.get (cline);
211                         
212                         final int ltotalCount = data [0];
213                         final int ltotalInstr = data [1];
214                         final int lcoverageCount = data [2];
215                         final int lcoverageInstr = data [3];
216                         
217                         if (lcoverageInstr > 0)
218                         {
219                             coverageLineCount += (PRECISION * lcoverageCount) / ltotalCount;
220                             coverageLineInstr += (PRECISION * lcoverageInstr) / ltotalInstr;
221                         }
222                         
223                         // side effect: populate line coverage data map [used by getLineCoverage()]
224

225                         final int lcoverageStatus;
226                         int [][] lcoverageRatio = null;
227                         
228                         if (lcoverageInstr == 0)
229                             lcoverageStatus = LineCoverageData.LINE_COVERAGE_ZERO;
230                         else if (lcoverageInstr == ltotalInstr)
231                             lcoverageStatus = LineCoverageData.LINE_COVERAGE_COMPLETE;
232                         else
233                         {
234                             lcoverageStatus = LineCoverageData.LINE_COVERAGE_PARTIAL;
235                             lcoverageRatio = new int [][] {{ltotalCount, lcoverageCount}, {ltotalInstr, lcoverageInstr}}; // note: ordering depends on IItemAttribute.UNITS_xxx
236
}
237                         
238                         lineCoverage.put (cline, new LineCoverageData (lcoverageStatus, lcoverageRatio));
239                         
240                         // side effect: compute m_firstLine
241

242                         if (cline < firstLine) firstLine = cline;
243                     }
244                     
245                     m_lineCoverage = lineCoverage; // side effect
246
m_firstLine = firstLine; // side effect
247

248                     aggregates [COVERAGE_LINE_COUNT] = coverageLineCount;
249                     aggregates [COVERAGE_LINE_INSTR] = coverageLineInstr;
250                     
251                     return aggregates [type];
252                 }
253                 //break;
254

255                             
256                 default: return super.getAggregate (type);
257             }
258         }
259         
260         return value;
261     }
262
263     
264     public void accept (final IItemVisitor visitor, final Object JavaDoc ctx)
265     {
266         visitor.visit (this, ctx);
267     }
268     
269     public final IItemMetadata getMetadata ()
270     {
271         return METADATA;
272     }
273     
274     public static IItemMetadata getTypeMetadata ()
275     {
276         return METADATA;
277     }
278     
279     // protected: .............................................................
280

281     // package: ...............................................................
282

283     // private: ...............................................................
284

285     
286     private final String JavaDoc m_name, m_fullVMName;
287     private IntObjectMap /* line_no:int -> LineCoverageData */ m_lineCoverage;
288     private int m_firstLine;
289     
290     private static final Item.ItemMetadata METADATA; // set in <clinit>
291

292     static
293     {
294         METADATA = new Item.ItemMetadata (IItemMetadata.TYPE_ID_SRCFILE, "srcfile",
295             1 << IItemAttribute.ATTRIBUTE_NAME_ID |
296             1 << IItemAttribute.ATTRIBUTE_CLASS_COVERAGE_ID |
297             1 << IItemAttribute.ATTRIBUTE_METHOD_COVERAGE_ID |
298             1 << IItemAttribute.ATTRIBUTE_BLOCK_COVERAGE_ID |
299             1 << IItemAttribute.ATTRIBUTE_LINE_COVERAGE_ID);
300     }
301
302 } // end of class
303
// ----------------------------------------------------------------------------
Popular Tags