/*
 * @(#)ApplicationPool.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 com.sun.java.util.collections.ArrayList;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Properties;
import oracle.jbo.ApplicationModule;

/**
 * This is the ApplicationPool interface. It needs to be implemented by any
 * class that is intended to provide a customized pool interface. Look at
 * ApplicationPoolImpl for the default implementation.
 * <BR>
 * <a HREF="ApplicationPool.txt">View Implementation of ApplicationPool</a>
 * <a HREF="ApplicationPoolImpl.txt">View Implementation of ApplicationPoolImpl</a>
 * <P>
 */
public interface ApplicationPool extends Serializable
{
   /**
    * This initializes the ApplicationPool. The Pool name should be unique
    * with respect to any other pools. An exception will be thrown on any
    * errors such as duplicate pool name or mismatched information within the
    * connectInfo parameter.
    *
    * @param poolName the name of the application module pool.
    *
    * @param applicationModule name of the application module for which the pool
    *    will be created.
    *
    * @param connectString the connection string to use to connect to the
    *    database.
    *
    * @param env name of the hash table containing the environment variables for
    *    the selected platform.
    */
   public void initialize(
      String poolName
      , String applicationModule
      , String connectString
      , Hashtable env);

   /**
    * Return the class name of the application modules being managed by the
    * pool.
    */
   public String getApplicationModuleClass();

   /**
    * Returns the Hashtable that was used to initialize the Context for the
    * application module instances.
    */
   public Hashtable getEnvironment();

   /**
    * This method may be used by clients if they are manually populating
    * the pool with application module instances using {@link #createInstance()}
    * to notify the pool when a new instance is ready for use by other threads.
    *
    * Pool clients should not use this method after an application module
    * has been set available for the first time.
    *
    * @param appModule the application module which will be made available
    */
   public void setAvailable(ApplicationModule appModule);

   /**
    * Returns an application module for the specified session cookie.  If the
    * session has not already checked out an application module instance and
    * the checkout flag is true then the application pool should checkout an
    * application module instance for the specified session.
    * <p>
    * The requesting thread may obtain an application module with the state from
    * a previous request by passing the previous request's cookie instance.  The 
    * cookie should be used by the pool to re-create an application module state 
    * from a previous request.
    * <p>
    * If an "empty" session cookie is specified then the pool should return a
    * stateless application module instance.  An empty session cookie is defined
    * as a cookie that does not reference a previous application module state.
    * Please see {@link oracle.jbo.common.ampool.SessionCookie#getPassivationId()}
    * for more information regarding application state maintenance.
    * <p>
    * In order to persist some internal state information, the application pool
    * may mutate the specified cookie.  Application pool clients should
    * consequently be careful to reference the cookie value that is returned in
    * the cookie value after checkout has been invoked.
    * <p>
    * @param cookie an empty/previous session cookie
    */
   public ApplicationModule useApplicationModule(SessionCookie cookie, boolean checkout);

   /**
    * Mark the session's application module as available for reuse by other
    * sessions.
    * <p>
    * If the managed flag is true then the pool will maintain logical
    * application module state while still sharing an application module
    * resource between sessions.
    * <p>
    * When an application module is marked available with managed state the
    * application module will be passivated immediately if failover support
    * has been requested (default).  If failover support has been disabled,
    * through the jbo.DoFailover system parameter, the application module will
    * not be passivated until it is re-used by a session other than the
    * session releasing in the application module.
    * <p>
    * Please see {@link oracle.jbo.common.ampool.SessionCookie} for more
    * information regarding session identification and application state
    * tracking.
    *
    * @param cookie a session cookie equal to the session cookie that was
    *   generated during checkout
    *
    * @param manageState indicates if the session's application module state
    *    should be managed by the pool
    */
   public void releaseApplicationModule(SessionCookie cookie, boolean manageState);

   /**
    * Remove all of the pool application module instances that have been
    * created so far.
    * <p>
    * The <tt>remove()</tt> method is called on the Application Modules being
    * represented by the application instance class
    */
   public ArrayList removeResources();

   /**
    * Remove the resource from the application pool.
    * <p>
    * The <tt>remove()</tt> method is called on the Application Module being
    * represented by the application instance class
    */
   public Object removeResource(Object resource);

   /**
    *  Returns the number of instances that the Application Pool has created.
    */
   public int  getInstanceCount();

   /**
    *  Returns the available number of instances in the Application Pool.
    */
   public int getAvailableInstanceCount();

