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

package org.apache.xpath.types;

import java.io.PrintStream;
import java.util.Vector;
import javax.xml.transform.TransformerException;

import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMFilter;
import org.apache.xml.dtm.XType;
import org.apache.xml.utils.QName;
import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionNode;
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.XBoolean;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XSequence;
import org.apache.xpath.parser.Node;
import org.apache.xpath.parser.SchemaContext;
import org.apache.xpath.parser.SequenceType;
import org.apache.xpath.parser.SimpleNode;
import org.apache.xpath.parser.XPath;

/**
 * This class implements the "instance of" production for XPath 2.0.
 * 
 * <p>(For easy reference, until the spec is more stable...)</p>
 * <pre>
 * [9]    InstanceofExpr    ::=    {Expr} ( <"instance" "of"> SequenceType )? 
 * [51]    SequenceType    ::=    (ItemType OccurrenceIndicator) |  "empty" 
 * [52]    ItemType    ::=    (("element" |  "attribute") ElemOrAttrType?)
 *                          |  "node"
 *                          |  "processing-instruction"
 *                          |  "comment"
 *                          |  "text"
 *                          |  "document"
 *                          |  "item"
 *                          |  AtomicType 
 *                          |  "untyped"
 *                          |  <"atomic" "value"> 
 * [53]    ElemOrAttrType    ::=    (QName (SchemaType |  SchemaContext?)) |  SchemaType 
 * [54]    SchemaType    ::=    <"of" "type"> QName 
 * [55]    AtomicType    ::=    QName 
 * [56]    OccurrenceIndicator    ::=    ("*" |  "+" |  "?")? 
 * </pre>
 * 
 * <p>Notes to Joe: You can call just the parser to give a diagnostic dump 
 * of the expression by calling org.apache.xpath.parser.XPath.main() with 
 * an argument of a an expression string (quote it): "foo instance of xsd:integer".
 * This will dump out thus:</p>
 * <pre>
 * Test[0]: foo instance of xsd:integer
 * |instance of
 * |   child::foo  org.apache.xpath.axes.ChildTestIterator
 * |   m_atomicTypeID: 2
 * |   m_elemOrAttrName: null
 * |   m_occurrenceIndicator: 2
 * |   m_schemaContext: null
 * |   m_schemaTypeName: null
 * |   m_whatToShow: 0
 * Success!!!!
 * I've only tested:
 * "foo instance of xsd:integer"
 * "foo instance of element of type baz"
 * "foo instance of element yada of type baz"
 * "foo instance of node"
 * "foo instance of text"
 * "foo instance of comment"
 * "foo instance of untyped"
 * </pre>
 * 
 * <p>It's highly likely that there are bugs in the construction with 
 * other expressions.  Come get me if that happens.</p>
 * <p>SchemaContext &amp; co is unimplemented right now.  Don't worry about 
 * it for right now.</p>
 * 
 * Created Jul 17, 2002
 * @author sboag
 */
public class InstanceofExpr extends Expression implements ExpressionOwner
{
  /** The sequence on which to act. **/
  private Expression m_targetExpr;
  
  /** The node type value, one of DTMFilter.SHOW_ATTRIBUTE, etc. 
   * %REVIEW% Why isn't this just the node type? **/
  private int m_whatToShow;
  
  /** The atomic type ID, one of XType.BOOLEAN, etc. **/
  private int m_atomicTypeID;
  
  // Occurence indicator ID values.
  public static final int ZERO_OR_MORE = 1;
  public static final int ONE_OR_MORE = 2;
  public static final int ZERO_OR_ONE = 3;
  public static final int EMPTY_SEQ = 4;
    
  /** The occurance indicator ID.  One of ZERO_OR_MORE, etc. or EMPTY_SEQ **/
  private int m_occurrenceIndicator = ONE_OR_MORE;
  
  /** The ElemOrAttrType name, meaning the tag QName, may be null. */
  private QName m_elemOrAttrName;

  /** The SchemaType name, meaning the tag QName, may be null. */
  private QName m_schemaTypeName;
  
  /** SchemaContext is not executable for the moment, so leave it 
   * as a NEE until we figure out what we want to do with it. **/
  private SchemaContext m_schemaContext;
	
  public InstanceofExpr() {
    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)
  {
    if(!(expr instanceof InstanceofExpr))
      return false;
    return false;
  }

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


