/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): Philippe Durieux
 * Contributor(s):
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas_ejb.container;

import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import org.objectweb.jonas_ejb.deployment.api.SessionDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc;
import org.objectweb.jonas_ejb.lib.JavaType;

/**
 * This class is a factory for a Session Stateful Bean.
 */
public class JStatefulFactory extends JSessionFactory {

    JStatefulPool statefulPool;

    /**
     * constructor
     */
    public JStatefulFactory(SessionStatefulDesc dd, JContainer cont, JStatefulPool sfp) {
	super((SessionDesc)dd, cont);
	TraceEjb.debugIc("JStatefulFactory constructor");
	isSynchro = javax.ejb.SessionSynchronization.class.isAssignableFrom(beanclass);
	isStateful = true;
	statefulPool = sfp;
    }

    // ---------------------------------------------------------------
    // BeanFactory implementation
    // ---------------------------------------------------------------

    /**
     * @return the Instance pool size for this Ejb
     */
    public int getPoolSize() {
	return 0;		// TODO
    }

    // ---------------------------------------------------------------
    // preInvoke / postInvoke
    // ---------------------------------------------------------------

    /**
     * preInvoke for Session beans stateful
     */
    public RequestCtx preInvoke(int txa, String secu) {
	TraceEjb.debugIc("JStatefulFactory preInvoke");
	RequestCtx rctx = super.preInvoke(txa, secu);
	return rctx;
    }

    /**
     * postinvoke
     */
    public void postInvoke(RequestCtx rctx) {
	TraceEjb.debugIc("JStatefulFactory postInvoke");
	super.postInvoke(rctx);
    }

    // ---------------------------------------------------------------
    // other public methods
    // ---------------------------------------------------------------

    /**
     * Creates a new Session Stateful
     * callback from createEJB
     */
    public JSessionSwitch createNewSession() throws RemoteException {
	TraceEjb.debugIc("JStatefulFactory createNewSession");
	JStatefulSwitch bs = new JStatefulSwitch(this, statefulPool);
	return bs;
    }

    /**
     * get a new session context
     * must call newInstance (EJB specs) => no pool should be used.
     */
    public JSessionContext getJContext() {
	TraceEjb.debugIc("JStatefulFactory getJContext");
	JStatefulContext bctx = null;
	try {
	    bctx = createNewInstance();
	} catch (Exception e) {
	    throw new EJBException("Cannot create a new instance");
	}
	return bctx;
    }

    // ---------------------------------------------------------------
    // private methods
    // ---------------------------------------------------------------

    /**
     * Create a new instance of the bean and its StatefulContext
     */
    private JStatefulContext createNewInstance() throws Exception {
	TraceEjb.debugIc("JStatefulFactory createNewInstance");
	// create the bean instance
	SessionBean bean = null;
	try {
	    bean = (SessionBean) beanclass.newInstance();
	} catch (InstantiationException e) {
	    TraceEjb.error(ejbname+" Cannot instantiate SessionBean");
	    throw e;
	} catch (IllegalAccessException e) {
	    TraceEjb.error(ejbname+" Cannot instantiate SessionBean");
	    throw e;
	}
	// create a new StatefulContext and bind it to the instance
	JStatefulContext bctx = new JStatefulContext(this, bean, isSynchro);
	bean.setSessionContext(bctx);
	return bctx;
    }

}