   /**
    *  Returns the pool's name.
    */
   public String getName();

   /**
    *  Returns the User Data hashtable. This is a generic container for
    *  any settings the user would like to associate with this application pool.
    */
   public Hashtable getUserData();

   /**
    * Replaces the userData with the new Hashtable.
    * @param the new hashtable to use for the environment information.
    */
   public void setUserData(Hashtable data);

   /**
    * Gets the time that it will tke to create the application module
    * (in milli-secs).
    * @param instance the application module instance for which you want to
    * know how long it will take to create it.
    */
   public long getTimeToCreateMillis(ApplicationModule instance);

   /**
    * Gets the time when the app module was created (in milli-secs).
    * @param instance the application module instance for which you want to
    * know the time of creation.
    */
   public long getCreationTimeMillis(ApplicationModule instance);

   /**
    * Given an intitial Application Module instance, synchronizes the caches of all
    * Application Module instances in the pool.
    * <p>
    * This method commits the transaction for <tt>instance</tt>.
    * Then, it loops through all other instances of the
    * Application Module
    * in the pool and synchronizes their caches with the
    * changes committed by <tt>instance</tt>.
    * For example:
    * <p>
    * <pre>
    *  // Insert a new row
    *     row = voEmp1.createRow();
    *
    *     row.setAttribute("EmpNum", new Integer(9999));
    *     row.setAttribute("EmpName", "NewPers");
    *     row.setAttribute("EmpJob", "JOBX");
    *
    *     voEmp1.insertRow(row);
    *
    *  // Commit the changes for the specified instance, then sync
    *  // them with the rest of the Application Module instances.
    *     pool1.commitAndSyncCache(am1);
    * </pre>
    * <p>
    * @param instance an instance of an Application Module in the pool.
    */
   public void commitAndSyncCache(ApplicationModule instance);

   /**
    * Get the application module strategy that will be used to create, connect,
    * disconnect, and reconnect the application module.
    */
   public ConnectionStrategy getConnectionStrategy();
   
   /**
    * Set the application module strategy that will be used to create, connect,
    * disconnect, and reconnect the application module.
    */
   public void setConnectionStrategy(ConnectionStrategy strategy);
     
   /**
    * Get the factory that will be used to create new session cookie instances.
    */
   public SessionCookieFactory getSessionCookieFactory();

   /**
    * Set the factory that will be used to create new session cookie instances.
    */
   public void setSessionCookieFactory(SessionCookieFactory sessionCookieFactory);

   /**
    * Create a session cookie for access to this pool.  Session cookies
    * are used by the application pool to uniquely identify a pool client.
    *
    * @param applicationId identifies the session application
    * @param cookieValue a cookieValue from a previous request
    * @param properties additional user properties.  This parameter may be used
    *    to pass application specific information to a session cookie factory.
    */
   public SessionCookie createSessionCookie(String applicationId, String cookieValue, Properties properties);

   /**
    * Add an existing session cookie to the pool.  The session cookie must
    * have been created by a pool instance with the same signature as this
    * pool.
    *
    * This method may be used to add a de-serialized cookie to an existing pool
    * instance.
    *
    * @see #createSessionCookie(String, String, Properties)
    * @see #validateSessionCookie(SessionCookie)
    */
   public void addSessionCookie(SessionCookie cookie);

   /**
    * Destroy a session cookie.
    */
   public void removeSessionCookie(SessionCookie cookie);

   /**
    * Validate that a session cookie is a valid handle for this pool.  Session
    * cookies may only access the pool from which they were created.
    *
    * @see #getSignature()
    */
   public boolean validateSessionCookie(SessionCookie cookie);

   /**
    * Return a signature for the application pool.
    * <p>
    * The pool signature will also be used to determine whether a cookie is a
    * valid handle to the pool instance.  The pool signature value should be
    * unique across pools and consistent across VMs.
    * <p>
    * @see #isValidSessionCookie(SessionCookie)
    */
   public long getSignature();

   public void dumpPoolStatistics(PrintWriter pw);

   /**
    * Get the maximum number of application module instances which may
    * be referenced by the application pool.
    */
   public int getMaxPoolSize();

   /**
    * Get the initial number of application module instances which will be
    * instantiated in the application pool.
    */
   public int getInitPoolSize();

   // DEPRECATED APIs
   /**
    * @deprecated Implementation detail.  This method has been made protected.
    * @since 9.0.2 
    */
   public boolean isAvailable(ApplicationModule appModule);

