/*
 * @(#)ApplicationModuleTag.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.html.jsp.datatags;

import java.io.IOException;
import java.lang.NumberFormatException;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
import oracle.jbo.ApplicationModule;
import oracle.jbo.common.JboEnvUtil;
import oracle.jbo.common.PropertyConstants;
import oracle.jbo.common.PropertyMetadata;
import oracle.jbo.common.ampool.ConnectionStrategy;
import oracle.jbo.common.ampool.SessionCookie;
import oracle.jbo.html.HtmlServices;
import oracle.jbo.html.RequestParameters;
import oracle.jbo.http.HttpContainer;
import oracle.jbo.http.HttpSessionCookieFactory;
import oracle.jbo.http.HttpUtil;

public class ApplicationModuleTag extends TagSupport
{
   String  definition;
   String  configName;
   String  sUserName;
   String  sPassword;
   String  siiopUserName;
   String  siiopPassword;
   String  releaseMode;
   boolean lock;
   int     waittimeout;

   public ApplicationModuleTag()
   {
      super();
      reset();
   }

   public void setConfigname(String configName)
   {
      this.configName = configName;
   }

   public void setUsername(String sValue)
   {
      this.sUserName = sValue;
   }

   public void setPassword(String sValue)
   {
      this.sPassword = sValue;
   }

   public void setIiop_username(String sValue)
   {
      this.siiopUserName = sValue;
   }

   public void setIiop_password(String sValue)
   {
      this.siiopPassword = sValue;
   }

   public void setDefinition(String sValue)
   {
      this.definition = sValue;
   }

   public void setLock(String sValue)
   {
      lock = Utils.isTrue(sValue);
   }

   public void setReleasemode(String sValue)
   {
      this.releaseMode = sValue;
   }
   

   public void setWaittimeout(String sValue)
      throws NumberFormatException
   {
      waittimeout = Integer.parseInt(sValue);
   }

   protected final String getPoolName()
   {
      String sPoolName = null;

      if(definition != null)
          sPoolName = definition;
      else if(configName != null)
        sPoolName = configName;

      return sPoolName;
   }

   public int doStartTag() throws JspException
   {
      Properties props = new Properties();
      props.put(HttpSessionCookieFactory.HTTP_SERVLET_REQUEST, pageContext.getRequest());
      
      SessionCookie cookie = null;
      if (definition != null)
      {
         cookie = HttpContainer.findSessionCookie(
            pageContext.getSession()
            , id
            , definition
            , props);
      }
      else
      {
         pageContext.setAttribute("JBO_AMCONFIGNAME", configName, PageContext.REQUEST_SCOPE);
         int index = configName.lastIndexOf('.');
         String configPackage = configName.substring(0, index);
         String configSection = configName.substring(index + 1);

         // strip out the am class
         configPackage = configPackage.substring(0, configPackage.lastIndexOf('.'));
         
         cookie = HttpContainer.findSessionCookie(
            pageContext.getSession()
            , id
            , getPoolName()
            , configPackage
            , configSection
            , null
            , props);
      }

      Hashtable env = cookie.getEnvironment();

      // Configure JDBC security
      if (sUserName != null)
         env.put(ConnectionStrategy.DB_USERNAME_PROPERTY, sUserName);

      if (sPassword != null)
         env.put(ConnectionStrategy.DB_PASSWORD_PROPERTY, sPassword);

      // Configure IIOP security
      // Do not override the existing cookie principal name if it already
      // exists.  The principal name was retrieved from the request.
      if ((siiopUserName != null) 
         && (cookie.getSSOUserName() == null))
      {
         env.put(PropertyMetadata.SECURITY_PRINCIPAL.pName, siiopUserName);
      }

      if (siiopPassword != null)
      {
         env.put(PropertyMetadata.SECURITY_CREDENTIALS.pName, siiopPassword);
      }

      try
      {
         cookie.setEnvironment(env);
      }
      catch(oracle.jbo.common.ampool.ApplicationPoolException apex)
      {
         // Ignore the application pool exception.  The cookie environment
         // has already been initialized.
      }
      
      // locks the session cookie for the current session thread
      // checks out the cookie application module
      ApplicationModule am = cookie.useApplicationModule(lock, waittimeout); //lock

      Locale locale = HttpUtil.determineLocale(pageContext.getRequest());

      // setup the Application Module's Locale based on the incoming request information
      if(locale != null)
          am.getSession().setLocale(locale);
      
      if (releaseMode != null && releaseMode.length() > 0)
      {
         // Only cache the releaseMode value in the cookie context if it
         // was explicitly specified by the developer
         cookie.getUserData().put(PropertyMetadata.AM_RELEASE_MODE.pName, releaseMode);

      }
      else
      {
         releaseMode = (String)cookie.getEnvironment().get(PropertyMetadata.AM_RELEASE_MODE.pName);
         if (releaseMode == null || releaseMode.length() <= 0)
         {
            releaseMode = JboEnvUtil.getProperty(
               PropertyMetadata.AM_RELEASE_MODE.pName
               , PropertyMetadata.AM_RELEASE_MODE.pDefault);
         }
      }

      // Reserve a passivation id if the release mode is stateful
      if (PropertyConstants.AM_RELEASE_STATEFUL.equals(releaseMode))
      {
         cookie.reservePassivationId(pageContext.getResponse());
      }

      // Save the am for the scriptable variable
      pageContext.setAttribute(id, cookie);

      // place default renderers into session, these will not be
      // exposed via config file
      HtmlServices.registerORDrenderer(pageContext.getSession());

      // Handle the parameters list 
      RequestParameters parameters;
      
      // Only do it on the first AM tag.
      parameters = (RequestParameters) pageContext.findAttribute(HtmlServices.ORD_PARAM);
      if (parameters == null)
      {
         try
         {
            parameters = HtmlServices.getRequestParameters((HttpServletRequest)pageContext.getRequest(), pageContext.getResponse(), cookie);
         }
         catch (IOException ex)
         {
            pageContext.getServletContext().log("Error retrieving request parameters", ex);
            throw new JspTagException(ex.getMessage());
         }
      
         pageContext.setAttribute(HtmlServices.ORD_PARAM, parameters, PageContext.REQUEST_SCOPE);
      }

      return SKIP_BODY;
   }

   private final void reset()
   {
      definition = null;
      configName = null;
      sUserName = null;
      sPassword = null;
      siiopUserName = null;
      siiopPassword = null;
      lock = false;
      waittimeout = 60000; // 60 seconds
      releaseMode = null;
   }
   
   /**
    * release
    */
   public void release()
   {
      super.release();
      reset();
   }

}
