vinayc      02/05/14 14:37:21

  Modified:    altrmi/src/java/org/apache/excalibur/altrmi/generator
                        ProxyGeneratorImpl.java
  Added:       altrmi/src/java/org/apache/excalibur/altrmi/generator
                        BCELProxyGeneratorImpl.java
  Log:
  BCEL Proxy Generator added
  
  Revision  Changes    Path
  1.8       +8 -8      
jakarta-avalon-excalibur/altrmi/src/java/org/apache/excalibur/altrmi/generator/ProxyGeneratorImpl.java
  
  Index: ProxyGeneratorImpl.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/altrmi/src/java/org/apache/excalibur/altrmi/generator/ProxyGeneratorImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ProxyGeneratorImpl.java   24 Apr 2002 23:39:42 -0000      1.7
  +++ ProxyGeneratorImpl.java   14 May 2002 21:37:21 -0000      1.8
  @@ -26,19 +26,19 @@
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
    * @author Mike Miller of www.gac.com
    * @author <a href="mailto:[EMAIL PROTECTED]">Peter Royal</a>
  - * @version $Revision: 1.7 $
  + * @version $Revision: 1.8 $
    */
   public class ProxyGeneratorImpl extends AbstractMethodHandler implements 
ProxyGenerator
   {
   
  -    private Class[] mInterfacesToExpose;
  -    private Class[] mAdditionalFacades;
  +    protected Class[] mInterfacesToExpose;
  +    protected Class[] mAdditionalFacades;
       protected String mSrcGenDir;
       protected String mClassGenDir;
       protected String mClasspath;
  -    private String mGenName;
  -    private boolean mVerbose;
  -    private PrintWriter mClassSource;
  +    protected String mGenName;
  +    protected boolean mVerbose;
  +    protected PrintWriter mClassSource;
   
       /**
        * Method setInterfacesToExpose
  @@ -639,7 +639,7 @@
           }
       }
   
  -    private String getClassType( Class rClass )
  +    protected String getClassType( Class rClass )
       {
   
           String cn = rClass.getName();
  @@ -701,7 +701,7 @@
           }
       }
   
  -    private boolean isAdditionalFacade( Class clazz )
  +    protected boolean isAdditionalFacade( Class clazz )
       {
   
           if( mAdditionalFacades == null )
  
  
  
  1.1                  
jakarta-avalon-excalibur/altrmi/src/java/org/apache/excalibur/altrmi/generator/BCELProxyGeneratorImpl.java
  
  Index: BCELProxyGeneratorImpl.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.altrmi.generator;
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.lang.reflect.Method;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  
  import org.apache.bcel.Constants;
  import org.apache.bcel.generic.ArrayType;
  import org.apache.bcel.generic.BranchInstruction;
  import org.apache.bcel.generic.ClassGen;
  import org.apache.bcel.generic.ConstantPoolGen;
  import org.apache.bcel.generic.DLOAD;
  import org.apache.bcel.generic.FieldGen;
  import org.apache.bcel.generic.INSTANCEOF;
  import org.apache.bcel.generic.Instruction;
  import org.apache.bcel.generic.InstructionConstants;
  import org.apache.bcel.generic.InstructionFactory;
  import org.apache.bcel.generic.InstructionHandle;
  import org.apache.bcel.generic.InstructionList;
  import org.apache.bcel.generic.MethodGen;
  import org.apache.bcel.generic.ObjectType;
  import org.apache.bcel.generic.PUSH;
  import org.apache.bcel.generic.Type;
  import org.apache.excalibur.altrmi.common.ProxyGenerator;
  import sun.security.krb5.internal.i;
  import sun.security.krb5.internal.m;
  import sun.security.krb5.internal.x;
  import sun.security.krb5.internal.crypto.c;
  import sun.security.krb5.internal.crypto.e;
  
  /**
   * Class BCElProxyGeneratorImpl
   *    This class generates Altrmi stubs using Jakarta BCEL library.
   * 
   * @HOWTO: Use 'javap' to read the bytecodes of the stubs generated
   *    by using the original stub-generator(which generates pure java code).
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Vinay Chandran</a>
   * @version $Revision: 1.1 $
   */
  public class BCELProxyGeneratorImpl
        extends ProxyGeneratorImpl
        implements ProxyGenerator
  {
  
        //bcel 
        private static final String mStubPrefix = "AltrmiGenerated";
        private InstructionFactory mFactory;
        private ConstantPoolGen mConstantsPool;
        private ClassGen mClassGen;
        private ArrayList mInternalFieldRepresentingClasses;
        private int mArrayDepth_ = 0;
  
        /*
         * @see ProxyGenerator#generateClass(ClassLoader)
         */
        public void generateClass(ClassLoader cL)
        {
  
                //create the Main Stubs:
                generateAltrmiProxyClass(mStubPrefix + mGenName + "_Main", 
mInterfacesToExpose);
                generateAltrmiProxyClass2(
                        mStubPrefix + "2" + mGenName + "_Main",
                        mStubPrefix + mGenName + "_Main",
                        mInterfacesToExpose);
  
                //Create the Additional Facades 
                if (mAdditionalFacades != null)
                {
                        for (int i = 0; i < mAdditionalFacades.length; i++)
                        {
                                String encodedClassName = 
encodeClassName(mAdditionalFacades[i]);
                                generateAltrmiProxyClass(
                                        mStubPrefix + mGenName + "_" + 
encodedClassName,
                                        new Class[] { mAdditionalFacades[i] });
                                generateAltrmiProxyClass2(
                                        mStubPrefix + "2" + mGenName + "_" + 
encodedClassName,
                                        mStubPrefix + mGenName + "_" + 
encodedClassName,
                                        new Class[] { mAdditionalFacades[i] });
  
                        }
                }
  
        }
  
        /**
         * Method generateAltrmiProxyClass.
         *              Create AltrmiProxy Implementation with all interface 
methods 
         *      Generating AltrmiGeneratedGENNAME_Main class
         * @param className
         * @param interfacesToStubify
         */
        private void generateAltrmiProxyClass(
                String mGeneratedClassName,
                Class[] interfacesToStubify)
        {
                //Start creating class 
                createNewClassDeclaration(mGeneratedClassName);
                /******** CONSTRUCTOR **************/
                //create constructor that takes ProxyHelper
                createConstructor(mGeneratedClassName);
                /******** FIELDS *************/
                //create fields 
                createFields();
                /******** METHODS *************/
                //create fields 
                createAltrmiGetReferenceIDMethod(mGeneratedClassName);
                createHelperMethodForDotClassCalls(mGeneratedClassName);
                createInterfaceMethods(mGeneratedClassName, 
interfacesToStubify);
                //TODO://Finally finally fInally "DUMP" the  class file  that 
we deligently prepared somewhere
                FileOutputStream fos = null;
                try
                {
                        fos = new FileOutputStream(mClassGenDir + "/" + 
mGeneratedClassName + ".class");
                        mClassGen.getJavaClass().dump(fos);
                        fos.close();
                }
                catch (FileNotFoundException fnfe)
                {
                        fnfe.printStackTrace();
                }
                catch (IOException ioe)
                {
                        ioe.printStackTrace();
                }
        }
  
        /**
         * Method generateAltrmiProxyClass2.
         *      Create the Stub Class purely implementing the Interface  and
         *                      inheriting the implementation from the helper 
class
         *      Generating AltrmiGenerated2GENNAME_Main class
         * @param className
         */
        private void generateAltrmiProxyClass2(
                String mGeneratedClassName2,
                String mGeneratedClassName,
                Class[] interfacesToStubify)
        {
                //start creating the class
                createNewClassDeclaration2(
                        mGeneratedClassName2,
                        mGeneratedClassName,
                        interfacesToStubify);
                //create the constructor 
                createConstructor2(mGeneratedClassName2, mGeneratedClassName);
                try
                {
                        FileOutputStream fos =
                                new FileOutputStream(mClassGenDir + "/" + 
mGeneratedClassName2 + ".class");
                        mClassGen.getJavaClass().dump(fos);
                        fos.close();
                }
                catch (FileNotFoundException fnfe)
                {
                        fnfe.printStackTrace();
                }
                catch (IOException ioe)
                {
                        ioe.printStackTrace();
                }
  
        }
  
        //<BCEL>  <!-- Enter the BCEL Arena -->
  
        /**
         * Method createAndInitializeClass.
         *      This method starts creating the class.
         */
        private void createNewClassDeclaration(String mGeneratedClassName)
        {
  
                mClassGen =
                        new ClassGen(
                                mGeneratedClassName,
                                "java.lang.Object",
                                mGeneratedClassName + ".java",
                                Constants.ACC_PUBLIC | Constants.ACC_SUPER,
                                new String[] { 
"org.apache.excalibur.altrmi.client.AltrmiProxy" });
                mConstantsPool = mClassGen.getConstantPool();
                mFactory = new InstructionFactory(mClassGen, mConstantsPool);
                mInternalFieldRepresentingClasses = new ArrayList();
  
        }
        /**
         * Method createNewClassDeclaration2.
         *      Create a class which extends a class contained the impl of the 
Interface and 
         *                                      and  implements the interface
         */
        private void createNewClassDeclaration2(
                String mGeneratedClassName2,
                String mGeneratedClassName,
                Class[] interfacesToStubify)
        {
                String[] mInterafacesToImplement = new 
String[interfacesToStubify.length];
                for (int i = 0; i < mInterafacesToImplement.length; i++)
                        mInterafacesToImplement[i] = 
interfacesToStubify[i].getName();
                mClassGen =
                        new ClassGen(
                                mGeneratedClassName2,
                                mGeneratedClassName,
                                mGeneratedClassName2 + ".java",
                                Constants.ACC_PUBLIC | Constants.ACC_FINAL | 
Constants.ACC_SUPER,
                                mInterafacesToImplement);
                mConstantsPool = mClassGen.getConstantPool();
                mFactory = new InstructionFactory(mClassGen, mConstantsPool);
        }
        /**
         * Method createConstructor.
         *      This method adds a constructor that takes in a ProxyHelper 
Instance
         */
        private void createConstructor(String mGeneratedClassName)
        {
                InstructionList il = new InstructionList();
                MethodGen method =
                        new MethodGen(
                                Constants.ACC_PUBLIC,
                                Type.VOID,
                                new Type[] { new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper")},
                                new String[] { "arg0" },
                                "<init>",
                                mGeneratedClassName,
                                il,
                                mConstantsPool);
                InstructionHandle ih_0 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.Object",
                                "<init>",
                                Type.VOID,
                                Type.NO_ARGS,
                                Constants.INVOKESPECIAL));
                InstructionHandle ih_4 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(mFactory.createLoad(Type.OBJECT, 1));
                il.append(
                        mFactory.createFieldAccess(
                                mGeneratedClassName,
                                "mProxyHelper",
                                new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper"),
                                Constants.PUTFIELD));
                InstructionHandle ih_9 = 
il.append(mFactory.createReturn(Type.VOID));
                method.setMaxStack();
                method.setMaxLocals();
                mClassGen.addMethod(method.getMethod());
                il.dispose();
        }
  
        /**
         * Method createConstructor2.
         */
        private void createConstructor2(
                String mGeneratedClassName2,
                String mGeneratedClassName)
        {
                InstructionList il = new InstructionList();
                MethodGen method =
                        new MethodGen(
                                Constants.ACC_PUBLIC,
                                Type.VOID,
                                new Type[] { new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper")},
                                new String[] { "arg0" },
                                "<init>",
                                mGeneratedClassName2,
                                il,
                                mConstantsPool);
                InstructionHandle ih_0 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(mFactory.createLoad(Type.OBJECT, 1));
                il.append(
                        mFactory.createInvoke(
                                mGeneratedClassName,
                                "<init>",
                                Type.VOID,
                                new Type[] { new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper")},
                                Constants.INVOKESPECIAL));
                InstructionHandle ih_5 = 
il.append(mFactory.createReturn(Type.VOID));
                method.setMaxStack();
                method.setMaxLocals();
                mClassGen.addMethod(method.getMethod());
                il.dispose();
        }
  
        /**
         * Method createFields.
         * =================adding===============
         *   private transient org.apache.excalibur.altrmi.client.ProxyHelper 
mProxyHelper;
         * =================adding===============
         *      Add 
         */
        private void createFields()
        {
                FieldGen field;
                field =
                        new FieldGen(
                                Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT,
                                new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper"),
                                "mProxyHelper",
                                mConstantsPool);
                mClassGen.addField(field.getField());
        }
  
        /**
         * Method createAltrmiGetReferenceIDMethod. 
         * =================adding=====================================
         *       public Long altrmiGetReferenceID(Object factoryThatIsAsking) {
         *   return mProxyHelper.getReferenceID(factoryThatIsAsking);
         *              }
         * =================adding=====================================
         */
        private void createAltrmiGetReferenceIDMethod(String 
mGeneratedClassName)
        {
                InstructionList il = new InstructionList();
                MethodGen method =
                        new MethodGen(
                                Constants.ACC_PUBLIC,
                                new ObjectType("java.lang.Long"),
                                new Type[] { Type.OBJECT },
                                new String[] { "arg0" },
                                "altrmiGetReferenceID",
                                mGeneratedClassName,
                                il,
                                mConstantsPool);
                InstructionHandle ih_0 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(
                        mFactory.createFieldAccess(
                                mGeneratedClassName,
                                "mProxyHelper",
                                new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper"),
                                Constants.GETFIELD));
                il.append(mFactory.createLoad(Type.OBJECT, 1));
                il.append(
                        mFactory.createInvoke(
                                
"org.apache.excalibur.altrmi.client.ProxyHelper",
                                "getReferenceID",
                                new ObjectType("java.lang.Long"),
                                new Type[] { Type.OBJECT },
                                Constants.INVOKEINTERFACE));
                InstructionHandle ih_8 = 
il.append(mFactory.createReturn(Type.OBJECT));
                method.setMaxStack();
                method.setMaxLocals();
                mClassGen.addMethod(method.getMethod());
                il.dispose();
        }
  
        /**
         * Method createHelperMethodForDotClassCalls.
         *      This class creates a method class$(String) which is used 
         *      during SomeClass.class instruction
         * 
         */
        private void createHelperMethodForDotClassCalls(String 
mGeneratedClassName)
        {
                InstructionList il = new InstructionList();
                MethodGen method =
                        new MethodGen(
                                Constants.ACC_STATIC,
                                new ObjectType("java.lang.Class"),
                                new Type[] { Type.STRING },
                                new String[] { "arg0" },
                                "class$",
                                mGeneratedClassName,
                                il,
                                mConstantsPool);
                InstructionHandle ih_0 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.Class",
                                "forName",
                                new ObjectType("java.lang.Class"),
                                new Type[] { Type.STRING },
                                Constants.INVOKESTATIC));
                InstructionHandle ih_4 = 
il.append(mFactory.createReturn(Type.OBJECT));
                InstructionHandle ih_5 = 
il.append(mFactory.createStore(Type.OBJECT, 1));
                il.append(mFactory.createNew("java.lang.NoClassDefFoundError"));
                il.append(InstructionConstants.DUP);
                il.append(mFactory.createLoad(Type.OBJECT, 1));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.Throwable",
                                "getMessage",
                                Type.STRING,
                                Type.NO_ARGS,
                                Constants.INVOKEVIRTUAL));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.NoClassDefFoundError",
                                "<init>",
                                Type.VOID,
                                new Type[] { Type.STRING },
                                Constants.INVOKESPECIAL));
                InstructionHandle ih_17 = 