   /**
    * @deprecated Replaced by {@link #getName()}.
    * @since 9.0.2 
    * @see #getName()
    */
   public String getPoolName();

   /**
    * @deprecated Implementation detail.  This method has been made protected.
    * Pool clients should not access pooled instances directly.  Use
    * {@link oracle.jbo.common.ampool.SessionCookie#useApplicationModule()}
    * to acquire ApplicationModule instances instead.
    * <p>
    * @since 9.0.2 
    */
   public ApplicationModule getInstance(int index);

   /**
    * @deprecated  Replaced by
    * {@link oracle.jbo.common.ampool.ConnectionStrategy#createApplicationModule(SessionCookie, EnvInfoProvider)}.
    * All extending logic that was implemented here should be implemented in a
    * custom ConnectionStrategy class that extends:
    *    {@link oracle.jbo.common.ampool.DefaultConnectionStrategy}.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.ConnectionStrategy#createApplicationModule(SessionCookie, EnvInfoProvider)
   */
   public ApplicationModule createNewInstance() throws Exception;

   /**
    * @deprecated Replaced by {@link #getAvailableInstanceCount()}
    * @since 9.0.2 
    * @see #getAvailableInstanceCount()
    */
   public int getAvailableNumPools();

   /**
    * Checks in an application instance that had previously been checked out.
    * This makes the application instance avalable for subsequent checkout
    * requests from this pool.
    * <p>
    * @param instance name of the application module instance to check in.
    * <p>
    * @deprecated Replaced by:
    *  {@link oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)}.
    * <p>
    * Application developers should invoke:
    *    <tt>SessionCookie.releaseApplicationModule(true, false)</tt>
    * instead of this method.  A session cookie instance may be acquired by
    * invoking:
    *    {@link #createSessionCookie(String, String, Properties)}.
    * <p>
    * This change was necessary to support the SessionCookie interface.  Please
    * see:
    *    {@link oracle.jbo.common.ampool.SessionCookie}
    * for more information about using SessionCookies with the application pool.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)
    * @see oracle.jbo.common.ampool.SessionCookie#useApplicationModule()
    */
   public void checkin(ApplicationModule instance);

   /**
    * Check-in the application module as being referenced by the invoking
    * session thread.
    * <p>
    * This method should be used by pool clients that wish to maintain logical
    * application module state while still sharing an application module
    * resource across requests.  The method returns a system generated session
    * id for the check-in that should be used as the unique application module
    * identifier by the client session.</p>
    * <p>
    * The application module will be passivated immediately if failover support
    * has been requested (default).  If failover support has been disable,
    * through the jbo.DoFailover system parameter, the application module will
    * not be passivated until it is re-used by a session other than the
    * session checking in the application module.</p>
    *
    * @param appModule the application module that will be checked in
    * <p>
    * @deprecated Replaced by:
    *  {@link oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)}.
    * <p>
    * Application developers should invoke:
    *    <tt>SessionCookie.releaseApplicationModule(true, true)</tt>
    * <p>
    * instead of this method.  A session cookie instance may be acquired by
    * invoking:
    *    {@link #createSessionCookie(String, String, Properties)}.
    * <p>
    * This change was necessary to support the SessionCookie interface.  Please
    * see:
    *    {@link oracle.jbo.common.ampool.SessionCookie}
    * <p>
    * for more information about using SessionCookies with the application pool.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)
    * @see oracle.jbo.common.ampool.SessionCookie#useApplicationModule()
    */
    public String checkinWithSessionState(ApplicationModule appModule);

   /**
    * Checks out stateless application instance from the pool. If the pool does
    * not have any available instances, it will create a new instance and return
    * it to the request thread.
    * <p>
    * @deprecated Replaced by:
    *   {@link oracle.jbo.common.ampool.SessionCookie#useApplicationModule()}.
    * <p>
    * Application developers should invoke:
    *    <tt>SessionCookie.useApplicationModule()</tt>
    * <p>
    * instead of this method.  A session cookie instance may be acquired by
    * invoking:
    *    {@link #createSessionCookie(String, String, Properties)}.
    * <p>
    * This change was necessary to support the SessionCookie interface.  Please
    * see:
    *    {@link oracle.jbo.common.ampool.SessionCookie}
    * for more information about using SessionCookies with the application pool.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.SessionCookie#useApplicationModule()
    * @see oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)
    */
   public ApplicationModule checkout() throws Exception;

