KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > bytecode > ConstPool


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.bytecode;
17
18 import java.io.DataInputStream JavaDoc;
19 import java.io.DataOutputStream JavaDoc;
20 import java.io.ByteArrayOutputStream JavaDoc;
21 import java.io.PrintWriter JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import javassist.CtClass;
26
27 /**
28  * Constant pool table.
29  */

30 public final class ConstPool {
31     LongVector items;
32     int numOfItems;
33     HashMap JavaDoc classes;
34     HashMap JavaDoc strings;
35     int thisClassInfo;
36
37     /**
38      * <code>CONSTANT_Class</code>
39      */

40     public static final int CONST_Class = ClassInfo.tag;
41
42     /**
43      * <code>CONSTANT_Fieldref</code>
44      */

45     public static final int CONST_Fieldref = FieldrefInfo.tag;
46
47     /**
48      * <code>CONSTANT_Methodref</code>
49      */

50     public static final int CONST_Methodref = MethodrefInfo.tag;
51
52     /**
53      * <code>CONSTANT_InterfaceMethodref</code>
54      */

55     public static final int CONST_InterfaceMethodref
56                                         = InterfaceMethodrefInfo.tag;
57
58     /**
59      * <code>CONSTANT_String</code>
60      */

61     public static final int CONST_String = StringInfo.tag;
62
63     /**
64      * <code>CONSTANT_Integer</code>
65      */

66     public static final int CONST_Integer = IntegerInfo.tag;
67
68     /**
69      * <code>CONSTANT_Float</code>
70      */

71     public static final int CONST_Float = FloatInfo.tag;
72
73     /**
74      * <code>CONSTANT_Long</code>
75      */

76     public static final int CONST_Long = LongInfo.tag;
77
78     /**
79      * <code>CONSTANT_Double</code>
80      */

81     public static final int CONST_Double = DoubleInfo.tag;
82
83     /**
84      * <code>CONSTANT_NameAndType</code>
85      */

86     public static final int CONST_NameAndType = NameAndTypeInfo.tag;
87
88     /**
89      * <code>CONSTANT_Utf8</code>
90      */

91     public static final int CONST_Utf8 = Utf8Info.tag;
92
93     /**
94      * Represents the class using this constant pool table.
95      */

96     public static final CtClass THIS = null;
97
98     /**
99      * Constructs a constant pool table.
100      *
101      * @param thisclass the name of the class using this constant
102      * pool table
103      */

104     public ConstPool(String JavaDoc thisclass) {
105         items = new LongVector();
106         numOfItems = 0;
107         addItem(null); // index 0 is reserved by the JVM.
108
classes = new HashMap JavaDoc();
109         strings = new HashMap JavaDoc();
110         thisClassInfo = addClassInfo(thisclass);
111     }
112
113     /**
114      * Constructs a constant pool table from the given byte stream.
115      *
116      * @param in byte stream.
117      */

118     public ConstPool(DataInputStream JavaDoc in) throws IOException JavaDoc {
119         classes = new HashMap JavaDoc();
120         strings = new HashMap JavaDoc();
121         thisClassInfo = 0;
122         /* read() initializes items and numOfItems, and do addItem(null).
123          */

124         read(in);
125     }
126
127     void prune() {
128         classes = new HashMap JavaDoc();
129         strings = new HashMap JavaDoc();
130     }
131
132     /**
133      * Returns the name of the class using this constant pool table.
134      */

135     public String JavaDoc getClassName() {
136         return getClassInfo(thisClassInfo);
137     }
138
139     /**
140      * Returns the index of <code>CONSTANT_Class_info</code> structure
141      * specifying the class using this constant pool table.
142      */

143     public int getThisClassInfo() {
144         return thisClassInfo;
145     }
146
147     void setThisClassInfo(int i) {
148         thisClassInfo = i;
149     }
150
151     ConstInfo getItem(int n) {
152         return (ConstInfo)items.elementAt(n);
153     }
154
155     /**
156      * Returns the <code>tag</code> field of the constant pool table
157      * entry at the given index.
158      */

159     public int getTag(int index) {
160         return getItem(index).getTag();
161     }
162
163     /**
164      * Reads <code>CONSTANT_Class_info</code> structure
165      * at the given index.
166      *
167      * @return a fully-qualified class or interface name specified
168      * by <code>name_index</code>.
169      */

170     public String JavaDoc getClassInfo(int index) {
171         ClassInfo c = (ClassInfo)getItem(index);
172         if (c == null)
173             return null;
174         else
175             return Descriptor.toJavaName(getUtf8Info(c.name));
176     }
177
178     /**
179      * Reads the <code>name_index</code> field of the
180      * <code>CONSTANT_NameAndType_info</code> structure
181      * at the given index.
182      */

183     public int getNameAndTypeName(int index) {
184         NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
185         return ntinfo.memberName;
186     }
187
188     /**
189      * Reads the <code>descriptor_index</code> field of the
190      * <code>CONSTANT_NameAndType_info</code> structure
191      * at the given index.
192      */

193     public int getNameAndTypeDescriptor(int index) {
194         NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
195         return ntinfo.typeDescriptor;
196     }
197
198     /**
199      * Reads the <code>class_index</code> field of the
200      * <code>CONSTANT_Fieldref_info</code> structure
201      * at the given index.
202      */

203     public int getFieldrefClass(int index) {
204         FieldrefInfo finfo = (FieldrefInfo)getItem(index);
205         return finfo.classIndex;
206     }
207
208     /**
209      * Reads the <code>class_index</code> field of the
210      * <code>CONSTANT_Fieldref_info</code> structure
211      * at the given index.
212      *
213      * @return the name of the class at that <code>class_index</code>.
214      */

215     public String JavaDoc getFieldrefClassName(int index) {
216         FieldrefInfo f = (FieldrefInfo)getItem(index);
217         if (f == null)
218             return null;
219         else
220             return getClassInfo(f.classIndex);
221     }
222
223     /**
224      * Reads the <code>name_and_type_index</code> field of the
225      * <code>CONSTANT_Fieldref_info</code> structure
226      * at the given index.
227      */

228     public int getFieldrefNameAndType(int index) {
229         FieldrefInfo finfo = (FieldrefInfo)getItem(index);
230         return finfo.nameAndTypeIndex;
231     }
232
233     /**
234      * Reads the <code>name_index</code> field of the
235      * <code>CONSTANT_NameAndType_info</code> structure
236      * indirectly specified by the given index.
237      *
238      * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
239      * @return the name of the field.
240      */

241     public String JavaDoc getFieldrefName(int index) {
242         FieldrefInfo f = (FieldrefInfo)getItem(index);
243         if (f == null)
244             return null;
245         else {
246             NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex);
247             if(n == null)
248                 return null;
249             else
250                 return getUtf8Info(n.memberName);
251         }
252     }
253
254     /**
255      * Reads the <code>descriptor_index</code> field of the
256      * <code>CONSTANT_NameAndType_info</code> structure
257      * indirectly specified by the given index.
258      *
259      * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
260      * @return the type descriptor of the field.
261      */

