/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Pluto", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * ====================================================================
 *
 * This source code implements specifications defined by the Java
 * Community Process. In order to remain compliant with the specification
 * DO NOT add / change / or delete method signatures!
 */

package javax.portlet;



/**
 * The <CODE>PortletSession</CODE> interface provides a way to identify a user
 * across more than one request and to store transient information about that user.
 * <p>
 * A <code>PortletSession</code> is created per user client per portlet application.
 * <p>
 * A portlet can bind an object attribute into a <code>PortletSession</code> by name.
 * The <code>PortletSession</code> interface defines two scopes for storing objects:
 * <ul>
 * <li><code>APPLICATION_SCOPE</code>
 * <li><code>PORTLET_SCOPE</code>
 * </ul>
 * All objects stored in the session using the <code>APPLICATION_SCOPE</code> 
 * must be available to all the portlets, servlets and 
 * JSPs that belongs to the same portlet application and that handles a 
 * request identified as being a part of the same session.
 * Objects stored in the session using the <code>PORTLET_SCOPE</code> must be
 * available to the portlet during requests for the same portlet window
 * that the objects where stored from. Attributes stored in the
 * <code>PORTLET_SCOPE</code> are not protected from other web components
 * of the portlet application. They are just conveniently namespaced.
 * <P>
 * The portlet session is based on the <code>HttpSession</code>. Therefore all
 * <code>HttpSession</code> listeners do apply to the portlet session and
 * attributes set in the portlet session are visible in the <code>HttpSession</code>
 * and vice versa.
 */
public interface PortletSession
{


  /**
   * This constant defines an application wide scope for the session attribute.
   * <code>APPLICATION_SCOPE</code> session attributes enable Portlets 
   * within one portlet application to share data.
   * <p>
   * Portlets may need to prefix attributes set in this scope with some
   * ID, to avoid overwriting each other's attributes in the
   * case where two portlets of the same portlet definition
   * are created.
   * <p>
   * Value: <code>0x01</code>
   */
  public static final int APPLICATION_SCOPE = 0x01;

  /**
   * This constant defines the scope of the session attribute to be
   * private to the portlet and its included resources. 
   * <p>
   * Value: <code>0x02</code>
   */
  public static final int PORTLET_SCOPE = 0x02;



  /**
   * Returns the object bound with the specified name in this session
   * under the <code>PORTLET_SCOPE</code>, or <code>null</code> if no 
   * object is bound under the name in that scope.
   *
   * @param name		a string specifying the name of the object
   *
   * @return			the object with the specified name for
   *                            the <code>PORTLET_SCOPE</code>.
   *
   * @exception java.lang.IllegalStateException	if this method is called on an
   *					invalidated session.
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */

  public java.lang.Object getAttribute(java.lang.String name);

  
  /**
   * Returns the object bound with the specified name in this session, 
   * or <code>null</code> if no object is bound under the name in the given scope.
   *
   * @param name		a string specifying the name of the object
   * @param scope               session scope of this attribute
   *
   * @return			the object with the specified name
   *
   * @exception java.lang.IllegalStateException	if this method is called on an
   *					invalidated session
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */

  public java.lang.Object getAttribute(java.lang.String name,int scope);


  /**
   * Returns an <code>Enumeration</code> of String objects containing the names of 
   * all the objects bound to this session under the <code>PORTLET_SCOPE</code>, or an
   * empty <code>Enumeration</code> if no attributes are available.
   *
   * @return			an <code>Enumeration</code> of 
   *				<code>String</code> objects specifying the
   *				names of all the objects bound to
   *				this session, or an empty <code>Enumeration</code> 
   *                if no attributes are available.
   *
   * @exception java.lang.IllegalStateException	if this method is called on an
   *					invalidated session   
   */
  
  public java.util.Enumeration getAttributeNames();


  /**
   * Returns an <code>Enumeration</code> of String objects containing the names of 
   * all the objects bound to this session in the given scope, or an
   * empty <code>Enumeration</code> if no attributes are available in the
   * given scope.
   *
   * @param scope               session scope of the attribute names
   *
   * @return			an <code>Enumeration</code> of 
   *				<code>String</code> objects specifying the
   *				names of all the objects bound to
   *				this session, or an empty <code>Enumeration</code> 
   *                            if no attributes are available in the given scope.
   *
   * @exception java.lang.IllegalStateException	if this method is called on an
   *					invalidated session   
   */
  
  public java.util.Enumeration getAttributeNames(int scope);

  /**
   * Returns the time when this session was created, measured in 
   * milliseconds since midnight January 1, 1970 GMT.  
   *
   * @return				a <code>long</code> specifying
   * 					when this session was created,
   *					expressed in 
   *					milliseconds since 1/1/1970 GMT
   *
   * @exception java.lang.IllegalStateException	if this method is called on an
   *					invalidated session
   */

  public long getCreationTime();
  

  /**
   * Returns a string containing the unique identifier assigned to this session. 
   *
   * @return				a string specifying the identifier
   *					assigned to this session
   */
  
  public java.lang.String getId();
  

