KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jarg > ConstantPoolSorter


1 /* ====================================================================
2  * Copyright (c) 2002, Hidetoshi Ohuchi <hchacha@users.sourceforge.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the hchacha nor the names of its contributors
17  * may be used to endorse or promote products derived from this
18  * software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  * ====================================================================
33  */

34 package jarg;
35
36 import java.util.Arrays JavaDoc;
37 import java.util.Comparator JavaDoc;
38
39 import org.apache.bcel.classfile.*;
40 import org.apache.bcel.generic.*;
41 import org.apache.bcel.Constants;
42
43 /**
44  * The class for sorting constants in the constant pool.
45  *
46  * @version $Id: ConstantPoolSorter.java,v 1.2 2002/04/19 09:56:56 hchacha Exp $
47  * @author Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;
48  */

49 class ConstantPoolSorter {
50    private ConstantPoolSorter() {
51    }
52
53    static ConstantPoolGen reshapeConstantPool(Constant[] cs) {
54       // cloning constants
55
Constant[] css = (Constant[])cs.clone();
56
57       // reordering
58
Arrays.sort(css, cpcomparator);
59       System.arraycopy(css, 0, css, 1, css.length-1);
60       css[0] = null;
61
62       // long null fitting
63
for (int i=1; i<css.length-2; i++) {
64          Constant c = css[i];
65          if (c != null) {
66             switch (c.getTag()) {
67             case Constants.CONSTANT_Long:
68             case Constants.CONSTANT_Double:
69                System.arraycopy(css, i+1, css, i+2, css.length-(i+2));
70                css[i+1] = null;
71                break;
72             }
73          }
74       }
75
76       // reindexing
77
Constant[] newcs = new Constant[css.length];
78       try {
79          for (int i=0; i<css.length; i++) {
80             Constant c = css[i];
81             if (c != null) {
82                Constant cc = (Constant)c.clone();
83                reindexConstants(cc, css, cs);
84                newcs[i] = cc;
85             }
86          }
87       } catch (CloneNotSupportedException JavaDoc ex) {
88          ex.printStackTrace();
89       }
90       ConstantPoolGen cpg = new ConstantPoolGen(newcs);
91
92 // ConstantPoolGen cpg = new ConstantPoolGen();
93
// for (int i=0; i<css.length; i++) {
94
// Constant c = css[i];
95
// if (c != null) {
96
// reshapeConstantPoolAddConstant(cpg, c, cs);
97
// }
98
// }
99
return cpg;
100    }
101
102    private static CPComparator cpcomparator = new CPComparator();
103    private static class CPComparator implements Comparator JavaDoc {
104       public int compare(Object JavaDoc o1, Object JavaDoc o2) {
105          Constant c1 = (Constant)o1;
106          Constant c2 = (Constant)o2;
107          int r = 0;
108
109          if (o1 == null) {
110             return 1;
111          }
112          if (o2 == null) {
113             return -1;
114          }
115          byte t1 = c1.getTag();
116          byte t2 = c2.getTag();
117          if (t1 != t2) {
118             r = getSortWeightOfConstantPoolTag(t1)
119               - getSortWeightOfConstantPoolTag(t2);
120          } else {
121             switch (t1) {
122             case Constants.CONSTANT_Utf8: {
123                ConstantUtf8 u1 = (ConstantUtf8)c1;
124                ConstantUtf8 u2 = (ConstantUtf8)c2;
125                r = u1.getBytes().compareTo(u2.getBytes());
126             } break;
127             case Constants.CONSTANT_String: {
128                ConstantString s1 = (ConstantString)c1;
129                ConstantString s2 = (ConstantString)c2;
130                r = s1.getStringIndex() - s2.getStringIndex();
131             } break;
132             case Constants.CONSTANT_NameAndType: {
133                ConstantNameAndType n1 = (ConstantNameAndType)c1;
134                ConstantNameAndType n2 = (ConstantNameAndType)c2;
135                r = n1.getNameIndex() - n2.getNameIndex();
136                if (r == 0) {
137                   r = n1.getSignatureIndex() - n2.getSignatureIndex();
138                }
139             } break;
140             case Constants.CONSTANT_Class: {
141                ConstantClass s1 = (ConstantClass)c1;
142                ConstantClass s2 = (ConstantClass)c2;
143                r = s1.getNameIndex() - s2.getNameIndex();
144             } break;
145             case Constants.CONSTANT_Fieldref: {
146                ConstantFieldref f1 = (ConstantFieldref)c1;
147                ConstantFieldref f2 = (ConstantFieldref)c2;
148                r = f1.getClassIndex() - f2.getClassIndex();
149                if (r == 0) {
150                   r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex();
151                }
152             } break;
153             case Constants.CONSTANT_Methodref: {
154                ConstantMethodref f1 = (ConstantMethodref)c1;
155                ConstantMethodref f2 = (ConstantMethodref)c2;
156                r = f1.getClassIndex() - f2.getClassIndex();
157                if (r == 0) {
158                   r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex();
159                }
160             } break;
161             case Constants.CONSTANT_InterfaceMethodref: {
162                ConstantInterfaceMethodref f1 = (ConstantInterfaceMethodref)c1;
163                ConstantInterfaceMethodref f2 = (ConstantInterfaceMethodref)c2;
164                r = f1.getClassIndex() - f2.getClassIndex();
165                if (r == 0) {
166                   r = f1.getNameAndTypeIndex() - f2.getNameAndTypeIndex();
167                }
168             } break;
169             case Constants.CONSTANT_Integer: {
170                ConstantInteger n1 = (ConstantInteger)c1;
171                ConstantInteger n2 = (ConstantInteger)c2;
172                r = n1.getBytes() - n2.getBytes();
173             } break;
174             case Constants.CONSTANT_Float: {
175                ConstantFloat n1 = (ConstantFloat)c1;
176                ConstantFloat n2 = (ConstantFloat)c2;
177                float nn1 = n1.getBytes();
178                float nn2 = n2.getBytes();
179                if (nn1 < nn2) { r = -1;
180                } else if (nn1 > nn2) { r = 1;
181                } else { r = 0;
182                }
183             } break;
184             case Constants.CONSTANT_Long: {
185                ConstantLong n1 = (ConstantLong)c1;
186                ConstantLong n2 = (ConstantLong)c2;
187                long nn1 = n1.getBytes();
188                long nn2 = n2.getBytes();
189                if (nn1 < nn2) { r = -1;
190                } else if (nn1 > nn2) { r = 1;
191                } else { r = 0;
192                }
193             } break;
194             case Constants.CONSTANT_Double: {
195                ConstantDouble n1 = (ConstantDouble)c1;
196                ConstantDouble n2 = (ConstantDouble)c2;
197                double nn1 = n1.getBytes();
198                double nn2 = n2.getBytes();
199                if (nn1 < nn2) { r = -1;
200                } else if (nn1 > nn2) { r = 1;
201                } else { r = 0;
202                }
203             } break;
204             default: // Never reached
205
throw new RuntimeException JavaDoc("Unknown constant tag : " + t1);
206             }
207          }
208          return r;
209       }
210       public boolean equals(Object JavaDoc obj) {
211          return false;
212       }
213    }
214
215    private static int getSortWeightOfConstantPoolTag(int tag) {
216       int r = 0;
217       switch (tag) {
218       case Constants.CONSTANT_String: r = 1; break;
219       case Constants.CONSTANT_NameAndType: r = 2; break;
220       case Constants.CONSTANT_Fieldref: r = 3; break;
221       case Constants.CONSTANT_Methodref: r = 4; break;
222       case Constants.CONSTANT_InterfaceMethodref: r = 5; break;
223       case Constants.CONSTANT_Class: r = 6; break;
224       case Constants.CONSTANT_Integer: r = 7; break;
225       case Constants.CONSTANT_Float: r = 8; break;
226       case Constants.CONSTANT_Long: r = 9; break;
227       case Constants.CONSTANT_Double: r = 10; break;
228       case Constants.CONSTANT_Utf8: r = 11; break;
229 // case Constants.CONSTANT_Utf8: r = 1; break;
230
// case Constants.CONSTANT_String: r = 2; break;
231
// case Constants.CONSTANT_Class: r = 3; break;
232
// case Constants.CONSTANT_NameAndType: r = 4; break;
233
// case Constants.CONSTANT_Fieldref: r = 5; break;
234
// case Constants.CONSTANT_Methodref: r = 6; break;
235
// case Constants.CONSTANT_InterfaceMethodref: r = 7; break;
236
// case Constants.CONSTANT_Integer: r = 8; break;
237
// case Constants.CONSTANT_Float: r = 9; break;
238
// case Constants.CONSTANT_Long: r = 10; break;
239
// case Constants.CONSTANT_Double: r = 11; break;
240
default: // Never reached
241
throw new RuntimeException JavaDoc("Unknown constant tag : " + tag);
242       }
243       return r;
244    }
245
246    private static int findIndex(Constant[] cs, Constant c) {
247       for (int i=0; i<cs.length; i++) {
248          if (cs[i] == c) {
249             return i;
250          }
251       }
252       return -1;
253    }
254
255    private static void reindexConstants(Constant c, Constant[] css, Constant[] constants) {
256       switch(c.getTag()) {
257       case Constants.CONSTANT_String: {
258          ConstantString s = (ConstantString)c;
259          ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
260          int idx = findIndex(css, u8);
261          s.setStringIndex(idx);
262       } break;
263       case Constants.CONSTANT_Class: {
264          ConstantClass s = (ConstantClass)c;
265          ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
266          int idx = findIndex(css, u8);
267          s.setNameIndex(idx);
268       } break;
269       case Constants.CONSTANT_NameAndType: {
270          ConstantNameAndType n = (ConstantNameAndType)c;
271          ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
272          ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
273          int idx = findIndex(css, u8);
274          int idx2 = findIndex(css, u8_2);
275          n.setNameIndex(idx);
276          n.setSignatureIndex(idx2);
277       } break;
278       case Constants.CONSTANT_Utf8:
279       case Constants.CONSTANT_Double:
280       case Constants.CONSTANT_Float:
281       case Constants.CONSTANT_Long:
282       case Constants.CONSTANT_Integer:
283          break;
284       case Constants.CONSTANT_InterfaceMethodref:
285       case Constants.CONSTANT_Methodref:
286       case Constants.CONSTANT_Fieldref: {
287          ConstantCP m = (ConstantCP)c;
288          ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
289          ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
290          int idx = findIndex(css, clazz);
291          int idx2 = findIndex(css, n);
292          m.setClassIndex(idx);
293          m.setNameAndTypeIndex(idx2);
294       } break;
295       default: // Never reached
296
throw new RuntimeException JavaDoc("Unknown constant type " + c);
297       }
298    }
299
300 // private static void reshapeConstantPoolAddConstant(ConstantPoolGen cpg, Constant c, Constant[] constants) {
301
// switch(c.getTag()) {
302
// case Constants.CONSTANT_String: {
303
// ConstantString s = (ConstantString)c;
304
// ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
305
// cpg.addString(u8.getBytes());
306
// } break;
307
// case Constants.CONSTANT_Class: {
308
// ConstantClass s = (ConstantClass)c;
309
// ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
310
// cpg.addClass(u8.getBytes());
311
// } break;
312
// case Constants.CONSTANT_NameAndType: {
313
// ConstantNameAndType n = (ConstantNameAndType)c;
314
// ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
315
// ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
316
// cpg.addNameAndType(u8.getBytes(), u8_2.getBytes());
317
// } break;
318
// case Constants.CONSTANT_Utf8:
319
// cpg.addUtf8(((ConstantUtf8)c).getBytes());
320
// break;
321
// case Constants.CONSTANT_Double:
322
// cpg.addDouble(((ConstantDouble)c).getBytes());
323
// break;
324
// case Constants.CONSTANT_Float:
325
// cpg.addFloat(((ConstantFloat)c).getBytes());
326
// break;
327
// case Constants.CONSTANT_Long:
328
// cpg.addLong(((ConstantLong)c).getBytes());
329
// break;
330
// case Constants.CONSTANT_Integer:
331
// cpg.addInteger(((ConstantInteger)c).getBytes());
332
// break;
333
// case Constants.CONSTANT_InterfaceMethodref:
334
// case Constants.CONSTANT_Methodref:
335
// case Constants.CONSTANT_Fieldref: {
336
// ConstantCP m = (ConstantCP)c;
337
// ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
338
// ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
339
// ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
340
// String class_name = u8.getBytes().replace('/', '.');
341
//
342
// u8 = (ConstantUtf8)constants[n.getNameIndex()];
343
// String name = u8.getBytes();
344
//
345
// u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
346
// String signature = u8.getBytes();
347
//
348
// switch(c.getTag()) {
349
// case Constants.CONSTANT_InterfaceMethodref:
350
// cpg.addInterfaceMethodref(class_name, name, signature);
351
// break;
352
// case Constants.CONSTANT_Methodref:
353
// cpg.addMethodref(class_name, name, signature);
354
// break;
355
// case Constants.CONSTANT_Fieldref:
356
// cpg.addFieldref(class_name, name, signature);
357
// break;
358
// default: // Never reached
359
// throw new RuntimeException("Unknown constant type " + c);
360
// }
361
// } break;
362
// default: // Never reached
363
// throw new RuntimeException("Unknown constant type " + c);
364
// }
365
// }
366
}
367
Popular Tags