262     public String JavaDoc getFieldrefType(int index) {
263         FieldrefInfo f = (FieldrefInfo)getItem(index);
264         if (f == null)
265             return null;
266         else {
267             NameAndTypeInfo n = (NameAndTypeInfo) getItem(f.nameAndTypeIndex);
268             if(n == null)
269                 return null;
270             else
271                 return getUtf8Info(n.typeDescriptor);
272         }
273     }
274
275     /**
276      * Reads the <code>class_index</code> field of the
277      * <code>CONSTANT_Methodref_info</code> structure
278      * at the given index.
279      */

280     public int getMethodrefClass(int index) {
281         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
282         return minfo.classIndex;
283     }
284
285     /**
286      * Reads the <code>class_index</code> field of the
287      * <code>CONSTANT_Methodref_info</code> structure
288      * at the given index.
289      *
290      * @return the name of the class at that <code>class_index</code>.
291      */

292     public String JavaDoc getMethodrefClassName(int index) {
293         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
294         if (minfo == null)
295             return null;
296         else
297             return getClassInfo(minfo.classIndex);
298     }
299
300     /**
301      * Reads the <code>name_and_type_index</code> field of the
302      * <code>CONSTANT_Methodref_info</code> structure
303      * at the given index.
304      */

305     public int getMethodrefNameAndType(int index) {
306         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
307         return minfo.nameAndTypeIndex;
308     }
309
310     /**
311      * Reads the <code>name_index</code> field of the
312      * <code>CONSTANT_NameAndType_info</code> structure
313      * indirectly specified by the given index.
314      *
315      * @param index an index to a <code>CONSTANT_Methodref_info</code>.
316      * @return the name of the method.
317      */

318     public String JavaDoc getMethodrefName(int index) {
319         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
320         if (minfo == null)
321             return null;
322         else {
323             NameAndTypeInfo n
324                 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
325             if(n == null)
326                 return null;
327             else
328                 return getUtf8Info(n.memberName);
329         }
330     }
331
332     /**
333      * Reads the <code>descriptor_index</code> field of the
334      * <code>CONSTANT_NameAndType_info</code> structure
335      * indirectly specified by the given index.
336      *
337      * @param index an index to a <code>CONSTANT_Methodref_info</code>.
338      * @return the descriptor of the method.
339      */

340     public String JavaDoc getMethodrefType(int index) {
341         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
342         if (minfo == null)
343             return null;
344         else {
345             NameAndTypeInfo n
346                 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
347             if(n == null)
348                 return null;
349             else
350                 return getUtf8Info(n.typeDescriptor);
351         }
352     }
353
354     /**
355      * Reads the <code>class_index</code> field of the
356      * <code>CONSTANT_InterfaceMethodref_info</code> structure
357      * at the given index.
358      */

359     public int getInterfaceMethodrefClass(int index) {
360         InterfaceMethodrefInfo minfo
361             = (InterfaceMethodrefInfo)getItem(index);
362         return minfo.classIndex;
363     }
364
365     /**
366      * Reads the <code>class_index</code> field of the
367      * <code>CONSTANT_InterfaceMethodref_info</code> structure
368      * at the given index.
369      *
370      * @return the name of the class at that <code>class_index</code>.
371      */

