/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */


package javax.jms;

/** A <CODE>ServerSession</CODE> object is an application server object that 
  * is used by a server to associate a thread with a JMS session (optional).
  *
  * <P>A <CODE>ServerSession</CODE> implements two methods:
  *
  * <UL>
  *   <LI><CODE>getSession</CODE> - returns the <CODE>ServerSession</CODE>'s 
  *       JMS session.
  *   <LI><CODE>start</CODE> - starts the execution of the 
  *       <CODE>ServerSession</CODE> 
  *       thread and results in the execution of the JMS session's 
  *       <CODE>run</CODE> method.
  * </UL>
  *
  * <P>A <CODE>ConnectionConsumer</CODE> implemented by a JMS provider uses a 
  * <CODE>ServerSession</CODE> to process one or more messages that have 
  * arrived. It does this by getting a <CODE>ServerSession</CODE> from the 
  * <CODE>ConnectionConsumer</CODE>'s <CODE>ServerSessionPool</CODE>; getting 
  * the <CODE>ServerSession</CODE>'s JMS session; loading it with the messages; 
  * and then starting the <CODE>ServerSession</CODE>.
  *
  * <P>In most cases the <CODE>ServerSession</CODE> will register some object 
  * it provides as the <CODE>ServerSession</CODE>'s thread run object. The 
  * <CODE>ServerSession</CODE>'s <CODE>start</CODE> method will call the 
  * thread's <CODE>start</CODE> method, which will start the new thread, and 
  * from it, call the <CODE>run</CODE> method of the 
  * <CODE>ServerSession</CODE>'s run object. This object will do some 
  * housekeeping and then call the <CODE>Session</CODE>'s <CODE>run</CODE> 
  * method. When <CODE>run</CODE> returns, the <CODE>ServerSession</CODE>'s run 
  * object can return the <CODE>ServerSession</CODE> to the 
  * <CODE>ServerSessionPool</CODE>, and the cycle starts again.
  *
  * <P>Note that the JMS API does not architect how the 
  * <CODE>ConnectionConsumer</CODE> loads the <CODE>Session</CODE> with 
  * messages. Since both the <CODE>ConnectionConsumer</CODE> and 
  * <CODE>Session</CODE> are implemented by the same JMS provider, they can 
  * accomplish the load using a private mechanism.
  *
  * @version     1.0 - 9 March 1998
  * @author      Mark Hapner
  * @author      Rich Burridge
  *
  * @see         javax.jms.ServerSessionPool
  * @see         javax.jms.ConnectionConsumer
  */

public interface ServerSession {

    /** Return the <CODE>ServerSession</CODE>'s <CODE>Session</CODE>. This must 
      * be a <CODE>Session</CODE> created by the same <CODE>Connection</CODE> 
      * that will be dispatching messages to it. The provider will assign one or
      * more messages to the <CODE>Session</CODE> 
      * and then call <CODE>start</CODE> on the <CODE>ServerSession</CODE>.
      *
      * @return the server session's session
      *  
      * @exception JMSException if the JMS provider fails to get the associated
      *                         session for this <CODE>ServerSession</CODE> due
      *                         to some internal error.
      **/

    Session
    getSession() throws JMSException;


    /** Cause the <CODE>Session</CODE>'s <CODE>run</CODE> method to be called 
      * to process messages that were just assigned to it.
      *  
      * @exception JMSException if the JMS provider fails to start the server
      *                         session to process messages due to some internal
      *                         error.
      */

    void 
    start() throws JMSException; 
}