  /**
   * Returns the last time the client sent a request associated with this session, 
   * as the number of milliseconds since midnight January 1, 1970 GMT.  
   *
   * <p>Actions that your portlet takes, such as getting or setting
   * a value associated with the session, do not affect the access
   * time.
   *
   * @return				a <code>long</code>
   *					representing the last time 
   *					the client sent a request associated
   *					with this session, expressed in 
   *					milliseconds since 1/1/1970 GMT
   */
  
  public long getLastAccessedTime();


  /**
   * Returns the maximum time interval, in seconds, for which the portlet container 
   * keeps this session open between client accesses. After this interval, 
   * the portlet container invalidates the session.  The maximum time 
   * interval can be set
   * with the <code>setMaxInactiveInterval</code> method.
   * A negative time indicates the session should never timeout.
   *
   * @return		an integer specifying the number of
   *			seconds this session remains open
   *			between client requests
   *
   * @see		#setMaxInactiveInterval
   */

  public int getMaxInactiveInterval();


  /**
   * Invalidates this session (all scopes) and unbinds any objects bound to it.  
   * <p>
   * Invalidating the portlet session will result in invalidating the underlying
   * <code>HttpSession</code>
   *
   * @exception java.lang.IllegalStateException	if this method is called on a
   *					session which has already been invalidated
   */

  public void invalidate();



  /**
   * Returns true if the client does not yet know about the session or 
   * if the client chooses not to join the session. 
   *
   * @return 				<code>true</code> if the 
   *					server has created a session, 
   *					but the client has not joined yet.
   *
   * @exception java.lang.IllegalStateException	if this method is called on a
   *					session which has already been invalidated
   *
   */

  public boolean isNew();
  

  /**
   * Removes the object bound with the specified name under
   * the <code>PORTLET_SCOPE</code> from
   * this session. If the session does not have an object
   * bound with the specified name, this method does nothing.
   * 
   * @param name   the name of the object to be
   *               removed from this session in the 
   *               <code> PORTLET_SCOPE</code>.
   *
   * @exception java.lang.IllegalStateException
   *                   if this method is called on a
   *                   session which has been invalidated
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */
  
  public void removeAttribute(String name) ;


  /**
   * Removes the object bound with the specified name and the given scope from
   * this session. If the session does not have an object
   * bound with the specified name, this method does nothing.
   * 
   * @param name   the name of the object to be
   *               removed from this session
   * @param scope  session scope of this attribute
   *
   * @exception java.lang.IllegalStateException
   *                   if this method is called on a
   *                   session which has been invalidated
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */
  
  public void removeAttribute(String name, int scope) ;


  /**
   * Binds an object to this session under the <code>PORTLET_SCOPE</code>, using the name specified.  
   * If an object of the same name in this scope is already bound to the session,
   * that object is replaced.
   *
   * <p>After this method has been executed, and if the new object
   * implements <code>HttpSessionBindingListener</code>,
   * the container calls 
   * <code>HttpSessionBindingListener.valueBound</code>. The container then   
   * notifies any <code>HttpSessionAttributeListeners</code> in the web 
   * application.
   * <p>If an object was already bound to this session 
   * that implements <code>HttpSessionBindingListener</code>, its 
   * <code>HttpSessionBindingListener.valueUnbound</code> method is called.
   *
   * <p>If the value is <code>null</code>, this has the same effect as calling 
   * <code>removeAttribute()</code>.
   *
   *
   * @param name		the name to which the object is bound under
   *                            the <code>PORTLET_SCOPE</code>;
   *				this cannot be <code>null</code>.
   * @param value		the object to be bound
   *
   * @exception java.lang.IllegalStateException	if this method is called on a
   *					session which has been invalidated
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */
  
  public void setAttribute(java.lang.String name, java.lang.Object value);


  /**
   * Binds an object to this session in the given scope, using the name specified.  
   * If an object of the same name in this scope is already bound to the session,
   * that object is replaced.
   *
   * <p>After this method has been executed, and if the new object
   * implements <code>HttpSessionBindingListener</code>,
   * the container calls 
   * <code>HttpSessionBindingListener.valueBound</code>. The container then   
   * notifies any <code>HttpSessionAttributeListeners</code> in the web 
   * application.
   * <p>If an object was already bound to this session 
   * that implements <code>HttpSessionBindingListener</code>, its 
   * <code>HttpSessionBindingListener.valueUnbound</code> method is called.
   *
   * <p>If the value is <code>null</code>, this has the same effect as calling 
   * <code>removeAttribute()</code>.
   *
   *
   * @param name		the name to which the object is bound;
   *				this cannot be <code>null</code>.
   * @param value		the object to be bound
   * @param scope               session scope of this attribute
   *
   * @exception java.lang.IllegalStateException	if this method is called on a
   *					session which has been invalidated
   * @exception  java.lang.IllegalArgumentException 
   *                            if name is <code>null</code>.
   */
  
  public void setAttribute(java.lang.String name, java.lang.Object value, int scope);


  /**
   * Specifies the time, in seconds, between client requests, before the 
   * portlet container invalidates this session. A negative time
   * indicates the session should never timeout.
   *
   * @param interval		An integer specifying the number
   * 				of seconds 
   */

  public void setMaxInactiveInterval(int interval);


  /**
   * Returns the portlet application context associated with this session.
   *
   * @return   the portlet application context
   */

  public PortletContext getPortletContext ();

}


