
// Copyright (c) 2000 Oracle Corporation
package oracle.jbo.html.jsp.datatags;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import oracle.jbo.*;
import oracle.jdeveloper.html.*;

/**
 * A Class class.
 * <P>
 * @author Juan Oropeza
 */
public class DataLoopTag extends BodyTagSupport
{
  String sDataSource;
  Row    origRow = null;

  public DataLoopTag()
  {
  }

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

  /**
     * 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
  {
    try
    {
      oracle.jdeveloper.html.DataWebBeanImpl ds = (oracle.jdeveloper.html.DataWebBeanImpl)pageContext.getAttribute(sDataSource);

      if(ds == null)
      {
        throw new Exception(Res.format(Res.DATA_SOURCE_NOT_FOUND,sDataSource));
      }

      RowSet rs = ds.getRowSet();

      if(rs.getCurrentRow() == null)
         rs.first();
         
      origRow = rs.getCurrentRow();

      rs.first();
      
      if(rs.getCurrentRow() != null)
      {
         return BodyTag.EVAL_BODY_TAG;
      }
      else
      {
        return SKIP_BODY;
      }
    }
    catch(Exception ex)
    {
      throw new JspException(ex.getMessage());
    }
  }

   /**
     * 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
   {
      try
      {
         RowSet rs = (RowSet)pageContext.getAttribute( sDataSource + "_RowSet");

         if(rs.hasNext())
         {
            // move on to the next row
            rs.next();

            return BodyTag.EVAL_BODY_TAG;
         }
         else
         {
            if(origRow != null)
               rs.setCurrentRow(origRow);

            return Tag.SKIP_BODY;
         }

      }
      catch(Exception ex)
      {
         throw new JspException(ex.getMessage());
      }
   }

   /**
     * Process the end tag. This method will be called on all Tag objects.
     *
     * All instance state associated with this instance must be reset.
     * The release() method should be called after this invocation.
     */
   public int doEndTag() throws JspException
   {
      try
      {
         if(this.bodyContent != null)
         {
            bodyContent.writeOut(bodyContent.getEnclosingWriter());
         }
      }
      catch(Exception ex)
      {
         throw new JspException(ex.getMessage());
      }
      return EVAL_PAGE;
   }

   /**
     * reset the state of the Tag
     */
   public void release()
   {
      sDataSource = null;
      origRow = null;

      super.release();
   }
}

