package org.jfox.ejb;
import java.lang.reflect.Method;
import org.jfox.ejb.invoker.local.LOCALContainerInvoker;
import org.jfox.ejb.invoker.local.LOCALContainerService;
import org.jfox.ejb.invoker.ContainerRemote;
import org.jfox.ejb.invoker.ContainerInvokerHelper;
import org.jfox.ejb.invoker.ClientContainerInvoker;
import org.jfox.ejb.meta.Protocol;
import javax.ejb.EJBException;
public class DelegateInvocationHandler implements ClientContainerInvoker {
private ObjectId objectId;
private String defualtRemoteProtocol;
private String defualtLocalProtocol;
private ClientContainerInvoker protocolInvocationHandler = null;
public DelegateInvocationHandler(ObjectId objectId, String remoteProtocol, String localProtocol) {
this.objectId = objectId;
this.defualtRemoteProtocol = remoteProtocol;
this.defualtLocalProtocol = localProtocol;
}
public ObjectId getObjectId() {
return objectId;
}
public ClientContainerInvoker getProtocolInvocationHandler() {
return protocolInvocationHandler;
}
public void setProtocolInvocationHandler(ClientContainerInvoker protocolInvocationHandler) {
this.protocolInvocationHandler = protocolInvocationHandler;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.equals(ExtendedEJBHomeMethod.UseProtocol)) {
String protocol = (String)args[0];
try {
protocolInvocationHandler = getInvocationHandlerByProtocol(protocol);
}
catch(EJBException e){
throw e;
}
catch(Exception e){
throw new EJBException("protocol " + protocol + " not supported!",e);
}
return null; }
if(protocolInvocationHandler == null) {
synchronized(this) {
protocolInvocationHandler = getInvocationHandlerByDefault();
}
}
return protocolInvocationHandler.invoke(proxy,method,args);
}
private ClientContainerInvoker getInvocationHandlerByProtocol(String protocol) throws Exception{
if(protocol.equalsIgnoreCase(Protocol.LOCAL)) {
if(!ObjectId.CONTAINER_IDENTITY.equals(objectId.getIdentity())){
throw new EJBException("can not use local protocol, because the bean is not in same JVM as Container");
}
else {
return new LOCALContainerInvoker(objectId,LOCALContainerService.getInstance());
}
}
else {
ContainerRemote invoker = ContainerInvokerHelper.lookupContainerInvoker(protocol);
return ContainerInvokerHelper.createClientInvocationHandler(protocol,objectId,invoker);
}
}
private ClientContainerInvoker getInvocationHandlerByDefault() throws Exception{
if(ObjectId.CONTAINER_IDENTITY.equals(objectId.getIdentity())){
return getInvocationHandlerByProtocol(defualtLocalProtocol);
}
else { return getInvocationHandlerByProtocol(defualtRemoteProtocol);
}
}
}