/*
 * @(#)DataSourceTag.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.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

import oracle.jbo.JboException;
import oracle.jbo.RowIterator;
import oracle.jbo.RowSet;
import oracle.jbo.html.DataSource;

public class DataSourceTag extends TagSupport
{
   protected String amId;
   protected String sViewObject;
   protected String sWhere;
   protected String sOrder;
   protected int nRangeSize;
   protected boolean bForwardOnly;
   protected String sIterMode;
   protected DataSource ds;

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

   public void setAppid(String amId)
   {
      this.amId = amId;
   }

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

   public void setWhereclause(String sWhere)
   {
      this.sWhere = sWhere;
   }

   public void setOrderbyclause(String sOrder)
   {
      this.sOrder = sOrder;
   }
   
   public void setRangesize(String sValue)
      throws NumberFormatException
   {
      nRangeSize = Integer.parseInt(sValue);
   }

   public void setForwardonly(String sValue)
   {
      bForwardOnly = Utils.isTrue(sValue);
   }

   public void setItermode(String sValue)
   {
      this.sIterMode = sValue;
   }

   // Used by children tags to retrieve context
   public DataSource getDataSource()
   {
      return ds;
   }
   
   /**
      * 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
   {
      ds = Utils.createDataSource(pageContext, amId, sViewObject, null, id, false);

      // Set the attribute on the pageContext for the scriptable variable (PAGE_SCOPE because of Orion)
      pageContext.setAttribute(id, ds);
      
      // Set the attribute on the pageContext at REQUEST_SCOPE for DataSourceRef tag
      pageContext.setAttribute(id, ds, PageContext.REQUEST_SCOPE);
      
      RowSet rs = ds.getRowSet();

      // Only set the range size if the property has been set.
      if (nRangeSize != 0)
         rs.setRangeSize(nRangeSize);
      
      // Always set the forward only flag (default is false)
      // This is because we don't want to carry the setting between multiple uses
      // off the viewObject.
      rs.setForwardOnly(bForwardOnly);

      // Only set the mode if the property has been set.
      if (sIterMode != null)
      {
         int iterMode;

         if (sIterMode.equalsIgnoreCase("LastPagePartial"))
         {
            iterMode = RowIterator.ITER_MODE_LAST_PAGE_PARTIAL;
         }
         else if (sIterMode.equalsIgnoreCase("LastPageFull"))
         {
            iterMode = RowIterator.ITER_MODE_LAST_PAGE_FULL;
         }
         else
         {
            throw new JboException(Res.format(Res.INVALID_ITERMODE, sIterMode));
         }

         rs.setIterMode(iterMode);
      }

      String sCurrentClause = rs.getViewObject().getWhereClause();
      boolean changeIt = false;

      // Only set the where clause if the property has been set.
      // To nullify a where clause it has to be an empty string
      if (sWhere != null)
      {
         if (sWhere.length() == 0)
         {
            if (sCurrentClause != null)
            {
               changeIt = true;
               sWhere = null;
            }
         }
         else if (!sWhere.equals(sCurrentClause))
         {
            changeIt = true;
         }
      }

      if (changeIt)
      {
         rs.getViewObject().setWhereClause(sWhere);
         rs.executeQuery();
      }

      // Only set the orderby if the property has been set.
      // To nullify an orderby it has to be an empty string
      String sCurrentOrderbyClause = rs.getViewObject().getOrderByClause();
      changeIt = false;
      if (sOrder != null)
      {
         if (sOrder.length() == 0)
         {
            if (sCurrentOrderbyClause != null)
            {
               changeIt = true;
               sOrder = null;
            }
         }
         else if (!sOrder.equals(sCurrentOrderbyClause))
         {
            changeIt = true;
         }
      }
      
      if (changeIt)
      {
         rs.getViewObject().setOrderByClause(sOrder);
         rs.executeQuery();
      }
      
      return Tag.EVAL_BODY_INCLUDE;
   }

   private void reset()
   {
      amId = null;
      sViewObject = null;
      sWhere = null;
      sOrder = null;
      nRangeSize = 0;
      bForwardOnly = false;
      sIterMode = null;
      ds = null;
   }
   
   /**
     * release() called after doEndTag() to reset state
     */
   public void release()
   {
      super.release();
      reset();
   }

}
