baliuka     02/03/06 06:00:07

  Modified:    simplestore/src/java/org/apache/commons/simplestore/tools
                        Enhancer.java MethodInterceptor.java
               simplestore/src/test/org/apache/commons/simplestore
                        TestEnhancer.java
  Added:       simplestore/src/java/org/apache/commons/simplestore/tools
                        ConstructionHandler.java
  Log:
  Added Handlers for Constructors
  
  Revision  Changes    Path
  1.10      +117 -12   
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.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Enhancer.java     5 Mar 2002 20:03:49 -0000       1.9
  +++ Enhancer.java     6 Mar 2002 14:00:07 -0000       1.10
  @@ -63,7 +63,7 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:[EMAIL PROTECTED]";>
    *      [EMAIL PROTECTED]</a>
  - *@version    $Id: Enhancer.java,v 1.9 2002/03/05 20:03:49 baliuka Exp $
  + *@version    $Id: Enhancer.java,v 1.10 2002/03/06 14:00:07 baliuka Exp $
    */
   public class Enhancer implements org.apache.bcel.Constants{
       
  @@ -87,6 +87,11 @@
       static final  String ENHAVCED_CLASS_SUFIX  = "$$EnhancedBySimplestore$$";
       static final  String ENHAVCED_CLASS_PREFIX  = "org.apache.";
       
  +    private static int addAfterConstructionRef(ConstantPoolGen cp){
  +        return   cp.addMethodref( Enhancer.class.getName() ,"handleConstruction",
  +        "(Ljava/lang/Object;[Ljava/lang/Object;)V");
  +        
  +    }
       private static int addAfterRef( ConstantPoolGen cp ){
           return   cp.addInterfaceMethodref(INTERCEPTOR_CLASS,"afterReturn",
           
"(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Ljava/lang/Object;ZLjava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;"
 );
  @@ -102,12 +107,47 @@
           
       }
       
  +    private static java.util.List costructionHandlers = new java.util.Vector();
  +    
       private static java.util.Map cache = new java.util.WeakHashMap();
       
       /** Creates a new instance of Enchancer */
       private Enhancer() {
       }
       
  +    public static void setMethodInterceptor(Object enhanced, MethodInterceptor 
ih)throws Throwable{
  +        
  +        enhanced.getClass().getField(FIELD_NAME).set(enhanced,ih);
  +        
  +    }
  +    
  +    public static  MethodInterceptor getMethodInterceptor(Object enhanced )throws 
Throwable{
  +        
  +       return 
(MethodInterceptor)enhanced.getClass().getField(FIELD_NAME).get(enhanced);
  +        
  +    }
  +    
  +    public static void addConstructionHandler(ConstructionHandler ch){
  +        
  +        costructionHandlers.add(ch);
  +        
  +    }
  +    
  +    public static void removeConstructionHandler(ConstructionHandler ch){
  +        
  +        costructionHandlers.remove(ch);
  +        
  +    }
  +    
  +    public static synchronized void handleConstruction(Object obj, Object 
args[])throws Throwable{
  +       
  +        for( java.util.Iterator i = costructionHandlers.iterator(); i.hasNext(); ){
  +            ((ConstructionHandler)i.next()).afterConstruction(obj,args);
  +        }
  +        
  +    }
  +    
  +    
       public static Object enhance(Class cls,Class interfaces [] , MethodInterceptor 
ih) throws Throwable{
           
           return 
enhance(cls,null,interfaces,ih,Thread.currentThread().getContextClassLoader());
  @@ -177,6 +217,40 @@
       }
       
       
  +    
  +    private static void addConstructors(ClassGen  cg, Class superClass )throws 
Throwable{
  +        addConstructor(cg);//default
  +        java.lang.reflect.Constructor constructors[] = superClass.getConstructors();
  +        String parentClass = cg.getSuperclassName();
  +        InstructionFactory factory = new InstructionFactory(cg);
  +        ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
  +        for ( int i = 0; i < constructors.length; i++   ){
  +            Class parmTypes[] = constructors[i].getParameterTypes();
  +            if( parmTypes.length == 1 &&
  +            
parmTypes[0].equals(org.apache.commons.simplestore.tools.MethodInterceptor.class) ) {
  +                continue;
  +            }
  +            InstructionList il = new InstructionList();
  +            MethodGen costructor  = toMethodGen(constructors[i],cg.getClassName(), 
il, cp);
  +            Type argTypes[] = toType(parmTypes);
  +            invokeSuper( cg, costructor, argTypes );
  +            
  +            int argArray = createArgArray(il,factory,cp,argTypes);
  +            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( new ALOAD( argArray  ) );
  +            il.append( new INVOKESTATIC( addAfterConstructionRef(cp) ));
  +            
  +            il.append( new RETURN() ) ;
  +            
  +            costructor.setMaxStack();
  +            costructor.setMaxLocals();
  +            cg.addMethod( costructor.getMethod() );
  +        }
  +    }
  +    
       private static void addConstructor(ClassGen  cg ){
           
           String parentClass = cg.getSuperclassName();
  @@ -195,6 +269,14 @@
           il.append( new ALOAD(0));
           il.append( new ALOAD(1));
           il.append( factory.createFieldAccess(cg.getClassName(),FIELD_NAME,new 
ObjectType(INTERCEPTOR_CLASS),PUTFIELD));
  +        Type argTypes[] = new Type[]{ new ObjectType(INTERCEPTOR_CLASS) };
  +        int argArray = createArgArray(il,factory,cp,argTypes);
  +        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( new ALOAD( argArray  ) );
  +        il.append( new INVOKESTATIC( addAfterConstructionRef(cp) ));
           il.append( new RETURN() );
           cg.addMethod( getMethod( costructor ) );
           
  @@ -222,12 +304,13 @@
           return gen;
       }
       
  -    private static JavaClass enhance( Class parentClass,String class_name,Class 
interfaces [],java.util.HashMap methodTable )  {
  +    private static JavaClass enhance( Class parentClass,String class_name,Class 
interfaces [],java.util.HashMap methodTable ) throws Throwable {
           
           ClassGen  cg = getClassGen(class_name,parentClass,interfaces);
           ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
           addHandlerField(cg);
  -        addConstructor(cg);
  +        addConstructors(cg,parentClass);
  +        
           int before =  addBeforeRef(cp);
           int after  =  addAfterRef(cp);
           int invokeSuper  = addInvokeSupperRef(cp);
  @@ -244,7 +327,7 @@
                   int mod = methods[i].getModifiers();
                   if( !java.lang.reflect.Modifier.isStatic(mod) &&
                   !java.lang.reflect.Modifier.isFinal(mod) &&
  -                ( java.lang.reflect.Modifier.isPublic(mod)||
  +                (java.lang.reflect.Modifier.isPublic(mod)||
                   java.lang.reflect.Modifier.isProtected(mod)) ){
                       methodSet.add( new  MethodWrapper( methods[i] ) );
                       
  @@ -485,6 +568,15 @@
           
       }
       
  +    private static Type[] toType(Class cls[]){
  +        
  +        Type tp []= new Type[ cls.length ];
  +        for(int i = 0; i < cls.length; i++ ){
  +            tp[i] = toType(cls[i]);
  +        }
  +        return tp;
  +    }
  +    
       private static Type toType(Class cls){
           
           if(cls.equals(void.class)){
  @@ -519,19 +611,29 @@
           throw new java.lang.InternalError(cls.getName());
       }
       
  +    private static void invokeSuper(ClassGen cg, MethodGen mg,  Type args[]){
  +        ConstantPoolGen cp = cg.getConstantPool();
  +        InstructionList il = mg.getInstructionList();
  +        int pos = 1;
  +        il.append(new ALOAD(0) );//this
  +        for( int i = 0; i < args.length; i++ ){//load args to stack
  +            pos = loadArg(il,args[i] , i, pos ) ;
  +        }
  +        il.append( new INVOKESPECIAL( cp.addMethodref(cg.getSuperclassName(),
  +        mg.getName(),mg.getSignature() ) ) );
  +    }
       
       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 ,
  +        return new MethodGen(ACC_PUBLIC, toType( mtd.getReturnType() ) , 
toType(mtd.getParameterTypes()) ,
           null, mtd.getName(), className ,  il, cp);
       }
  +    private static MethodGen toMethodGen( java.lang.reflect.Constructor mtd,String 
className,
  +    InstructionList il ,ConstantPoolGen cp){
  +        return new MethodGen(ACC_PUBLIC, Type.VOID , 
toType(mtd.getParameterTypes()),
  +        null, CONSTRUCTOR_NAME , className,  il, cp );
  +    }
  +    
       
       private static  Method  generateMethod( java.lang.reflect.Method method,
       String fieldName,
  @@ -605,6 +707,7 @@
                   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
  @@ -612,6 +715,8 @@
               }
               il.append( new INVOKESPECIAL( cp.addMethodref(cg.getSuperclassName(),
               method.getName(),mg.getSignature() ) ) );
  +             */
  +            invokeSuper(cg,mg,types);
               if( wrapper != null ){
                   il.append( initWrapper(mg.getReturnType(),cp) );
               }
  
  
  
  1.2       +19 -11    
jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/MethodInterceptor.java
  
  Index: MethodInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/MethodInterceptor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MethodInterceptor.java    3 Mar 2002 19:36:41 -0000       1.1
  +++ MethodInterceptor.java    6 Mar 2002 14:00:07 -0000       1.2
  @@ -58,20 +58,28 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:[EMAIL PROTECTED]";>
    *      [EMAIL PROTECTED]</a>
  - *@version    $Id: MethodInterceptor.java,v 1.1 2002/03/03 19:36:41 baliuka Exp $
  + *@version    $Id: MethodInterceptor.java,v 1.2 2002/03/06 14:00:07 baliuka Exp $
    */
   public interface MethodInterceptor {
       
  -    public Object beforeInvoke( Object obj,java.lang.reflect.Method method,
  -                                                               Object args[] )
  -                                                               throws 
java.lang.Throwable;
  +    public Object beforeInvoke( Object obj,
  +                                java.lang.reflect.Method method,
  +                                Object args[] )throws java.lang.Throwable;
  +    
  +    public boolean invokeSuper( Object obj,
  +                                java.lang.reflect.Method method,
  +                                Object args[],
  +                                Object retValFromBefore )
  +                                             throws java.lang.Throwable;    
  +    
  +    public Object afterReturn(  Object obj, 
  +                                java.lang.reflect.Method method,
  +                                Object args[],
  +                                Object retValFromBefore,
  +                                boolean invokedSuper,
  +                                Object retValFromSuper,
  +                                java.lang.Throwable e )
  +                                             throws java.lang.Throwable;
       
  -    public boolean invokeSuper( Object obj,java.lang.reflect.Method method,
  -                                        Object args[], Object retValFromBefore )
  -                                        throws java.lang.Throwable;    
       
  -    public Object afterReturn(  Object obj,     java.lang.reflect.Method method,
  -                                Object args[],  Object retValFromBefore,
  -                                 boolean invokedSuper, Object retValFromSuper,
  -                                  java.lang.Throwable e )throws java.lang.Throwable;
   }
  
  
  
  1.1                  
jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/tools/ConstructionHandler.java
  
  Index: ConstructionHandler.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.commons.simplestore.tools;
  
  /**
   *@author     Juozas Baliuka <a href="mailto:[EMAIL PROTECTED]";>
   *      [EMAIL PROTECTED]</a>
   *@version    $Id: ConstructionHandler.java,v 1.1 2002/03/06 14:00:07 baliuka Exp $
   */
  public interface ConstructionHandler {
      
   
      public void afterConstruction(  Object obj, Object args[] )
                                               throws java.lang.Throwable;
      
  }
  
  
  
  1.4       +48 -42    
jakarta-commons-sandbox/simplestore/src/test/org/apache/commons/simplestore/TestEnhancer.java
  
  Index: TestEnhancer.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/simplestore/src/test/org/apache/commons/simplestore/TestEnhancer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestEnhancer.java 5 Mar 2002 20:03:49 -0000       1.3
  +++ TestEnhancer.java 6 Mar 2002 14:00:07 -0000       1.4
  @@ -64,7 +64,7 @@
   /**
    *@author     Juozas Baliuka <a href="mailto:[EMAIL PROTECTED]";>
    *      [EMAIL PROTECTED]</a>
  - *@version    $Id: TestEnhancer.java,v 1.3 2002/03/05 20:03:49 baliuka Exp $
  + *@version    $Id: TestEnhancer.java,v 1.4 2002/03/06 14:00:07 baliuka Exp $
    */
   public class TestEnhancer  extends TestCase {
       
  @@ -85,13 +85,13 @@
       private static void printArgs(Object args[]){
           System.err.print("  args:");
           if( args == null ){
  -           System.err.print( args);
  +            System.err.print( args);
           }else{
  -         for ( int i = 0; i < args.length; i++ ){
  -           System.err.print( " [ " + args[i] + " ] ");
  -         }
  +            for ( int i = 0; i < args.length; i++ ){
  +                System.err.print( " [ " + args[i] + " ] ");
  +            }
           }
  -      System.err.println();
  +        System.err.println();
       }
       public void testEnhance()throws Throwable{
           //test enchance vector:
  @@ -105,51 +105,57 @@
               public Object beforeInvoke( Object obj,java.lang.reflect.Method method,
               Object args[] )
               throws java.lang.Throwable{
  -               System.err.print("beforeInvoke:" + method);
  -               printArgs(args);
  -             return null;
  +                System.err.print("beforeInvoke:" + method);
  +                printArgs(args);
  +                return null;
               }
               
               public boolean invokeSuper( Object obj,java.lang.reflect.Method method,
               Object args[], Object retValFromBefore )
               throws java.lang.Throwable{
  -               
  +                
                   System.err.print("invokeSuper:" + method);
  -                printArgs(args); 
  -               if( "remove".equals(method.getName()) ) return false;//owerride size 
  -             return true;//let super to call this
  +                printArgs(args);
  +                if( "remove".equals(method.getName()) ) return false;//owerride size
  +                return true;//let super to call this
               }
               
  -            public Object afterReturn(  Object obj,     java.lang.reflect.Method 
method,
  -            Object args[],  Object retValFromBefore,
  -            boolean invokedSuper, Object retValFromSuper,
  -            java.lang.Throwable e )throws java.lang.Throwable{
  -                if( e != null ){
  -                  System.err.println("Cauth Exeption from super " + 
obj.getClass().getSuperclass().getName());  
  -                  e.printStackTrace();
  -                  System.err.println();
  -                }
  -               System.err.print("afterReturn:" + method + " returned:" + 
retValFromSuper);
  -               printArgs(args);
  -              if( !invokedSuper )return new Boolean(false); //it was "remove"
  -              return retValFromSuper;//return the same as supper
  -            }
  +            public void afterConstruction(Object obj,Object args[] ){
  +                System.err.print("costructed: " + obj);
  +                printArgs(args);
  +              }
               
  -        });
  -      //TODO : Add meanigful asserts  
  -      String value = "VALUE";  
  -      vector.add(null);
  -      vector.elements();  
  -      vector.size();  
  -      vector.add(this);
  -      vector.add(value);
  -      vector.remove(value);  
  -      vector.remove(value);  
  -      vector.contains(value);
  -      vector.get(vector.indexOf("NOTHING"));//must catch exeption in afterReturn
  -      System.err.println("Enchanced Vector " + vector);
  -    }
  -      
  +        public Object afterReturn(  Object obj,     java.lang.reflect.Method method,
  +        Object args[],  Object retValFromBefore,
  +        boolean invokedSuper, Object retValFromSuper,
  +        java.lang.Throwable e )throws java.lang.Throwable{
  +            if( e != null ){
  +                System.err.println("Cauth Exeption from super " + 
obj.getClass().getSuperclass().getName());
  +                e.printStackTrace();
  +                System.err.println();
  +            }
  +            System.err.print("afterReturn:" + method + " returned:" + 
retValFromSuper);
  +            printArgs(args);
  +            if( !invokedSuper )return new Boolean(false); //it was "remove"
  +            return retValFromSuper;//return the same as supper
  +        }
  +        
  +    });
  +    //TODO : Add meanigful asserts
  +    String value = "VALUE";
  +    vector.add(null);
  +    vector.elements();
  +    vector.size();
  +    vector.add(this);
  +    vector.add(value);
  +    vector.remove(value);
  +    vector.remove(value);
  +    vector.contains(value);
  +    vector.get(vector.indexOf("NOTHING"));//must catch exeption in afterReturn
  +    System.err.println("Enchanced Vector " + vector);
  +    
  +}
  +
   }
   
   
  
  
  

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

Reply via email to