il.append(InstructionConstants.ATHROW);
                method.addExceptionHandler(
                        ih_0,
                        ih_4,
                        ih_5,
                        new ObjectType("java.lang.ClassNotFoundException"));
                method.setMaxStack();
                method.setMaxLocals();
                mClassGen.addMethod(method.getMethod());
                il.dispose();
        }
  
        /**
         * Method createInterfaceMethods.
         *      This methods shall iterate through the set of methods
         *      of the interface creating equivalent methods for the
         *      stubs in the process.
         */
        private void createInterfaceMethods(
                String mGeneratedClassName,
                Class[] interfacesToStubify)
        {
                for (int x = 0; x < interfacesToStubify.length; x++)
                {
                        Class clazz = interfacesToStubify[x];
  
                        if (mVerbose)
                        {
                                System.out.println("ProxyGen: Processing 
interface: " + clazz.getName());
                        }
                        Method[] methods = clazz.getMethods();
                        for (int i = 0; i < methods.length; i++)
                        {
                                createInterfaceMethod(mGeneratedClassName, 
methods[i]);
                        }
  
                }
  
        }
  
        /**
         * Method createInterfaceMethod.
         *      Add the java.lang.reflect.Method wrapper into the stub
         * @param m
         */
        private void createInterfaceMethod(String mGeneratedClassName, Method m)
        {
                InstructionList il = new InstructionList();
                MethodGen method =
                        new MethodGen(
                                Constants.ACC_PUBLIC,
                                getReturnType(m),
                                getArguments(m),
                                getArgumentNames(m),
                                m.getName(),
                                mGeneratedClassName,
                                il,
                                mConstantsPool);
  
                //debug(getArguments(m));
  
                // **** TO Insert TEST Bytecode Inside the stub ,uncomment the 
subsequent lines
                //if (mVerbose)
                //      createTestMethod(il, "calling " + m.getName());
  
                /*
                 *  Declaration of Arrays
                 * =======================
                 *  Object[] args = new Object[__number__of__arguments];
                 *  Class[] argClasses = new Class[__number__of__arguments]; 
                 */
  
                int variableIndex, numberOfArguments;
                Class[] paramTypes = m.getParameterTypes();
                numberOfArguments = paramTypes.length;
                variableIndex = getFreeIndexToStart(paramTypes);
                InstructionHandle ih_0 = il.append(new PUSH(mConstantsPool, 
numberOfArguments));
                il.append((Instruction) mFactory.createNewArray(Type.OBJECT, 
(short) 1));
                il.append(mFactory.createStore(Type.OBJECT, ++variableIndex));
                InstructionHandle ih_5 = il.append(new PUSH(mConstantsPool, 
numberOfArguments));
                il.append(
                        (Instruction) mFactory.createNewArray(
                                new ObjectType("java.lang.Class"),
                                (short) 1));
                il.append(mFactory.createStore(Type.OBJECT, ++variableIndex));
  
                /*
                 *  Assigning parameter into Object[] and Class[] Array
                 * ====================================================
                 *   args[0] = v0;
                 *   argClasses[0]=v0Class.class
                 */
                //Used for adjustment of double/long datatype: 
                Type _previousType = null;
                int _loadIndex = 0;
                for (int i = 0; i < numberOfArguments; i++)
                {
                        // assigning the obj ref's
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex - 1));
                        il.append(new PUSH(mConstantsPool, i));
                        String className = paramTypes[i].getName();
                        //adjust for any previous wider datatype (double/long)
                        if (_previousType != null
                                && (_previousType == Type.DOUBLE || 
_previousType == Type.LONG))
                                ++_loadIndex;
                        if (paramTypes[i].isPrimitive())
                        {
                                
il.append(mFactory.createNew(getJavaWrapperClass(className)));
                                il.append(InstructionConstants.DUP);
                                
il.append(mFactory.createLoad(getBCELPrimitiveType(className), ++_loadIndex));
                                il.append(
                                        mFactory.createInvoke(
                                                getJavaWrapperClass(className),
                                                "<init>",
                                                Type.VOID,
                                                new Type[] { 
getBCELPrimitiveType(className)},
                                                Constants.INVOKESPECIAL));
                                il.append(InstructionConstants.AASTORE);
                        }
                        else
                        {
  
                                //create the static fields for enabling .class 
calls
                                String _encodedFieldName;
                                if (paramTypes[i].isArray())
                                {
                                        int _index = className.lastIndexOf('[');
                                        if (className.charAt(_index + 1) == 'L')
                                                _encodedFieldName =
                                                        "array$"
                                                                + 
className.substring(1 + _index, className.length() - 1).replace('.', '$');
                                        else
                                                _encodedFieldName =
                                                        "array$" + 
className.substring(1 + _index, className.length());
                                }
                                else
                                        _encodedFieldName = "class$" + 
className.replace('.', '$');
                                
                                addField(_encodedFieldName);
                                // ******** TODO assign the obj reference 
                                il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex - 1));
                                il.append(new PUSH(mConstantsPool, i));
                                il.append(mFactory.createLoad(Type.OBJECT, 
++_loadIndex));
                                il.append(InstructionConstants.AASTORE);
  
                                // *********TODO assign the class ref's
                                il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex));
                                il.append(new PUSH(mConstantsPool, i));
                                il.append(
                                        mFactory.createFieldAccess(
                                                mGeneratedClassName,
                                                _encodedFieldName,
                                                new 
ObjectType("java.lang.Class"),
                                                Constants.GETSTATIC));
                                BranchInstruction ifnull =
                                        