372     public String JavaDoc getInterfaceMethodrefClassName(int index) {
373         InterfaceMethodrefInfo minfo
374             = (InterfaceMethodrefInfo)getItem(index);
375         return getClassInfo(minfo.classIndex);
376     }
377
378     /**
379      * Reads the <code>name_and_type_index</code> field of the
380      * <code>CONSTANT_InterfaceMethodref_info</code> structure
381      * at the given index.
382      */

383     public int getInterfaceMethodrefNameAndType(int index) {
384         InterfaceMethodrefInfo minfo
385             = (InterfaceMethodrefInfo)getItem(index);
386         return minfo.nameAndTypeIndex;
387     }
388
389     /**
390      * Reads the <code>name_index</code> field of the
391      * <code>CONSTANT_NameAndType_info</code> structure
392      * indirectly specified by the given index.
393      *
394      * @param index an index to
395      * a <code>CONSTANT_InterfaceMethodref_info</code>.
396      * @return the name of the method.
397      */

398     public String JavaDoc getInterfaceMethodrefName(int index) {
399         InterfaceMethodrefInfo minfo
400             = (InterfaceMethodrefInfo)getItem(index);
401         if (minfo == null)
402             return null;
403         else {
404             NameAndTypeInfo n
405                 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
406             if(n == null)
407                 return null;
408             else
409                 return getUtf8Info(n.memberName);
410         }
411     }
412
413     /**
414      * Reads the <code>descriptor_index</code> field of the
415      * <code>CONSTANT_NameAndType_info</code> structure
416      * indirectly specified by the given index.
417      *
418      * @param index an index to
419      * a <code>CONSTANT_InterfaceMethodref_info</code>.
420      * @return the descriptor of the method.
421      */

422     public String JavaDoc getInterfaceMethodrefType(int index) {
423         InterfaceMethodrefInfo minfo
424             = (InterfaceMethodrefInfo)getItem(index);
425         if (minfo == null)
426             return null;
427         else {
428             NameAndTypeInfo n
429                 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
430             if(n == null)
431                 return null;
432             else
433                 return getUtf8Info(n.typeDescriptor);
434         }
435     }
436     /**
437      * Reads <code>CONSTANT_Integer_info</code>, <code>_Float_info</code>,
438      * <code>_Long_info</code>, <code>_Double_info</code>, or
439      * <code>_String_info</code> structure.
440      * These are used with the LDC instruction.
441      *
442      * @return a <code>String</code> value or a wrapped primitive-type
443      * value.
444      */

445     public Object JavaDoc getLdcValue(int index) {
446         ConstInfo constInfo = this.getItem(index);
447         Object JavaDoc value = null;
448         if (constInfo instanceof StringInfo)
449             value = this.getStringInfo(index);
450         else if (constInfo instanceof FloatInfo)
451             value = new Float JavaDoc(getFloatInfo(index));
452         else if (constInfo instanceof IntegerInfo)
453             value = new Integer JavaDoc(getIntegerInfo(index));
454         else if (constInfo instanceof LongInfo)
455             value = new Long JavaDoc(getLongInfo(index));
456         else if (constInfo instanceof DoubleInfo)
457             value = new Double JavaDoc(getDoubleInfo(index));
458         else
459             value = null;
460
461         return value;
462     }
463
464     /**
465      * Reads <code>CONSTANT_Integer_info</code> structure
466      * at the given index.
467      *
468      * @return the value specified by this entry.
469      */

470     public int getIntegerInfo(int index) {
471         IntegerInfo i = (IntegerInfo)getItem(index);
472         return i.value;
473     }
474
475     /**
476      * Reads <code>CONSTANT_Float_info</code> structure
477      * at the given index.
478      *
479      * @return the value specified by this entry.
480      */

481     public float getFloatInfo(int index) {
482         FloatInfo i = (FloatInfo)getItem(index);
483         return i.value;
484     }
485
486     /**
487      * Reads <code>CONSTANT_Long_info</code> structure
488      * at the given index.
489      *
490      * @return the value specified by this entry.
491      */

492     public long getLongInfo(int index) {
493         LongInfo i = (LongInfo)getItem(index);
494         return i.value;
495     }
496
497     /**
498      * Reads <code>CONSTANT_Double_info</code> structure
499      * at the given index.
500      *
501      * @return the value specified by this entry.
502      */

503     public double getDoubleInfo(int index) {
504         DoubleInfo i = (DoubleInfo)getItem(index);
505         return i.value;
506     }
507
508     /**
509      * Reads <code>CONSTANT_String_info</code> structure
510      * at the given index.
511      *
512      * @return the string specified by <code>string_index</code>.
513      */

514     public String JavaDoc getStringInfo(int index) {
515         StringInfo si = (StringInfo)getItem(index);
516         return getUtf8Info(si.string);
517     }
518
519     /**
520      * Reads <code>CONSTANT_utf8_info</code> structure
521      * at the given index.
522      *
523      * @return the string specified by this entry.
524      */

525     public String JavaDoc getUtf8Info(int index) {
526         Utf8Info utf = (Utf8Info)getItem(index);
527         return utf.string;
528     }
529
530     /**
531      * Determines whether <code>CONSTANT_Methodref_info</code>
532      * structure at the given index represents the constructor
533      * of the given class.
534      *
535      * @return the <code>descriptor_index</code> specifying
536      * the type descriptor of the that constructor.
537      * If it is not that constructor,
538      * <code>isConstructor()</code> returns 0.
539      */