  /**
   * @see Expression#execute(XPathContext)
   */
  public XObject execute(XPathContext xctxt) throws TransformerException
  {
 	// m_atomicTypeID: Integer XType primitive, IFF no m_schemaTypeName
	// m_schemaContext: SchemaContext, UNSPECIFIED AT THIS TIME
	//	and hence unsupported.
 	boolean isInstance=true;
 	
 	XObject value=m_targetExpr.execute(xctxt);
 	
 	
 	switch(value.getType())
 	{
 		case XObject.CLASS_UNKNOWN:
	 		// If not XSLT type, can't be instance of ...?
	 		// %REVIEW% what SHOW_ITEM and SHOW_UNTYPED mean
 		case XObject.CLASS_NULL:
	 		isInstance=false; 
	 		break;
	 		
		case XObject.CLASS_NODESET:	
		case XObject.CLASS_RTREEFRAG:
			int len=0;
			XSequence valNodeSet= value.xseq();
 			for( XObject next=valNodeSet.next();
 				isInstance && next!=null;
 				next=valNodeSet.next(),++len)
 			{
        int handle = next.getNodeHandle();
        if(DTM.NULL == handle)
          continue;
 				if(m_whatToShow!=0)
 				{
 					int nodetype=xctxt.getDTM(handle).getNodeType(handle);
 					if(0==(m_whatToShow & 1<<(nodetype-1)))
 						isInstance=false;
 					else if(m_elemOrAttrName!=null)
 					{
 						isInstance&=
 							(m_elemOrAttrName.getNamespace/*URI*/()
 								==xctxt.getDTM(handle).getNamespaceURI(handle))
 							&& 
 							(m_elemOrAttrName.getLocalName()
 								==xctxt.getDTM(handle).getLocalName(handle));
 					} 				
 				}
 				if(m_schemaTypeName!=null)
 				{
 					isInstance&=
 						xctxt.getDTM(handle).isNodeSchemaType(
 							handle, 
 							m_schemaTypeName.getNamespaceURI(),
 							m_schemaTypeName.getLocalName());
 				}
 				else if(m_atomicTypeID!=0)
 				{
 					// Unless DTM implements awareness of these
 					// typenumbers, or our sequence/nodeset layers
 					// handle this for us, we need to convert back
 					// to strings. We also have to convert from the
 					// Schema_datatype namespace, used in requesting the
 					// primitive, to the Schema namespace used when
 					// the node was declared.
 					isInstance&=
 						xctxt.getDTM(handle).isNodeSchemaType(
 							handle, 
 							XType.XMLSCHEMA_NAMESPACE,
 							XType.getLocalNameFromType(m_atomicTypeID));
 				} 				
			} // End scan contents
 			switch(m_occurrenceIndicator)
 			{
 				case ZERO_OR_MORE:
 					break; // Anything is OK
 				case ONE_OR_MORE:
 					isInstance&=(len>=1);
 					break;
 				case ZERO_OR_ONE:
 					isInstance&=(len<2);
 					break;
 				case EMPTY_SEQ:
 					isInstance&=(len==0);
 					break;
 			}
 			break;
 	
 		case XObject.CLASS_BOOLEAN:
			isInstance&=(m_elemOrAttrName==null);
			isInstance&=(m_schemaTypeName==null);
			isInstance&=(m_whatToShow==0);
			isInstance&=(m_atomicTypeID==XType.BOOLEAN);
			break;
			
		case XObject.CLASS_NUMBER:
			isInstance&=(m_elemOrAttrName==null);
			isInstance&=(m_schemaTypeName==null);
			isInstance&=(m_whatToShow==0);
			// %REVIEW% XNumber is just that, a number.
			// We want *it* to tell *us* whether it's straight
			// decimal or double or whatever...?
			isInstance&=(m_atomicTypeID==XType.DECIMAL
				|| m_atomicTypeID==XType.DOUBLE);
			break;
			
		case XObject.CLASS_STRING:
			isInstance&=(m_elemOrAttrName==null);
			isInstance&=(m_schemaTypeName==null);
			isInstance&=(m_whatToShow==0);
			isInstance&=(m_atomicTypeID==XType.STRING);
			break;
 			
 		default:
			// Should never arise
			isInstance=false;
 			break;
 	}
 	
 	return isInstance ? XBoolean.S_TRUE : XBoolean.S_FALSE;
  }


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


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


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

