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]>