KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > enhancer > classfile > ConstantPool


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24
25 package com.sun.jdo.api.persistence.enhancer.classfile;
26
27 import java.util.Vector JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import java.io.*;
30
31 /**
32  * Constant Pool implementation - this represents the constant pool
33  * of a class in a class file.
34  */

35
36 public class ConstantPool implements VMConstants {
37
38   /* The actual pool */
39   private Vector JavaDoc pool = new Vector JavaDoc();
40
41   /* uniqifier tables */
42   private boolean hashed = false;
43   private Hashtable JavaDoc utfTable = new Hashtable JavaDoc(11);
44   private Hashtable JavaDoc unicodeTable = new Hashtable JavaDoc(3);
45   private Hashtable JavaDoc stringTable = new Hashtable JavaDoc(11);
46   private Hashtable JavaDoc classTable = new Hashtable JavaDoc(11);
47   private Hashtable JavaDoc intTable = new Hashtable JavaDoc(3);
48   private Hashtable JavaDoc floatTable = new Hashtable JavaDoc(3);
49   private Hashtable JavaDoc longTable = new Hashtable JavaDoc(3);
50   private Hashtable JavaDoc doubleTable = new Hashtable JavaDoc(3);
51
52   private Vector JavaDoc methodRefTable = new Vector JavaDoc();
53   private Vector JavaDoc fieldRefTable = new Vector JavaDoc();
54   private Vector JavaDoc ifaceMethodRefTable = new Vector JavaDoc();
55   private Vector JavaDoc nameAndTypeTable = new Vector JavaDoc();
56
57   /* public accessors */
58
59   /**
60    * Return the number of pool entries.
61    */

62   public int nEntries() {
63     return pool.size();
64   }
65
66   /**
67    * Return the constant in the pool at the specified entry index
68    */

69   public ConstBasic constantAt (int index) {
70     return (ConstBasic) pool.elementAt(index);
71   }
72
73   /**
74    * Find or create a class constant in the pool
75    */

76   public ConstClass addClass (String JavaDoc className) {
77     hashConstants();
78     ConstClass c = (ConstClass) classTable.get(className);
79     if (c == null) {
80       c = new ConstClass(addUtf8(className));
81       internConstant(c);
82     }
83     return c;
84   }
85   
86   /**
87    * Find or create a field constant in the pool
88    */

89   public ConstFieldRef addFieldRef (String JavaDoc className, String JavaDoc fieldName,
90                                      String JavaDoc type) {
91     hashConstants();
92     ConstFieldRef f = (ConstFieldRef)
93       searchTable(fieldRefTable, className, fieldName, type);
94
95     if (f == null) {
96       f = new ConstFieldRef (addClass(className),
97                  addNameAndType(fieldName, type));
98       internConstant(f);
99     }
100     return f;
101   }
102
103   /**
104    * Find or create a method constant in the pool
105    */

106   public ConstMethodRef addMethodRef (String JavaDoc className, String JavaDoc methodName,
107                       String JavaDoc type) {
108     hashConstants();
109     ConstMethodRef m = (ConstMethodRef)
110       searchTable(methodRefTable, className, methodName, type);
111     if (m == null) {
112       m = new ConstMethodRef (addClass(className),
113                   addNameAndType(methodName, type));
114       internConstant(m);
115     }
116     return m;
117   }
118
119   /**
120    * Find or create an interface method constant in the pool
121    */

122   public ConstInterfaceMethodRef addInterfaceMethodRef (String JavaDoc className,
123                               String JavaDoc methodName, String JavaDoc type) {
124     hashConstants();
125     ConstInterfaceMethodRef m = (ConstInterfaceMethodRef)
126       searchTable(ifaceMethodRefTable, className, methodName, type);
127     if (m == null) {
128       m = new ConstInterfaceMethodRef (addClass(className),
129                        addNameAndType(methodName, type));
130       internConstant(m);
131     }
132     return m;
133   }
134
135   /**
136    * Find or create a string constant in the pool
137    */

138   public ConstString addString (String JavaDoc s) {
139     hashConstants();
140     ConstString cs = (ConstString) stringTable.get(s);
141     if (cs == null) {
142       cs = new ConstString(addUtf8(s));
143       internConstant(cs);
144     }
145     return cs;
146   }
147   
148   /**
149    * Find or create an integer constant in the pool
150    */

151   public ConstInteger addInteger (int i) {
152     hashConstants();
153     Integer JavaDoc io = new Integer JavaDoc(i);
154     ConstInteger ci = (ConstInteger) intTable.get(io);
155     if (ci == null) {
156       ci = new ConstInteger(i);
157       internConstant(ci);
158     }
159     return ci;
160   }
161   
162   /**
163    * Find or create a float constant in the pool
164    */

165   public ConstFloat addFloat (float f) {
166     hashConstants();
167     Float JavaDoc fo = new Float JavaDoc(f);
168     ConstFloat cf = (ConstFloat) floatTable.get(fo);
169     if (cf == null) {
170       cf = new ConstFloat(f);
171       internConstant(cf);
172     }
173     return cf;
174   }
175   
176   /**
177    * Find or create a long constant in the pool
178    */

179   public ConstLong addLong (long l) {
180     hashConstants();
181     Long JavaDoc lo = new Long JavaDoc(l);
182     ConstLong cl = (ConstLong) longTable.get(lo);
183     if (cl == null) {
184       cl = new ConstLong(l);
185       internConstant(cl);
186       internConstant(null);
187     }
188     return cl;
189   }
190   
191   /**
192    * Find or create a double constant in the pool
193    */

194   public ConstDouble addDouble (double d) {
195     hashConstants();
196     Double JavaDoc dobj = new Double JavaDoc(d);
197     ConstDouble cd = (ConstDouble) doubleTable.get(dobj);
198     if (cd == null) {
199       cd = new ConstDouble(d);
200       internConstant(cd);
201       internConstant(null);
202     }
203     return cd;
204   }
205   
206   /**
207    * Find or create a name/type constant in the pool
208    */

209   public ConstNameAndType addNameAndType (String JavaDoc name, String JavaDoc type) {
210     hashConstants();
211     for (int i=0; i<nameAndTypeTable.size(); i++) {
212       ConstNameAndType nt = (ConstNameAndType) nameAndTypeTable.elementAt(i);
213       if (nt.name().asString().equals(name) &&
214       nt.signature().asString().equals(type))
215     return nt;
216     }
217
218     ConstNameAndType nt =
219       new ConstNameAndType(addUtf8(name), addUtf8(type));
220     internConstant(nt);
221     return nt;
222   }
223
224   /**
225    * Find or create a utf8 constant in the pool
226    */

227   public ConstUtf8 addUtf8 (String JavaDoc s) {
228     hashConstants();
229     ConstUtf8 u = (ConstUtf8) utfTable.get(s);
230     if (u == null) {
231       u = new ConstUtf8(s);
232       internConstant(u);
233     }
234     return u;
235   }
236
237   /**
238    * Find or create a unicode constant in the pool
239    * Obsolete?
240    */

241   public ConstUnicode addUnicode (String JavaDoc s) {
242     hashConstants();
243     ConstUnicode u = (ConstUnicode) unicodeTable.get(s);
244     if (u == null) {
245       u = new ConstUnicode(s);
246       internConstant(u);
247     }
248     return u;
249   }
250
251   /* package local methods */
252
253   ConstantPool() {
254     pool.addElement(null);
255   }
256
257   ConstantPool(DataInputStream input) throws IOException {
258     pool.addElement(null);
259     int nconstants = input.readUnsignedShort()-1;
260     while (nconstants > 0)
261       nconstants -= readConstant(input);
262
263     resolvePool();
264   }
265
266   void print (PrintStream out) {
267     for (int i=0; i<pool.size(); i++) {
268       ConstBasic c = constantAt(i);
269       if (c != null) {
270         out.print (i);
271         out.print (": ");//NOI18N
272
out.println (c.toString());
273       }
274     }
275   }
276
277   void summarize () {
278     int stringSize = 0;
279     int nStrings = 0;
280     for (int i=0; i<pool.size(); i++) {
281       ConstBasic c = constantAt(i);
282       if (c != null && c.tag() == CONSTANTUtf8) {
283     ConstUtf8 utf8 = (ConstUtf8) c;
284     stringSize += utf8.asString().length();
285     nStrings++;
286       }
287     }
288     System.out.println(" " + nStrings + " strings totalling " + //NOI18N
289
stringSize + " bytes");//NOI18N
290
}
291
292   void write (DataOutputStream buff) throws IOException {
293     buff.writeShort(pool.size());
294     for (int i=1; i<pool.size(); i++) {
295       ConstBasic cb = (ConstBasic) pool.elementAt(i);
296       if (cb != null) {
297     buff.writeByte((byte) cb.tag());
298     cb.formatData(buff);
299       }
300     }
301   }
302
303   /* private methods */
304
305   private void resolvePool() {
306     /* resolve indexes to object references */
307     for (int i=0; i<pool.size(); i++) {
308       ConstBasic c = constantAt(i);
309       if (c != null) {
310     c.setIndex(i);
311         c.resolve(this);
312       }
313     }
314   }
315
316   private void hashConstants() {
317     if (hashed)
318       return;
319
320     /* Enter objects into the hash tables */
321     for (int j=0; j<pool.size(); j++) {
322       ConstBasic c = constantAt(j);
323       if (c != null) {
324     recordConstant(c);
325       }
326     }
327
328     hashed = true;
329   }
330
331   /* returns the number of slots used */
332   private int readConstant(DataInputStream input) throws IOException {
333     ConstBasic basic;
334     byte b = input.readByte();
335     int slots = 1;
336     switch (b) {
337     case CONSTANTUtf8:
338       basic = ConstUtf8.read(input);
339       break;
340     case CONSTANTUnicode:
341       basic = ConstUnicode.read(input);
342       break;
343     case CONSTANTInteger:
344       basic = ConstInteger.read(input);
345       break;
346     case CONSTANTFloat:
347       basic = ConstFloat.read(input);
348       break;
349     case CONSTANTLong:
350       basic = ConstLong.read(input);
351       slots = 2;
352       break;
353     case CONSTANTDouble:
354       basic = ConstDouble.read(input);
355       slots = 2;
356       break;
357     case CONSTANTClass:
358       basic = ConstClass.read(input);
359       break;
360     case CONSTANTString:
361       basic = ConstString.read(input);
362       break;
363     case CONSTANTFieldRef:
364       basic = ConstFieldRef.read(input);
365       break;
366     case CONSTANTMethodRef:
367       basic = ConstMethodRef.read(input);
368       break;
369     case CONSTANTInterfaceMethodRef:
370       basic = ConstInterfaceMethodRef.read(input);
371       break;
372     case CONSTANTNameAndType:
373       basic = ConstNameAndType.read(input);
374       break;
375     default:
376         throw new ClassFormatError JavaDoc("Don't know this constant type: " +//NOI18N
377
Integer.toString(b));
378     }
379
380     pool.addElement(basic);
381     if (slots > 1)
382       pool.addElement(null);
383     return slots;
384   }
385
386   private void internConstant (ConstBasic c) {
387     if (c != null) {
388       c.setIndex(pool.size());
389       recordConstant(c);
390     }
391     pool.addElement(c);
392   }
393
394   private void recordConstant (ConstBasic c) {
395     if (c != null) {
396       switch (c.tag()) {
397       case CONSTANTUtf8:
398     utfTable.put(((ConstUtf8)c).asString(), c);
399     break;
400       case CONSTANTUnicode:
401     unicodeTable.put(((ConstUnicode)c).asString(), c);
402     break;
403       case CONSTANTInteger:
404     intTable.put(new Integer JavaDoc(((ConstInteger)c).value()), c);
405     break;
406       case CONSTANTFloat:
407     floatTable.put(new Float JavaDoc(((ConstFloat)c).value()), c);
408     break;
409       case CONSTANTLong:
410     longTable.put(new Long JavaDoc(((ConstLong)c).value()), c);
411     break;
412       case CONSTANTDouble:
413     doubleTable.put(new Double JavaDoc(((ConstDouble)c).value()), c);
414     break;
415       case CONSTANTClass:
416     classTable.put(((ConstClass)c).asString(), c);
417     break;
418       case CONSTANTString:
419     stringTable.put(((ConstString)c).value().asString(), c);
420     break;
421       case CONSTANTFieldRef:
422     fieldRefTable.addElement(c);
423     break;
424       case CONSTANTMethodRef:
425     methodRefTable.addElement(c);
426     break;
427       case CONSTANTInterfaceMethodRef:
428     ifaceMethodRefTable.addElement(c);
429     break;
430       case CONSTANTNameAndType:
431     nameAndTypeTable.addElement(c);
432     break;
433       }
434     }
435   }
436
437   private ConstBasicMemberRef searchTable(Vector JavaDoc table, String JavaDoc cname,
438                       String JavaDoc mname, String JavaDoc sig) {
439     for (int i=0; i<table.size(); i++) {
440       ConstBasicMemberRef memRef = (ConstBasicMemberRef) table.elementAt(i);
441       if (memRef.className().asString().equals(cname) &&
442       memRef.nameAndType().name().asString().equals(mname) &&
443       memRef.nameAndType().signature().asString().equals(sig))
444     return memRef;
445     }
446     return null;
447   }
448
449
450 }
451
452
Popular Tags