KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jas > ClassEnv


1
2 package jas;
3
4 import java.io.*;
5 import java.util.Hashtable JavaDoc;
6 import java.util.Enumeration JavaDoc;
7 import java.util.Vector JavaDoc;
8
9 /**
10  * This is the place where all information about the class to
11  * be created resides.
12  *
13  * @author $Author: fqian $
14  * @version $Revision: 1.1 $
15  */

16
17 public class ClassEnv implements RuntimeConstants
18 {
19   int magic;
20   short version_lo, version_hi;
21   CP this_class, super_class;
22   short class_access;
23   Hashtable JavaDoc cpe, cpe_index;
24   Vector JavaDoc interfaces;
25   Vector JavaDoc vars;
26   Vector JavaDoc methods;
27   SourceAttr source;
28   Vector JavaDoc generic;
29   boolean hasSuperClass;
30   InnerClassAttr inner_class_attr;
31   boolean classSynth;
32   SyntheticAttr synthAttr;
33   DeprecatedAttr deprAttr = null;
34   SignatureAttr sigAttr = null;
35   VisibilityAnnotationAttr visAnnotAttr = null;
36   EnclMethAttr encl_meth_attr;
37   boolean highVersion = false;
38   
39   public ClassEnv()
40   {
41                                 // Fill in reasonable defaults
42
magic = JAVA_MAGIC;
43     version_lo = (short) JAVA_MINOR_VERSION;
44     version_hi = (short) JAVA_VERSION;
45                                 // Initialize bags
46
cpe = new Hashtable JavaDoc();
47     cpe_index = null;
48     interfaces = new Vector JavaDoc();
49     vars = new Vector JavaDoc();
50     methods = new Vector JavaDoc();
51     generic = new Vector JavaDoc();
52   }
53
54   public void setHighVersion(boolean b){
55     highVersion = b;
56     //System.out.println("setting high version number");
57
version_lo = (short) JAVA_MINOR_HIGH_VERSION;
58     version_hi = (short) JAVA_HIGH_VERSION;
59   }
60   
61   /**
62    * Define this class to have this name.
63    * @param name CPE representing name for class. (This is usually
64    * a ClassCP)
65    */

66   public void setClass(CP name)
67   { this_class = name; addCPItem(name); }
68   
69   /**
70    * Define this class to have no superclass. Should only ever
71    * be used for java.lang.Object
72    */

73   public void setNoSuperClass()
74   {
75     hasSuperClass = false;
76   }
77
78   /**
79    * Define this class to have this superclass
80    * @param name CPE representing name for class. (This is usually
81    * a ClassCP)
82    */

83   public void setSuperClass(CP name)
84   {
85     hasSuperClass = true;
86     super_class = name;
87     addCPItem(name);
88   }
89
90   /**
91    * Set the class access for this class. Constants understood
92    * by this are present along with the java Beta distribution.
93    * @param access number representing access permissions for
94    * the entire class.
95    * @see RuntimeConstants
96    */

97   public void setClassAccess(short access)
98   { class_access = access; }
99
100   /**
101    * Add this CP to the list of interfaces supposedly implemented by
102    * this class. Note that the CP ought to be a ClassCP to make
103    * sense to the VM.
104    */

105
106   public void addInterface(CP ifc)
107   {
108     addCPItem(ifc);
109     interfaces.addElement(ifc);
110   }
111
112   /**
113    * Add this to the list of interfaces supposedly implemented
114    * by this class. Note that each CP is usually a ClassCP.
115    * @param ilist An array of CP items representing the
116    * interfaces implemented by this class.
117    */

118   public void addInterface(CP ilist[])
119   {
120     for (int i=0; i<ilist.length; i++)
121       {
122         interfaces.addElement(ilist[i]);
123         addCPItem(ilist[i]);
124       }
125   }
126
127   public void addField(Var v)
128   {
129     vars.addElement(v);
130     v.resolve(this);
131   }
132   /**
133    * Write the contents of the class.
134    *
135    * @param out DataOutputStream on which the contents are written.
136    */

137   public void write(DataOutputStream out)
138     throws IOException, jasError
139   {
140                 // Headers
141
out.writeInt(magic);
142     out.writeShort(version_lo);
143     out.writeShort(version_hi);
144
145                 // cpe items
146
int curidx = 1;
147                 // make up indices for entries
148
cpe_index = new Hashtable JavaDoc();
149     for (Enumeration JavaDoc e = cpe.elements(); e.hasMoreElements();)
150       {
151         CP tmp = (CP)(e.nextElement());
152         cpe_index.put(tmp.getUniq(), new Integer JavaDoc(curidx));
153         curidx++;
154         if ((tmp instanceof LongCP) ||
155             (tmp instanceof DoubleCP))
156           curidx++;
157       }
158     out.writeShort((short)curidx);
159
160                 // Now write out all the entries
161
for (Enumeration JavaDoc e = cpe.elements(); e.hasMoreElements();)
162       {
163         CP now = (CP) (e.nextElement());
164         now.write(this, out);
165       }
166
167                 // Class hierarchy/access
168
out.writeShort(class_access);
169     out.writeShort(getCPIndex(this_class));
170     if (hasSuperClass)
171       { out.writeShort(getCPIndex(super_class)); }
172     else
173       { out.writeShort(0); }
174                                 // interfaces
175
out.writeShort(interfaces.size());
176     for (Enumeration JavaDoc e = interfaces.elements(); e.hasMoreElements();)
177       {
178         CP c = (CP)(e.nextElement());
179         out.writeShort(getCPIndex(c));
180       }
181                                 // variables
182
out.writeShort(vars.size());
183     for (Enumeration JavaDoc e = vars.elements(); e.hasMoreElements();)
184       {
185         Var v = (Var)(e.nextElement());
186         v.write(this, out);
187       }
188
189                                 // methods
190
out.writeShort(methods.size());
191     for (Enumeration JavaDoc e = methods.elements(); e.hasMoreElements();)
192       {
193         Method m = (Method)(e.nextElement());
194         m.write(this, out);
195       }
196                                 // additional attributes
197
short numExtra = 0;
198     if (source != null)
199       { numExtra = 1; }
200     numExtra += generic.size();
201     if (inner_class_attr != null) {
202         numExtra++;
203     }
204     if (isClassSynth()){
205         numExtra++;
206     }
207     if (deprAttr != null){
208         numExtra++;
209     }
210     if (sigAttr != null){
211         numExtra++;
212     }
213     if (visAnnotAttr != null){
214         numExtra++;
215     }
216     if (encl_meth_attr != null){
217         numExtra++;
218     }
219     
220     out.writeShort(numExtra);
221     if (source != null)
222       { source.write(this, out); }
223     for (Enumeration JavaDoc gen=generic.elements(); gen.hasMoreElements(); )
224       {
225     GenericAttr gattr = (GenericAttr)gen.nextElement();
226     gattr.write(this, out);
227       }
228     
229     // synthetic attr
230
if (isClassSynth()){
231         //System.out.println("class is synthetic");
232
//SyntheticAttr sa = new SyntheticAttr();
233
//sa.resolve(this);
234
synthAttr.write(this, out);
235     }
236     // deprecated attr
237
if (deprAttr != null){
238         deprAttr.write(this, out);
239     }
240     // signature attr
241
if (sigAttr != null){
242         sigAttr.write(this, out);
243     }
244     // encl meth attr
245
if (encl_meth_attr != null){
246         encl_meth_attr.write(this, out);
247     }
248     // visibility annotation attr
249
if (visAnnotAttr != null){
250         visAnnotAttr.write(this, out);
251     }
252     // inner class attr
253
if (inner_class_attr != null){
254         inner_class_attr.write(this, out);
255     }
256     out.flush();
257   }
258
259   /**
260    * This is the method to add CPE items to a class. CPE items for
261    * a class are "uniquefied". Ie, if you add a CPE items whose
262    * contents already exist in the class, only one entry is finally
263    * written out when the class is written.
264    *
265    * @param cp Item to be added to the class
266    */

267
268   public void addCPItem(CP cp)
269   {
270     String JavaDoc uniq = cp.getUniq();
271     CP intern;
272     //System.out.println("adding CP: "+uniq);
273

274     if ((intern = (CP)(cpe.get(uniq))) == null)
275       {
276                 // add it
277
cpe.put(uniq, cp);
278     //System.out.println("added uniq to cpe: "+cpe.get(uniq));
279
// resolve it so it adds anything
280
// which it depends on
281
cp.resolve(this);
282     
283       }
284     //System.out.println("cp: "+cp);
285
}
286
287   /**
288    * Here is where code gets added to a class.
289    * @param acc method_access permissions, expressed with some combination
290    * of the values defined in RuntimeConstants
291    * @param name Name of the method
292    * @param sig Signature for the method
293    * @param code Actual code for the method
294    * @param ex Any exception attribute to be associated with method
295    */

296   public void
297   addMethod(short acc, String JavaDoc name, String JavaDoc sig, CodeAttr code, ExceptAttr ex)
298   {
299     Method x = new Method(acc, new AsciiCP(name), new AsciiCP(sig),
300                           code, ex);
301     x.resolve(this);
302     methods.addElement(x);
303   }
304
305  
306   public void setClassSynth(boolean b){
307     classSynth = b;
308     synthAttr = new SyntheticAttr();
309     synthAttr.resolve(this);
310   }
311
312   public boolean isClassSynth(){
313     return classSynth;
314   }
315
316   public void setClassDepr(DeprecatedAttr d){
317     deprAttr = d;
318     deprAttr.resolve(this);
319   }
320   
321   public void setClassSigAttr(SignatureAttr s){
322     sigAttr = s;
323     sigAttr.resolve(this);
324   }
325   
326   public void setClassAnnotAttr(VisibilityAnnotationAttr s){
327     visAnnotAttr = s;
328     visAnnotAttr.resolve(this);
329   }
330   
331   public void finishInnerClassAttr(InnerClassAttr attr){
332       inner_class_attr = attr;
333       inner_class_attr.resolve(this);
334   }
335
336   public void addEnclMethAttr(EnclMethAttr attr){
337       encl_meth_attr = attr;
338       encl_meth_attr.resolve(this);
339   }
340   
341   /**
342    * Add an attribute specifying the name of the source file
343    * for the class
344    * @param source SourceAttribute specifying the source for the file
345    */

346
347   public void setSource(SourceAttr source)
348   { this.source = source; source.resolve(this); }
349
350   /**
351    * Add an attribute specifying the name of the source file
352    * for the clas.
353    * @param source String with the name of the class
354    */

355   public void setSource(String JavaDoc source)
356   { this.source = new SourceAttr(source); this.source.resolve(this); }
357
358   /**
359    * Add a generic attribute to the class file. A generic attribute
360    * contains a stream of uninterpreted bytes which is ignored by
361    * the VM (as long as its name doesn't conflict with other names
362    * for attributes that are understood by the VM)
363    */

364   public void addGenericAttr(GenericAttr g)
365   { generic.addElement(g); g.resolve(this); }
366
367   /**
368    * This allows more control over generating CP's for methods
369    * if you feel so inclined.
370    */

371   public void addMethod(Method m)
372   {
373     m.resolve(this);
374     methods.addElement(m);
375   }
376
377   // LJH changed from short to int so that wide check works,
378
// otherwise nums > 32K become negative and then not made wide
379
/* short */ int getCPIndex(CP cp)
380     throws jasError
381   {
382       if (cpe_index == null) {
383          throw new jasError("Internal error: CPE index has not been generated");
384       }
385     //System.out.println("cp uniq: "+cp.getUniq());
386
//System.out.println("cpe_index: "+cpe_index);
387

388     Integer JavaDoc idx = (Integer JavaDoc)(cpe_index.get(cp.getUniq()));
389     // LJH -----------------------------
390
//System.out.println("Getting idx " + idx);
391
if (idx == null)
392       throw new jasError("Item " + cp + " not in the class");
393     return (idx.intValue());
394   }
395 }
396
Popular Tags