/*
 * @(#)SessionCookie.java
 *
 * Copyright 2000-2002 by Oracle Corporation,
 * 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Oracle Corporation.
 */

package oracle.jbo.common.ampool;

import java.util.Date;
import java.util.Hashtable;

import oracle.jbo.ApplicationModule;

/**
 * Interface for session cookies.
 *
 * Session cookies are used by the client side BC4J frameworks to identify
 * unique client sessions.
 * <p>
 * The session cookie is used to uniquely identify a client session across
 * server requests and server instances.  Examples of clients include web
 * browsers and java applications.
 * <p>
 * Session cookie equality should be determined by the application and session identifiers
 * of the cookie.  Session identifiers should be unique across all client
 * sessions.  Session identifiers should also be consistent across web servers.
 * These requirements are necessary to support consistent session identification
 * across web server instances.
 * <p>
 * To illustrate the usages of the session and application identifiers consider
 * a stateful web application that is load balanced across many servlet
 * containers.  Assume that two users are accessing this application
 * from two different browsers.  Further assume that the first http request from
 * browser one is forwarded to web server one and that the first request from
 * browser two is forwarded be web server two.
 * <p>
 * At this point each browser session has created application state that is
 * maintained by their respective servers.  The BC4J portions of these states
 * are represented by two session cookie instances that have been created for
 * the two client sessions on their respective servers.  These session cookies
 * will be stored in the server session context that has been created for each
 * browser.
 * <p>
 * Now assume that the second request from browser one is forwarded to web
 * server two.  The server load balancing implementation may copy the session
 * context, which should include the session cookie that was created by the
 * first request, from web server one to web server two.
 * <p>
 * Now, if the session identifiers of the browser session cookies are
 * equal then the second request from browser one may be identified as having
 * originated from browser two and the request could "see" the state for browser
 * two.  Among other things, this could result in security leaks (imagine that
 * I am using an online shopping application and am suddenly shown a page that
 * contains the credit card information of another user).
 * <p>
 * In addition to the session identifier that is described above, the session
 * cookie also supports an application identifier.  Application identifers may
 * be used to identify unique applications.  To illustrate, assume that an online
 * shopping application must support multiple shopping carts of the same type
 * or class for each session.  One shopping cart is used to store book orders
 * while the other is used to store cd orders.  Further, in order for the
 * application to scale, assume that it is necessary to support
 * both applications with the same pool of application modules.  In order to
 * maintain the two application states separately the application framework must
 * be able to distinguish between the two session applications.  The session
 * cookie uses the application id to segment the session context for multiple
 * applications.
 * <p>
 * Developers who are implementing their own session cookies should use both
 * the application identifier and the session identifier in order to test
 * equality between cookies.
 * <p>
 * Finally, a session cookie value is a string representation of session
 * application state.  Because this representation may be activated in different
 * physical sessions (if the web server crashed between requests) the cookie
 * value should contain both the session and the passivation identifiers of the
 * cookie.  The application id a good candidate for naming the cookie because
 * it should be unique within a given session context.
 * <p>
 */
public interface SessionCookie extends ApplicationModuleRef
{
   public static final int NULL_PASSIVATION_ID = -1;

   public static final boolean SHARED = true;
   public static final boolean UNSHARED = false;
   public static final boolean STATE_MANAGED = true;
   public static final boolean STATE_UNMANAGED = false;
   
   /**
    * Returns the application id for this session cookie.
    */
   public String getApplicationId();

   /**
    * Returns the session identifier.
    * <p>
    * Session identifers should be uniques across sessions and consistent
    * across servers.
    */
   public String getSessionId();

   /**
    * Returns the session cookie value.
    * <p>
    * Session cookie values represent the session application state.
    */
   public String getValue();

   public EnvInfoProvider getEnvInfoProvider();
   
   public void setEnvInfoProvider(EnvInfoProvider envInfo);
   
   /**
    * Write the cookie value to the specified data sink.
    * <p>
    * @param sink a data sink
    */
   public void writeValue(Object sink);

   /**
    * Read the cookie value to the specified data sink.
    * <p>
    * @param source a data source
    */
   public String readValue(Object source);

   /**
    * Return an identifier for the last persisted session application state.
    * The passivation id should may used to activate a previous application
    * state.
    */
   public int getPassivationId();

   /**
    * Sets the identifier for the last persisted session application state.
    */
   public void setPassivationId(int passivationId);

   /**
    * Reserves a unique identifier for the session application.  The identifier
    * will be used to persist the session application state if session state
    * management has been enabled.
    * <p>
    * A passivation id should not be reserved if one has already been reserved, 
    * if the session cookie does not reference a reserved application module, 
    * or if failover is disabled.
    *
    * @see #getReservedPassivationId() 
    */
   public void reservePassivationId();