540     public int isConstructor(String JavaDoc classname, int index) {
541         return isMember(classname, MethodInfo.nameInit, index);
542     }
543
544     /**
545      * Determines whether <code>CONSTANT_Methodref_info</code>,
546      * <code>CONSTANT_Fieldref_info</code>, or
547      * <code>CONSTANT_InterfaceMethodref_info</code> structure
548      * at the given index represents the member with the specified
549      * name and declaring class.
550      *
551      * @param classname the class declaring the member
552      * @param membername the member name
553      * @param index the index into the constant pool table
554      *
555      * @return the <code>descriptor_index</code> specifying
556      * the type descriptor of that member.
557      * If it is not that member,
558      * <code>isMember()</code> returns 0.
559      */

560     public int isMember(String JavaDoc classname, String JavaDoc membername, int index) {
561         MemberrefInfo minfo = (MemberrefInfo)getItem(index);
562         if (getClassInfo(minfo.classIndex).equals(classname)) {
563             NameAndTypeInfo ntinfo
564                 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
565             if (getUtf8Info(ntinfo.memberName).equals(membername))
566                 return ntinfo.typeDescriptor;
567         }
568
569         return 0; // false
570
}
571
572     private int addItem(ConstInfo info) {
573         items.addElement(info);
574         return numOfItems++;
575     }
576
577     /**
578      * Copies the n-th item in this ConstPool object into the destination
579      * ConstPool object.
580      * The class names that the item refers to are renamed according
581      * to the given map.
582      *
583      * @param n the <i>n</i>-th item
584      * @param dest destination constant pool table
585      * @param classnames the map or null.
586      * @return the index of the copied item into the destination ClassPool.
587      */

588     public int copy(int n, ConstPool dest, Map JavaDoc classnames) {
589         if (n == 0)
590             return 0;
591
592         ConstInfo info = getItem(n);
593         return info.copy(this, dest, classnames);
594     }
595
596     int addConstInfoPadding() {
597         return addItem(new ConstInfoPadding());
598     }
599
600     /**
601      * Adds a new <code>CONSTANT_Class_info</code> structure.
602      *
603      * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
604      * for storing the class name.
605      *
606      * @return the index of the added entry.
607      */

608     public int addClassInfo(CtClass c) {
609         if (c == THIS)
610             return thisClassInfo;
611         else if (!c.isArray())
612             return addClassInfo(c.getName());
613         else {
614             // an array type is recorded in the hashtable with
615
// the key "[L<classname>;" instead of "<classname>".
616
//
617
// note: toJvmName(toJvmName(c)) is equal to toJvmName(c).
618

619             return addClassInfo(Descriptor.toJvmName(c));
620         }
621     }
622
623     /**
624      * Adds a new <code>CONSTANT_Class_info</code> structure.
625      *
626      * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
627      * for storing the class name.
628      *
629      * @param qname a fully-qualified class name
630      * (or the JVM-internal representation of that name).
631      * @return the index of the added entry.
632      */

633     public int addClassInfo(String JavaDoc qname) {
634         ClassInfo info = (ClassInfo)classes.get(qname);
635         if (info != null)
636             return info.index;
637         else {
638             int utf8 = addUtf8Info(Descriptor.toJvmName(qname));
639             info = new ClassInfo(utf8, numOfItems);
640             classes.put(qname, info);
641             return addItem(info);
642         }
643     }
644
645     /**
646      * Adds a new <code>CONSTANT_NameAndType_info</code> structure.
647      *
648      * <p>This also adds <code>CONSTANT_Utf8_info</code> structures.
649      *
650      * @param name <code>name_index</code>
651      * @param type <code>descriptor_index</code>
652      * @return the index of the added entry.
653      */

654     public int addNameAndTypeInfo(String JavaDoc name, String JavaDoc type) {
655         return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type));
656     }
657
658     /**
659      * Adds a new <code>CONSTANT_NameAndType_info</code> structure.
660      *
661      * @param name <code>name_index</code>
662      * @param type <code>descriptor_index</code>
663      * @return the index of the added entry.
664      */

665     public int addNameAndTypeInfo(int name, int type) {
666         return addItem(new NameAndTypeInfo(name, type));
667     }
668
669     /**
670      * Adds a new <code>CONSTANT_Fieldref_info</code> structure.
671      *
672      * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
673      * structure.
674      *
675      * @param classInfo <code>class_index</code>
676      * @param name <code>name_index</code>
677      * of <code>CONSTANT_NameAndType_info</code>.
678      * @param type <code>descriptor_index</code>
679      * of <code>CONSTANT_NameAndType_info</code>.
680      * @return the index of the added entry.
681      */

682     public int addFieldrefInfo(int classInfo, String JavaDoc name, String JavaDoc type) {
683         int nt = addNameAndTypeInfo(name, type);
684         return addFieldrefInfo(classInfo, nt);
685     }
686
687     /**
688      * Adds a new <code>CONSTANT_Fieldref_info</code> structure.
689      *
690      * @param classInfo <code>class_index</code>
691      * @param nameAndTypeInfo <code>name_and_type_index</code>.
692      * @return the index of the added entry.
693      */

