/* 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 javax.ejb.SessionBean;
import javax.ejb.Handle;
import javax.ejb.RemoveException;
import javax.ejb.EnterpriseBean;
import javax.ejb.SessionContext;

/**
 * 执行在 EJBObject EJBHome 中定义的方法
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class StatelessSessionBulk extends SessionBulk {

  private StatelessSessionObjectPool instancePool = null;
  /**
   * StatlessSessionBean 每次返回同样的ObjectId
   */
  private ObjectId beanObjectId = null;
  private SessionContext ejbConext = null;

  public StatelessSessionBulk(BulkMetaData meta) {
    super(meta);
  }

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

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

  }

  // 对于 StatelessSessionBean,这个方法不执行任何操作
  public void remove(Handle handle) throws RemoteException, RemoveException {
    try {
      EJBPoolableObject pobj = (EJBPoolableObject)instancePool.retrieveObject();
      remove(pobj.getBeanInstance());
    }
    catch(Exception e) {
      throw new RemoveException(e.getMessage());
    }
  }

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

  // 对于 StatelessSessionBean, 总是返回 true
  public boolean isIdentical(ObjectId thisObjectId, ObjectId thatObjectId) throws RemoteException {
    return true;
  }

  public EJBPoolableObject retrieveBean(Object key) throws Exception {
    StatelessEJBPoolableObject pobj = (StatelessEJBPoolableObject)instancePool.retrieveObject();
    if(pobj.isFresh()) { // 新生的对象,要调用 setSessionContext, ejbCreate
      SessionBean bean = (SessionBean)pobj.getBeanInstance();
      setSessionContext(bean, ejbConext);
      ejbCreate(bean,"create",null);
      pobj.notFresh();
    }
    return pobj;
  }

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

  public ObjectId createBean(Invocation invocation) throws Exception {
    if(beanObjectId == null) { // 第一次调用 create ,生成 beanObjectId,ejbContext
      beanObjectId = oidGenerator.nextBeanObjectId();
      ejbConext = new SessionContextImpl(beanObjectId,bulkMeta);
    }
    StatelessEJBPoolableObject pobj = (StatelessEJBPoolableObject)instancePool.createObject();
    if(pobj.isFresh()) { // 新生的对象,要调用 setSessionContext, ejbCreate
      SessionBean bean = (SessionBean)pobj.getBeanInstance();
      setSessionContext(bean, ejbConext);
      // stateless session bean 只有一个没有参数的 ejbCreate 方法
      ejbCreate(bean,"create",null);
      pobj.notFresh();
    }
    this.restoreBean(invocation.getObjectId(),pobj);
    return beanObjectId;
  }

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

  protected void doDestroy() throws Exception {
    super.doDestroy();
    instancePool.destroy();
  }
}