   /**
    * Reserves a unique identifier for the session application.  The identifier
    * will be used to persist the session application state if session state
    * management has been enabled.
    * <p>
    * If a not null sink is passed then reservePassivationId should persist
    * the reserved passivation id to the sink using {@link #writeValue(Object)}.
    * <p>
    * A passivation id should not be reserved if one has already been reserved,
    * if the session cookie does not reference a reserved application module,
    * or if failover is disabled.
    *
    * @see #getReservedPassivationId()
    */
   public void reservePassivationId(Object sink);
   
   /**
    * Return the identifier that will be used to persist the session application
    * state at the end of the request.
    * <p>
    * The next passivation id should be used when generating the session cookie
    * value.
    */
   public int getReservedPassivationId();

   /**
    * Set the identifier that will be used to persist the session application
    * state.
    */
   public void setReservedPassivationId(int reservedPassivationId);

   /**
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public void resetStateInternal();

   /**
    * Returns the signature of the pool for which this session cookie is a
    * handle.
    */
   public long getPoolSignature();

   /**
    * Sets the session environment.  When creating a session cookie the
    * application pool should use this method to initialize the new session
    * cookie instance with the default pool environment.  After initializiation
    * the developer may use this method to modify any session level application
    * pool properties.  An ApplicationPoolException will be thrown if this
    * method is invoked after the session cookie has become active.
    */
   public void setEnvironment(Hashtable environment);


   /**
    * Sets the session environment.  When creating a session cookie the
    * application pool should use this method to initialize the new session
    * cookie instance with the default pool environment.  After initializiation
    * the developer may use this method to modify any session level application
    * pool properties.  An ApplicationPoolException will be thrown if this
    * method is invoked after the session cookie has become active.
    */
   public void setEnvironment(Object key, Object value);

   /**
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public Object getSyncLock();

   /**
    * Returns a date value indicating the last time the state of this cookie
    * was updated.
    */
   public Date getLastUpdate();

   /**
    * Copies the state of this cookie into the target cookie.
    *
    * @param cookie the target of the copy.
    */
   public void copyInto(SessionCookie cookie);

   /**
    * Indicates that session application module state should be persisted
    * to secondary storage immediately upon a managed release.
    * <p>
    * Session cookie developers should be careful that this value not change
    * after a session cookie has become active.
    */
   public boolean isFailoverEnabled();

   /**
    * Indicates that the session application module resource's JDBC connection
    * should be released immediately upon release to the application pool.
    * <p>
    * Session cookie developers should be careful that this value not change
    * after a session cookie has become active.
    */
   public boolean isConnectionPoolingEnabled();

   /**
    * Indicates whether or not the non-transactional state of the session
    * application module resource should be preserved upon an unmanaged release
    * to the application pool.
    * <p>
    * Transactional state includes the state of the transaction caches (EO and VO)
    * and database state.  Non-transactional state includes child view usage
    * and application module usage instances and their related state including dynamic
    * where clauses, order by clauses, and bind parameters.  If connection pooling
    * has been disabled for the application pool then non-transaction state will
    * also include any cached JDBC statements.
    */
   public boolean isResetNonTransactionalState();

   /**
    * Indicates that state activation is required upon the next
    * checkout for this session.
    *
    * INTERNAL USE ONLY.  Applications should not use this method.
    * @deprecated ApplicationDevelopers should instead override:
    * <p>
    * {@link #isActivationRequired(ApplicationModule)}
    * <p>
    * This method will still be invoked from the new method.  
    * @since 9.0.2 
    */
   public boolean isActivationRequired();

   /**
    * Indicates that state activation is required upon the next
    * checkout for this session.  The application module is passed
    * to provide some context for the activation check.  For example, an
    * advanced developer could store some additional properties on the 
    * ApplicationModule to indicate whether or not it is necessary to 
    * activate that ApplicationModule.
    * <p>
    * The ApplicationModule may not yet be in a valid state so care
    * should be taken when accessing the ApplicationModule from a custom
    * SessionCookie implementation.
    * <p>
    * This method is invoked only if the session's affinity to its 
    * ApplicationModule was maintained between requests.  The return value 
    * of this method is ignored if the session's affinity to its 
    * ApplicationModule was lost.
    * 
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public boolean isActivationRequired(ApplicationModule context);

   /**
    * May be used to force activation upon the next checkout for this
    * session.
    *
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public void setActivationRequired(boolean activateRequired);

   /**
    * Set a session cookie listener on the cookie.
    * 
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public void setSessionCookieListener(SessionCookieListener listener);

   // These methods are automatically implemented by Object.  They have
   // been added to the interface as a reminder that they should be
   // overriden.
   public String toString();

   public int hashCode();

   public boolean equals(Object obj);

   public String getSSOUserName();

   public String getSSOSubscriber();

   /**
    * INTERNAL USE ONLY.  Applications should not use this method.
    */
   public int getThreadRefCount();
}