694     public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) {
695         return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo));
696     }
697
698     /**
699      * Adds a new <code>CONSTANT_Methodref_info</code> structure.
700      *
701      * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
702      * structure.
703      *
704      * @param classInfo <code>class_index</code>
705      * @param name <code>name_index</code>
706      * of <code>CONSTANT_NameAndType_info</code>.
707      * @param type <code>descriptor_index</code>
708      * of <code>CONSTANT_NameAndType_info</code>.
709      * @return the index of the added entry.
710      */

711     public int addMethodrefInfo(int classInfo, String JavaDoc name, String JavaDoc type) {
712         int nt = addNameAndTypeInfo(name, type);
713         return addMethodrefInfo(classInfo, nt);
714     }
715
716     /**
717      * Adds a new <code>CONSTANT_Methodref_info</code> structure.
718      *
719      * @param classInfo <code>class_index</code>
720      * @param nameAndTypeInfo <code>name_and_type_index</code>.
721      * @return the index of the added entry.
722      */

723     public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) {
724         return addItem(new MethodrefInfo(classInfo, nameAndTypeInfo));
725     }
726
727     /**
728      * Adds a new <code>CONSTANT_InterfaceMethodref_info</code>
729      * structure.
730      *
731      * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
732      * structure.
733      *
734      * @param classInfo <code>class_index</code>
735      * @param name <code>name_index</code>
736      * of <code>CONSTANT_NameAndType_info</code>.
737      * @param type <code>descriptor_index</code>
738      * of <code>CONSTANT_NameAndType_info</code>.
739      * @return the index of the added entry.
740      */

741     public int addInterfaceMethodrefInfo(int classInfo, String JavaDoc name,
742                                          String JavaDoc type) {
743         int nt = addNameAndTypeInfo(name, type);
744         return addInterfaceMethodrefInfo(classInfo, nt);
745     }
746
747     /**
748      * Adds a new <code>CONSTANT_InterfaceMethodref_info</code>
749      * structure.
750      *
751      * @param classInfo <code>class_index</code>
752      * @param nameAndTypeInfo <code>name_and_type_index</code>.
753      * @return the index of the added entry.
754      */

755     public int addInterfaceMethodrefInfo(int classInfo,
756                                          int nameAndTypeInfo) {
757         return addItem(new InterfaceMethodrefInfo(classInfo,
758                                                   nameAndTypeInfo));
759     }
760
761     /**
762      * Adds a new <code>CONSTANT_String_info</code>
763      * structure.
764      *
765      * <p>This also adds a new <code>CONSTANT_Utf8_info</code>
766      * structure.
767      *
768      * @return the index of the added entry.
769      */

770     public int addStringInfo(String JavaDoc str) {
771         return addItem(new StringInfo(addUtf8Info(str)));
772     }
773
774     /**
775      * Adds a new <code>CONSTANT_Integer_info</code>
776      * structure.
777      *
778      * @return the index of the added entry.
779      */

780     public int addIntegerInfo(int i) {
781         return addItem(new IntegerInfo(i));
782     }
783
784     /**
785      * Adds a new <code>CONSTANT_Float_info</code>
786      * structure.
787      *
788      * @return the index of the added entry.
789      */

790     public int addFloatInfo(float f) {
791         return addItem(new FloatInfo(f));
792     }
793
794     /**
795      * Adds a new <code>CONSTANT_Long_info</code>
796      * structure.
797      *
798      * @return the index of the added entry.
799      */

800     public int addLongInfo(long l) {
801         int i = addItem(new LongInfo(l));
802         addItem(new ConstInfoPadding());
803         return i;
804     }
805
806     /**
807      * Adds a new <code>CONSTANT_Double_info</code>
808      * structure.
809      *
810      * @return the index of the added entry.
811      */

812     public int addDoubleInfo(double d) {
813         int i = addItem(new DoubleInfo(d));
814         addItem(new ConstInfoPadding());
815         return i;
816     }
817
818     /**
819      * Adds a new <code>CONSTANT_Utf8_info</code>
820      * structure.
821      *
822      * <p>If the given utf8 string has been already recorded in the
823      * table, then this method does not add a new entry to avoid adding
824      * a duplicated entry.
825      * Instead, it returns the index of the entry already recorded.
826      *
827      * @return the index of the added entry.
828      */

829     public int addUtf8Info(String JavaDoc utf8) {
830         Utf8Info info = (Utf8Info)strings.get(utf8);
831         if (info != null)
832             return info.index;
833         else {
834             info = new Utf8Info(utf8, numOfItems);
835             strings.put(utf8, info);
836             return addItem(info);
837         }
838     }
839
840     /**
841      * Replaces all occurrences of a class name.
842      *
843      * @param oldName the replaced name
844      * @param newName the substituted name.
845      */

846     public void renameClass(String JavaDoc oldName, String JavaDoc newName) {
847         LongVector v = items;
848         int size = numOfItems;
849         for (int i = 1; i < size; ++i)
850             ((ConstInfo)v.elementAt(i)).renameClass(this, oldName, newName);
851     }
852
853     /**
854      * Replaces all occurrences of class names.
855      *
856      * @param classnames specifies pairs of replaced and substituted
857      * name.
858      */