mFactory.createBranchInstruction(Constants.IFNULL, null);
                                il.append(ifnull);
                                il.append(
                                        mFactory.createFieldAccess(
                                                mGeneratedClassName,
                                                _encodedFieldName,
                                                new 
ObjectType("java.lang.Class"),
                                                Constants.GETSTATIC));
                                BranchInstruction goHeadToStoreRef =
                                        
mFactory.createBranchInstruction(Constants.GOTO, null);
                                il.append(goHeadToStoreRef);
                                InstructionHandle ifnullStartHere =
                                        il.append(new PUSH(mConstantsPool, 
className));
  
                                ifnull.setTarget(ifnullStartHere);
  
                                il.append(
                                        mFactory.createInvoke(
                                                mGeneratedClassName,
                                                "class$",
                                                new 
ObjectType("java.lang.Class"),
                                                new Type[] { Type.STRING },
                                                Constants.INVOKESTATIC));
                                il.append(InstructionConstants.DUP);
                                il.append(
                                        mFactory.createFieldAccess(
                                                mGeneratedClassName,
                                                _encodedFieldName,
                                                new 
ObjectType("java.lang.Class"),
                                                Constants.PUTSTATIC));
                                InstructionHandle storeClassRef = 
il.append(InstructionConstants.AASTORE);
                                goHeadToStoreRef.setTarget(storeClassRef);
  
                        }
                        _previousType = getBCELPrimitiveType(className);
                }
  
                /* Within the stub put the 
                 * Call processObjectRequest on the instance ProxyHelper held 
within the stub
                 * Thus,
                 * Injecting the following
                 * ================================================
                 * try 
                 * {
                         *      Object retVal = 
mProxyHelper.processObjectRequest("foo1(int, float, java.lang.String, 
java.lang.Integer)",args,argClasses);
                         *      return (java.lang.String) retVal;
                 * } 
                 *  catch (Throwable t) 
                 *      {
                         *              if (t instanceof RuntimeException) 
                         *              { 
                         *               throw (RuntimeException) t;
                         *      } else if (t instanceof Error) 
                         *              { 
                         *                     throw (Error) t;
                         *      } else 
                         *              { 
                         *                     t.printStackTrace(); 
                         *                      throw new 
org.apache.excalibur.altrmi.common.AltrmiInvocationException("Should never get 
here: " + t.getMessage()); 
                         *      } 
                         *      }
                 * ================================================
                 */
                InstructionHandle ihe1 = 
