KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > LibraryClass


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 library 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 library 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 Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.classfile;
22
23 import proguard.classfile.util.*;
24 import proguard.classfile.visitor.*;
25 import proguard.classfile.attribute.visitor.AttributeVisitor;
26 import proguard.classfile.constant.*;
27 import proguard.classfile.constant.visitor.ConstantVisitor;
28
29 /**
30  * This Clazz is a compact representation of the essential data in a Java class.
31  *
32  * @author Eric Lafortune
33  */

34 public class LibraryClass implements Clazz
35 {
36     public int u2accessFlags;
37     public String JavaDoc thisClassName;
38     public String JavaDoc superClassName;
39     public String JavaDoc[] interfaceNames;
40     public LibraryField[] fields;
41     public LibraryMethod[] methods;
42
43     /**
44      * An extra field pointing to the superclass of this class.
45      * This field is filled out by the {@link ClassSuperHierarchyInitializer}.
46      */

47     public Clazz superClass;
48
49     /**
50      * An extra field pointing to the interfaces of this class.
51      * This field is filled out by the {@link ClassSuperHierarchyInitializer}.
52      */

53     public Clazz[] interfaceClasses;
54
55     /**
56      * An extra field pointing to the subclasses of this class.
57      * This field is filled out by the {@link ClassSubHierarchyInitializer}.
58      */

59     public Clazz[] subClasses;
60
61     /**
62      * An extra field in which visitors can store information.
63      */

64     public Object JavaDoc visitorInfo;
65
66
67     /**
68      * Creates an empty LibraryClass.
69      */

70     public LibraryClass() {}
71
72
73     /**
74      * Returns whether this library class is visible to the outside world.
75      */

76     boolean isVisible()
77     {
78         return (u2accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0;
79     }
80
81
82     /**
83      * Returns the class name of the ClassConstant at the specified index in the
84      * given constant pool.
85      */

86     private String JavaDoc toName(Constant[] constantPool, int constantIndex)
87     {
88         ClassConstant classEntry = (ClassConstant)constantPool[constantIndex];
89         Utf8Constant nameEntry = (Utf8Constant)constantPool[classEntry.u2nameIndex];
90
91         return nameEntry.getString();
92     }
93
94
95     // Implementations for Clazz.
96

97     public int getAccessFlags()
98     {
99         return u2accessFlags;
100     }
101
102     public String JavaDoc getName()
103     {
104         return thisClassName;
105     }
106
107     public String JavaDoc getSuperName()
108     {
109         // This may be java/lang/Object, in which case there is no super.
110
return superClassName;
111     }
112
113     public int getInterfaceCount()
114     {
115         return interfaceClasses.length;
116     }
117
118     public String JavaDoc getInterfaceName(int index)
119     {
120         return interfaceNames[index];
121     }
122
123     public int getTag(int constantIndex)
124     {
125         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
126     }
127
128     public String JavaDoc getString(int constantIndex)
129     {
130         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
131     }
132
133     public String JavaDoc getStringString(int constantIndex)
134     {
135         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
136     }
137
138     public String JavaDoc getClassName(int constantIndex)
139     {
140         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
141     }
142
143     public String JavaDoc getName(int constantIndex)
144     {
145         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
146     }
147
148     public String JavaDoc getType(int constantIndex)
149     {
150         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store constant pool");
151     }
152
153
154     public void addSubClass(Clazz clazz)
155     {
156         if (subClasses == null)
157         {
158             subClasses = new Clazz[1];
159         }
160         else
161         {
162             // Copy the old elements into new larger array.
163
Clazz[] temp = new Clazz[subClasses.length+1];
164             System.arraycopy(subClasses, 0, temp, 0, subClasses.length);
165             subClasses = temp;
166         }
167
168         subClasses[subClasses.length-1] = clazz;
169     }
170
171
172     public Clazz getSuperClass()
173     {
174         return superClass;
175     }
176
177
178     public Clazz getInterface(int index)
179     {
180         return interfaceClasses[index];
181     }
182
183
184     public boolean extends_(Clazz clazz)
185     {
186         if (this.equals(clazz))
187         {
188             return true;
189         }
190
191         Clazz superClass = getSuperClass();
192         return superClass != null &&
193                superClass.extends_(clazz);
194     }
195
196
197     public boolean extendsOrImplements(Clazz clazz)
198     {
199         if (this.equals(clazz))
200         {
201             return true;
202         }
203
204         Clazz superClass = getSuperClass();
205         if (superClass != null &&
206             superClass.extendsOrImplements(clazz))
207         {
208             return true;
209         }
210
211         if (interfaceClasses != null)
212         {
213             for (int index = 0; index < interfaceClasses.length; index++)
214             {
215                 Clazz interfaceClass = interfaceClasses[index];
216                 if (interfaceClass != null &&
217                     interfaceClass.extendsOrImplements(clazz))
218                 {
219                     return true;
220                 }
221             }
222         }
223
224         return false;
225     }
226
227
228     public Field findField(String JavaDoc name, String JavaDoc descriptor)
229     {
230         for (int index = 0; index < fields.length; index++)
231         {
232             Field field = fields[index];
233             if (field != null &&
234                 (name == null || field.getName(this).equals(name)) &&
235                 (descriptor == null || field.getDescriptor(this).equals(descriptor)))
236             {
237                 return field;
238             }
239         }
240
241         return null;
242     }
243
244
245     public Method findMethod(String JavaDoc name, String JavaDoc descriptor)
246     {
247         for (int index = 0; index < methods.length; index++)
248         {
249             Method method = methods[index];
250             if (method != null &&
251                 (name == null || method.getName(this).equals(name)) &&
252                 (descriptor == null || method.getDescriptor(this).equals(descriptor)))
253             {
254                 return method;
255             }
256         }
257
258         return null;
259     }
260
261
262     public void accept(ClassVisitor classVisitor)
263     {
264         classVisitor.visitLibraryClass(this);
265     }
266
267
268     public void hierarchyAccept(boolean visitThisClass,
269                                 boolean visitSuperClass,
270                                 boolean visitInterfaces,
271                                 boolean visitSubclasses,
272                                 ClassVisitor classVisitor)
273     {
274         // First visit the current classfile.
275
if (visitThisClass)
276         {
277             accept(classVisitor);
278         }
279
280         // Then visit its superclass, recursively.
281
if (visitSuperClass)
282         {
283             if (superClass != null)
284             {
285                 superClass.hierarchyAccept(true,
286                                            true,
287                                            visitInterfaces,
288                                            false,
289                                            classVisitor);
290             }
291         }
292
293         // Then visit its interfaces, recursively.
294
if (visitInterfaces)
295         {
296             if (interfaceClasses != null)
297             {
298                 for (int index = 0; index < interfaceClasses.length; index++)
299                 {
300                     Clazz interfaceClass = interfaceClasses[index];
301                     if (interfaceClass != null)
302                     {
303                         interfaceClass.hierarchyAccept(true,
304                                                        true,
305                                                        true,
306                                                        false,
307                                                        classVisitor);
308                     }
309                 }
310             }
311         }
312
313         // Then visit its subclasses, recursively.
314
if (visitSubclasses)
315         {
316             if (subClasses != null)
317             {
318                 for (int index = 0; index < subClasses.length; index++)
319                 {
320                     subClasses[index].hierarchyAccept(true,
321                                                       false,
322                                                       false,
323                                                       true,
324                                                       classVisitor);
325                 }
326             }
327         }
328     }
329
330
331     public void constantPoolEntriesAccept(ConstantVisitor constantVisitor)
332     {
333         // This class doesn't keep references to its constant pool entries.
334
}
335
336
337     public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor)
338     {
339         // This class doesn't keep references to its constant pool entries.
340
}
341
342
343     public void fieldsAccept(MemberVisitor memberVisitor)
344     {
345         for (int index = 0; index < fields.length; index++)
346         {
347             Field field = fields[index];
348             if (field != null)
349             {
350                 field.accept(this, memberVisitor);
351             }
352         }
353     }
354
355
356     public void fieldAccept(String JavaDoc name, String JavaDoc descriptor, MemberVisitor memberVisitor)
357     {
358         Field field = findField(name, descriptor);
359         if (field != null)
360         {
361             field.accept(this, memberVisitor);
362         }
363     }
364
365
366     public void methodsAccept(MemberVisitor memberVisitor)
367     {
368         for (int index = 0; index < methods.length; index++)
369         {
370             Method method = methods[index];
371             if (method != null)
372             {
373                 method.accept(this, memberVisitor);
374             }
375         }
376     }
377
378
379     public void methodAccept(String JavaDoc name, String JavaDoc descriptor, MemberVisitor memberVisitor)
380     {
381         Method method = findMethod(name, descriptor);
382         if (method != null)
383         {
384             method.accept(this, memberVisitor);
385         }
386     }
387
388
389     public boolean mayHaveImplementations(Method method)
390     {
391         return
392            (u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
393            (method == null ||
394             ((method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
395                                          ClassConstants.INTERNAL_ACC_STATIC |
396                                          ClassConstants.INTERNAL_ACC_FINAL)) == 0 &&
397                                                                                   !method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)));
398     }
399
400
401     private boolean isSpecial(Method method)
402     {
403         return
404             (method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
405                                         ClassConstants.INTERNAL_ACC_STATIC)) != 0 ||
406                                                                                   method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);
407     }
408
409
410     public void methodImplementationsAccept(Method method,
411                                             boolean visitThisMethod,
412                                             MemberVisitor memberVisitor)
413     {
414         methodImplementationsAccept(method.getName(this),
415                                     method.getDescriptor(this),
416                                     method,
417                                     visitThisMethod,
418                                     true,
419                                     true,
420                                     true,
421                                     memberVisitor);
422     }
423
424
425     public void methodImplementationsAccept(String JavaDoc name,
426                                             String JavaDoc descriptor,
427                                             boolean visitThisMethod,
428                                             MemberVisitor memberVisitor)
429     {
430         methodImplementationsAccept(name,
431                                     descriptor,
432                                     visitThisMethod,
433                                     true,
434                                     true,
435                                     true,
436                                     memberVisitor);
437     }
438
439
440     public void methodImplementationsAccept(String JavaDoc name,
441                                             String JavaDoc descriptor,
442                                             boolean visitThisMethod,
443                                             boolean visitSpecialMethods,
444                                             boolean visitSuperMethods,
445                                             boolean visitOverridingMethods,
446                                             MemberVisitor memberVisitor)
447     {
448         methodImplementationsAccept(name,
449                                     descriptor,
450                                     findMethod(name, descriptor),
451                                     visitThisMethod,
452                                     visitSpecialMethods,
453                                     visitSuperMethods,
454                                     visitOverridingMethods,
455                                     memberVisitor);
456     }
457
458
459     public void methodImplementationsAccept(String JavaDoc name,
460                                             String JavaDoc descriptor,
461                                             Method method,
462                                             boolean visitThisMethod,
463                                             boolean visitSpecialMethods,
464                                             boolean visitSuperMethods,
465                                             boolean visitOverridingMethods,
466                                             MemberVisitor memberVisitor)
467     {
468         // Do we have the method in this class?
469
if (method != null)
470         {
471             // Is it a special method?
472
if (isSpecial(method))
473             {
474                 // Visit the special method in this class, if allowed.
475
if (visitSpecialMethods)
476                 {
477                     method.accept(this, memberVisitor);
478
479                     // The method can't have any other implementations.
480
return;
481                 }
482             }
483             else
484             {
485                 // Visit the method in this class, if allowed.
486
if (visitThisMethod)
487                 {
488                     method.accept(this, memberVisitor);
489                 }
490
491                 // We don't have to look in subclasses if there can't be
492
// any overriding implementations.
493
if (!mayHaveImplementations(method))
494                 {
495                     visitOverridingMethods = false;
496                 }
497
498                 // We don't have to look in superclasses if we have a concrete
499
// implementation here.
500
if ((method.getAccessFlags() & ClassConstants.INTERNAL_ACC_ABSTRACT) == 0)
501                 {
502                     visitSuperMethods = false;
503                 }
504             }
505         }
506
507         // Then visit the method in its subclasses, recursively.
508
if (visitOverridingMethods)
509         {
510             // Go looking for implementations in all of the subclasses.
511
if (subClasses != null)
512             {
513                 for (int index = 0; index < subClasses.length; index++)
514                 {
515                     Clazz subClass = subClasses[index];
516                     subClass.methodImplementationsAccept(name,
517                                                          descriptor,
518                                                          true,
519                                                          false,
520                                                          visitSuperMethods,
521                                                          true,
522                                                          memberVisitor);
523                 }
524             }
525
526             // We don't have to look in superclasses right away if we dont't
527
// have a concrete class here.
528
if ((u2accessFlags & (ClassConstants.INTERNAL_ACC_INTERFACE |
529                                   ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
530             {
531                 visitSuperMethods = false;
532             }
533         }
534
535         // Then visit the method in its superclass, recursively.
536
if (visitSuperMethods)
537         {
538             Clazz superClass = getSuperClass();
539             if (superClass != null)
540             {
541                 superClass.methodImplementationsAccept(name,
542                                                        descriptor,
543                                                        true,
544                                                        false,
545                                                        true,
546                                                        false,
547                                                        memberVisitor);
548             }
549         }
550     }
551
552
553     public void attributesAccept(AttributeVisitor attributeVisitor)
554     {
555         throw new UnsupportedOperationException JavaDoc("Library class ["+thisClassName+"] doesn't store attributes");
556     }
557
558
559     // Implementations for VisitorAccepter.
560

561     public Object JavaDoc getVisitorInfo()
562     {
563         return visitorInfo;
564     }
565
566     public void setVisitorInfo(Object JavaDoc visitorInfo)
567     {
568         this.visitorInfo = visitorInfo;
569     }
570 }
571
Popular Tags