  /**
   * @see SimpleNode#shouldReduceIfOneChild()
   */
  public boolean shouldReduceIfOneChild()
  {
    return (m_whatToShow == 0 && m_atomicTypeID == 0) ? true : false;
  }


  /**
   * Returns the occurrenceIndicator.
   * @return int
   */
  public int getOccurrenceIndicator()
  {
    return m_occurrenceIndicator;
  }

  /**
   * Returns the schemaContext.
   * @return SchemaContext
   */
  public SchemaContext getSchemaContext()
  {
    return m_schemaContext;
  }

  /**
   * Returns the schemaTypeName.
   * @return QName
   */
  public QName getSchemaTypeName()
  {
    return m_schemaTypeName;
  }

  /**
   * Returns the targetExpr.
   * @return Expression
   */
  public Expression getTargetExpr()
  {
    return m_targetExpr;
  }

  /**
   * Returns the whatToShow.
   * @return int
   */
  public int getWhatToShow()
  {
    return m_whatToShow;
  }

  /**
   * Sets the occurrenceIndicator.
   * @param occurrenceIndicator The occurrenceIndicator to set
   */
  public void setOccurrenceIndicator(int occurrenceIndicator)
  {
    m_occurrenceIndicator = occurrenceIndicator;
  }

  /**
   * Sets the schemaContext.
   * @param schemaContext The schemaContext to set
   */
  public void setSchemaContext(SchemaContext schemaContext)
  {
    m_schemaContext = schemaContext;
  }

  /**
   * Sets the schemaTypeName.
   * @param schemaTypeName The schemaTypeName to set
   */
  public void setSchemaTypeName(QName schemaTypeName)
  {
    m_schemaTypeName = schemaTypeName;
  }

  /**
   * Sets the targetExpr.
   * @param targetExpr The targetExpr to set
   */
  public void setTargetExpr(Expression targetExpr)
  {
    m_targetExpr = targetExpr;
  }

  /**
   * Sets the whatToShow.
   * @param whatToShow The whatToShow to set
   */
  public void setWhatToShow(int whatToShow)
  {
    m_whatToShow = whatToShow;
  }
  
  /**
   * @see org.apache.xpath.parser.Node#jjtAddChild(Node, int)
   */
  public void jjtAddChild(Node n, int i)
  {
    if(0 == i)
    {
      n = this.fixupPrimarys(n);
      m_targetExpr = (Expression)n;
    }
    else if(2 == i) // skip the child at index 1, which is the instance of keyword.
    {
      SequenceType stype = (SequenceType)n;
      m_atomicTypeID = stype.getAtomicTypeID();
      m_elemOrAttrName = stype.getElemOrAttrName();
      m_occurrenceIndicator = stype.getOccurrenceIndicator();
      m_schemaContext = stype.getSchemaContext();
      m_schemaTypeName = stype.getSchemaTypeName();
      m_whatToShow = stype.getWhatToShow();
    }
  }

  /**
   * @see org.apache.xpath.ExpressionNode#exprGetChild(int)
   */
  public ExpressionNode exprGetChild(int i)
  {
    // This doesn't work perfectly, but it's good enough.
    return (0 == i) ? m_targetExpr : (1 == 0) ? m_schemaContext : null;
  }

  /**
   * @see org.apache.xpath.ExpressionNode#exprGetNumChildren()
   */
  public int exprGetNumChildren()
  {
    // This doesn't work perfectly, but it's good enough.
    return ((null == m_targetExpr) ? 1 : 0)+((null == m_schemaContext) ? 1 : 0);
  }

  /**
   * @see org.apache.xpath.parser.SimpleNode#dump(String, PrintStream)
   */
  public void dump(String prefix, PrintStream ps)
  {
    super.dump(prefix, ps);
    prefix = prefix+"   ";
    ps.print(prefix);
    ps.println("m_atomicTypeID: "+m_atomicTypeID);
    ps.print(prefix);
    ps.println("m_elemOrAttrName: "+m_elemOrAttrName);
    ps.print(prefix);
    ps.println("m_occurrenceIndicator: "+m_occurrenceIndicator);
    ps.print(prefix);
    ps.println("m_schemaContext: "+m_schemaContext);
    ps.print(prefix);
    ps.println("m_schemaTypeName: "+m_schemaTypeName);
    ps.print(prefix);
    ps.println("m_whatToShow: "+m_whatToShow);
  }

  /**
   * @see java.lang.Object#toString()
   */
  public String toString()
  {
    return "instance of";
  }

}
