package org.mockejb;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import net.sf.cglib.proxy.*;
import org.apache.commons.logging.*;
import org.mockejb.interceptor.InterceptableProxy;
import org.mockejb.interceptor.InterceptorInvoker;
public class EntityBeanSubclass implements MethodInterceptor {
private static Log logger = LogFactory.getLog( EntityBeanSubclass.class.getName() );
public static EntityBeanSubclass newInstance( Class abstractEntityClass ){
return (EntityBeanSubclass)InterceptableProxy.create( EntityBeanSubclass.class,
new EntityBeanSubclass( abstractEntityClass ) );
}
private Class abstractEntityClass;
private Map fieldVals = new HashMap();
EntityBeanSubclass(){
}
private EntityBeanSubclass( Class abstractEntityClass ){
this.abstractEntityClass = abstractEntityClass;
}
public Object create( ){
Enhancer e = new Enhancer();
e.setSuperclass( abstractEntityClass );
e.setCallback( this );
return e.create();
}
public Object intercept(Object obj, Method method, Object[] paramVals,
MethodProxy cglibMethodProxy) throws Throwable {
String methodName = method.getName();
Object returnVal = null;
if ( isAbstractAndStartsWith( method, "set" ) ){
String fieldName = deriveFieldName( methodName );
if (paramVals.length != 1)
throw new IllegalArgumentException("Attempt to call setter "+method+
" with incorrect number of parameters");
if (!method.getReturnType().getName().equals("void") ) {
throw new IllegalArgumentException("Attempt to call setter "+method+
" which has the return type other than void");
}
logger.debug("Calling setter for "+fieldName+" with the value "+paramVals[0]);
fieldVals.put(fieldName, paramVals[0]);
}
else if ( isAbstractAndStartsWith( method, "get" ) ) {
String fieldName = deriveFieldName( methodName );
if (paramVals.length > 0)
throw new IllegalArgumentException("Attempt to call getter method "+method+
" with parameters. The method should not have any parameters");
returnVal = fieldVals.get( fieldName );
Class returnClass = method.getReturnType();
if ( java.util.Collection.class.isAssignableFrom(returnClass ) && returnVal==null) {
returnVal=new ArrayList();
}
else if ( java.util.Set.class.isAssignableFrom(returnClass ) && returnVal==null) {
returnVal=new HashSet();
}
logger.debug("Calling getter for "+fieldName+" with return value "+returnVal);
}
else if ( isAbstractAndStartsWith( method, "ejbSelect" ) ) {
returnVal = invokeEjbSelect( obj, method, paramVals );
}
else {
returnVal = cglibMethodProxy.invokeSuper(obj, paramVals);
}
return returnVal;
}
private boolean isAbstractAndStartsWith( Method method, String prefix ){
return ( method.getName().startsWith( prefix ) && Modifier.isAbstract( method.getModifiers()) );
}
private String deriveFieldName( String methodName ){
return methodName.substring(3);
}
protected Object invokeEjbSelect( Object subclassObj, Method ejbSelectMethod,
Object[] paramVals ) throws Exception{
Object returnObj = null;
DummyCMPBean dummyCmpBean = new DummyCMPBean();
InterceptorInvoker interceptorInvoker= new InterceptorInvoker();
try {
returnObj = interceptorInvoker.invoke( subclassObj, ejbSelectMethod, dummyCmpBean,
dummyCmpBean.getTargetMethod(), paramVals );
}
catch ( MustBeInterceptedException mbie ){
throw new MustBeInterceptedException( ejbSelectMethod );
}
return returnObj;
}
}