859     public void renameClass(Map JavaDoc classnames) {
860         LongVector v = items;
861         int size = numOfItems;
862         for (int i = 1; i < size; ++i)
863             ((ConstInfo)v.elementAt(i)).renameClass(this, classnames);
864     }
865
866     private void read(DataInputStream JavaDoc in) throws IOException JavaDoc {
867         int n = in.readUnsignedShort();
868
869         int size = (n / LongVector.SIZE + 1) * LongVector.SIZE;
870         items = new LongVector(size);
871         numOfItems = 0;
872         addItem(null); // index 0 is reserved by the JVM.
873

874         while (--n > 0) { // index 0 is reserved by JVM
875
int tag = readOne(in);
876             if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) {
877                 addItem(new ConstInfoPadding());
878                 --n;
879             }
880         }
881     }
882
883     private int readOne(DataInputStream JavaDoc in) throws IOException JavaDoc {
884         ConstInfo info;
885         int tag = in.readUnsignedByte();
886         switch (tag) {
887         case Utf8Info.tag : // 1
888
info = new Utf8Info(in, numOfItems);
889             strings.put(((Utf8Info)info).string, info);
890             break;
891         case IntegerInfo.tag : // 3
892
info = new IntegerInfo(in);
893             break;
894         case FloatInfo.tag : // 4
895
info = new FloatInfo(in);
896             break;
897         case LongInfo.tag : // 5
898
info = new LongInfo(in);
899             break;
900         case DoubleInfo.tag : // 6
901
info = new DoubleInfo(in);
902             break;
903         case ClassInfo.tag : // 7
904
info = new ClassInfo(in, numOfItems);
905             // classes.put(<classname>, info);
906
break;
907         case StringInfo.tag : // 8
908
info = new StringInfo(in);
909             break;
910         case FieldrefInfo.tag : // 9
911
info = new FieldrefInfo(in);
912             break;
913         case MethodrefInfo.tag : // 10
914
info = new MethodrefInfo(in);
915             break;
916         case InterfaceMethodrefInfo.tag : // 11
917
info = new InterfaceMethodrefInfo(in);
918             break;
919         case NameAndTypeInfo.tag : // 12
920
info = new NameAndTypeInfo(in);
921             break;
922         default :
923             throw new IOException JavaDoc("invalid constant type: " + tag);
924         }
925
926         addItem(info);
927         return tag;
928     }
929
930     /**
931      * Writes the contents of the constant pool table.
932      */

933     public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
934         out.writeShort(numOfItems);
935         LongVector v = items;
936         int size = numOfItems;
937         for (int i = 1; i < size; ++i)
938             ((ConstInfo)v.elementAt(i)).write(out);
939     }
940
941     /**
942      * Prints the contents of the constant pool table.
943      */

944     public void print() {
945         print(new PrintWriter JavaDoc(System.out, true));
946     }
947
948     /**
949      * Prints the contents of the constant pool table.
950      */

951     public void print(PrintWriter JavaDoc out) {
952         int size = numOfItems;
953         for (int i = 1; i < size; ++i) {
954             out.print(i);
955             out.print(" ");
956             ((ConstInfo)items.elementAt(i)).print(out);
957         }
958     }
959 }
960
961 abstract class ConstInfo {
962     public abstract int getTag();
963
964     public void renameClass(ConstPool cp, String JavaDoc oldName, String JavaDoc newName) {}
965     public void renameClass(ConstPool cp, Map JavaDoc classnames) {}
966     public abstract int copy(ConstPool src, ConstPool dest, Map JavaDoc classnames);
967                         // ** classnames is a mapping between JVM names.
968

969     public abstract void write(DataOutputStream JavaDoc out) throws IOException JavaDoc;
970     public abstract void print(PrintWriter JavaDoc out);
971
972     public String JavaDoc toString() {
973         ByteArrayOutputStream JavaDoc bout = new ByteArrayOutputStream JavaDoc();
974         PrintWriter JavaDoc out = new PrintWriter JavaDoc(bout);
975         print(out);
976         return bout.toString();
977     }
978 }
979
980 /* padding following DoubleInfo or LongInfo.
981  */

