KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > data > MetaData


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

9 package com.vladium.emma.data;
10
11 import java.io.DataInput JavaDoc;
12 import java.io.DataOutput JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import com.vladium.logging.Logger;
20 import com.vladium.util.asserts.$assert;
21
22 // ----------------------------------------------------------------------------
23
/*
24  * Average mem size/class entry: 6166 bytes [1.4.1, rt.jar], 5764 bytes [1.3.1, rt.jar]
25  */

26 /**
27  * @author Vlad Roubtsov, (C) 2003
28  */

29 final class MetaData implements IMetaData, Cloneable JavaDoc
30 {
31     // public: ................................................................
32

33     // TODO: MT-safety model
34

35     // TODO: no duplicate detection is done here at the moment
36
// [may require supporting fast lookup for already added descriptors]
37

38     public IMetaData shallowCopy ()
39     {
40         final MetaData _clone;
41         try
42         {
43             _clone = (MetaData) super.clone ();
44         }
45         catch (CloneNotSupportedException JavaDoc cnse)
46         {
47             throw new Error JavaDoc (cnse.toString ());
48         }
49         
50         final HashMap JavaDoc _classMap;
51         
52         synchronized (lock ())
53         {
54             _classMap = (HashMap JavaDoc) m_classMap.clone ();
55         }
56         
57         // [m_packagesWarned is not cloned by design]
58

59         _clone.m_classMap = _classMap;
60         
61         return _clone;
62     }
63     
64     public CoverageOptions getOptions ()
65     {
66         return m_options;
67     }
68     
69     public int size ()
70     {
71         return m_classMap.size ();
72     }
73     
74     public boolean hasSrcFileData ()
75     {
76         return m_hasSrcFileInfo;
77     }
78     
79     public boolean hasLineNumberData ()
80     {
81         return m_hasLineNumberInfo;
82     }
83     
84     public Iterator JavaDoc iterator ()
85     {
86         return m_classMap.values ().iterator ();
87     }
88     
89 // public boolean hasDescriptor (final ClassDescriptor cls)
90
// {
91
// if ($assert.ENABLED) $assert.ASSERT (cls != null, "cls is null");
92
//
93
// return m_classes.contains (cls);
94
// }
95

96     public boolean hasDescriptor (final String JavaDoc classVMName)
97     {
98         if ($assert.ENABLED) $assert.ASSERT (classVMName != null, "className is null");
99         
100         return m_classMap.containsKey (classVMName);
101     }
102     
103     public Object JavaDoc lock ()
104     {
105         return m_classMap;
106     }
107         
108     public boolean add (final ClassDescriptor cls, final boolean overwrite)
109     {
110         if ($assert.ENABLED) $assert.ASSERT (cls != null, "cls is null");
111         
112         final String JavaDoc classVMName = cls.getClassVMName ();
113         
114         if (overwrite || ! m_classMap.containsKey (classVMName))
115         {
116             m_classMap.put (classVMName, cls);
117             
118             boolean incompleteDebugInfo = false;
119
120             if (! cls.hasSrcFileInfo ())
121             {
122                 m_hasSrcFileInfo = false;
123                 incompleteDebugInfo = true;
124             }
125             
126             if (! cls.hasCompleteLineNumberInfo ())
127             {
128                 m_hasLineNumberInfo = false;
129                 incompleteDebugInfo = true;
130             }
131             
132             // SF FR 971176: provide user with sample classes that may later
133
// caused warnings about line coverage not available
134

135             if (incompleteDebugInfo)
136             {
137                 final Logger log = Logger.getLogger ();
138                 
139                 if (log.atINFO ())
140                 {
141                     final String JavaDoc packageVMName = cls.getPackageVMName ();
142                     
143                     if (m_packagesWarned.add (packageVMName))
144                     {
145                         log.info ("package [" + packageVMName + "] contains classes [" + cls.getName () + "] without full debug info");
146                     }
147                 }
148             }
149             
150             return true;
151         }
152
153         return false;
154     }
155     
156     // IMergeable:
157

158     public boolean isEmpty ()
159     {
160         return m_classMap.isEmpty ();
161     }
162     
163     /*
164      * note: rhs entries must override current entries
165      */

166     public IMergeable merge (final IMergeable rhs)
167     {
168         if ((rhs == null) || rhs.isEmpty () || (rhs == this))
169             return this;
170         else
171         {
172             final MetaData rhsmdata = (MetaData) rhs; // TODO: redesign to avoid this cast?
173
final Map JavaDoc rhsclasses = rhsmdata.m_classMap;
174             
175             // rhs entries always override existing content:
176

177             for (Iterator JavaDoc entries = rhsclasses.entrySet ().iterator (); entries.hasNext (); )
178             {
179                 final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next ();
180                 
181                 final String JavaDoc classVMName = (String JavaDoc) entry.getKey ();
182                 final Object JavaDoc rhsdescriptor = entry.getValue ();
183                     
184                 m_classMap.put (classVMName, rhsdescriptor);
185             }
186             
187             // update debug info flags if necessary:
188

189             if (! rhsmdata.hasSrcFileData ()) m_hasSrcFileInfo = false;
190             if (! rhsmdata.hasLineNumberData ()) m_hasLineNumberInfo = false;
191                 
192             return this;
193         }
194     }
195     
196     // protected: .............................................................
197

198     // package: ...............................................................
199

200     
201     MetaData (final CoverageOptions options)
202     {
203         if ($assert.ENABLED) $assert.ASSERT (options != null, "options is null");
204         m_options = options;
205         
206         m_hasSrcFileInfo = true;
207         m_hasLineNumberInfo = true;
208         
209         m_classMap = new HashMap JavaDoc ();
210         m_packagesWarned = new HashSet JavaDoc ();
211     }
212     
213     
214     static MetaData readExternal (final DataInput JavaDoc in)
215         throws IOException JavaDoc
216     {
217         final CoverageOptions options = CoverageOptions.readExternal (in);
218         
219         final boolean hasSrcFileInfo = in.readBoolean ();
220         final boolean hasLineNumberInfo = in.readBoolean ();
221         
222         final int size = in.readInt ();
223         final HashMap JavaDoc classMap = new HashMap JavaDoc (size);
224         
225         for (int i = 0; i < size; ++ i)
226         {
227             final String JavaDoc classVMName = in.readUTF ();
228             final ClassDescriptor cls = ClassDescriptor.readExternal (in);
229             
230             classMap.put (classVMName, cls);
231         }
232         
233         // [m_packagesWarned is not part of persisted state]
234

235         return new MetaData (options, classMap, hasSrcFileInfo, hasLineNumberInfo);
236     }
237     
238     static void writeExternal (final MetaData mdata, final DataOutput JavaDoc out)
239         throws IOException JavaDoc
240     {
241         CoverageOptions.writeExternal (mdata.m_options, out);
242         
243         out.writeBoolean (mdata.m_hasSrcFileInfo);
244         out.writeBoolean (mdata.m_hasLineNumberInfo);
245         
246         final Map JavaDoc classMap = mdata.m_classMap;
247         
248         final int size = classMap.size ();
249         out.writeInt (size); // too bad the capacity is not visible
250

251         final Iterator JavaDoc entries = classMap.entrySet ().iterator ();
252         for (int i = 0; i < size; ++ i)
253         {
254             final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next ();
255             
256             final String JavaDoc classVMName = (String JavaDoc) entry.getKey ();
257             final ClassDescriptor cls = (ClassDescriptor) entry.getValue ();
258             
259             out.writeUTF (classVMName);
260             ClassDescriptor.writeExternal (cls, out);
261         }
262         
263         // [m_packagesWarned is not part of persisted state]
264
}
265     
266     // private: ...............................................................
267

268     
269     private MetaData (final CoverageOptions options, final HashMap JavaDoc classMap,
270                       final boolean hasSrcFileInfo, final boolean hasLineNumberInfo)
271     {
272         if ($assert.ENABLED) $assert.ASSERT (options != null, "options is null");
273         m_options = options;
274         
275         m_hasSrcFileInfo = hasSrcFileInfo;
276         m_hasLineNumberInfo = hasLineNumberInfo;
277         
278         m_classMap = classMap;
279     }
280     
281     
282     private final CoverageOptions m_options; // [never null]
283
private boolean m_hasSrcFileInfo, m_hasLineNumberInfo;
284     private /*final*/ HashMap JavaDoc /* classVMName:String->ClassDescriptor */ m_classMap; // [never null]
285

286     private /*final*/ transient HashSet JavaDoc /* packageVMName:String */ m_packagesWarned; // [never null]
287

288 } // end of class
289
// ----------------------------------------------------------------------------
Popular Tags