home *** CD-ROM | disk | FTP | other *** search
- package sunw.demo.classfile;
-
- import java.beans.BeanInfo;
- import java.beans.IntrospectionException;
- import java.beans.Introspector;
- import java.beans.MethodDescriptor;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.lang.reflect.Method;
- import java.util.Hashtable;
-
- public final class DelegatorClassFile {
- private Class[] targets;
- private FieldConstant[] fields;
- private static String superclassName;
- private String className;
- private ClassFile classFile;
- private Hashtable generatedMethods = new Hashtable();
- private char[] buff = new char[200];
- // $FF: renamed from: ix int
- private int field_0;
-
- public DelegatorClassFile(String var1, Class[] var2) throws IOException, ClassNotFoundException {
- this.className = var1;
- this.targets = var2;
- superclassName = this.targets[0].getName();
- this.classFile = new ClassFile(var1, this.targets[0].getName());
- this.allocateFields();
- this.recordInheritedMethods();
- this.generateDelegatedMethods();
- this.generateConstructor();
- }
-
- private void allocateFields() {
- this.fields = new FieldConstant[this.targets.length];
-
- for(int var1 = 1; var1 < this.targets.length; ++var1) {
- String var2 = "t" + var1;
- String var3 = this.getInternalTypeString(this.targets[var1]);
- this.classFile.addFieldDesc(new FieldDesc(var2, var3, (short)2, this.classFile, (Attribute[])null));
- FieldConstant var4 = this.classFile.addFieldConstant(this.className, var2, var3);
- this.fields[var1] = var4;
- }
-
- }
-
- private void generateConstructor() {
- Code var1 = new Code(this.classFile, (short)(this.targets.length + 2), (short)(this.targets.length + 4));
- String var2 = "(";
-
- for(int var3 = 1; var3 < this.targets.length; ++var3) {
- var2 = var2 + this.getInternalTypeString(this.targets[var3]);
- }
-
- var2 = var2 + ")V";
- var1.addOp((byte)42);
- MethodConstant var4 = this.classFile.addMethodConstant(ClassFile.fullyQualifiedForm(superclassName), "<init>", "()V");
- var1.addOpShort((byte)-73, ((ConstantPoolEntry)var4).getConstantPoolIndex());
-
- for(int var5 = 1; var5 < this.fields.length; ++var5) {
- var1.addOp((byte)42);
- this.pushArg(var1, this.targets[var5], var5);
- var1.addOpShort((byte)-75, this.fields[var5].getConstantPoolIndex());
- }
-
- var1.addOp((byte)-79);
- this.classFile.addMethodDesc(new MethodDesc("<init>", var2, (short)1, this.classFile, var1));
- }
-
- private void generateDelegateMethod(FieldConstant var1, Method var2) {
- Class[] var3 = var2.getParameterTypes();
- String var4 = this.getMethodTypeString(var2);
- String var5 = var2.getName() + var4;
- if (this.generatedMethods.get(var5) == null) {
- this.generatedMethods.put(var5, var5);
- Code var6 = new Code(this.classFile, (short)(var3.length + 2), (short)(2 + 2 * var3.length));
- var6.addOp((byte)42);
- var6.addOpShort((byte)-76, ((ConstantPoolEntry)var1).getConstantPoolIndex());
-
- for(int var7 = 0; var7 < var3.length; ++var7) {
- this.pushArg(var6, var3[var7], var7 + 1);
- }
-
- MethodConstant var8 = this.classFile.addMethodConstant(var2.getDeclaringClass().getName().replace('.', '/'), var2.getName(), var4);
- var6.addOpShort((byte)-74, ((ConstantPoolEntry)var8).getConstantPoolIndex());
- this.generateReturn(var6, var2.getReturnType());
- MethodDesc var9 = new MethodDesc(var2.getName(), var4, (short)1, this.classFile, var6);
- this.classFile.addMethodDesc(var9);
- }
- }
-
- private void generateDelegatedMethods() {
- for(int var1 = 0; var1 < this.targets.length; ++var1) {
- Class var2 = this.targets[var1];
-
- BeanInfo var3;
- try {
- var3 = Introspector.getBeanInfo(var2);
- } catch (IntrospectionException var8) {
- System.err.println("Introspection failed on " + var2);
- return;
- }
-
- MethodDescriptor[] var4 = var3.getMethodDescriptors();
-
- for(int var5 = 0; var5 < var4.length; ++var5) {
- MethodDescriptor var6 = var4[var5];
- Method var7 = var6.getMethod();
- this.generateDelegateMethod(this.fields[var1], var7);
- }
- }
-
- }
-
- void generateReturn(Code var1, Class var2) {
- byte var3;
- if (var2.isPrimitive()) {
- if (var2 == Void.TYPE) {
- var3 = -79;
- } else if (var2 == Long.TYPE) {
- var3 = -83;
- } else if (var2 == Float.TYPE) {
- var3 = -82;
- } else if (var2 == Double.TYPE) {
- var3 = -81;
- } else {
- var3 = -84;
- }
- } else {
- var3 = -80;
- }
-
- var1.addOp(var3);
- }
-
- private String getInternalTypeString(Class var1) {
- this.field_0 = 0;
- this.push(var1);
- return new String(this.buff, 0, this.field_0);
- }
-
- private String getMethodTypeString(Method var1) {
- this.field_0 = 0;
-
- try {
- this.buff[this.field_0++] = '(';
- Class[] var3 = var1.getParameterTypes();
-
- for(int var4 = 0; var4 < var3.length; ++var4) {
- this.push(var3[var4]);
- }
-
- this.buff[this.field_0++] = ')';
- this.push(var1.getReturnType());
- return new String(this.buff, 0, this.field_0);
- } catch (ArrayIndexOutOfBoundsException var5) {
- if (this.field_0 >= this.buff.length) {
- this.buff = new char[2 * this.buff.length];
- return this.getMethodTypeString(var1);
- } else {
- throw var5;
- }
- }
- }
-
- private void push(Class var1) {
- while(var1.isArray()) {
- var1 = var1.getComponentType();
- this.buff[this.field_0++] = '[';
- }
-
- if (var1.isPrimitive()) {
- if (var1 == Void.TYPE) {
- this.buff[this.field_0++] = 'V';
- } else if (var1 == Integer.TYPE) {
- this.buff[this.field_0++] = 'I';
- } else if (var1 == Boolean.TYPE) {
- this.buff[this.field_0++] = 'Z';
- } else if (var1 == Long.TYPE) {
- this.buff[this.field_0++] = 'J';
- } else if (var1 == Float.TYPE) {
- this.buff[this.field_0++] = 'F';
- } else if (var1 == Double.TYPE) {
- this.buff[this.field_0++] = 'D';
- } else if (var1 == Character.TYPE) {
- this.buff[this.field_0++] = 'C';
- } else if (var1 == Byte.TYPE) {
- this.buff[this.field_0++] = 'B';
- } else {
- if (var1 != Short.TYPE) {
- throw new Error("Unexpected primitive type " + var1.getName());
- }
-
- this.buff[this.field_0++] = 'S';
- }
- } else {
- this.buff[this.field_0++] = 'L';
- String var2 = var1.getName();
- int var3 = var2.length();
-
- for(int var4 = 0; var4 < var3; ++var4) {
- char var5 = var2.charAt(var4);
- if (var5 == '.') {
- var5 = '/';
- }
-
- this.buff[this.field_0++] = var5;
- }
-
- this.buff[this.field_0++] = ';';
- }
-
- }
-
- void pushArg(Code var1, Class var2, int var3) {
- byte var4;
- byte var5;
- if (var2.isPrimitive()) {
- if (var2 == Long.TYPE) {
- var4 = 22;
- var5 = 30;
- } else if (var2 == Float.TYPE) {
- var4 = 23;
- var5 = 34;
- } else if (var2 == Double.TYPE) {
- var4 = 24;
- var5 = 38;
- } else {
- var4 = 21;
- var5 = 26;
- }
- } else {
- var4 = 25;
- var5 = 42;
- }
-
- if (var3 < 4) {
- var1.addOp((byte)(var5 + var3));
- } else {
- var1.addOp1(var4, (byte)var3);
- }
-
- }
-
- private void recordInheritedMethods() {
- Method[] var1 = this.targets[0].getMethods();
-
- for(int var2 = 0; var2 < var1.length; ++var2) {
- Method var3 = var1[var2];
- String var4 = this.getMethodTypeString(var3);
- String var5 = var3.getName() + var4;
- this.generatedMethods.put(var5, var5);
- }
-
- }
-
- public void write(OutputStream var1) throws IOException {
- this.classFile.write(var1);
- }
- }
-