/* Generated By:JJTree: Do not edit this line. IfLpar.java */

/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.xpath.conditional;

import javax.xml.transform.TransformerException;

import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionOwner;
import org.apache.xpath.VariableComposeState;
import org.apache.xpath.XPathContext;
import org.apache.xpath.XPathVisitor;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.parser.IfExpr;
import org.apache.xpath.parser.Node;

public class If extends Expression implements ExpressionOwner
{

  public If()
  {
    super();
  }

  /** Accept the visitor. **/
  public Object jjtAccept(
    org.apache.xpath.parser.XPathVisitor visitor,
    Object data)
  {
    return visitor.visit(this, data);
  }

  /**
   * @see Expression#deepEquals(Expression)
   */
  public boolean deepEquals(Expression expr)
  {
    return false;
  }

  /**
   * @see Expression#fixupVariables(Vector, int)
   */
  public void fixupVariables(VariableComposeState vcs)
  {
  }

  /**
   * @see Expression#execute(XPathContext)
   */
  public XObject execute(XPathContext xctxt) throws TransformerException
  {
    
    XObject test = m_test.execute(xctxt);

      if (test.bool())
      {
      	// Execute Then expression
      	return m_then.execute(xctxt);
      	
      }
      else
      {
      	// execute else expression
      	return m_else.execute(xctxt); 
      }
  }

  /**
   * @see XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
   */
  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
  {
  }

  /**
   * @see ExpressionOwner#getExpression()
   */
  public Expression getExpression()
  {
    return null;
  }

  /**
   * @see ExpressionOwner#setExpression(Expression)
   */
  public void setExpression(Expression exp)
  {
  }

  Expression m_test;

  Expression m_then;

  Expression m_else;

  /**
   * Returns the e.
   * @return Expression
   */
  public Expression getElse()
  {
    return m_else;
  }

  /**
   * Returns the test.
   * @return Expression
   */
  public Expression getTest()
  {
    return m_test;
  }

  /**
   * Returns the then.
   * @return Expression
   */
  public Expression getThen()
  {
    return m_then;
  }

  /**
   * Sets the e.
   * @param e The e to set
   */
  public void setElse(Expression e)
  {
    m_else = e;
  }

  /**
   * Sets the test.
   * @param test The test to set
   */
  public void setTest(Expression test)
  {
    m_test = test;
  }

  /**
   * Sets the then.
   * @param then The then to set
   */
  public void setThen(Expression then)
  {
    m_then = then;
  }

  /**
   * @see org.apache.xpath.parser.Node#jjtSetParent(Node)
   */
  public void jjtSetParent(Node n)
  {
    super.jjtSetParent(n);
    if (n instanceof IfExpr) // don't fix up if we're reducing
    {
      IfExpr ifexpr = (IfExpr) n;

      // At this point all children should have been added except this node.
      // This has a fixed number of children.
      m_test = (Expression) ifexpr.jjtGetChild(1);
      m_test.jjtSetParent(this);
      m_then = (Expression) ifexpr.jjtGetChild(3);
      m_then.jjtSetParent(this);
      m_else = (Expression) ifexpr.jjtGetChild(5);
      m_else.jjtSetParent(this);

      ifexpr.m_exprs.setSize(1);
    }
  }
  

  /**
   * @see org.apache.xpath.parser.Node#jjtGetChild(int)
   */
  public Node jjtGetChild(int i)
  {
    return (i == 0) ? m_test : (i == 1) ? m_then : (i == 2) ? m_else : null;
  }

  /**
   * @see org.apache.xpath.parser.Node#jjtGetNumChildren()
   */
  public int jjtGetNumChildren()
  {
    return 3;
  }

  /**
   * @see org.apache.xpath.parser.SimpleNode#isPathExprReduced()
   */
  public boolean isPathExprReduced()
  {
    return false; // never reduce.
  }

}
