// Copyright (c) 1999, 2000 Oracle Corporation
package oracle.jbo.http;

import javax.servlet.jsp.PageContext;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;

import oracle.jbo.ApplicationModule;

import oracle.jbo.common.Configuration;

import oracle.jbo.common.ampool.ApplicationPool;

import oracle.jbo.html.jsp.JSPApplicationRegistry;

import oracle.jbo.html.jsp.datatags.ReleasePageResourcesTag;

import java.util.Properties;
import java.util.Hashtable;

/**
 * Implement a binding listener for application modules.  The binding listener
 * notifies the JSPApplication registry when an application module
 * has been unbound from the JBO HttpContainer.
 */
public class ApplicationBindingListener implements BindingListener
{
   ApplicationModule mAppModule = null;
   ApplicationPool   mPool      = null;

   public static final String RELEASE_MODE            = "releasemode";
   public static final String HTTP_RESPONSE           = "httpResponse";

   public ApplicationBindingListener(
      ApplicationModule appModule
      , ApplicationPool pool)
   {
      mAppModule = appModule;
      mPool = pool;
   }

   public void valueBound(BindingEvent ev)
   {
   }

   /**
    * Release an application module to the application module pool.  The
    * application module may be passivated and released or simply released.  If
    * a unit of work is still in progress then the application module state
    * should be passivated in order to guarantee continuity and failover support.
    * If a a unit of work has been completed at the request's end then it is not
    * necessary to passivate the application module because the application
    * module does not have any state that must be maintained between requests.
    */
   public void valueUnbound(BindingEvent ev)
   {
      Properties userProperties = ev.getUserProperties();

      // Check if the release mode has been specified in the binding event.
      String releaseMode =
         (userProperties != null)
         ? userProperties.getProperty(RELEASE_MODE)
         : null;

      // If the release mode is null then default the release mode to be
      // reserved.
      if (releaseMode == null)
      {
         releaseMode = JSPApplicationRegistry.RESERVED;
      }

      releaseApplicationModule(ev, releaseMode);
   }

   public void timeout(BindingEvent ev)
   {
      System.err.println(
         "The binding listener for "
         + mAppModule.getName()
         + " was timed out");

      JSPApplicationRegistry appRegistry = JSPApplicationRegistry.getInstance();
      releaseApplicationModule(ev, JSPApplicationRegistry.STATELESS);
   }

   private void releaseApplicationModule(BindingEvent ev, String releaseMode)
   {
      PageContext pageContext = null;
      HttpSession session = null;

      JSPApplicationRegistry appRegistry = JSPApplicationRegistry.getInstance();

      // Prime case for splitting this listener into two classes - one for
      // the session and the second for page contexts.  However this may
      // introduce complexities in other portions of the code.  Leave as
      // is for right now.
      if (ev.getParentContext() instanceof PageContext)
      {
         pageContext = (PageContext)ev.getParentContext();
         session = pageContext.getSession();

         appRegistry.releaseAppModuleInstance(
            mAppModule
            , mPool
            , pageContext
            , releaseMode);
      }
      else if (ev.getParentContext() instanceof HttpSession)
      {
         session = (HttpSession)ev.getParentContext();

         appRegistry.releaseAppModuleInstance(
            mAppModule
            , mPool
            , session
            , (ev.getUserProperties() != null)
               ? (HttpServletResponse)ev.getUserProperties().get(HTTP_RESPONSE)
               : null
            , releaseMode);
      }
   }
}
