/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.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
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.lib.ejb21;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.security.Principal;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.RemoveException;
import javax.ejb.SessionBean;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.xml.rpc.handler.MessageContext;

import org.objectweb.util.monolog.api.BasicLevel;

/**
 * This class extends JSessionContext in case of Stateless Session Bean.
 * @author Philippe Durieux
 */
public class JStatelessContext extends JSessionContext implements TimerService {

    /**
     * constructor
     * @param bf The Bean Factory
     * @param sb The Session Bean instance.
     */
    public JStatelessContext(JSessionFactory bf, SessionBean sb) {
        super(bf, sb);
        if (TraceEjb.isDebugIc()) {
            TraceEjb.interp.log(BasicLevel.DEBUG, "");
        }
    }

    /**
     * Get access to the EJB Timer Service.
     * @return the EJB Timer Service
     * @throws IllegalStateException Thrown if the instance is not allowed to
     *         use this method
     */
    public TimerService getTimerService() throws IllegalStateException {
        if (TraceEjb.isDebugIc()) {
            TraceEjb.interp.log(BasicLevel.DEBUG, "");
        }
        if (getState() == 0) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        if (getState() == 1) {
            // Called from ejbCreate : getTimerService should work, but
            // not the timer operations! (See spec EJB 2.1 page 100)
            return this;
        }
        return bf.getTimerService();
    }

    /**
     * set this instance as removed
     */
    public void setRemoved() throws RemoteException, RemoveException {
        if (TraceEjb.isDebugIc()) {
            TraceEjb.interp.log(BasicLevel.DEBUG, "");
        }
        // Set a flag to finish remove at postInvoke.
        ismarkedremoved = true;
    }

    /**
     * Obtain a reference to the JAX-RPC MessageContext.
     * @return The MessageContext for this web service invocation.
     * @throws java.lang.IllegalStateException - the instance is in a state that
     *         does not allow access to this method.
     */
    public MessageContext getMessageContext() throws IllegalStateException {
        if (bs == null) {
            throw new IllegalStateException("No SessionSwitch for that bean");
        }
        MessageContext mc = ((JStatelessSwitch) bs).getMsgContext();
        if (mc == null) {
            throw new IllegalStateException("No ServiceEndpoint for that bean");
        }
        return mc;
    }

    /**
     * Set the connection list for this instance.
     */
    public void setConnectionList(List conlist) {
        throw new IllegalStateException("Stateless beans should not reuse connections");
    }

    /**
     * Obtain the java.security.Principal that identifies the caller.
     * throws a java.lang.IllegalStateException if there is no security context available
     * @return The Principal object that identifies the caller.
     * @throws IllegalStateException no security context exists
     */
    public Principal getCallerPrincipal() throws IllegalStateException {
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return super.getCallerPrincipal();
    }

    /**
     * Test if the caller has a given role.
     * @param roleName The name of the security role. The role must be one of
     *        the security-role-ref that is defined in the deployment
     *        descriptor.
     * @return True if the caller has the specified role.
     * @throws IllegalStateException Security service not started
     */
    public boolean isCallerInRole(String roleName) throws IllegalStateException {
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return super.isCallerInRole(roleName);
    }

    /**
     * @see javax.ejb.TimerService#createTimer(long, java.io.Serializable)
     */
    public Timer createTimer(long arg0, Serializable arg1) throws IllegalArgumentException, IllegalStateException, EJBException {
        // Not allowed when called from ejbCreate
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return getTimerService().createTimer(arg0, arg1);
    }

    /**
     * @see javax.ejb.TimerService#createTimer(long, long, java.io.Serializable)
     */
    public Timer createTimer(long arg0, long arg1, Serializable arg2) throws IllegalArgumentException,
            IllegalStateException, EJBException {
        // Not allowed when called from ejbCreate
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return getTimerService().createTimer(arg0, arg1, arg2);
    }

    /**
     * @see javax.ejb.TimerService#createTimer(java.util.Date, java.io.Serializable)
     */
    public Timer createTimer(Date arg0, Serializable arg1) throws IllegalArgumentException, IllegalStateException, EJBException {
        // Not allowed when called from ejbCreate
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return getTimerService().createTimer(arg0, arg1);
    }

    /**
     * @see javax.ejb.TimerService#createTimer(java.util.Date, long, java.io.Serializable)
     */
    public Timer createTimer(Date arg0, long arg1, Serializable arg2) throws IllegalArgumentException, IllegalStateException, EJBException {
        // Not allowed when called from ejbCreate
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return getTimerService().createTimer(arg0, arg1, arg2);
  }

    /**
     * @see javax.ejb.TimerService#getTimers()
     */
    public Collection getTimers() throws IllegalStateException, EJBException {
        // Not allowed when called from ejbCreate
        if (getState() < 2) {
            throw new IllegalStateException("the instance is not allowed to call this method");
        }
        return getTimerService().getTimers();
   }


}
