/*
 * @(#)ViewCriteriaIterateTag.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 java.util.Enumeration;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
import oracle.jbo.RowSet;
import oracle.jbo.ViewCriteria;
import oracle.jbo.ViewCriteriaRow;
import oracle.jbo.html.DataSource;

public class ViewCriteriaIterateTag extends BodyTagSupport
{
   String            sDataSource;
   DataSource        ds;
   RowSet            rs;
   Enumeration       rows;
   ViewCriteriaRow   vr;

   public ViewCriteriaIterateTag()
   {
      reset();
   }

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

   public String getDatasource()
   {
      return sDataSource;
   }

   public ViewCriteriaRow getCriteriaRow()
   {
      return vr;
   }

   protected void initialize()
   {
      ds = Utils.getDataSourceFromContext(pageContext, sDataSource);
      rs = ds.getRowSet();
   }
   
   /**
      * 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
   {
      initialize();
      
      ViewCriteria vc = rs.getViewObject().getViewCriteria();
      if (vc == null)
      {
         return SKIP_BODY;
      }
      
      rows = vc.elements();

      if (rows != null && rows.hasMoreElements())
      {
         vr = (ViewCriteriaRow) rows.nextElement();
         return EVAL_BODY_AGAIN;
      }
      else
      {
         return SKIP_BODY;
      }
   }

   /**
     * Actions after some body has been evaluated.
     *
     * Not invoked in empty tags or in tags returning SKIP_BODY in doStartTag()
     * This method is invoked after every body evaluation.
     * The pair "BODY -- doAfterBody()" is invoked initially if doStartTag()
     * returned EVAL_BODY_TAG, and it is repeated as long
     * as the doAfterBody() evaluation returns EVAL_BODY_TAG
     * <p>
     * The method re-invocations may be lead to different actions because
     * there might have been some changes to shared state, or because
     * of external computation.
     *
     * @returns whether additional evaluations of the body are desired
     * @seealso #doInitBody
     */
   public int doAfterBody() throws JspException
   {
      BodyContent body = getBodyContent();
      
      // Flush content and reset
      try
      {
         body.writeOut(getPreviousOut());
         body.clearBody();
      }
      catch (java.io.IOException ex)
      {
         pageContext.getServletContext().log(Res.getString(Res.IO_ERROR), ex);
         throw new JspTagException(ex.getMessage());
      }
      
      if (rows.hasMoreElements())
      {
         vr = (ViewCriteriaRow) rows.nextElement();
      }
      else
      {
         return SKIP_BODY;
      }
      
      return EVAL_BODY_AGAIN;
   }

   // Use by the constructor and the release method to reset the member variable values
   private void reset()
   {
      sDataSource = null;
      ds = null;
      rs = null;
      vr = null;
      rows = null;
   }
   
   
   /**
     * reset the state of the Tag
     */
   public void release()
   {
      reset();
      super.release();
   }
}