il.append(mFactory.createLoad(Type.OBJECT, 0));
                il.append(
                        mFactory.createFieldAccess(
                                mGeneratedClassName,
                                "mProxyHelper",
                                new 
ObjectType("org.apache.excalibur.altrmi.client.ProxyHelper"),
                                Constants.GETFIELD));
                // **** Check if the return type is facade ***
                Class _returnClass=m.getReturnType();
                if(_returnClass.isArray())
                                _returnClass=_returnClass.getComponentType();
                
                if (isAdditionalFacade(m.getReturnType()))
                {
                        String _encodedReturnClassName="class$" + 
encodeClassName(_returnClass);
                        addField(_encodedReturnClassName);
                        il.append(
                                mFactory.createFieldAccess(
                                        mGeneratedClassName,
                                        _encodedReturnClassName,
                                        new ObjectType("java.lang.Class"),
                                        Constants.GETSTATIC));
                        BranchInstruction ifnullReturnClass =
                                
mFactory.createBranchInstruction(Constants.IFNULL, null);
                        il.append(ifnullReturnClass);
                        il.append(
                                mFactory.createFieldAccess(
                                        mGeneratedClassName,
                                        _encodedReturnClassName,
                                        new ObjectType("java.lang.Class"),
                                        Constants.GETSTATIC));
                        BranchInstruction gotoReturnClass =
                                
mFactory.createBranchInstruction(Constants.GOTO, null);
                        il.append(gotoReturnClass);
                        
                        InstructionHandle ihPushMethodName =
                                il.append(new PUSH(mConstantsPool, 
_returnClass.getName()));
                        ifnullReturnClass.setTarget(ihPushMethodName);
                        il.append(
                                mFactory.createInvoke(
                                        mGeneratedClassName,
                                        "class$",
                                        new ObjectType("java.lang.Class"),
                                        new Type[] { Type.STRING },
                                        Constants.INVOKESTATIC));
                        il.append(InstructionConstants.DUP);
                        il.append(
                                mFactory.createFieldAccess(
                                        mGeneratedClassName,
                                        _encodedReturnClassName,
                                        new ObjectType("java.lang.Class"),
                                        Constants.PUTSTATIC));
                        InstructionHandle ihPushSignature =
                                il.append(new PUSH(mConstantsPool, 
getMethodSignature(m)));
                        gotoReturnClass.setTarget(ihPushSignature);
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex-1));
                        il.append(new PUSH(mConstantsPool, encodeClassName( 
getClassType( _returnClass ) )));
                        il.append(
                                mFactory.createInvoke(
                                        
"org.apache.excalibur.altrmi.client.ProxyHelper",
                                        "processObjectRequestGettingFacade",
                                        Type.OBJECT,
                                        new Type[] {
                                                new 
ObjectType("java.lang.Class"),
                                                Type.STRING,
                                                new ArrayType(Type.OBJECT, 1),
                                                Type.STRING },
                                        Constants.INVOKEINTERFACE));
                }
                else
                {
                        //method signature = METHODNAME(arguments....)   
                        il.append(new PUSH(mConstantsPool, 
getMethodSignature(m)));
                        variableIndex -= 2;
                        il.append(mFactory.createLoad(Type.OBJECT, 
++variableIndex));
                        il.append(mFactory.createLoad(Type.OBJECT, 
++variableIndex));
                        il.append(
                                mFactory.createInvoke(
                                        
"org.apache.excalibur.altrmi.client.ProxyHelper",
                                        "processObjectRequest",
                                        Type.OBJECT,
                                        new Type[] {
                                                Type.STRING,
                                                new ArrayType(Type.OBJECT, 1),
                                                new ArrayType(new 
ObjectType("java.lang.Class"), 1)},
                                        Constants.INVOKEINTERFACE));
                }
                il.append(mFactory.createStore(Type.OBJECT, ++variableIndex));
                il.append(mFactory.createLoad(Type.OBJECT, variableIndex));
  
                InstructionHandle ihe2;
                if (m.getReturnType().isPrimitive())
                {
                        if (getBCELPrimitiveType(m.getReturnType().getName()) 
== Type.VOID)
                        {
                                ihe2 = 
il.append(mFactory.createReturn(Type.VOID));
                        }
                        else
                        {
                                il.append(
                                        mFactory.createCheckCast(
                                                new 
ObjectType(getJavaWrapperClass(m.getReturnType().getName()))));
                                il.append(
                                        mFactory.createInvoke(
                                                
getJavaWrapperClass(m.getReturnType().getName()),
                                                m.getReturnType().getName() + 
"Value",
                                                
getBCELPrimitiveType(m.getReturnType().getName()),
                                                Type.NO_ARGS,
                                                Constants.INVOKEVIRTUAL));
                                ihe2 =
                                        il.append(
                                                
mFactory.createReturn(getBCELPrimitiveType(m.getReturnType().getName())));
                        }
                }
                else
                {
                        il.append(
                                mFactory.createCheckCast(new 
ObjectType(m.getReturnType().getName())));
                        ihe2 = il.append(mFactory.createReturn(Type.OBJECT));
                }
  
                InstructionHandle ihe3 =
                        il.append(mFactory.createStore(Type.OBJECT, 
variableIndex));
  
                //add custom exceptionHandling here 
                Class[] _exceptionClasses = m.getExceptionTypes();
                InstructionHandle _customHandler = null;
                BranchInstruction _ifCustomExceptionBranch = null;
                for (int i = 0; i < _exceptionClasses.length; i++)
                {
  
                        _customHandler = 
il.append(mFactory.createLoad(Type.OBJECT, variableIndex));
                        //create the series of custom exception handlers for 
the classes
                        if (_ifCustomExceptionBranch != null)
                                
_ifCustomExceptionBranch.setTarget(_customHandler);
                        il.append(
                                new INSTANCEOF(
                                        mConstantsPool.addClass(new 
ObjectType(_exceptionClasses[i].getName()))));
                        _ifCustomExceptionBranch =
                                
mFactory.createBranchInstruction(Constants.IFEQ, null);
                        il.append(_ifCustomExceptionBranch);
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex));
                        il.append(
                                mFactory.createCheckCast(new 
ObjectType(_exceptionClasses[i].getName())));
                        il.append(InstructionConstants.ATHROW);
                }
  
                InstructionHandle _defaultExceptionHandler =
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex));
                if (_customHandler != null)
                        
