KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jarg > JavaClassReshaper


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 org.apache.bcel.classfile.*;
37 import org.apache.bcel.generic.*;
38 import org.apache.bcel.Constants;
39
40 /**
41  * The class for reshaping the java class.
42  *
43  * @version $Id: JavaClassReshaper.java,v 1.6 2002/05/01 05:21:58 hchacha Exp $
44  * @author Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;
45  */

46 class JavaClassReshaper {
47    private Jarg app;
48    private PackageHandler pkgh;
49
50    JavaClassReshaper(Jarg app, PackageHandler pkgh) {
51       this.app = app;
52       this.pkgh = pkgh;
53    }
54
55    JavaClass reshapeJavaClass(JavaClass jcls, String JavaDoc class_name, String JavaDoc super_class_name) {
56       String JavaDoc file_name = null;
57       int access_flags = jcls.getAccessFlags();
58       String JavaDoc[] interfaces = jcls.getInterfaceNames();
59       JavaClass jcls1;
60       JavaClass jcls2;
61
62       // phase 1
63
{
64          ConstantPoolGen cpg;
65          ClassGen cg;
66
67          cpg = new ConstantPoolGen();
68          cg = new ClassGen(class_name, super_class_name, file_name, access_flags, interfaces, cpg);
69          jcls1 = reshapeJavaClass0(jcls, cg);
70       }
71
72       // optimizing the byte-code
73
if (app.isByteCodeOptimizing) {
74          BytecodeOptimizer bcopt = new BytecodeOptimizer(this.app, this.pkgh);
75          jcls1 = bcopt.optimizeBytecodeOfJavaClass(jcls1);
76
77          ConstantPoolGen cpg = new ConstantPoolGen();
78          ClassGen cg = new ClassGen(class_name, super_class_name, file_name, access_flags, interfaces, cpg);
79          jcls1 = reshapeJavaClass0(jcls1, cg);
80       }
81
82       // phase 2
83
{
84          Constant[] cs = jcls1.getConstantPool().getConstantPool();
85          ConstantPoolGen cpg;
86          ClassGen cg;
87
88          cpg = ConstantPoolSorter.reshapeConstantPool(cs);
89          cpg = ConstantPoolSorter.reshapeConstantPool(cpg.getFinalConstantPool().getConstantPool());
90          cg = new ClassGen(class_name, super_class_name, file_name, access_flags, interfaces, cpg);
91          jcls2 = reshapeJavaClass0(jcls1, cg);
92       }
93
94       return jcls2;
95    }
96
97    private JavaClass reshapeJavaClass0(JavaClass jcls, ClassGen cg) {
98       String JavaDoc oldclsnm = jcls.getClassName();
99       String JavaDoc class_name = pkgh.convClassName(oldclsnm);
100
101       if (app.isVerboseAll) {
102          System.out.println("Reshaping " + class_name);
103       }
104
105       ConstantPoolGen cpg0 = new ConstantPoolGen(jcls.getConstantPool());
106       ConstantPoolGen cpg = cg.getConstantPool();
107
108       // dummy
109
{
110          // interfaces are registered, since the interface is not registered
111
// into a constant pool at this time.
112
int[] dmy = cg.getInterfaces();
113       }
114
115       // version
116
cg.setMajor(jcls.getMajor());
117       cg.setMinor(jcls.getMinor());
118
119       // fields
120
{
121          FieldReshaper fr = new FieldReshaper(app, pkgh);
122          Field[] fs = jcls.getFields();
123          for (int i=0; i < fs.length; i++) {
124             Field f = fs[i];
125             if (f != null) {
126                Field nf = fr.reshapeField(jcls, cpg0, cg, cpg, f);
127                cg.addField(nf);
128             }
129          }
130       }
131
132       // methods
133
{
134          MethodReshaper mr = new MethodReshaper(app, pkgh);
135          Method[] ms = jcls.getMethods();
136          for (int i=0; i < ms.length; i++) {
137             Method m = ms[i];
138             if (m != null) {
139                Method nm = mr.reshapeMethod(jcls, cpg0, cg, cpg, m);
140                cg.addMethod(nm);
141             }
142          }
143       }
144
145       // class attributes
146
reshapeClassAttributes(jcls, cg, cpg);
147
148       return cg.getJavaClass();
149    }
150
151    private void reshapeClassAttributes(JavaClass jcls, ClassGen cg, ConstantPoolGen cpg) {
152       // class attributes
153
Attribute[] ats = jcls.getAttributes();
154       ConstantPool cp0 = jcls.getConstantPool();
155
156       for (int i=0; i < ats.length; i++) {
157          Attribute at = ats[i];
158          if (at instanceof SourceFile) {
159             // source file attribute
160
if (!app.isRemoveSourceFile) {
161                reshapeClassAttributesSourceFile(jcls, cg, cpg);
162             }
163          } else if (at instanceof InnerClasses) {
164             // inner class attribute
165
if (!app.isRemoveInnerClasses) {
166                reshapeClassAttributesInnerClass(jcls, cg, cpg, (InnerClasses)at, cp0);
167             }
168          } else if (at instanceof Synthetic) {
169             // synthetic class attribute
170
if (!app.isRemoveSynthetic) {
171                reshapeClassAttributesSynthetic(jcls, cg, cpg, (Synthetic)at);
172             }
173          } else if (at instanceof Deprecated JavaDoc) {
174             // deprecated class attribute
175
reshapeClassAttributesDeprecated(jcls, cg, cpg, (Deprecated JavaDoc)at);
176          } else {
177             System.err.println("[ERR Class Attr]" + at);
178          }
179       }
180    }
181
182    private void reshapeClassAttributesSourceFile(JavaClass jcls, ClassGen cg, ConstantPoolGen cpg) {
183       // source file attribute
184
String JavaDoc srcnm = jcls.getSourceFileName();
185       if (srcnm != null) {
186          cg.addAttribute(new SourceFile(
187                cpg.addUtf8("SourceFile"), 2,
188                cpg.addUtf8(jcls.getSourceFileName()), cpg.getConstantPool()));
189       }
190    }
191
192    private void reshapeClassAttributesInnerClass(JavaClass jcls, ClassGen cg, ConstantPoolGen cpg, InnerClasses inn, ConstantPool cp0) {
193       // inner class attribute
194
InnerClass[] iclss = inn.getInnerClasses();
195
196       int i_name_index = cpg.addUtf8("InnerClasses");
197       int i_len = iclss.length;
198       InnerClass[] i_inner = new InnerClass[i_len];
199
200       for (int j=0; j < i_inner.length; j++) {
201          InnerClass icls = iclss[j];
202          Constant ct;
203          int inner_class_index = 0;
204          int outer_class_index = 0;
205          int inner_name_index = 0;
206
207          ct = cp0.getConstant(icls.getInnerClassIndex());
208          if (ct != null) {
209             ct = cp0.getConstant(((ConstantClass)ct).getNameIndex());
210             if (ct != null) {
211                String JavaDoc inner_cname = pkgh.convClassName(((ConstantUtf8)ct).getBytes());
212                inner_class_index = cpg.addClass(inner_cname);
213             }
214          }
215
216          ct = cp0.getConstant(icls.getOuterClassIndex());
217          if (ct != null) {
218             ct = cp0.getConstant(((ConstantClass)ct).getNameIndex());
219             if (ct != null) {
220                String JavaDoc outer_cname = pkgh.convClassName(((ConstantUtf8)ct).getBytes());
221                outer_class_index = cpg.addClass(outer_cname);
222             }
223          }
224
225          ct = cp0.getConstant(icls.getInnerNameIndex());
226          if (ct != null) {
227             String JavaDoc inner_name = pkgh.convClassName(((ConstantUtf8)ct).getBytes());
228             inner_name_index = cpg.addUtf8(inner_name);
229          }
230
231          int inner_access_flags = icls.getInnerAccessFlags();
232
233          i_inner[j] = new InnerClass(inner_class_index, outer_class_index, inner_name_index, inner_access_flags);
234       }
235       i_len = 2 + 8 * i_inner.length;
236       cg.addAttribute(new InnerClasses(i_name_index, i_len, i_inner, cpg.getConstantPool()));
237    }
238
239    private void reshapeClassAttributesSynthetic(JavaClass jcls, ClassGen cg, ConstantPoolGen cpg, Synthetic st) {
240       // synthetic class attribute
241
int s_name_index = cpg.addUtf8("Synthetic");
242       int s_len = st.getLength();
243       byte[] s_bytes = st.getBytes();
244       cg.addAttribute(new Synthetic(s_name_index, s_len, s_bytes, cpg.getConstantPool()));
245    }
246
247    private void reshapeClassAttributesDeprecated(JavaClass jcls, ClassGen cg, ConstantPoolGen cpg, Deprecated JavaDoc dp) {
248       // deprecated class attribute
249
int s_name_index = cpg.addUtf8("Deprecated");
250       int s_len = dp.getLength();
251       byte[] s_bytes = dp.getBytes();
252       cg.addAttribute(new Deprecated JavaDoc(s_name_index, s_len, s_bytes, cpg.getConstantPool()));
253    }
254 }
255
Popular Tags