package org.mockejb;
import java.io.Serializable;
import java.lang.reflect.*;
import java.rmi.RemoteException;
import javax.ejb.*;
import org.mockejb.interceptor.*;
abstract class BasicEjbHome implements InvocationHandler, Serializable {
private static MethodContainer standardMethods;
static {
standardMethods = new MethodContainer( SessionBeanHome.class );
standardMethods.add("getEJBMetaData");
standardMethods.add("getHomeHandle");
Class objectArg[] = {Object.class};
standardMethods.add("remove", objectArg );
standardMethods.add("toString" );
standardMethods.add("equals", objectArg );
standardMethods.add("hashCode" );
standardMethods.add("toString" );
}
private BasicEjbDescriptor descriptor;
private Object proxy;
private MockEjbMetaData ejbMetaData;
protected InterceptorInvoker interceptorInvoker= new InterceptorInvoker();
BasicEjbHome( BasicEjbDescriptor descriptor ){
this.descriptor = descriptor;
interceptorInvoker.setContext("descriptor", descriptor );
ejbMetaData = new MockEjbMetaData( descriptor );
}
public Object createProxy( ) {
Class homeClass = descriptor.getHomeClass();
proxy = Proxy.newProxyInstance( homeClass.getClassLoader(),
new Class[] { homeClass, GenericHome.class }, this );
ejbMetaData.setHomeProxy( proxy );
return proxy;
}
protected Object getHomeProxy(){
return proxy;
}
public Object invoke( Object thisProxy, Method homeMethod, Object[] paramVals )
throws Throwable {
Object returnValue = null;
Method method = standardMethods.find( homeMethod );
if ( method != null ){
returnValue = interceptorInvoker.invoke( proxy, homeMethod, this, method, paramVals );
}
else if ( homeMethod.getName().startsWith("create") ||
homeMethod.getDeclaringClass().equals( GenericHome.class ) ) {
MockEjbObject ejbObject = new MockEjbObject( descriptor.getIfaceClass() );
ejbObject.setHomeImpl(this);
ejbObject.setHomeProxy(proxy);
returnValue = create( descriptor, ejbObject, homeMethod, paramVals );
}
else
returnValue = invokeHomeMethod( descriptor, homeMethod, paramVals );
return returnValue;
}
public abstract Object create( BasicEjbDescriptor descriptor, MockEjbObject ejbObject,
Method homeMethod, Object[] paramVals ) throws Exception;
public abstract Object invokeHomeMethod( BasicEjbDescriptor descriptor,
Method homeMethod, Object[] paramVals ) throws Exception;
protected Object createBean(BasicEjbDescriptor descriptor) {
Object bean;
if ( descriptor.getBean() == null ) {
bean = invokeNewInstance( descriptor.getBeanClass() );
}
else {
bean = descriptor.getBean();
}
return bean;
}
protected Object invokeBeanMethod( Object bean, Method homeMethod, String methodName,
Class[] paramTypes, Object[] paramVals ) throws Exception {
Method method;
try {
method = bean.getClass().getMethod( methodName, paramTypes);
}
catch ( NoSuchMethodException noSuchMethodEx ) {
throw new MockEjbSystemException( "EJB "+bean.getClass().getName()+
" does not implement method "+
methodName, noSuchMethodEx );
}
return interceptorInvoker.invoke( getHomeProxy(),homeMethod, bean, method, paramVals );
}
Object invokeBeanMethod( Object bean, Method homeMethod,
String methodName ) throws Exception {
Class paramTypes[]={};
Object args[]={};
return invokeBeanMethod( bean, homeMethod, methodName, paramTypes, args);
}
protected Object invokeBeanCreateMethod( Object bean, Method createMethod,
Object[] paramVals ) throws Exception {
Object returnVal = null;
if ( createMethod.getName().startsWith("create")) {
returnVal = invokeBeanMethodWithPrefix( "ejb", bean, createMethod, paramVals );
}
else {
returnVal = invokeBeanMethod( bean, createMethod, "ejbCreate", createMethod.getParameterTypes(),
paramVals );
}
return returnVal;
}
protected Object invokeBeanMethodWithPrefix( String prefix, Object bean, Method homeMethod,
Object[] paramVals ) throws Exception {
String methodName = prefix+homeMethod.getName().substring(0,1).toUpperCase()+
homeMethod.getName().substring(1);
return invokeBeanMethod( bean, homeMethod, methodName, homeMethod.getParameterTypes(),
paramVals );
}
protected Object invokeNewInstance( Class beanClass ) {
Object bean = null;
try {
bean = beanClass.newInstance();
}
catch ( IllegalAccessException iae ) {
throw new MockEjbSystemException( "Error instantiating a bean "+
beanClass.getName(), iae );
}
catch ( InstantiationException ie ) {
throw new MockEjbSystemException( "Error instantiating a bean "+
beanClass.getName(), ie );
}
return bean;
}
public void remove( Object obj) throws RemoveException {
throwMethodNotImplemented("remove( obj )");
}
public EJBMetaData getEJBMetaData() throws RemoteException {
return ejbMetaData;
}
public HomeHandle getHomeHandle() throws RemoteException {
throwMethodNotImplemented("getHomeHandle()");
return null;
}
public boolean equals( Object obj ){
if (descriptor.getHomeClass().isInstance( obj ) )
return (proxy==obj);
else
return super.equals( obj );
}
public int hashCode() {
return descriptor.getHomeClass().hashCode();
}
public String toString(){
return "Home object: HomeIface: "+descriptor.getHomeClass().getName()+
" BusinessIface: "+descriptor.getIfaceClass().getName();
}
protected void throwMethodNotImplemented( String methodName ){
throw new MethodNotImplementedException( methodName,
this.getClass().getName() );
}
}