   /**
    * Returns an application module for the specified session.  The session
    * id must have been generated by a previous call to:
    *    {@link #checkinWithSessionState(ApplicationModule)}
    * <p>
    * against this application module pool.
    * <p>
    * The session id should be used to re-create an application module state
    * from a previous request.
    * <p>
    * If an unrecognized session id is specified then the pool should return
    * a stateless application module instance.
    * <p>
    * @param sessionId a session identifier from a previous request
    *
    * @deprecated Replaced by:
    *    {@link oracle.jbo.common.ampool.SessionCookie#useApplicationModule()}.
    * <p>
    * Application developers should invoke:
    *   <tt>SessionCookie.useApplicationModule()</tt>
    * <p>
    * instead of this method.  A session cookie instance may be acquired by
    * invoking:
    *    {@link #createSessionCookie(String, String, Properties)}.
    * <p>
    * This change was necessary to support the SessionCookie interface.  Please
    * see:
    *    {@link oracle.jbo.common.ampool.SessionCookie}
    * <p>
    * for more information about using SessionCookies with the application pool.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.SessionCookie#useApplicationModule()
    * @see oracle.jbo.common.ampool.SessionCookie#releaseApplicationModule(boolean, boolean)
    */
   public ApplicationModule checkout(String sessionId);

   /**
    * Returns the user name.
    *
    * @deprecated This value should be passed to the pool connection strategy as
    * SessionCookie environment or by implementing an EnvInfoProvider.  The
    * value may be acquired from the ApplicationPool or SessionCookie
    * environment by using the <tt>Configuration.DB_USERNAME_PROPERTY</tt> key.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.ConnectionStrategy
    * @see oracle.jbo.common.ampool.EnvInfoProvider
    * @see oracle.jbo.common.ampool.SessionCookie
    */
   public String getUserName();

   /**
    * @deprecated This value should be passed to the pool connection strategy as
    * SessionCookie environment or by implementing an EnvInfoProvider.  The
    * value may be set in the ApplicationPool or SessionCookie
    * environment by using the <tt>Configuration.DB_USERNAME_PROPERTY</tt> key.
    * <p>
    * @since 9.0.2 
    * @see oracle.jbo.common.ampool.ConnectionStrategy
    * @see oracle.jbo.common.ampool.EnvInfoProvider
    * @see oracle.jbo.common.ampool.SessionCookie
    */
   public void setUserName(String sUser);

   /**
    * Returns the password.
    * 
    * @deprecated This value should be passed to the pool connection strategy as
    * SessionCookie environment or by implementing an EnvInfoProvider.  The
    * value may be acquired from the ApplicationPool or SessionCookie
    * environment by using the <tt>Configuration.DB_PASSWORD_PROPERTY</tt> key.
    * <p>
    * @since 9.0.2
    * @see oracle.jbo.common.ampool.ConnectionStrategy
    * @see oracle.jbo.common.ampool.EnvInfoProvider
    * @see oracle.jbo.common.ampool.SessionCookie
    */
   public String getPassword();

   /**
    * @deprecated This value should be passed to the pool connection strategy as
    * SessionCookie environment or by implementing an EnvInfoProvider.  The
    * value may be set in the ApplicationPool or SessionCookie
    * environment by using the <tt>Configuration.DB_PASSWORD_PROPERTY</tt> key.
    * <p>
    * @since 9.0.2
    * @see oracle.jbo.common.ampool.ConnectionStrategy
    * @see oracle.jbo.common.ampool.EnvInfoProvider
    * @see oracle.jbo.common.ampool.SessionCookie
    */    
   public void setPassword(String sPassword);
   
   /**
    * @deprecated This value should be passed to the pool connection strategy as
    * SessionCookie environment or by implementing an EnvInfoProvider.  The
    * value may be acquired from the ApplicationPool or SessionCookie
    * environment by using the <tt>ConnectionStrategy.DB_CONNECT_STRING_PROPERTY</tt> key.
    * <p>
    * @since 9.0.2
    * @see oracle.jbo.common.ampool.ConnectionStrategy
    * @see oracle.jbo.common.ampool.EnvInfoProvider
    * @see oracle.jbo.common.ampool.SessionCookie
    */
   public String getConnectString();

   /**
    * @deprecated  Replaced by:
    *   {@link oracle.jbo.pool.ResourcePool#removeResources()}.  Method
    * <p>
    * may be confused with releaseResource.
    * @since 9.0.2
    * @see oracle.jbo.pool.ResourcePool#removeResources()
    */
   public void releaseInstances();
}
