commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bali...@apache.org
Subject cvs commit: jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools Enhancer.java
Date Mon, 04 Mar 2002 12:38:18 GMT
baliuka     02/03/04 04:38:17

  Modified:    simplestore build.xml
               simplestore/src/java/org/apache/commons/simplestore/tools
                        Enhancer.java
  Log:
  implemented Cache for enhanced Classes
  
  Revision  Changes    Path
  1.15      +2 -2      jakarta-commons-sandbox/simplestore/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/build.xml,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- build.xml	11 Feb 2002 20:24:01 -0000	1.14
  +++ build.xml	4 Mar 2002 12:38:17 -0000	1.15
  @@ -2,7 +2,7 @@
   
   <!--
           "simplestore" component of the Jakarta Commons Subproject
  -        $Id: build.xml,v 1.14 2002/02/11 20:24:01 froehlich Exp $
  +        $Id: build.xml,v 1.15 2002/03/04 12:38:17 baliuka Exp $
   -->
   
   <!-- ========== Executable Targets ======================================== -->
  @@ -127,7 +127,7 @@
     </target>
     
     <target name="test" depends="build-test" description="runs (junit) unit tests">
  -    <java classname="${test.runner}" fork="no" failonerror="${test.failonerror}" 
  +    <java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}" 
        maxmemory="${maxmemory}">
         <arg value="${test.entry}"/>
           <classpath>
  
  
  
  1.4       +155 -76   jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/Enhancer.java
  
  Index: Enhancer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/Enhancer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Enhancer.java	4 Mar 2002 10:50:40 -0000	1.3
  +++ Enhancer.java	4 Mar 2002 12:38:17 -0000	1.4
  @@ -63,7 +63,7 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:baliuka@mwm.lt">
    *      baliuka@mwm.lt</a>
  - *@version    $Id: Enhancer.java,v 1.3 2002/03/04 10:50:40 baliuka Exp $
  + *@version    $Id: Enhancer.java,v 1.4 2002/03/04 12:38:17 baliuka Exp $
    */
   public class Enhancer implements org.apache.bcel.Constants{
       
  @@ -84,6 +84,7 @@
       static final  String CONSTRUCTOR_NAME      =  "<init>";
       static final  String FIELD_NAME            =  "h";
       static final  String SOURCE_FILE           =  "<generated>";
  +    static final  String ENHAVCED_CLASS_SUFIX  = "$$EnhancedBySimplestore$$";
       
       private static int addAfterRef( ConstantPoolGen cp ){
           return   cp.addInterfaceMethodref(INTERCEPTOR_CLASS,"afterReturn",
  @@ -100,51 +101,62 @@
           
       }
       
  +    private static java.util.Map cache = new java.util.WeakHashMap();
       
       /** Creates a new instance of Enchancer */
       private Enhancer() {
       }
       
  -    public static Object enhance(Class cls , MethodInterceptor ih) {
  +    public static Object enhance(Class cls , MethodInterceptor ih) throws Throwable{
           
           return enhance(cls,ih,Thread.currentThread().getContextClassLoader());
       }
  -    public static Object enhance(Class cls, MethodInterceptor ih,ClassLoader loader) {
  +    public synchronized static Object enhance(Class cls, MethodInterceptor ih,ClassLoader
loader)throws Throwable {
           
  -        JavaClass clazz = enhance(cls);
  +        java.util.Map map = (java.util.Map)cache.get(loader);
           
  -        try{
  +        if( map == null){
  +            map = new java.util.HashMap();
  +            cache.put( loader, map );
  +            
  +        }
  +        
  +        
  +        Class result = (Class)map.get(cls);
  +        
  +        if(result == null){
  +            
  +            JavaClass clazz = enhance(cls);
               
               byte b [] = clazz.getBytes();
               java.lang.reflect.Method m =
               ClassLoader.class.getDeclaredMethod("defineClass",
               new Class[]{String.class,byte[].class,int.class,int.class}
               );
  -            
  +            // protected method invocaton
               boolean flag = m.isAccessible();
               m.setAccessible(true);
  -            Class result = (Class)m.invoke(loader,new Object[]{clazz.getClassName(),b,new
Integer(0),new Integer(b.length)});
  +            result = (Class)m.invoke(loader,new Object[]{clazz.getClassName(),b,new Integer(0),new
Integer(b.length)});
               m.setAccessible(flag);
               
  -            java.lang.reflect.Method methods [] = result.getMethods();
  -            for( int i = 0; i < methods.length; i++ ){
  -                try{
  -                    result.getField("mtd_" + methods[i].getName() + "$" +
  -                    methods[i].getParameterTypes().length
  -                    ).set(null,methods[i]);
  -                }catch( java.lang.NoSuchFieldException nsfe ){
  -                }
  -            }
  -            
  -            
  -            return result.getConstructor(new Class[]{ MethodInterceptor.class} ).
  -            newInstance(new Object[]{ih});
  -            
  +            map.put(cls,result);
               
  -        }catch( Exception e){
  -            e.printStackTrace();
           }
  -        return null;
  +        java.lang.reflect.Method methods [] = result.getMethods();
  +        for( int i = 0; i < methods.length; i++ ){
  +            try{
  +                result.getField("mtd_" + methods[i].getName() + "$" +
  +                methods[i].getParameterTypes().length
  +                ).set(null,methods[i]);
  +            }catch( java.lang.NoSuchFieldException nsfe ){
  +            }
  +        }
  +        
  +        
  +        return result.getConstructor(new Class[]{ MethodInterceptor.class} ).
  +        newInstance(new Object[]{ih});
  +        
  +        
           
       }
       
  @@ -190,8 +202,7 @@
       
       private static JavaClass enhance( Class parentClass )  {
           
  -        String class_name = parentClass.getName() + "$$FinalImpl";
  -        JavaClass parent = Repository.lookupClass(parentClass.getName());
  +        String class_name = parentClass.getName() + ENHAVCED_CLASS_SUFIX;
           ClassGen  cg = getClassGen(class_name,parentClass);
           ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
           addHandlerField(cg);
  @@ -199,10 +210,9 @@
           int before =  addBeforeRef(cp);
           int after  =  addAfterRef(cp);
           int invokeSuper  = addInvokeSupperRef(cp);
  -        Method  methods[] = parent.getMethods();
  +        java.lang.reflect.Method  methods[] = parentClass.getMethods();
           for( int i = 0 ; i < methods.length; i++ ){
  -            if(  !methods[i].getName().equals(CONSTRUCTOR_NAME) && (
  -            ( methods[i].getAccessFlags()& ACC_STATIC ) == 0 ) ){
  +            if( ! java.lang.reflect.Modifier.isStatic(methods[i].getModifiers())  ){
                   cg.addMethod( generateMethod( methods[i], cg,
                   before, after, invokeSuper ) );
               }
  @@ -417,6 +427,7 @@
           
       }
       
  +    
       private static int loadArg(InstructionList il, Type t, int index,int pos ){
           
           
  @@ -445,36 +456,93 @@
           }
           
       }
  -    private static  Method  generateMethod( Method method,
  +    
  +    private static Type toType(Class cls){
  +        
  +        if(cls.equals(void.class)){
  +            return Type.VOID;
  +        }
  +        
  +        if(cls.isPrimitive()){
  +            
  +            if( int.class.equals(cls) ){
  +                return Type.INT;
  +            }else if( char.class.equals(cls) ){
  +                return Type.CHAR;
  +            }else if( short.class.equals(cls) ){
  +                return Type.SHORT;
  +            }else if( byte.class.equals(cls) ){
  +                return Type.BYTE;
  +            }else if( long.class.equals(cls)){
  +                return Type.LONG;
  +            }else if (float.class.equals(cls)){
  +                return Type.FLOAT;
  +            }else if (double.class.equals(cls)){
  +                return Type.DOUBLE;
  +            }
  +            
  +        }else if (cls.isArray()){
  +            
  +            return toType(cls.getComponentType());
  +            
  +        }else return new ObjectType(cls.getName());
  +        return null;
  +        
  +    }
  +    
  +    
  +    private static MethodGen toMethodGen( java.lang.reflect.Method mtd,String className,
  +    InstructionList il ,ConstantPoolGen cp){
  +        Class args [] = mtd.getParameterTypes();
  +        Type arg_types [] =  new Type[ args.length ];
  +        for( int i = 0; i < arg_types.length; i++){
  +            arg_types[ i ] = toType(args[i]);
  +        }
  +        
  +        return new MethodGen(ACC_PUBLIC, toType( mtd.getReturnType() ) , arg_types ,
  +        null, mtd.getName(), className ,  il, cp);
  +        
  +        
  +        
  +    }
  +    
  +    private static  Method  generateMethod( java.lang.reflect.Method method,
       ClassGen cg,int before,
       int after, int invokeSuper){
           
           InstructionList    il      = new InstructionList();
           InstructionFactory factory = new InstructionFactory(cg);
           ConstantPoolGen cp = cg.getConstantPool();
  -        MethodGen mg = new MethodGen(method, cg.getClassName(), cp);
  +        MethodGen mg = toMethodGen(method, cg.getClassName(),il, cp);
           Type types[] = mg.getArgumentTypes();
           int argCount = types.length;
           
           String fieldName = "mtd_" + method.getName() + "$" + argCount;
           addMethodField( fieldName, cg );
           
  -        boolean returnsValue = ! mg.getReturnType().equals(Type.VOID);
  -        
  -        mg.setAccessFlags(ACC_PUBLIC);
  -        mg.setInstructionList(il);
  +        boolean returnsValue = !mg.getReturnType().equals( Type.VOID );
  +        boolean abstractM    = java.lang.reflect.Modifier.isAbstract(method.getModifiers());
  +        InstructionHandle ehEnd = null;
  +        GOTO gotoHandled = null;
  +        IFEQ ifInvoke = null;
  +        InstructionHandle condition = null;
  +        InstructionHandle ehHandled = null;
  +        InstructionHandle ehStart = null;
           
           InstructionHandle start = il.getStart();
  -        //  il.append(  new BIPUSH ((byte)argCount) );
  +        
           int loaded = createArgArray(il,factory,cp,mg.getArgumentTypes());
           int argArray = loaded;
           il.append( new ASTORE(argArray) );
  -        il.append( new ALOAD(0) );
  -        il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new ObjectType(INTERCEPTOR_CLASS),GETFIELD));
  -        il.append( new ALOAD(0) );
  -        il.append( factory.createGetStatic(cg.getClassName(),fieldName, METHOD_OBJECT )
);
  -        il.append( new ALOAD( argArray  ) );
  -        il.append( new INVOKEINTERFACE(before,4) );
  +        if(!abstractM){// invoke before
  +            il.append( new ALOAD(0) );
  +            il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new ObjectType(INTERCEPTOR_CLASS),GETFIELD));
  +            il.append( new ALOAD(0) );
  +            il.append( factory.createGetStatic(cg.getClassName(),fieldName, METHOD_OBJECT
) );
  +            il.append( new ALOAD( argArray  ) );
  +            il.append( new INVOKEINTERFACE(before,4) );
  +        }
  +        //locals
           int resutFromBefore = ++loaded ;
           il.append( new ASTORE( resutFromBefore ) );
           il.append( new ACONST_NULL() );
  @@ -486,41 +554,49 @@
           il.append( new ACONST_NULL() );
           int error = ++loaded;
           il.append( new ASTORE( error  ) );
  -        il.append( new ALOAD(0) );//this.handler
  -        il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new ObjectType(INTERCEPTOR_CLASS),GETFIELD));
  -        il.append( new ALOAD(0) );//this
  -        il.append( factory.createGetStatic(cg.getClassName(),fieldName, METHOD_OBJECT )
);
  -        il.append( new ALOAD(argArray) );
  -        il.append( new ALOAD(resutFromBefore) );
  -        il.append( new INVOKEINTERFACE(invokeSuper,5) );
  -        IFEQ ifInvoke = new IFEQ(null);
  -        InstructionHandle condition = il.append( ifInvoke );
  -        il.append( new ICONST(1));
  -        InstructionHandle ehStart = il.append( new ISTORE( superInvoked ) );// Ivoked =
true
  -        Instruction wrapper = newWrapper( mg.getReturnType(),cp );
  -        if( wrapper != null ){
  -            ehStart = il.append( wrapper );
  -            il.append( new DUP() );
  +        if(!abstractM){//test before invoke super
  +            il.append( new ALOAD(0) );//this.handler
  +            il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new ObjectType(INTERCEPTOR_CLASS),GETFIELD));
  +            il.append( new ALOAD(0) );//this
  +            il.append( factory.createGetStatic(cg.getClassName(),fieldName, METHOD_OBJECT
) );
  +            il.append( new ALOAD(argArray) );
  +            il.append( new ALOAD(resutFromBefore) );
  +            il.append( new INVOKEINTERFACE(invokeSuper,5) );
  +            //test returned true
  +            ifInvoke = new IFEQ(null);
  +            condition = il.append( ifInvoke );
  +            il.append( new ICONST(1));
  +            ehStart = il.append( new ISTORE( superInvoked ) );// Ivoked = true
  +            Instruction wrapper = newWrapper( mg.getReturnType(),cp );
  +            if( wrapper != null ){
  +                ehStart = il.append( wrapper );
  +                il.append( new DUP() );
  +            }
  +            //invokeSuper
  +            int pos = 1;
  +            il.append(new ALOAD(0) );//this
  +            for( int i = 0; i < argCount; i++ ){//load args to stack
  +                pos = loadArg(il,types[i] , i, pos ) ;
  +            }
  +            il.append( new INVOKESPECIAL( cp.addMethodref(cg.getSuperclassName(),
  +            method.getName(),mg.getSignature() ) ) );
  +            if( wrapper != null ){
  +                il.append( initWrapper(mg.getReturnType(),cp) );
  +            }
  +            
  +            ehEnd = il.append( new ASTORE(resultFromSuper) );
  +            gotoHandled = new GOTO(null);
  +            il.append( gotoHandled );
  +            ehHandled =  il.append( new ASTORE(error ) );
           }
  -        int pos = 1;
  -        il.append(new ALOAD(0) );//this
  -        for( int i = 0; i < argCount; i++ ){//load args to stack
  -            pos = loadArg(il,types[i] , i, pos ) ;
  -        }
  -        //invokeSuper
  -        
  -        il.append( new INVOKESPECIAL( cp.addMethodref(cg.getSuperclassName(), method.getName(),method.getSignature()
) ) );
  -        if( wrapper != null ){
  -            il.append( initWrapper(mg.getReturnType(),cp) );
  -        }
  -        
  -        InstructionHandle ehEnd = il.append( new ASTORE(resultFromSuper) );
  -        GOTO gotoHandled = new GOTO(null);
  -        il.append( gotoHandled );
  -        InstructionHandle ehHandled =  il.append( new ASTORE(error ) );
  +        
           InstructionHandle endif = il.append( new ALOAD(0) );//this
  -        ifInvoke.setTarget(endif);
  -        gotoHandled.setTarget(endif);
  +        
  +        if( !abstractM ){
  +            ifInvoke.setTarget(endif);
  +            gotoHandled.setTarget(endif);
  +        }
  +        
           il.append(factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new ObjectType(INTERCEPTOR_CLASS),GETFIELD));
           il.append( new ALOAD(0) );//this
           il.append( factory.createGetStatic(cg.getClassName(),fieldName,METHOD_OBJECT )
);
  @@ -533,7 +609,10 @@
           
           
           InstructionHandle exitMethod =  generateReturnValue(il,factory,cp,mg.getReturnType(),++loaded);
  -        mg.addExceptionHandler(ehStart,ehEnd,ehHandled,Type.THROWABLE);
  +        
  +        if( !abstractM ){
  +            mg.addExceptionHandler(ehStart,ehEnd,ehHandled,Type.THROWABLE);
  +        }
           
           mg.setMaxStack();
           mg.setMaxLocals();
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message