/*
 * @(#)UrlEventTag.java
 *
 * Copyright 2001-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 javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import oracle.jbo.JboException;
import oracle.jbo.Row;
import oracle.jbo.html.DataSource;
import oracle.jbo.html.HtmlServices;
import oracle.jbo.html.BC4JContext;

/**
 *
 * @author Charles Gayraud
 */
public class UrlEventTag extends TagSupport
{
   public static final String paramNames[] = new String[]{ OnEventTag.JBOEVENT, OnEventTag.JBOEVENTVO, DataTagBase.ROWKEY_PARAM, "amId", "currentPath" };
   protected String event;
   protected String targetUrl;
   protected String targetParam;
   protected String voName;
   protected String dsName;
   protected boolean addRowkey;
   protected String extra;

   public void setTargeturl(String sValue)
   {
      this.targetUrl = sValue;
   }
   
   public void setTargeturlparam(String sValue)
   {
      this.targetParam = sValue;
   }

   public void setEvent(String sValue)
   {
      this.event = sValue;
   }

   public void setViewobject(String sValue)
   {
      this.voName = sValue;
   }

   public void setDatasource(String sValue)
   {
      this.dsName = sValue;
   }

   public void setAddrowkey(String sValue)
   {
      this.addRowkey = Utils.isTrue(sValue);
   }

   public void setExtraparameters(String sValue)
   {
      this.extra = sValue;
   }
   
   /**
    * Process the start tag for this instance.
    *
    * The doStartTag() method assumes that all setter methods have been
    * invoked before.
    *
    * When this method is invoked, the body has not yet been invoked.
    *
    * @returns EVAL_BODY_INCLUDE if the tag wants to process body, SKIP_BODY if it
    * does ont want to process it.
    */
   public int doStartTag() throws JspException
   {
      String amId = null;
      String currentPath = null;

      if (targetParam != null)
      {
         if (targetUrl != null)
         {
            throw new JboException(Res.getString(Res.NEED_TARGET_OR_TARGETPARAM));
         }
         
         targetUrl = (String) HtmlServices.getRequestParameter(pageContext, targetParam);
      }

      HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
      
      // If the target URL is not specified, default to itself
      if (targetUrl == null)
      {
         targetUrl = request.getRequestURI();
      }
      else
      {
         if (targetUrl.startsWith("/"))
         {
            String context = request.getContextPath();
            if (!targetUrl.startsWith(context))
            {
               targetUrl = request.getContextPath() + targetUrl;
            }
         }
      }
      
      DataSource ds = null;
      if (dsName != null)
      {
         if (voName != null)
         {
            throw new JboException(Res.getString(Res.NEED_DS_OR_VO));
         }
         
         ds = Utils.getDataSourceFromContext(pageContext, dsName);
         voName = ds.getViewObjectName();
         amId = ds.getApplicationId();
      }

      BC4JContext bc4jContext = null;
      Object contextObject = pageContext.getRequest().getAttribute(BC4JContext.ContextAttrName);
      // Only do the casting if object is found
      if (contextObject != null)
      {
         bc4jContext = (BC4JContext) contextObject;
      }
      
      // If we have a context, we need to pass along the currentPath
      if (bc4jContext != null)
      {
         currentPath = bc4jContext.getCurrentPath();
      }
      
      // This is when the datasource info is not passed through, we are using the amId request param
      if (amId == null)
      {
         amId = HtmlServices.getRequestParameter(pageContext, "amId");

         // If no application id in the request parameter, rely on the BC4JContext.
         // This only work for Struts
         if (amId == null && bc4jContext != null)
         {
            amId = bc4jContext.getSessionCookie().getApplicationId();
         }
      }

      String rowkey = null;
      if (addRowkey)
      {
         Row row = DataTagBase.getRowFromContext(this, dsName, ds);
         if (row == null)
         {
            throw new JboException(Res.getString(Res.CANT_FIND_ROW_FOR_ROWKEY));
         }
         rowkey = row.getKey().toStringFormat(true);
      }

      String url = Utils.buildUrl(targetUrl, paramNames, new String[]{ event, voName, rowkey, amId, currentPath });
      if (extra != null)
      {
         if (!extra.startsWith("&"))
         {
            url += "&";
         }

         url += extra;
      }
      
      
      try
      {
         pageContext.getOut().print(url);
      }
      catch (java.io.IOException ex)
      {
         pageContext.getServletContext().log(Res.getString(Res.IO_ERROR), ex);
         throw new JspTagException(ex.getMessage());
      }
      
      return Tag.SKIP_BODY;
   }

   public void release()
   {
      event = null;
      targetUrl = null;
      targetParam = null;
      voName = null;
      dsName = null;
      addRowkey = false;
      extra= null;
      
      super.release();
   }

}
