You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by vi...@apache.org on 2002/05/14 23:37:21 UTC

cvs commit: jakarta-avalon-excalibur/altrmi/src/java/org/apache/excalibur/altrmi/generator BCELProxyGeneratorImpl.java ProxyGeneratorImpl.java

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:Paul_Hammant@yahoo.com">Paul_Hammant@yahoo.com</a>
    * @author Mike Miller of www.gac.com
    * @author <a href="mailto:proyal@apache.org">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:vinayc77@yahoo.com">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:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-avalon-excalibur/altrmi/src/java/org/apache/excalibur/altrmi/generator BCELProxyGeneratorImpl.java ProxyGeneratorImpl.java

Posted by Peter Donald <pe...@apache.org>.
On Wed, 15 May 2002 07:37, vinayc@apache.org wrote:
> 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

Very kool!

-- 
Cheers,

Peter Donald


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>