home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 1999 March / maximum-cd-1999-03.iso / Feature / Lotus / ORGANIZE / COMPNENT / LTOUIN21.ZIP / sunw / demo / classfile / DelegatorClassFile.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-03-12  |  7.0 KB  |  261 lines

  1. package sunw.demo.classfile;
  2.  
  3. import java.beans.BeanInfo;
  4. import java.beans.IntrospectionException;
  5. import java.beans.Introspector;
  6. import java.beans.MethodDescriptor;
  7. import java.io.IOException;
  8. import java.io.OutputStream;
  9. import java.lang.reflect.Method;
  10. import java.util.Hashtable;
  11.  
  12. public final class DelegatorClassFile {
  13.    private Class[] targets;
  14.    private FieldConstant[] fields;
  15.    private static String superclassName;
  16.    private String className;
  17.    private ClassFile classFile;
  18.    private Hashtable generatedMethods = new Hashtable();
  19.    private char[] buff = new char[200];
  20.    // $FF: renamed from: ix int
  21.    private int field_0;
  22.  
  23.    public DelegatorClassFile(String var1, Class[] var2) throws IOException, ClassNotFoundException {
  24.       this.className = var1;
  25.       this.targets = var2;
  26.       superclassName = this.targets[0].getName();
  27.       this.classFile = new ClassFile(var1, this.targets[0].getName());
  28.       this.allocateFields();
  29.       this.recordInheritedMethods();
  30.       this.generateDelegatedMethods();
  31.       this.generateConstructor();
  32.    }
  33.  
  34.    private void allocateFields() {
  35.       this.fields = new FieldConstant[this.targets.length];
  36.  
  37.       for(int var1 = 1; var1 < this.targets.length; ++var1) {
  38.          String var2 = "t" + var1;
  39.          String var3 = this.getInternalTypeString(this.targets[var1]);
  40.          this.classFile.addFieldDesc(new FieldDesc(var2, var3, (short)2, this.classFile, (Attribute[])null));
  41.          FieldConstant var4 = this.classFile.addFieldConstant(this.className, var2, var3);
  42.          this.fields[var1] = var4;
  43.       }
  44.  
  45.    }
  46.  
  47.    private void generateConstructor() {
  48.       Code var1 = new Code(this.classFile, (short)(this.targets.length + 2), (short)(this.targets.length + 4));
  49.       String var2 = "(";
  50.  
  51.       for(int var3 = 1; var3 < this.targets.length; ++var3) {
  52.          var2 = var2 + this.getInternalTypeString(this.targets[var3]);
  53.       }
  54.  
  55.       var2 = var2 + ")V";
  56.       var1.addOp((byte)42);
  57.       MethodConstant var4 = this.classFile.addMethodConstant(ClassFile.fullyQualifiedForm(superclassName), "<init>", "()V");
  58.       var1.addOpShort((byte)-73, ((ConstantPoolEntry)var4).getConstantPoolIndex());
  59.  
  60.       for(int var5 = 1; var5 < this.fields.length; ++var5) {
  61.          var1.addOp((byte)42);
  62.          this.pushArg(var1, this.targets[var5], var5);
  63.          var1.addOpShort((byte)-75, this.fields[var5].getConstantPoolIndex());
  64.       }
  65.  
  66.       var1.addOp((byte)-79);
  67.       this.classFile.addMethodDesc(new MethodDesc("<init>", var2, (short)1, this.classFile, var1));
  68.    }
  69.  
  70.    private void generateDelegateMethod(FieldConstant var1, Method var2) {
  71.       Class[] var3 = var2.getParameterTypes();
  72.       String var4 = this.getMethodTypeString(var2);
  73.       String var5 = var2.getName() + var4;
  74.       if (this.generatedMethods.get(var5) == null) {
  75.          this.generatedMethods.put(var5, var5);
  76.          Code var6 = new Code(this.classFile, (short)(var3.length + 2), (short)(2 + 2 * var3.length));
  77.          var6.addOp((byte)42);
  78.          var6.addOpShort((byte)-76, ((ConstantPoolEntry)var1).getConstantPoolIndex());
  79.  
  80.          for(int var7 = 0; var7 < var3.length; ++var7) {
  81.             this.pushArg(var6, var3[var7], var7 + 1);
  82.          }
  83.  
  84.          MethodConstant var8 = this.classFile.addMethodConstant(var2.getDeclaringClass().getName().replace('.', '/'), var2.getName(), var4);
  85.          var6.addOpShort((byte)-74, ((ConstantPoolEntry)var8).getConstantPoolIndex());
  86.          this.generateReturn(var6, var2.getReturnType());
  87.          MethodDesc var9 = new MethodDesc(var2.getName(), var4, (short)1, this.classFile, var6);
  88.          this.classFile.addMethodDesc(var9);
  89.       }
  90.    }
  91.  
  92.    private void generateDelegatedMethods() {
  93.       for(int var1 = 0; var1 < this.targets.length; ++var1) {
  94.          Class var2 = this.targets[var1];
  95.  
  96.          BeanInfo var3;
  97.          try {
  98.             var3 = Introspector.getBeanInfo(var2);
  99.          } catch (IntrospectionException var8) {
  100.             System.err.println("Introspection failed on " + var2);
  101.             return;
  102.          }
  103.  
  104.          MethodDescriptor[] var4 = var3.getMethodDescriptors();
  105.  
  106.          for(int var5 = 0; var5 < var4.length; ++var5) {
  107.             MethodDescriptor var6 = var4[var5];
  108.             Method var7 = var6.getMethod();
  109.             this.generateDelegateMethod(this.fields[var1], var7);
  110.          }
  111.       }
  112.  
  113.    }
  114.  
  115.    void generateReturn(Code var1, Class var2) {
  116.       byte var3;
  117.       if (var2.isPrimitive()) {
  118.          if (var2 == Void.TYPE) {
  119.             var3 = -79;
  120.          } else if (var2 == Long.TYPE) {
  121.             var3 = -83;
  122.          } else if (var2 == Float.TYPE) {
  123.             var3 = -82;
  124.          } else if (var2 == Double.TYPE) {
  125.             var3 = -81;
  126.          } else {
  127.             var3 = -84;
  128.          }
  129.       } else {
  130.          var3 = -80;
  131.       }
  132.  
  133.       var1.addOp(var3);
  134.    }
  135.  
  136.    private String getInternalTypeString(Class var1) {
  137.       this.field_0 = 0;
  138.       this.push(var1);
  139.       return new String(this.buff, 0, this.field_0);
  140.    }
  141.  
  142.    private String getMethodTypeString(Method var1) {
  143.       this.field_0 = 0;
  144.  
  145.       try {
  146.          this.buff[this.field_0++] = '(';
  147.          Class[] var3 = var1.getParameterTypes();
  148.  
  149.          for(int var4 = 0; var4 < var3.length; ++var4) {
  150.             this.push(var3[var4]);
  151.          }
  152.  
  153.          this.buff[this.field_0++] = ')';
  154.          this.push(var1.getReturnType());
  155.          return new String(this.buff, 0, this.field_0);
  156.       } catch (ArrayIndexOutOfBoundsException var5) {
  157.          if (this.field_0 >= this.buff.length) {
  158.             this.buff = new char[2 * this.buff.length];
  159.             return this.getMethodTypeString(var1);
  160.          } else {
  161.             throw var5;
  162.          }
  163.       }
  164.    }
  165.  
  166.    private void push(Class var1) {
  167.       while(var1.isArray()) {
  168.          var1 = var1.getComponentType();
  169.          this.buff[this.field_0++] = '[';
  170.       }
  171.  
  172.       if (var1.isPrimitive()) {
  173.          if (var1 == Void.TYPE) {
  174.             this.buff[this.field_0++] = 'V';
  175.          } else if (var1 == Integer.TYPE) {
  176.             this.buff[this.field_0++] = 'I';
  177.          } else if (var1 == Boolean.TYPE) {
  178.             this.buff[this.field_0++] = 'Z';
  179.          } else if (var1 == Long.TYPE) {
  180.             this.buff[this.field_0++] = 'J';
  181.          } else if (var1 == Float.TYPE) {
  182.             this.buff[this.field_0++] = 'F';
  183.          } else if (var1 == Double.TYPE) {
  184.             this.buff[this.field_0++] = 'D';
  185.          } else if (var1 == Character.TYPE) {
  186.             this.buff[this.field_0++] = 'C';
  187.          } else if (var1 == Byte.TYPE) {
  188.             this.buff[this.field_0++] = 'B';
  189.          } else {
  190.             if (var1 != Short.TYPE) {
  191.                throw new Error("Unexpected primitive type " + var1.getName());
  192.             }
  193.  
  194.             this.buff[this.field_0++] = 'S';
  195.          }
  196.       } else {
  197.          this.buff[this.field_0++] = 'L';
  198.          String var2 = var1.getName();
  199.          int var3 = var2.length();
  200.  
  201.          for(int var4 = 0; var4 < var3; ++var4) {
  202.             char var5 = var2.charAt(var4);
  203.             if (var5 == '.') {
  204.                var5 = '/';
  205.             }
  206.  
  207.             this.buff[this.field_0++] = var5;
  208.          }
  209.  
  210.          this.buff[this.field_0++] = ';';
  211.       }
  212.  
  213.    }
  214.  
  215.    void pushArg(Code var1, Class var2, int var3) {
  216.       byte var4;
  217.       byte var5;
  218.       if (var2.isPrimitive()) {
  219.          if (var2 == Long.TYPE) {
  220.             var4 = 22;
  221.             var5 = 30;
  222.          } else if (var2 == Float.TYPE) {
  223.             var4 = 23;
  224.             var5 = 34;
  225.          } else if (var2 == Double.TYPE) {
  226.             var4 = 24;
  227.             var5 = 38;
  228.          } else {
  229.             var4 = 21;
  230.             var5 = 26;
  231.          }
  232.       } else {
  233.          var4 = 25;
  234.          var5 = 42;
  235.       }
  236.  
  237.       if (var3 < 4) {
  238.          var1.addOp((byte)(var5 + var3));
  239.       } else {
  240.          var1.addOp1(var4, (byte)var3);
  241.       }
  242.  
  243.    }
  244.  
  245.    private void recordInheritedMethods() {
  246.       Method[] var1 = this.targets[0].getMethods();
  247.  
  248.       for(int var2 = 0; var2 < var1.length; ++var2) {
  249.          Method var3 = var1[var2];
  250.          String var4 = this.getMethodTypeString(var3);
  251.          String var5 = var3.getName() + var4;
  252.          this.generatedMethods.put(var5, var5);
  253.       }
  254.  
  255.    }
  256.  
  257.    public void write(OutputStream var1) throws IOException {
  258.       this.classFile.write(var1);
  259.    }
  260. }
  261.