_ifCustomExceptionBranch.setTarget(_defaultExceptionHandler);
                il.append(
                        new INSTANCEOF(
                                mConstantsPool.addClass(new 
ObjectType("java.lang.RuntimeException"))));
                BranchInstruction b1 = 
mFactory.createBranchInstruction(Constants.IFEQ, null);
                il.append(b1);
                il.append(mFactory.createLoad(Type.OBJECT, variableIndex));
                il.append(
                        mFactory.createCheckCast(new 
ObjectType("java.lang.RuntimeException")));
                il.append(InstructionConstants.ATHROW);
                InstructionHandle ih1 =
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex));
                il.append(
                        new INSTANCEOF(mConstantsPool.addClass(new 
ObjectType("java.lang.Error"))));
                BranchInstruction b2 = 
mFactory.createBranchInstruction(Constants.IFEQ, null);
                il.append(b2);
                il.append(mFactory.createLoad(Type.OBJECT, variableIndex));
                il.append(mFactory.createCheckCast(new 
ObjectType("java.lang.Error")));
                il.append(InstructionConstants.ATHROW);
                InstructionHandle ih2 =
                        il.append(mFactory.createLoad(Type.OBJECT, 
variableIndex));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.Throwable",
                                "printStackTrace",
                                Type.VOID,
                                Type.NO_ARGS,
                                Constants.INVOKEVIRTUAL));
                il.append(
                        mFactory.createNew(
                                
"org.apache.excalibur.altrmi.common.AltrmiInvocationException"));
                il.append(InstructionConstants.DUP);
                il.append(mFactory.createNew("java.lang.StringBuffer"));
                il.append(InstructionConstants.DUP);
                il.append(new PUSH(mConstantsPool, "Should never get here: "));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.StringBuffer",
                                "<init>",
                                Type.VOID,
                                new Type[] { Type.STRING },
                                Constants.INVOKESPECIAL));
                il.append(mFactory.createLoad(Type.OBJECT, variableIndex));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.Throwable",
                                "getMessage",
                                Type.STRING,
                                Type.NO_ARGS,
                                Constants.INVOKEVIRTUAL));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.StringBuffer",
                                "append",
                                Type.STRINGBUFFER,
                                new Type[] { Type.STRING },
                                Constants.INVOKEVIRTUAL));
                il.append(
                        mFactory.createInvoke(
                                "java.lang.StringBuffer",
                                "toString",
                                Type.STRING,
                                Type.NO_ARGS,
                                Constants.INVOKEVIRTUAL));
                il.append(
                        mFactory.createInvoke(
                                
"org.apache.excalibur.altrmi.common.AltrmiInvocationException",
                                "<init>",
                                Type.VOID,
                                new Type[] { Type.STRING },
                                Constants.INVOKESPECIAL));
                il.append(InstructionConstants.ATHROW);
  
                b1.setTarget(ih1);
                b2.setTarget(ih2);
                method.addExceptionHandler(
                        ihe1,
                        ihe2,
                        ihe3,
                        new ObjectType("java.lang.Throwable"));
                method.setMaxStack();
                method.setMaxLocals();
                mClassGen.addMethod(method.getMethod());
                il.dispose();
        }
  
        /**
         * Method getFreeIndexToStart.
         *      Returns the index to start allocating the subsequent stack 
variables
         * @param ca
         * @return int
         */
        private int getFreeIndexToStart(Class[] ca)
        {
                int _index = 0;
                for (int i = 0; i < ca.length; i++)
                {
                        if (getBCELType(ca[i]) == Type.DOUBLE) //|| 
getBCELType(ca[i])==Type.LONG)
                        {
                                _index += 2;
                        }
                        _index += 1;
                }
  
                return _index;
        }
        /**
         * Method getArguments.
         *      Convert the arguments of the method 
         *              into equivalent BCEL datatypes
         * @param m
         * @return Type[]
         */
        private Type[] getArguments(Method m)
        {
                Class[] _classes = m.getParameterTypes();
                if (_classes.length == 0)
                        return Type.NO_ARGS;
  
                Type[] types = new Type[_classes.length];
                for (int i = 0; i < _classes.length; i++)
                {
                        types[i] = getBCELType(_classes[i]);
                }
                return types;
        }
  
        /**
         * Method getReturnType.
         *      Convert the returnType of the method into BCEL datatype
         * @param m
         * @return Type
         */
        private Type getReturnType(Method m)
        {
                return getBCELType(m.getReturnType());
        }
  
        /**
         * Method getArgumentNames.
         *      The arguments are arg0,arg1,.....
         * @param m
         * @return String[]
         */
        private String[] getArgumentNames(Method m)
        {
                Class[] _classes = m.getParameterTypes();
                String[] _args = new String[_classes.length];
                for (int i = 0; i < _classes.length; i++)
                {
                        _args[i] = "arg" + i;
                }
                return _args;
        }
  
        /**
         * Method getBCELType.
         *      Maps the java datatype and the BCEL datatype
         * @param c
         * @return Type
         */
        private Type getBCELType(Class c)
        {
  
                if (c.isPrimitive())
                {
                        return getBCELPrimitiveType(c.getName());
                }
                else if (!c.isArray())
                {
                        return new ObjectType(c.getName());
                }
                else
                {
                        String className = c.getName();
                        int _index = className.lastIndexOf('[');
                        int _arrayDepth = className.indexOf('[') - 
className.lastIndexOf('[') + 1;
                        if (className.charAt(_index + 1) == 'L')
                        {
                                return new ArrayType(new 
ObjectType(c.getComponentType().getName()), _arrayDepth);
                        }
  
                        return new ArrayType(
                                
getBCELPrimitiveType(className.substring(_arrayDepth)),
                                _arrayDepth);
                }
  
        }
  
        /**
         * Method getBCELPrimitiveType.
         *      Returns the BCEL Type given the Class Name 
         * @param javaDataType
         * @return Type
         */
        private Type getBCELPrimitiveType(String javaDataType)
        {
                switch (javaDataType.charAt(0))
                {
  
                        case 'b' :
                                if (javaDataType.toString().charAt(1) == 'o')
                                        return Type.BOOLEAN;
                                else
                                        return Type.BYTE;
                        case 'c' :
                        case 'C' :
                                return Type.CHAR;
                        case 's' :
                        case 'S' :
                                return Type.SHORT;
                        case 'i' :
                        case 'I' :
                                return Type.INT;
                        case 'l' :
                        case 'L' :
                                return Type.LONG;
                        case 'f' :
                        case 'F' :
                                return Type.FLOAT;
                        case 'd' :
                        case 'D' :
                                return Type.DOUBLE;
                                //boolean array appears in this format
                        case 'Z' :
                                return Type.BOOLEAN;
                        case 'B' :
                                return Type.BYTE;
                        case 'v' :
                        case 'V' :
                                return Type.VOID;
                }
                return null;
        }
  
        /**
         * Method getJavaWrapperClass.
         *      Returns the String representing the Wrapper class given the 
         *              primitive datatype
         * @param javaDataType
         * @return String
         */
        private String getJavaWrapperClass(String javaDataType)
        {
                switch (javaDataType.charAt(0))
                {
  
                        case 'b' :
                                if (javaDataType.charAt(1) == 'o')
                                        return "java.lang.Boolean";
                                else
                                        return "java.lang.Byte";
                        case 'c' :
                        case 'C' :
                                return "java.lang.Character";
                        case 's' :
                        case 'S' :
                                return "java.lang.Short";
                        case 'i' :
                        case 'I' :
                                return "java.lang.Integer";
                        case 'l' :
                        case 'L' :
                                return "java.lang.Long";
                        case 'f' :
                        case 'F' :
                                return "java.lang.Float";
                        case 'd' :
                        case 'D' :
                                return "java.lang.Double";
                        case 'B' :
                                return "java.lang.Byte";
                        case 'Z' :
                                return "java.lang.Boolean";
                        case 'v' :
                        case 'V' :
                                return "java.lang.Void";
                        case '[' :
                                mArrayDepth_++;
                                return 
getJavaWrapperClass(javaDataType.substring(1));
  
                }
                return null; //never occurs;
        }
  
        private void addField(String _encodedFieldName)
        {
                if 
(!mInternalFieldRepresentingClasses.contains(_encodedFieldName))
                {
                        
//System.out.println("method."+method.getName()+".addingfield[" + 
_encodedFieldName + "]");
                        FieldGen field =
                                new FieldGen(
                                        Constants.ACC_STATIC,
                                        new ObjectType("java.lang.Class"),
                                        _encodedFieldName,
                                        mConstantsPool);
                        mClassGen.addField(field.getField());
                        
mInternalFieldRepresentingClasses.add(_encodedFieldName);
                }
  
        }
        
        //++++++++++++++++++testing
        private void createTestMethod(InstructionList il, String msg)
        {
                il.append(
                        mFactory.createFieldAccess(
                                "java.lang.System",
                                "out",
                                new ObjectType("java.io.PrintStream"),
                                Constants.GETSTATIC));
                il.append(new PUSH(mConstantsPool, msg));
                il.append(
                        mFactory.createInvoke(
                                "java.io.PrintStream",
                                "println",
                                Type.VOID,
                                new Type[] { Type.STRING },
                                Constants.INVOKEVIRTUAL));
        }
  
        private void debug(String prefix, Object[] a)
        {
                System.out.print(prefix);
                for (int i = 0; i < a.length; i++)
                        System.out.print(a[i] + ":");
                System.out.println();
        }
  
        public Class getGeneratedClass(String mGeneratedClassName)
        {
                return getAltrmiClass(mGeneratedClassName);
        }
  
        /**
         * Method getAltrmiClass.
         *      This get the Class definition from the bytes
         * @return Class
         */
        private Class getAltrmiClass(String className)
        {
  
                /*
                FromJavaClassClassLoader fromJavaClassClassLoader =
                        new FromJavaClassClassLoader();
                Class clazz =
                        
fromJavaClassClassLoader.getClassFromJavaClass(mClassGen.getJavaClass());
                */
                Class clazz = null;
  
                try
                {
                        URLClassLoader urlCL =
                                new URLClassLoader(
                                        new URL[] {
                                                 new URL("file:/" + new 
File(mClassGenDir).getCanonicalPath() + "/")},
                        //
                        this.getClass().getClassLoader());
                        clazz = urlCL.loadClass(className);
                }
  
                catch (ClassNotFoundException e)
                {
                        e.printStackTrace();
                }
                catch (MalformedURLException e)
                {
                        e.printStackTrace();
                }
                catch (IOException e)
                {
  
                }
  
                return clazz;
        }
  
        //++++++++++++++++++testing
        //</BCEL>
  
  }
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to