KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > editor > ConstantPoolEditor


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.classfile.editor;
22
23 import proguard.classfile.*;
24 import proguard.classfile.constant.*;
25
26 /**
27  * This class can add constant pool entries to given classes.
28  *
29  * @author Eric Lafortune
30  */

31 public class ConstantPoolEditor
32 {
33     private static final boolean DEBUG = false;
34
35
36     /**
37      * Finds or creates a IntegerConstant constant pool entry with the given value,
38      * in the given class.
39      * @return the constant pool index of the Utf8Constant.
40      */

41     public int addIntegerConstant(ProgramClass programClass,
42                                   int value)
43     {
44         int constantPoolCount = programClass.u2constantPoolCount;
45         Constant[] constantPool = programClass.constantPool;
46
47         // Check if the entry already exists.
48
for (int index = 1; index < constantPoolCount; index++)
49         {
50             Constant constant = constantPool[index];
51
52             if (constant != null &&
53                 constant.getTag() == ClassConstants.CONSTANT_Integer)
54             {
55                 IntegerConstant integerConstant = (IntegerConstant)constant;
56                 if (integerConstant.getValue() == value)
57                 {
58                     return index;
59                 }
60             }
61         }
62
63         return addConstant(programClass, new IntegerConstant(value));
64     }
65
66
67     /**
68      * Finds or creates a LongConstant constant pool entry with the given value,
69      * in the given class.
70      * @return the constant pool index of the Utf8Constant.
71      */

72     public int addLongConstant(ProgramClass programClass,
73                                long value)
74     {
75         int constantPoolCount = programClass.u2constantPoolCount;
76         Constant[] constantPool = programClass.constantPool;
77
78         // Check if the entry already exists.
79
for (int index = 1; index < constantPoolCount; index++)
80         {
81             Constant constant = constantPool[index];
82
83             if (constant != null &&
84                 constant.getTag() == ClassConstants.CONSTANT_Long)
85             {
86                 LongConstant longConstant = (LongConstant)constant;
87                 if (longConstant.getValue() == value)
88                 {
89                     return index;
90                 }
91             }
92         }
93
94         return addConstant(programClass, new LongConstant(value));
95     }
96
97
98     /**
99      * Finds or creates a FloatConstant constant pool entry with the given value,
100      * in the given class.
101      * @return the constant pool index of the Utf8Constant.
102      */

103     public int addFloatConstant(ProgramClass programClass,
104                                 float value)
105     {
106         int constantPoolCount = programClass.u2constantPoolCount;
107         Constant[] constantPool = programClass.constantPool;
108
109         // Check if the entry already exists.
110
for (int index = 1; index < constantPoolCount; index++)
111         {
112             Constant constant = constantPool[index];
113
114             if (constant != null &&
115                 constant.getTag() == ClassConstants.CONSTANT_Float)
116             {
117                 FloatConstant floatConstant = (FloatConstant)constant;
118                 if (floatConstant.getValue() == value)
119                 {
120                     return index;
121                 }
122             }
123         }
124
125         return addConstant(programClass, new FloatConstant(value));
126     }
127
128
129     /**
130      * Finds or creates a DoubleConstant constant pool entry with the given value,
131      * in the given class.
132      * @return the constant pool index of the Utf8Constant.
133      */

134     public int addDoubleConstant(ProgramClass programClass,
135                                   double value)
136     {
137         int constantPoolCount = programClass.u2constantPoolCount;
138         Constant[] constantPool = programClass.constantPool;
139
140         // Check if the entry already exists.
141
for (int index = 1; index < constantPoolCount; index++)
142         {
143             Constant constant = constantPool[index];
144
145             if (constant != null &&
146                 constant.getTag() == ClassConstants.CONSTANT_Double)
147             {
148                 DoubleConstant doubleConstant = (DoubleConstant)constant;
149                 if (doubleConstant.getValue() == value)
150                 {
151                     return index;
152                 }
153             }
154         }
155
156         return addConstant(programClass, new DoubleConstant(value));
157     }
158
159
160     /**
161      * Finds or creates a StringConstant constant pool entry with the given value,
162      * in the given class.
163      * @return the constant pool index of the ClassConstant.
164      */

165     public int addStringConstant(ProgramClass programClass,
166                                  String JavaDoc string,
167                                  Clazz referencedClass,
168                                  Member referencedMember)
169     {
170         int constantPoolCount = programClass.u2constantPoolCount;
171         Constant[] constantPool = programClass.constantPool;
172
173         // Check if the entry already exists.
174
for (int index = 1; index < constantPoolCount; index++)
175         {
176             Constant constant = constantPool[index];
177
178             if (constant != null &&
179                 constant.getTag() == ClassConstants.CONSTANT_String)
180             {
181                 StringConstant classConstant = (StringConstant)constant;
182                 if (classConstant.getString(programClass).equals(string))
183                 {
184                     return index;
185                 }
186             }
187         }
188
189         int nameIndex = addUtf8Constant(programClass, string);
190
191         return addConstant(programClass,
192                            new StringConstant(nameIndex,
193                                               referencedClass,
194                                               referencedMember));
195     }
196
197
198     /**
199      * Finds or creates a FieldrefConstant constant pool entry for the given
200      * class and field, in the given class.
201      * @return the constant pool index of the FieldrefConstant.
202      */

203     public int addFieldrefConstant(ProgramClass programClass,
204                                    Clazz referencedClass,
205                                    Member referencedMember)
206     {
207         return addFieldrefConstant(programClass,
208                                    referencedClass.getName(),
209                                    referencedMember.getName(referencedClass),
210                                    referencedMember.getDescriptor(referencedClass),
211                                    referencedClass,
212                                    referencedMember);
213     }
214
215
216     /**
217      * Finds or creates a FieldrefConstant constant pool entry with the given
218      * class name, field name, and descriptor, in the given class.
219      * @return the constant pool index of the FieldrefConstant.
220      */

221     public int addFieldrefConstant(ProgramClass programClass,
222                                    String JavaDoc className,
223                                    String JavaDoc name,
224                                    String JavaDoc descriptor,
225                                    Clazz referencedClass,
226                                    Member referencedMember)
227     {
228         return addFieldrefConstant(programClass,
229                                    className,
230                                    addNameAndTypeConstant(programClass,
231                                                           name,
232                                                           descriptor),
233                                    referencedClass,
234                                    referencedMember);
235     }
236
237
238     /**
239      * Finds or creates a FieldrefConstant constant pool entry with the given
240      * class name, field name, and descriptor, in the given class.
241      * @return the constant pool index of the FieldrefConstant.
242      */

243     public int addFieldrefConstant(ProgramClass programClass,
244                                    String JavaDoc className,
245                                    int nameAndTypeIndex,
246                                    Clazz referencedClass,
247                                    Member referencedMember)
248     {
249         return addFieldrefConstant(programClass,
250                                    addClassConstant(programClass,
251                                                     className,
252                                                     referencedClass),
253                                    nameAndTypeIndex,
254                                    referencedClass,
255                                    referencedMember);
256     }
257
258
259     /**
260      * Finds or creates a FieldrefConstant constant pool entry with the given
261      * class constant pool entry index, field name, and descriptor, in the
262      * given class.
263      * @return the constant pool index of the FieldrefConstant.
264      */

265     public int addFieldrefConstant(ProgramClass programClass,
266                                    int classIndex,
267                                    String JavaDoc name,
268                                    String JavaDoc descriptor,
269                                    Clazz referencedClass,
270                                    Member referencedMember)
271     {
272         return addFieldrefConstant(programClass,
273                                    classIndex,
274                                    addNameAndTypeConstant(programClass,
275                                                           name,
276                                                           descriptor),
277                                    referencedClass,
278                                    referencedMember);
279     }
280
281
282     /**
283      * Finds or creates a FieldrefConstant constant pool entry with the given
284      * class constant pool entry index and name and type constant pool entry index
285      * the given class.
286      * @return the constant pool index of the FieldrefConstant.
287      */

288     public int addFieldrefConstant(ProgramClass programClass,
289                                    int classIndex,
290                                    int nameAndTypeIndex,
291                                    Clazz referencedClass,
292                                    Member referencedMember)
293     {
294         int constantPoolCount = programClass.u2constantPoolCount;
295         Constant[] constantPool = programClass.constantPool;
296
297         // Check if the entry already exists.
298
for (int index = 1; index < constantPoolCount; index++)
299         {
300             Constant constant = constantPool[index];
301
302             if (constant != null &&
303                 constant.getTag() == ClassConstants.CONSTANT_Fieldref)
304             {
305                 FieldrefConstant fieldrefConstant = (FieldrefConstant)constant;
306                 if (fieldrefConstant.u2classIndex == classIndex &&
307                     fieldrefConstant.u2nameAndTypeIndex == nameAndTypeIndex)
308                 {
309                     return index;
310                 }
311             }
312         }
313
314         return addConstant(programClass,
315                            new FieldrefConstant(classIndex,
316                                                 nameAndTypeIndex,
317                                                 referencedClass,
318                                                 referencedMember));
319     }
320
321
322     /**
323      * Finds or creates a InterfaceMethodrefConstant constant pool entry with the
324      * given class name, method name, and descriptor, in the given class.
325      * @return the constant pool index of the InterfaceMethodrefConstant.
326      */

327     public int addInterfaceMethodrefConstant(ProgramClass programClass,
328                                              String JavaDoc className,
329                                              String JavaDoc name,
330                                              String JavaDoc descriptor,
331                                              Clazz referencedClass,
332                                              Member referencedMember)
333     {
334         return addInterfaceMethodrefConstant(programClass,
335                                              className,
336                                              addNameAndTypeConstant(programClass,
337                                                                     name,
338                                                                     descriptor),
339                                                                     referencedClass,
340                                                                     referencedMember);
341     }
342
343
344     /**
345      * Finds or creates a InterfaceMethodrefConstant constant pool entry with the
346      * given class name, method name, and descriptor, in the given class.
347      * @return the constant pool index of the InterfaceMethodrefConstant.
348      */

349     public int addInterfaceMethodrefConstant(ProgramClass programClass,
350                                              String JavaDoc className,
351                                              int nameAndTypeIndex,
352                                              Clazz referencedClass,
353                                              Member referencedMember)
354     {
355         return addInterfaceMethodrefConstant(programClass,
356                                              addClassConstant(programClass,
357                                                               className,
358                                                               referencedClass),
359                                                               nameAndTypeIndex,
360                                                               referencedClass,
361                                                               referencedMember);
362     }
363
364
365     /**
366      * Finds or creates a InterfaceMethodrefConstant constant pool entry for the
367      * given class and method, in the given class.
368      * @return the constant pool index of the InterfaceMethodrefConstant.
369      */

370     public int addInterfaceMethodrefConstant(ProgramClass programClass,
371                                              Clazz referencedClass,
372                                              Member referencedMember)
373     {
374         return addInterfaceMethodrefConstant(programClass,
375                                              referencedClass.getName(),
376                                              referencedMember.getName(referencedClass),
377                                              referencedMember.getDescriptor(referencedClass),
378                                              referencedClass,
379                                              referencedMember);
380     }
381
382
383     /**
384      * Finds or creates a InterfaceMethodrefConstant constant pool entry with the
385      * given class constant pool entry index, method name, and descriptor, in
386      * the given class.
387      * @return the constant pool index of the InterfaceMethodrefConstant.
388      */

389     public int addInterfaceMethodrefConstant(ProgramClass programClass,
390                                              int classIndex,
391                                              String JavaDoc name,
392                                              String JavaDoc descriptor,
393                                              Clazz referencedClass,
394                                              Member referencedMember)
395     {
396         return addInterfaceMethodrefConstant(programClass,
397                                              classIndex,
398                                              addNameAndTypeConstant(programClass,
399                                                                     name,
400                                                                     descriptor),
401                                              referencedClass,
402                                              referencedMember);
403     }
404
405
406     /**
407      * Finds or creates a InterfaceMethodrefConstant constant pool entry with the
408      * given class constant pool entry index and name and type constant pool
409      * entry index the given class.
410      * @return the constant pool index of the InterfaceMethodrefConstant.
411      */

412     public int addInterfaceMethodrefConstant(ProgramClass programClass,
413                                              int classIndex,
414                                              int nameAndTypeIndex,
415                                              Clazz referencedClass,
416                                              Member referencedMember)
417     {
418         int constantPoolCount = programClass.u2constantPoolCount;
419         Constant[] constantPool = programClass.constantPool;
420
421         // Check if the entry already exists.
422
for (int index = 1; index < constantPoolCount; index++)
423         {
424             Constant constant = constantPool[index];
425
426             if (constant != null &&
427                             constant.getTag() == ClassConstants.CONSTANT_InterfaceMethodref)
428             {
429                 InterfaceMethodrefConstant methodrefConstant = (InterfaceMethodrefConstant)constant;
430                 if (methodrefConstant.u2classIndex == classIndex &&
431                                 methodrefConstant.u2nameAndTypeIndex == nameAndTypeIndex)
432                 {
433                     return index;
434                 }
435             }
436         }
437
438         return addConstant(programClass,
439                            new InterfaceMethodrefConstant(classIndex,
440                                                           nameAndTypeIndex,
441                                                           referencedClass,
442                                                           referencedMember));
443     }
444
445
446     /**
447      * Finds or creates a MethodrefConstant constant pool entry for the given
448      * class and method, in the given class.
449      * @return the constant pool index of the MethodrefConstant.
450      */

451     public int addMethodrefConstant(ProgramClass programClass,
452                                     Clazz referencedClass,
453                                     Member referencedMember)
454     {
455         return addMethodrefConstant(programClass,
456                                     referencedClass.getName(),
457                                     referencedMember.getName(referencedClass),
458                                     referencedMember.getDescriptor(referencedClass),
459                                     referencedClass,
460                                     referencedMember);
461     }
462
463
464     /**
465      * Finds or creates a MethodrefConstant constant pool entry with the given
466      * class name, method name, and descriptor, in the given class.
467      * @return the constant pool index of the MethodrefConstant.
468      */

469     public int addMethodrefConstant(ProgramClass programClass,
470                                     String JavaDoc className,
471                                     String JavaDoc name,
472                                     String JavaDoc descriptor,
473                                     Clazz referencedClass,
474                                     Member referencedMember)
475     {
476         return addMethodrefConstant(programClass,
477                                     className,
478                                     addNameAndTypeConstant(programClass,
479                                                            name,
480                                                            descriptor),
481                                     referencedClass,
482                                     referencedMember);
483     }
484
485
486     /**
487      * Finds or creates a MethodrefConstant constant pool entry with the given
488      * class name, method name, and descriptor, in the given class.
489      * @return the constant pool index of the MethodrefConstant.
490      */

491     public int addMethodrefConstant(ProgramClass programClass,
492                                     String JavaDoc className,
493                                     int nameAndTypeIndex,
494                                     Clazz referencedClass,
495                                     Member referencedMember)
496     {
497         return addMethodrefConstant(programClass,
498                                     addClassConstant(programClass,
499                                                      className,
500                                                      referencedClass),
501                                     nameAndTypeIndex,
502                                     referencedClass,
503                                     referencedMember);
504     }
505
506
507     /**
508      * Finds or creates a MethodrefConstant constant pool entry with the given
509      * class constant pool entry index, method name, and descriptor, in the
510      * given class.
511      * @return the constant pool index of the MethodrefConstant.
512      */

513     public int addMethodrefConstant(ProgramClass programClass,
514                                     int classIndex,
515                                     String JavaDoc name,
516                                     String JavaDoc descriptor,
517                                     Clazz referencedClass,
518                                     Member referencedMember)
519     {
520         return addMethodrefConstant(programClass,
521                                     classIndex,
522                                     addNameAndTypeConstant(programClass,
523                                                            name,
524                                                            descriptor),
525                                     referencedClass,
526                                     referencedMember);
527     }
528
529
530     /**
531      * Finds or creates a MethodrefConstant constant pool entry with the given
532      * class constant pool entry index and name and type constant pool entry index
533      * the given class.
534      * @return the constant pool index of the MethodrefConstant.
535      */

536     public int addMethodrefConstant(ProgramClass programClass,
537                                     int classIndex,
538                                     int nameAndTypeIndex,
539                                     Clazz referencedClass,
540                                     Member referencedMember)
541     {
542         int constantPoolCount = programClass.u2constantPoolCount;
543         Constant[] constantPool = programClass.constantPool;
544
545         // Check if the entry already exists.
546
for (int index = 1; index < constantPoolCount; index++)
547         {
548             Constant constant = constantPool[index];
549
550             if (constant != null &&
551                 constant.getTag() == ClassConstants.CONSTANT_Methodref)
552             {
553                 MethodrefConstant methodrefConstant = (MethodrefConstant)constant;
554                 if (methodrefConstant.u2classIndex == classIndex &&
555                     methodrefConstant.u2nameAndTypeIndex == nameAndTypeIndex)
556                 {
557                     return index;
558                 }
559             }
560         }
561
562         return addConstant(programClass,
563                            new MethodrefConstant(classIndex,
564                                                  nameAndTypeIndex,
565                                                  referencedClass,
566                                                  referencedMember));
567     }
568
569
570     /**
571      * Finds or creates a ClassConstant constant pool entry for the given class,
572      * in the given class.
573      * @return the constant pool index of the ClassConstant.
574      */

575     public int addClassConstant(ProgramClass programClass,
576                                 Clazz referencedClass)
577     {
578         return addClassConstant(programClass,
579                                 referencedClass.getName(),
580                                 referencedClass);
581     }
582
583
584     /**
585      * Finds or creates a ClassConstant constant pool entry with the given name,
586      * in the given class.
587      * @return the constant pool index of the ClassConstant.
588      */

589     public int addClassConstant(ProgramClass programClass,
590                                 String JavaDoc name,
591                                 Clazz referencedClass)
592     {
593         int constantPoolCount = programClass.u2constantPoolCount;
594         Constant[] constantPool = programClass.constantPool;
595
596         // Check if the entry already exists.
597
for (int index = 1; index < constantPoolCount; index++)
598         {
599             Constant constant = constantPool[index];
600
601             if (constant != null &&
602                 constant.getTag() == ClassConstants.CONSTANT_Class)
603             {
604                 ClassConstant classConstant = (ClassConstant)constant;
605                 if (classConstant.getName(programClass).equals(name))
606                 {
607                     return index;
608                 }
609             }
610         }
611
612         int nameIndex = addUtf8Constant(programClass, name);
613
614         return addConstant(programClass,
615                            new ClassConstant(nameIndex,
616                                              referencedClass));
617     }
618
619
620     /**
621      * Finds or creates a NameAndTypeConstant constant pool entry with the given
622      * name and type, in the given class.
623      * @return the constant pool index of the NameAndTypeConstant.
624      */

625     public int addNameAndTypeConstant(ProgramClass programClass,
626                                       String JavaDoc name,
627                                       String JavaDoc type)
628     {
629         int constantPoolCount = programClass.u2constantPoolCount;
630         Constant[] constantPool = programClass.constantPool;
631
632         // Check if the entry already exists.
633
for (int index = 1; index < constantPoolCount; index++)
634         {
635             Constant constant = constantPool[index];
636
637             if (constant != null &&
638                 constant.getTag() == ClassConstants.CONSTANT_NameAndType)
639             {
640                 NameAndTypeConstant nameAndTypeConstant = (NameAndTypeConstant)constant;
641                 if (nameAndTypeConstant.getName(programClass).equals(name) &&
642                     nameAndTypeConstant.getType(programClass).equals(type))
643                 {
644                     return index;
645                 }
646             }
647         }
648
649         int nameIndex = addUtf8Constant(programClass, name);
650         int descriptorIndex = addUtf8Constant(programClass, type);
651
652         return addConstant(programClass,
653                            new NameAndTypeConstant(nameIndex,
654                                                    descriptorIndex));
655     }
656
657
658     /**
659      * Finds or creates a Utf8Constant constant pool entry for the given string,
660      * in the given class.
661      * @return the constant pool index of the Utf8Constant.
662      */

663     public int addUtf8Constant(ProgramClass programClass,
664                                String JavaDoc string)
665     {
666         int constantPoolCount = programClass.u2constantPoolCount;
667         Constant[] constantPool = programClass.constantPool;
668
669         // Check if the entry already exists.
670
for (int index = 1; index < constantPoolCount; index++)
671         {
672             Constant constant = constantPool[index];
673
674             if (constant != null &&
675                 constant.getTag() == ClassConstants.CONSTANT_Utf8)
676             {
677                 Utf8Constant utf8Constant = (Utf8Constant)constant;
678                 if (utf8Constant.getString().equals(string))
679                 {
680                     return index;
681                 }
682             }
683         }
684
685         return addConstant(programClass, new Utf8Constant(string));
686     }
687
688
689     /**
690      * Adds a given constant pool entry to the end of the constant pool
691      * in the given class.
692      * @return the constant pool index for the added entry.
693      */

694     public int addConstant(ProgramClass programClass,
695                            Constant constant)
696     {
697         int constantPoolCount = programClass.u2constantPoolCount;
698         Constant[] constantPool = programClass.constantPool;
699
700         // Make sure there is enough space for another constant pool entry.
701
if (constantPool.length < constantPoolCount+2)
702         {
703             programClass.constantPool = new Constant[constantPoolCount+2];
704             System.arraycopy(constantPool, 0,
705                              programClass.constantPool, 0,
706                              constantPoolCount);
707             constantPool = programClass.constantPool;
708         }
709
710         if (DEBUG)
711         {
712             System.out.println(programClass.getName()+": adding ["+constant.getClass().getName()+"] at index "+programClass.u2constantPoolCount);
713         }
714
715         // Create a new Utf8Constant for the given string.
716
constantPool[programClass.u2constantPoolCount++] = constant;
717
718         // Long constants and double constants take up two entries in the
719
// constant pool.
720
int tag = constant.getTag();
721         if (tag == ClassConstants.CONSTANT_Long ||
722             tag == ClassConstants.CONSTANT_Double)
723         {
724             constantPool[programClass.u2constantPoolCount++] = null;
725         }
726
727         return constantPoolCount;
728     }
729 }
730
Popular Tags