KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > util > ClassSuperHierarchyInitializer


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.util;
22
23 import proguard.classfile.visitor.ClassVisitor;
24 import proguard.classfile.constant.visitor.ConstantVisitor;
25 import proguard.classfile.constant.ClassConstant;
26 import proguard.classfile.*;
27
28 /**
29  * This ClassVisitor initializes the superclass hierarchy of all classes that
30  * it visits.
31  * <p>
32  * Visited library classes get direct references to their superclasses and
33  * interfaces, replacing the superclass names and interface names. The direct
34  * references are equivalent to the names, but they are more efficient to work
35  * with.
36  * <p>
37  * This visitor optionally prints warnings if some items can't be found.
38  *
39  * @author Eric Lafortune
40  */

41 public class ClassSuperHierarchyInitializer
42 extends SimplifiedVisitor
43 implements ClassVisitor,
44              ConstantVisitor
45 {
46     private ClassPool programClassPool;
47     private ClassPool libraryClassPool;
48     private WarningPrinter warningPrinter;
49
50
51     /**
52      * Creates a new ClassSuperHierarchyInitializer that initializes the super
53      * hierarchy of all visited class files, optionally printing warnings if
54      * some classes can't be found.
55      */

56     public ClassSuperHierarchyInitializer(ClassPool programClassPool,
57                                           ClassPool libraryClassPool,
58                                           WarningPrinter warningPrinter)
59     {
60         this.programClassPool = programClassPool;
61         this.libraryClassPool = libraryClassPool;
62         this.warningPrinter = warningPrinter;
63     }
64
65
66     // Implementations for ClassVisitor.
67

68     public void visitProgramClass(ProgramClass programClass)
69     {
70         // Link to the super class.
71
if (programClass.u2superClass != 0)
72         {
73             programClass.constantPoolEntryAccept(programClass.u2superClass,
74                                                  this);
75         }
76
77         // Link to the interfaces.
78
for (int index = 0; index < programClass.u2interfacesCount; index++)
79         {
80             programClass.constantPoolEntryAccept(programClass.u2interfaces[index],
81                                                  this);
82         }
83     }
84
85
86     public void visitLibraryClass(LibraryClass libraryClass)
87     {
88         String JavaDoc className = libraryClass.getName();
89
90         // Link to the super class.
91
String JavaDoc superClassName = libraryClass.superClassName;
92         if (superClassName != null)
93         {
94             // Keep a reference to the superclass.
95
libraryClass.superClass = findClass(className, superClassName);
96         }
97
98         // Link to the interfaces.
99
if (libraryClass.interfaceNames != null)
100         {
101             String JavaDoc[] interfaceNames = libraryClass.interfaceNames;
102             Clazz[] interfaceClasses = new Clazz[interfaceNames.length];
103
104             for (int index = 0; index < interfaceNames.length; index++)
105             {
106                 // Keep a reference to the interface class.
107
interfaceClasses[index] =
108                     findClass(className, interfaceNames[index]);
109             }
110
111             libraryClass.interfaceClasses = interfaceClasses;
112         }
113
114         // Discard the name Strings. From now on, we'll use the object
115
// references.
116
libraryClass.superClassName = null;
117         libraryClass.interfaceNames = null;
118     }
119
120
121     // Implementations for ConstantVisitor.
122

123     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
124     {
125         classConstant.referencedClass =
126             findClass(clazz.getName(), classConstant.getName(clazz));
127     }
128
129
130     // Small utility methods.
131

132     /**
133      * Returns the class with the given name, either for the program class pool
134      * or from the library class pool, or <code>null</code> if it can't be found.
135      */

136     private Clazz findClass(String JavaDoc subClassName, String JavaDoc name)
137     {
138         // First look for the class in the program class pool.
139
Clazz clazz = programClassPool.getClass(name);
140
141         // Otherwise look for the class in the library class pool.
142
if (clazz == null)
143         {
144             clazz = libraryClassPool.getClass(name);
145         }
146
147         if (clazz == null &&
148             warningPrinter != null)
149         {
150             // We didn't find the superclass or interface. Print a warning.
151
warningPrinter.print("Warning: " +
152                                  ClassUtil.externalClassName(subClassName) +
153                                  ": can't find superclass or interface " +
154                                  ClassUtil.externalClassName(name));
155         }
156
157         return clazz;
158     }
159 }
160
Popular Tags