/* 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;

import java.rmi.RemoteException;
import java.lang.reflect.Proxy;
import javax.ejb.RemoveException;
import javax.ejb.Handle;
import javax.ejb.EnterpriseBean;
import javax.ejb.SessionBean;
import javax.ejb.EJBObject;

import org.jfox.ejb.invoker.ContainerInvokerSupport;

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

public class StatefulSessionBulk extends SessionBulk {

  private StatefulSessionObjectPool instancePool = null;
  public StatefulSessionBulk(BulkMetaData meta) {
    super(meta);
  }

  /**
   * 来自 EJBHome 的方法
   * @param invocation
   * @return
   * @throws Exception
   */
  public Object invokeHome(Invocation invocation) throws Exception {
    logger.debug("invokeHome " + invocation.getMethod().getName());
    return StatefulInvokerChain.getInstance().invokeHome(this,invocation);
  }

  /**
   * 执行 Bean 的方法
   * @param invocation
   * @return
   * @throws Exception
   */  
  public Object invokeBean(Invocation invocation) throws Exception {
    logger.debug("invokeBean " + invocation.getMethod().getName());
    return StatefulInvokerChain.getInstance().invokeBean(this,invocation);
  }

  public void remove(EnterpriseBean bean) throws RemoteException, RemoveException {
    ejbRemove((SessionBean)bean);
  }

  public void remove(Handle handle) throws RemoteException, RemoveException {
    EJBObject ejbObject = handle.getEJBObject();
    // Handle 实际上是一个代理对象,保存了 ObjectId 在里面
    ObjectId objectId = ((ContainerInvokerSupport)Proxy.getInvocationHandler(ejbObject)).getObjectId();
    try {
      EJBPoolableObject pobj = (EJBPoolableObject)instancePool.retrieveObject(objectId);
      remove(pobj.getBeanInstance());
    }
    catch(Exception e) {
      throw new RemoveException(e.getMessage());
    }
  }

  public boolean isIdentical(ObjectId thisObjectId, ObjectId thatObjectId) throws RemoteException {
    return thisObjectId.equals(thatObjectId);
  }

  public EJBPoolableObject retrieveBean(Object key) {
    try {
      return (EJBPoolableObject)instancePool.retrieveObject(key);
    }
    catch(Exception e){
      e.printStackTrace();
      return null;
    }
  }

  public void restoreBean(Object key, EJBPoolableObject pobj) {
    instancePool.restoreObject(key,pobj);
  }

  public ObjectId createBean(Invocation invocation) throws Exception {
    ObjectId beanObjectId = oidGenerator.nextBeanObjectId();
    EJBPoolableObject pobj = (EJBPoolableObject)instancePool.createObject();
    SessionBean bean = (SessionBean)pobj.getBeanInstance();
    setSessionContext(bean, new SessionContextImpl(beanObjectId,bulkMeta));
    ejbCreate(bean,invocation.getMethod().getName(),invocation.getArgs());
    instancePool.restoreObject(beanObjectId,pobj);
    return beanObjectId;
  }

  protected void doInit() throws Exception {
    instancePool = new StatefulSessionObjectPool(this,new EJBObjectFactory(EJBPoolableObject.class,bulkMeta.getBeanClass()));
    instancePool.init();
    super.doInit();
  }

  protected void doDestroy() throws Exception {
    super.doDestroy();
    // 销毁 instancePool 的时候,会序列化所有的实例,并且不再受 LifeCycleManager 的监控
    instancePool.destroy();
  }

  public static void main(String[] args) {

  }
}