
// Copyright (c) 1999, 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.*;
import oracle.jbo.common.TransPostControl;

/**
 * A Class class.
 * <P>
 * @author Juan Oropeza
 */
public class RowTag extends TagSupport
{
  String sid = "not set";
  String sDataSource;
  Row    row = null;
  RowSet rs = null;
  String sRowKey = null;
  String sRowKeyParam = null;
  String sAction = "Current";
  boolean bUseRequest = true;
  
   /**
    * Constructor
    */
   public RowTag() {
   }

   public void setId(String sid)
   {
    this.sid = sid;
   }

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

   public void setAction(String sValue)
   {
      sAction = sValue;
   }
   
   public void setRowkeyparam(String rowkey)
   {
    this.sRowKeyParam = rowkey;
   }

   public void setRowkey(String rowkey)
   {
    this.sRowKey = rowkey;
   }

   public void setUserequest(String sUse)
   {
      if(sUse.equalsIgnoreCase("Yes") || sUse.equalsIgnoreCase("True"))
      {
         bUseRequest = true;
      }
      else
      {
         bUseRequest = false;
      }
   }
   
   public RowSet getRowSet()
   {
    return this.rs;
   }

   public Row getRow()
   {
      return row;
   }

   /**
     * 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("Data Source was not found in page context.");
      }

      rs = ds.getRowSet();

      if(sAction.equalsIgnoreCase("Find"))
      {
         row = getRowFromUrlParameterOrKeyValue(rs);

         if(row != null)
         {
             rs.setCurrentRow(row);
         }
         else
         {
            throw new JspException("Row was not found using request parameter:" + sRowKey);
         }
      }
      else if (sAction.equalsIgnoreCase("Create"))
      {
         row = rs.createRow();
//         rs.insertRow(row);
      }
      else if (sAction.equalsIgnoreCase("Update"))
      {
         row = getRowFromUrlParameterOrKeyValue(rs);
         updateRowAttributesFromUrl(rs);
      }
      else if (sAction.equalsIgnoreCase("Delete"))
      {
         row = getRowFromUrlParameterOrKeyValue(rs);
         row.remove();
      }
      else if (sAction.equalsIgnoreCase("Lock"))
      {
         row = getRowFromUrlParameterOrKeyValue(rs);
         row.lock();
      }
      else if (sAction.equalsIgnoreCase("Current"))
      {
         row = rs.getCurrentRow();
         if(row == null)
         {
            row = rs.first();
            if(row == null)
            {
               rs.executeQuery();
               row = rs.first();
            }
         }
      }

      if(row != null)
      {
        pageContext.setAttribute(sid , row);
      }
      else
      {
        throw new RuntimeException("Row for Row Tag is null");
      }

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

  protected Row getRowFromUrlParameterOrKeyValue(RowSet rs) throws Exception
  {
      // find the row using the key
      if(sRowKey == null && sRowKeyParam == null)
      {
        throw new Exception("rowkey or rowkeyparam attribute must be set");
      }

      if(sRowKeyParam != null)
        sRowKey = pageContext.getRequest().getParameter(sRowKeyParam);

      if(sRowKey == null)
      {
        throw new Exception(" RowKey is null, row tag cannot find a row");
      }
      
      Key key = new Key(sRowKey, rs.getViewObject().getKeyAttributeDefs());

      Row rows[] = rs.findByKey(key,1);

      Row row = rows[0];

      return row;
  }

   protected void updateRowAttributesFromUrl(RowSet qView) throws Exception
   {
      try
      {
         // If user selects not to use the request object's values return from this call
         if(!bUseRequest)
            return;
            
         // Set the query conditions and generate the query table
         AttributeDef[]    attrs =  qView.getViewObject().getAttributeDefs();

         // goto the appropriate row
         Integer   RowNumber;
         String    sName;
         String    sNewValue;
         Object    OldValue;

         if (row == null)
         {
            throw new RuntimeException("No Rows available for Editing");
         }

         // get the attribute values and update those that need it
         for (int attrNo = 0; attrNo < attrs.length ; attrNo++)
         {
			      sName = attrs[attrNo].getName();

            if (row.isAttributeUpdateable(attrs[attrNo].getIndex()))
            {
               sNewValue = pageContext.getRequest().getParameter(sName);

               if (sNewValue != null)
               {
                  sNewValue = sNewValue.trim();

                  OldValue = row.getAttribute( attrs[attrNo].getIndex() );

                  // empty out value if the string 'null' is used
                  if(sNewValue.equalsIgnoreCase("null"))
                  {
                     sNewValue = "";
                  }

                  // compare only with generated value to minimize overwrites of
                  // attributes that didn't change.
                  if(pageContext.getRequest().getParameter(sName + "_PREVIOUS") != null)
                  {
                     OldValue = pageContext.getRequest().getParameter(sName + "_PREVIOUS");
                  }

                  if (OldValue != null)
                  {
                     if (!sNewValue.equals(OldValue.toString()))
                     {

                        if (!sNewValue.equals(""))
                        {
                           row.setAttribute(attrs[attrNo].getIndex()  , sNewValue);
                        }
                        else
                        {
                           row.setAttribute(attrs[attrNo].getIndex()  , null);
                        }
                     }
                  }
                  else
                  {
                     if (!sNewValue.equals(""))
                     {
                        row.setAttribute(attrs[attrNo].getIndex()  , sNewValue);
                     }
                  }
               }
            }
         }
      }
      catch (DMLException ex)
      {
         ((TransPostControl) qView.getApplicationModule()).transPostRevert(ex.getEntityRowHandle());
         throw ex;
      }
      catch (Exception e)
      {
         throw e;
      }
   }

  /**
   * doEndTag
   * @return int
   * @exception javax.servlet.jsp.JspException
   */
  public int doEndTag() throws JspException
  {
    if (sAction.equalsIgnoreCase("Create"))
    {
         oracle.jdeveloper.html.DataWebBeanImpl ds = (oracle.jdeveloper.html.DataWebBeanImpl)pageContext.getAttribute(sDataSource);

         if(ds == null)
         {
            throw new RuntimeException("Data Source was not found in page context.");
         }

         rs = ds.getRowSet();

         if(row != null)
            rs.insertRow(row);
    }

    return super.doEndTag();
  }

  /**
   * release
   */
  public void release()
  {
    rs = null;
    row = null;
    sid = "not set";
    sDataSource = null;
    sRowKey = null;
    sAction = "Current";
    bUseRequest = true;
    sRowKeyParam = null;

    super.release();
  }
}