982 class ConstInfoPadding extends ConstInfo {
983     public int getTag() { return 0; }
984
985     public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
986         return dest.addConstInfoPadding();
987     }
988
989     public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {}
990
991     public void print(PrintWriter JavaDoc out) {
992         out.println("padding");
993     }
994 }
995
996 class ClassInfo extends ConstInfo {
997     static final int tag = 7;
998     int name;
999     int index;
1000
1001    public ClassInfo(int className, int i) {
1002        name = className;
1003        index = i;
1004    }
1005
1006    public ClassInfo(DataInputStream JavaDoc in, int i) throws IOException JavaDoc {
1007        name = in.readUnsignedShort();
1008        index = i;
1009    }
1010
1011    public int getTag() { return tag; }
1012
1013    public void renameClass(ConstPool cp, String JavaDoc oldName, String JavaDoc newName) {
1014        String JavaDoc nameStr = cp.getUtf8Info(name);
1015        if (nameStr.equals(oldName))
1016            name = cp.addUtf8Info(newName);
1017        else if (nameStr.charAt(0) == '[') {
1018            String JavaDoc nameStr2 = Descriptor.rename(nameStr, oldName, newName);
1019            if (nameStr != nameStr2)
1020                name = cp.addUtf8Info(nameStr2);
1021        }
1022    }
1023
1024    public void renameClass(ConstPool cp, Map JavaDoc map) {
1025        String JavaDoc oldName = cp.getUtf8Info(name);
1026        if (oldName.charAt(0) == '[') {
1027            String JavaDoc newName = Descriptor.rename(oldName, map);
1028            if (oldName != newName)
1029                name = cp.addUtf8Info(newName);
1030        }
1031        else {
1032            String JavaDoc newName = (String JavaDoc)map.get(oldName);
1033            if (newName != null && !newName.equals(oldName))
1034                name = cp.addUtf8Info(newName);
1035        }
1036    }
1037
1038    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1039        String JavaDoc classname = src.getUtf8Info(name);
1040        if (map != null) {
1041            String JavaDoc newname = (String JavaDoc)map.get(classname);
1042            if (newname != null)
1043                classname = newname;
1044        }
1045
1046        return dest.addClassInfo(classname);
1047    }
1048
1049    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1050        out.writeByte(tag);
1051        out.writeShort(name);
1052    }
1053
1054    public void print(PrintWriter JavaDoc out) {
1055        out.print("Class #");
1056        out.println(name);
1057    }
1058}
1059
1060class NameAndTypeInfo extends ConstInfo {
1061    static final int tag = 12;
1062    int memberName;
1063    int typeDescriptor;
1064
1065    public NameAndTypeInfo(int name, int type) {
1066        memberName = name;
1067        typeDescriptor = type;
1068    }
1069
1070    public NameAndTypeInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1071        memberName = in.readUnsignedShort();
1072        typeDescriptor = in.readUnsignedShort();
1073    }
1074
1075    public int getTag() { return tag; }
1076
1077    public void renameClass(ConstPool cp, String JavaDoc oldName, String JavaDoc newName) {
1078        String JavaDoc type = cp.getUtf8Info(typeDescriptor);
1079        String JavaDoc type2 = Descriptor.rename(type, oldName, newName);
1080        if (type != type2)
1081            typeDescriptor = cp.addUtf8Info(type2);
1082    }
1083
1084    public void renameClass(ConstPool cp, Map JavaDoc map) {
1085        String JavaDoc type = cp.getUtf8Info(typeDescriptor);
1086        String JavaDoc type2 = Descriptor.rename(type, map);
1087        if (type != type2)
1088            typeDescriptor = cp.addUtf8Info(type2);
1089    }
1090
1091    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1092        String JavaDoc mname = src.getUtf8Info(memberName);
1093        String JavaDoc tdesc = src.getUtf8Info(typeDescriptor);
1094        tdesc = Descriptor.rename(tdesc, map);
1095        return dest.addNameAndTypeInfo(dest.addUtf8Info(mname),
1096                                       dest.addUtf8Info(tdesc));
1097    }
1098
1099    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1100        out.writeByte(tag);
1101        out.writeShort(memberName);
1102        out.writeShort(typeDescriptor);
1103    }
1104
1105    public void print(PrintWriter JavaDoc out) {
1106        out.print("NameAndType #");
1107        out.print(memberName);
1108        out.print(", type #");
1109        out.println(typeDescriptor);
1110    }
1111}
1112
1113abstract class MemberrefInfo extends ConstInfo {
1114    int classIndex;
1115    int nameAndTypeIndex;
1116
1117    public MemberrefInfo(int cindex, int ntindex) {
1118        classIndex = cindex;
1119        nameAndTypeIndex = ntindex;
1120    }
1121
1122    public MemberrefInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1123        classIndex = in.readUnsignedShort();
1124        nameAndTypeIndex = in.readUnsignedShort();
1125    }
1126
1127    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1128        int classIndex2 = src.getItem(classIndex).copy(src, dest, map);
1129        int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map);
1130        return copy2(dest, classIndex2, ntIndex2);
1131    }
1132
1133    abstract protected int copy2(ConstPool dest, int cindex, int ntindex);
1134
1135    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1136        out.writeByte(getTag());
1137        out.writeShort(classIndex);
1138        out.writeShort(nameAndTypeIndex);
1139    }
1140
1141    public void print(PrintWriter JavaDoc out) {
1142        out.print(getTagName() + " #");
1143        out.print(classIndex);
1144        out.print(", name&type #");
1145        out.println(nameAndTypeIndex);
1146    }
1147
1148    public abstract String JavaDoc getTagName();
1149}
1150
1151class FieldrefInfo extends MemberrefInfo {
1152    static final int tag = 9;
1153
1154    public FieldrefInfo(int cindex, int ntindex) {
1155        super(cindex, ntindex);
1156    }
1157
1158    public FieldrefInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1159        super(in);
1160    }
1161
1162    public int getTag() { return tag; }
1163
1164    public String JavaDoc getTagName() { return "Field"; }
1165
1166    protected int copy2(ConstPool dest, int cindex, int ntindex) {
1167        return dest.addFieldrefInfo(cindex, ntindex);
1168    }
1169}
1170
1171class MethodrefInfo extends MemberrefInfo {
1172    static final int tag = 10;
1173
1174    public MethodrefInfo(int cindex, int ntindex) {
1175        super(cindex, ntindex);
1176    }
1177
1178    public MethodrefInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1179        super(in);
1180    }
1181
1182    public int getTag() { return tag; }
1183
1184    public String JavaDoc getTagName() { return "Method"; }
1185
1186    protected int copy2(ConstPool dest, int cindex, int ntindex) {
1187        return dest.addMethodrefInfo(cindex, ntindex);
1188    }
1189}
1190
1191class InterfaceMethodrefInfo extends MemberrefInfo {
1192    static final int tag = 11;
1193
1194    public InterfaceMethodrefInfo(int cindex, int ntindex) {
1195        super(cindex, ntindex);
1196    }
1197
1198    public InterfaceMethodrefInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1199        super(in);
1200    }
1201
1202    public int getTag() { return tag; }
1203
1204    public String JavaDoc getTagName() { return "Interface"; }
1205
1206    protected int copy2(ConstPool dest, int cindex, int ntindex) {
1207        return dest.addInterfaceMethodrefInfo(cindex, ntindex);
1208    }
1209}
1210
1211class StringInfo extends ConstInfo {
1212    static final int tag = 8;
1213    int string;
1214
1215    public StringInfo(int str) {
1216        string = str;
1217    }
1218
1219    public StringInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1220        string = in.readUnsignedShort();
1221    }
1222
1223    public int getTag() { return tag; }
1224
1225    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1226        return dest.addStringInfo(src.getUtf8Info(string));
1227    }
1228
1229    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1230        out.writeByte(tag);
1231        out.writeShort(string);
1232    }
1233
1234    public void print(PrintWriter JavaDoc out) {
1235        out.print("String #");
1236        out.println(string);
1237    }
1238}
1239
1240class IntegerInfo extends ConstInfo {
1241    static final int tag = 3;
1242    int value;
1243
1244    public IntegerInfo(int i) {
1245        value = i;
1246    }
1247
1248    public IntegerInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1249        value = in.readInt();
1250    }
1251
1252    public int getTag() { return tag; }
1253
1254    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1255        return dest.addIntegerInfo(value);
1256    }
1257
1258    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1259        out.writeByte(tag);
1260        out.writeInt(value);
1261    }
1262
1263    public void print(PrintWriter JavaDoc out) {
1264        out.print("Integer ");
1265        out.println(value);
1266    }
1267}
1268
1269class FloatInfo extends ConstInfo {
1270    static final int tag = 4;
1271    float value;
1272
1273    public FloatInfo(float f) {
1274        value = f;
1275    }
1276
1277    public FloatInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1278        value = in.readFloat();
1279    }
1280
1281    public int getTag() { return tag; }
1282
1283    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1284        return dest.addFloatInfo(value);
1285    }
1286
1287    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1288        out.writeByte(tag);
1289        out.writeFloat(value);
1290    }
1291
1292    public void print(PrintWriter JavaDoc out) {
1293        out.print("Float ");
1294        out.println(value);
1295    }
1296}
1297
1298class LongInfo extends ConstInfo {
1299    static final int tag = 5;
1300    long value;
1301
1302    public LongInfo(long l) {
1303        value = l;
1304    }
1305
1306    public LongInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1307        value = in.readLong();
1308    }
1309
1310    public int getTag() { return tag; }
1311
1312    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1313        return dest.addLongInfo(value);
1314    }
1315
1316    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1317        out.writeByte(tag);
1318        out.writeLong(value);
1319    }
1320
1321    public void print(PrintWriter JavaDoc out) {
1322        out.print("Long ");
1323        out.println(value);
1324    }
1325}
1326
1327class DoubleInfo extends ConstInfo {
1328    static final int tag = 6;
1329    double value;
1330
1331    public DoubleInfo(double d) {
1332        value = d;
1333    }
1334
1335    public DoubleInfo(DataInputStream JavaDoc in) throws IOException JavaDoc {
1336        value = in.readDouble();
1337    }
1338
1339    public int getTag() { return tag; }
1340
1341    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1342        return dest.addDoubleInfo(value);
1343    }
1344
1345    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1346        out.writeByte(tag);
1347        out.writeDouble(value);
1348    }
1349
1350    public void print(PrintWriter JavaDoc out) {
1351        out.print("Double ");
1352        out.println(value);
1353    }
1354}
1355
1356class Utf8Info extends ConstInfo {
1357    static final int tag = 1;
1358    String JavaDoc string;
1359    int index;
1360
1361    public Utf8Info(String JavaDoc utf8, int i) {
1362        string = utf8;
1363        index = i;
1364    }
1365
1366    public Utf8Info(DataInputStream JavaDoc in, int i) throws IOException JavaDoc {
1367        string = in.readUTF();
1368        index = i;
1369    }
1370
1371    public int getTag() { return tag; }
1372
1373    public int copy(ConstPool src, ConstPool dest, Map JavaDoc map) {
1374        return dest.addUtf8Info(string);
1375    }
1376
1377    public void write(DataOutputStream JavaDoc out) throws IOException JavaDoc {
1378        out.writeByte(tag);
1379        out.writeUTF(string);
1380    }
1381
1382    public void print(PrintWriter JavaDoc out) {
1383        out.print("UTF8 \"");
1384        out.print(string);
1385        out.println("\"");
1386    }
1387}
1388
Popular Tags