/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.com
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

package org.jfox.ejb.invoker.local;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.ejb.EJBObject;

import org.jfox.ejb.EJBHomeMethod;
import org.jfox.ejb.EJBObjectMethod;
import org.jfox.ejb.HandleImpl;
import org.jfox.ejb.Invocation;
import org.jfox.ejb.InvocationImpl;
import org.jfox.ejb.ObjectId;
import org.jfox.ejb.invoker.ContainerRemote;
import org.jfox.ejb.invoker.ContainerInvokerSupport;

/**
 * 
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class LOCALContainerInvoker extends ContainerInvokerSupport{

  public LOCALContainerInvoker(ObjectId objectId, ContainerRemote invoker) {
    super(objectId, invoker);
    if(!(invoker instanceof LOCALContainerService)) {
//      System.out.println(invoker.getClass().getClassLoader() + " <=> " + LOCALContainerService.class.getClassLoader());
      throw new RuntimeException(invoker + " is not a instance of " + LOCALContainerService.class);
    }
  }

  protected Object invokeHome(Object proxy, Method method, Object[] args) throws Exception {
    Invocation invocation = new InvocationImpl(objectId,new Long(getMethodHash(method)).toString(),args);

    if(method.equals(EJBHomeMethod.GetEJBMetaData)) {
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBHomeMethod.GetHomeHandle)) {
//      String homeClass = objectId.getHomeInterfName();
//      return new HomeHandleImpl(homeClass);
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBHomeMethod.RemoveByHandle)){
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBHomeMethod.RemoveByPrimaryKey)){
      return invoker.invoke(invocation);
    }
    else { // create 方法
      Object obj = invoker.invoke(invocation); // obj 是 EJBObject 的 ID
      ObjectId objectId = (ObjectId)obj;
      ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
      // get the EJBObject class name
      String remoteInterfaceName = objectId.getRemoteInterfaceName();
      Class remoteInterface = ctxLoader.loadClass(remoteInterfaceName);
      // 构造本地的 EJBObject 代理对象
      return Proxy.newProxyInstance(ctxLoader,
              new Class[]{remoteInterface},
              new LOCALContainerInvoker(objectId,invoker));
    }
  }

  protected Object invokeBean(Object proxy, Method method, Object[] args) throws Exception {
    Invocation invocation = new InvocationImpl(objectId,new Long(getMethodHash(method)).toString(),args);
    if(method.equals(EJBObjectMethod.GetEJBHome)) {
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBObjectMethod.GetHandle)){
      ContainerInvokerSupport invocationHandler = (ContainerInvokerSupport)Proxy.getInvocationHandler(proxy);
      return new HandleImpl(invocationHandler);
    }
    else if(method.equals(EJBObjectMethod.GetPrimaryKey)){
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBObjectMethod.IsIdentical)){
      // 把参数 args[0] 转换为 EJBObject 的 ObjectId,服务端只用 ObjectId 来比较
      EJBObject ejbObject = (EJBObject)args[0];
      ObjectId _objectId = ((ContainerInvokerSupport)(Proxy.getInvocationHandler(ejbObject))).getObjectId();
      invocation = new InvocationImpl(objectId,new Long(getMethodHash(method)).toString(),new ObjectId[]{_objectId});
      return invoker.invoke(invocation);
    }
    else if(method.equals(EJBObjectMethod.Remove)){
      return invoker.invoke(invocation);
    }
    else {
      return invoker.invoke(invocation);
    }
  }

  public static void main(String[] args) {

  }
}