package org.jfox.ejb;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.RemoteException;
import java.net.InetAddress;
import javax.ejb.EJBMetaData;
import javax.ejb.EJBObject;
import javax.ejb.EJBHome;
import javax.ejb.HomeHandle;
import javax.ejb.EJBException;
import javax.ejb.EnterpriseBean;
import org.huihoo.jfox.system.ComponentSupport;
import org.huihoo.jfox.logging.Logger;
import org.jfox.ejb.deploy.EJBClassLoader;
import org.jfox.ejb.meta.EJBDescriptor;
public abstract class BulkSupport extends ComponentSupport implements Bulk {
protected BulkMetaData bulkMeta = null;
protected String homeClassName = null;
protected Map beanMethods = new HashMap();
protected Map homeMethods = new HashMap();
protected OIDGenerator oidGenerator = null;
protected List interceptors = new ArrayList();
private static String ipAddress = "127.0.0.1";
static {
try {
ipAddress = InetAddress.getLocalHost().getHostAddress();
}
catch(Exception e){
}
};
public BulkSupport(BulkMetaData meta) {
this.bulkMeta = meta;
logger = Logger.getLogger(bulkMeta.getBeanClass().getName());
oidGenerator = OIDGenerator.newInstance(ipAddress,
meta.getEJBMetaData().getHomeInterfaceClass().getName(),
meta.getEJBMetaData().getRemoteInterfaceClass().getName());
this.homeClassName = meta.getEJBMetaData().getHomeInterfaceClass().getName();
homeMethods = introspectorInterfMethods(meta.getEJBMetaData().getHomeInterfaceClass());
beanMethods = introspectorBeanMethods(meta.getBeanClass(),meta.getEJBMetaData().getRemoteInterfaceClass());
beanMethods.putAll(introspectorInterfMethods(EJBObject.class));
((EJBMetaDataImpl)meta.getEJBMetaData()).setEJBHome(createEJBHome());
}
public EJBClassLoader getEJBClassLoader() {
return (EJBClassLoader)bulkMeta.getBeanClass().getClassLoader();
}
public EJBMetaData getEJBMetaData() throws RemoteException {
return bulkMeta.getEJBMetaData();
}
public EJBHome getEJBHome() throws RemoteException {
return bulkMeta.getEJBMetaData().getEJBHome();
}
public HomeHandle getHomeHandle() throws RemoteException {
return new HomeHandleImpl(bulkMeta.getEJBDescriptor().getJndiName());
}
public void ejbCreate(EnterpriseBean bean, String createMethod, Object[] args) throws RemoteException {
char c = createMethod.charAt(0);
String ejbCreateMethodName = "ejb" + Character.toUpperCase(c) + createMethod.substring(1);
logger.debug(bean + " " + ejbCreateMethodName);
Class[] signatures = null;
if(args !=null && args.length !=0 ){
signatures = new Class[args.length];
for(int i=0;i<args.length;i++){
signatures[i] = args[i].getClass();
}
}
try {
bean.getClass().getMethod(ejbCreateMethodName,signatures).invoke(bean,args);
}
catch(Exception e){
throw new RemoteException(e.getMessage(),e);
}
}
private EJBHome createEJBHome(){
EJBHome home = (EJBHome)Proxy.newProxyInstance(bulkMeta.getEJBMetaData().getHomeInterfaceClass().getClassLoader(),
new Class[]{bulkMeta.getEJBMetaData().getHomeInterfaceClass(), ExtendedEJBHome.class},
new DelegateInvocationHandler(oidGenerator.getHomeObjectId(),
bulkMeta.getEJBDescriptor().getRemoteProtocol(),
bulkMeta.getEJBDescriptor().getLocalProtocol())
);
logger.debug("createEJBHome "+ homeClassName +" Successful");
return home;
}
protected Map introspectorInterfMethods(Class classObj) {
Map homeMethods = new HashMap();
Method[] methods = classObj.getMethods();
for(int i=0; i<methods.length; i++){
long hashCode = MethodHasher.getMethodHash(methods[i]);
homeMethods.put(String.valueOf(hashCode), methods[i]);
logger.debug("Cache method: " + hashCode + " => " + methods[i].getName());
}
return homeMethods;
}
protected Map introspectorBeanMethods(Class beanClass,Class remoteInterface) {
Map methods = new HashMap();
Method[] remoteMethods = remoteInterface.getDeclaredMethods();
for(int i=0; i<remoteMethods.length; i++){
Method _method = remoteMethods[i];
try {
Method method = beanClass.getMethod(_method.getName(),_method.getParameterTypes());
long hashCode = MethodHasher.getMethodHash(method);
methods.put(String.valueOf(hashCode), method);
logger.debug("Cache business method: " + hashCode + " => " + method.getName());
}
catch(Exception e){
throw new EJBException(e);
}
}
return methods;
}
public Method getHomeMethod(Invocation invocation) throws NoSuchMethodException {
if(!homeMethods.containsKey(invocation.getMethodHash())) {
throw new NoSuchMethodException("no such EJBHome method with method hash is " + invocation.getMethodHash());
}
return (Method)homeMethods.get(invocation.getMethodHash());
}
public Method getBeanMethod(Invocation invocation) throws NoSuchMethodException {
if(!beanMethods.containsKey(invocation.getMethodHash())) {
throw new NoSuchMethodException("no such EnterpriseBean method with method hash is " + invocation.getMethodHash());
}
return (Method)beanMethods.get(invocation.getMethodHash());
}
public EJBDescriptor getEJBDescriptor(){
return bulkMeta.getEJBDescriptor();
}
protected void doInit() throws Exception {
ContainerImpl.INITIAL_CONTEXT.bind(bulkMeta.getEJBDescriptor().getJndiName(),bulkMeta.getEJBMetaData().getEJBHome());
}
protected void doDestroy() throws Exception {
ContainerImpl.INITIAL_CONTEXT.unbind(bulkMeta.getEJBDescriptor().getJndiName());
}
}