sboag       99/12/13 00:06:02

  Modified:    src/org/apache/xalan/xpath MutableNodeListImpl.java
                        XPath.java XPathSupport.java
                        XPathSupportDefault.java
  Added:       src/org/apache/xalan/xpath NodeCallback.java
                        UnionContext.java
  Log:
  Support for XLocator callbacks and depth-first in-order searches.  Not 
enabled at the moment.
  
  Revision  Changes    Path
  1.4       +10 -2     
xml-xalan/src/org/apache/xalan/xpath/MutableNodeListImpl.java
  
  Index: MutableNodeListImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/MutableNodeListImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MutableNodeListImpl.java  1999/12/02 06:04:06     1.3
  +++ MutableNodeListImpl.java  1999/12/13 08:06:01     1.4
  @@ -70,9 +70,17 @@
      */
     public MutableNodeListImpl() 
     {
  -    super();
  +    super(512);
     }
  - 
  +
  +  /**
  +   * Create an empty nodelist.
  +   */
  +  public MutableNodeListImpl(int blocksize) 
  +  {
  +    super(blocksize);
  +  }
  +
     /**
      * Create a MutableNodeListImpl, and copy the members of the 
      * given nodelist into it.
  
  
  
  1.9       +81 -72    xml-xalan/src/org/apache/xalan/xpath/XPath.java
  
  Index: XPath.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XPath.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XPath.java        1999/12/03 22:30:56     1.8
  +++ XPath.java        1999/12/13 08:06:01     1.9
  @@ -272,7 +272,7 @@
       int opPos = 0;
       if(m_opMap[opPos] == OP_MATCHPATTERN)
       {
  -      opPos+=2;
  +      opPos = getFirstChildPos(opPos);
         
         XLocator locator = execContext.getXLocatorFromNode(context);
         
  @@ -283,7 +283,7 @@
         {
           int nextOpPos = getNextOpPos(opPos);
           
  -        // opPos+=2;        
  +        // opPos = getFirstChildPos(opPos);        
           score = locator.locationPathPattern(this, execContext, context, 
opPos);
   
           if(score != MATCH_SCORE_NONE)
  @@ -313,7 +313,7 @@
       int opPos = 0;
       if(m_opMap[opPos] == OP_MATCHPATTERN)
       {
  -      opPos+=2;
  +      opPos = getFirstChildPos(opPos);
         
         XLocator locator = execContext.getXLocatorFromNode(dtm.getDocument());
         
  @@ -327,7 +327,7 @@
         {
           int nextOpPos = getNextOpPos(opPos);
           
  -        // opPos+=2;        
  +        // opPos = getFirstChildPos(opPos);        
           score = dtmLocator.locationPathPattern(this, execContext, dtm, 
context, opPos);
   
           if(score != MATCH_SCORE_NONE)
  @@ -486,7 +486,7 @@
     protected XBoolean or(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       XBoolean result;
       XObject expr1 = execute(execContext, context, opPos);
  @@ -518,7 +518,7 @@
     protected XBoolean and(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       XObject expr1 = execute(execContext, context, opPos);
       if(expr1.bool())
  @@ -539,7 +539,7 @@
     protected XBoolean notequals(XPathSupport execContext, Node context, int 
opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -558,7 +558,7 @@
     protected XBoolean equals(XPathSupport execContext, Node context, int 
opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -576,7 +576,7 @@
     protected XBoolean lte(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -594,7 +594,7 @@
     protected XBoolean lt(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -612,7 +612,7 @@
     protected XBoolean gte(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -631,7 +631,7 @@
     protected XBoolean gt(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -649,7 +649,7 @@
     protected XNumber plus(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -667,7 +667,7 @@
     protected XNumber minus(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -685,7 +685,7 @@
     protected XNumber mult(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -703,7 +703,7 @@
     protected XNumber div(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -721,7 +721,7 @@
     protected XNumber mod(XPathSupport execContext, Node context, int opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -743,7 +743,7 @@
       // Actually, this is no longer supported by xpath...
       warn(XPATHErrorResources.WARNING0005); //"Old syntax: quo(...) is no 
longer defined in XPath.");
       
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
       XObject expr1 = execute(execContext, context, opPos);
  @@ -807,7 +807,7 @@
       
       return new XNumber(expr1.num());
     }
  -
  +  
     /**
      * Computes the union of its operands which must be node-sets.
      * @param context The current source tree context node.
  @@ -817,26 +817,14 @@
     protected XNodeSet union(XPathSupport execContext, Node context, int 
opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  -    XNodeSet resultNodeSet = null;
  -
  -    while(m_opMap[opPos] == OP_LOCATIONPATH)
  -    {
  -      int nextOpPos = getNextOpPos(opPos);
  -      XNodeSet expr = (XNodeSet)execute(execContext, context, opPos);
  -      if(null == resultNodeSet)
  -      {
  -        resultNodeSet = expr;
  -      }
  -      else
  -      {
  -        MutableNodeList nl = resultNodeSet.mutableNodeset();
  -        nl.addNodesInDocOrder(expr.nodeset(), execContext);
  -      }
  -      opPos = nextOpPos;
  -    }
  +    XLocator xlocator = execContext.getXLocatorFromNode(context);
       
  -    return resultNodeSet;
  +    if(null == xlocator)
  +      xlocator = m_defaultXLocator;
  +      
  +    XNodeSet results = xlocator.union(this, execContext, context, opPos);
  +    
  +    return results;
     }
   
     /**
  @@ -847,7 +835,7 @@
      */
     protected XString literal(XPathSupport execContext, Node context, int 
opPos) 
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       
       // TODO: It's too expensive to create an object every time...
       return (XString)m_tokenQueue[m_opMap[opPos]];
  @@ -862,7 +850,7 @@
     protected XObject variable(XPathSupport execContext, Node context, int 
opPos) 
       throws org.xml.sax.SAXException
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       String varName = (String)m_tokenQueue[m_opMap[opPos]];
       // System.out.println("variable name: "+varName);
       // TODO: I don't this will be parsed right in the first place...
  @@ -909,7 +897,7 @@
      */
     protected XNumber numberlit(XPathSupport execContext, Node context, int 
opPos) 
     {
  -    opPos+=2;
  +    opPos = getFirstChildPos(opPos);
       
       return (XNumber)m_tokenQueue[m_opMap[opPos]];
     }
  @@ -949,32 +937,7 @@
     public XNodeSet locationPath(XPathSupport execContext, Node context, int 
opPos) 
       throws org.xml.sax.SAXException
     {    
  -    int stepType = m_opMap[opPos+2];
       XLocator xlocator = execContext.getXLocatorFromNode(context);
  -    /*
  -    XLocator xlocator = null;
  -    if(OP_VARIABLE == stepType)
  -    {
  -      // Bit of a hack here...
  -      XObject obj = execute(context, opPos+2);
  -      NodeList nl = obj.nodeset();
  -      if(nl.getLength() > 0)
  -      {
  -        // Use the xlocator of the first node...
  -        // I guess we should really loop through the contexts, but things 
  -        // will get very nasty quick, so just do this for now.
  -        xlocator = execContext.getXLocatorFromNode(nl.item(0));
  -      }
  -      else
  -      {
  -        xlocator = execContext.getXLocatorFromNode(context);
  -      }
  -    }
  -    else
  -    {
  -      xlocator = execContext.getXLocatorFromNode(context);
  -    }
  -    */
       
       if(null == xlocator)
         xlocator = m_defaultXLocator;
  @@ -1165,7 +1128,7 @@
     protected XNumber locationPathPattern(XPathSupport execContext, Node 
context, int opPos) 
       throws org.xml.sax.SAXException
     {    
  -    // opPos+=2;
  +    // opPos = getFirstChildPos(opPos);
       XLocator locator = execContext.getXLocatorFromNode(context);
       
       if(null == locator)
  @@ -1185,7 +1148,7 @@
       while(m_opMap[opPos] == OP_LOCATIONPATHPATTERN)
       {
         int nextOpPos = getNextOpPos(opPos);
  -      opPos+=2;
  +      opPos = getFirstChildPos(opPos);
         
         while( m_opMap[opPos] != ENDOP )
         {
  @@ -1353,7 +1316,7 @@
       case OP_EXTFUNCTION:
         {
           int endExtFunc = opPos+m_opMap[opPos+1]-1;
  -        opPos+=2;
  +        opPos = getFirstChildPos(opPos);
           String ns = (String)m_tokenQueue[m_opMap[opPos]];
           opPos++;
           String funcName = (String)m_tokenQueue[m_opMap[opPos]];
  @@ -1371,7 +1334,7 @@
       case OP_FUNCTION:
         {
           int endFunc = opPos+m_opMap[opPos+1]-1;
  -        opPos+=2;
  +        opPos = getFirstChildPos(opPos);
           int funcID = m_opMap[opPos];
           opPos++;
           Vector args = new Vector();
  @@ -1459,14 +1422,60 @@
       return result;
     }
     
  +  // ============= Op Code Position Helper Functions =================
  +  private void ____OPCODE_POSITION_HELPER_FUNCTIONS____(){}
  +  
     /**
  -   * Given an opperation position, return the end position, i.e. the 
  +   * Given an operation position, return the current op.
  +   * @return position of next operation in m_opMap.
  +   */
  +  public int getOp(int opPos)
  +  {
  +    return m_opMap[opPos];
  +  }
  +
  +  /**
  +   * Given an operation position, return the end position, i.e. the 
      * beginning of the next operation.
  -   * @return position of next opperation in m_opMap.
  +   * @return position of next operation in m_opMap.
      */
     public int getNextOpPos(int opPos)
     {
       return opPos+m_opMap[opPos+1];
  +  }
  +  
  +  /**
  +   * Given an operation position, return the end position, i.e. the 
  +   * beginning of the next operation.
  +   * @return position of next operation in m_opMap.
  +   */
  +  public static int getNextOpPos(int[] opMap, int opPos)
  +  {
  +    return opPos+opMap[opPos+1];
  +  }
  +  
  +  /**
  +   * Go to the first child of a given operation.
  +   */
  +  public static int getFirstChildPos(int opPos)
  +  {
  +    return opPos+2;
  +  }
  +
  +  /**
  +   * Go to the first child of a given operation.
  +   */
  +  public int getArgLengthOfStep(int opPos)
  +  {
  +    return m_opMap[opPos+MAPINDEX_LENGTH+1]-3;
  +  }
  +
  +  /**
  +   * Go to the first child of a given operation.
  +   */
  +  public static int getFirstChildPosOfStep(int opPos)
  +  {
  +    return opPos+3;
     }
   
     // ============= DIAGNOSTIC & ERROR HANDLINING =================
  
  
  
  1.4       +25 -0     xml-xalan/src/org/apache/xalan/xpath/XPathSupport.java
  
  Index: XPathSupport.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XPathSupport.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XPathSupport.java 1999/11/28 10:26:17     1.3
  +++ XPathSupport.java 1999/12/13 08:06:01     1.4
  @@ -185,6 +185,31 @@
            ExtensionFunctionHandler extNS);
     
     /**
  +   * Set a callback that may be called by XPath as nodes are located.
  +   * The callback will only be called if the XLocator determines that 
  +   * the location path can process the nodes in document order.
  +   * If the callback is called, the nodes will not be put into the 
  +   * node list, and the LocationPath will return an empty node list.
  +   * The callback will be set to null after the given LocationPath or 
  +   * Union is processed.
  +   * @param callback Interface that implements the processLocatedNode method.
  +   * @param callbackInfo Object that will be passed to the 
processLocatedNode method.
  +   */
  +  public void setCallback(NodeCallback callback, Object callbackInfo);
  +  
  +  /**
  +   * Get the callback that may be called by XPath as nodes are located.
  +   * @return the current callback method.
  +   */
  +  public NodeCallback getCallback();
  +
  +  /**
  +   * Get the object that will be passed to the processLocatedNode method.
  +   * @return object that will be passed to the processLocatedNode method.
  +   */
  +  public Object getCallbackInfo();
  +  
  +  /**
      * Function that is called when a problem event occurs.
      * 
      * @param   where             Either and XMLPARSER, XSLPROCESSOR, or 
QUERYENGINE.
  
  
  
  1.5       +50 -0     
xml-xalan/src/org/apache/xalan/xpath/XPathSupportDefault.java
  
  Index: XPathSupportDefault.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/XPathSupportDefault.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XPathSupportDefault.java  1999/11/28 10:26:17     1.4
  +++ XPathSupportDefault.java  1999/12/13 08:06:01     1.5
  @@ -357,5 +357,55 @@
            ExtensionFunctionHandler extNS)
     {
     }
  +  
  +  /**
  +   * Callback that may be executed when a node is found, if the 
  +   * XPath query can be done in document order.
  +   * The callback will be set to null after the next LocationPath or 
  +   * Union is processed.
  +   */
  +  private NodeCallback m_callback = null;
  +  
  +  /**
  +   * Object that will be passed to the processLocatedNode method.
  +   * The object will be set to null after the next LocationPath or 
  +   * Union is processed.
  +   */
  +  private Object m_callbackInfo = null;
  +
  +  /**
  +   * Set a callback that may be called by XPath as nodes are located.
  +   * The callback will only be called if the XLocator determines that 
  +   * the location path can process the nodes in document order.
  +   * If the callback is called, the nodes will not be put into the 
  +   * node list, and the LocationPath will return an empty node list.
  +   * The callback will be set to null after the next LocationPath or 
  +   * Union is processed.
  +   * @param callback Interface that implements the processLocatedNode method.
  +   * @param callbackInfo Object that will be passed to the 
processLocatedNode method.
  +   */
  +  public void setCallback(NodeCallback callback, Object callbackInfo)
  +  {
  +    m_callback = callback;
  +    m_callbackInfo = callbackInfo;
  +  }
  +  
  +  /**
  +   * Get the callback that may be called by XPath as nodes are located.
  +   * @return the current callback method.
  +   */
  +  public NodeCallback getCallback()
  +  {
  +    return m_callback;
  +  }
  +
  +  /**
  +   * Get the object that will be passed to the processLocatedNode method.
  +   * @return object that will be passed to the processLocatedNode method.
  +   */
  +  public Object getCallbackInfo()
  +  {
  +    return m_callbackInfo;
  +  }
   
   }
  
  
  
  1.1                  xml-xalan/src/org/apache/xalan/xpath/NodeCallback.java
  
  Index: NodeCallback.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 "XSLT4J" 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 [EMAIL PROTECTED]
   *
   * 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.xalan.xpath;
  
  import org.w3c.dom.Node;
  import org.xml.sax.SAXException;
  
  /**
   * This interface describes a callback that may be executed when 
   * a node is found, if the XPath query can be done in document 
   * order.
   * @param execContext Execution context.
   * @param sourceNode The source node that was located.
   * @param callbackInfo Opaque info for the caller's benefit.
   */
  public interface NodeCallback
  {
    public void processLocatedNode(XPathSupport execContext, 
                        Node sourceNode,
                        Object callbackInfo)
      throws SAXException;
  }
  
  
  
  1.1                  xml-xalan/src/org/apache/xalan/xpath/UnionContext.java
  
  Index: UnionContext.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 "XSLT4J" 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 [EMAIL PROTECTED]
   *
   * 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.xalan.xpath;
  
  import org.apache.xalan.xpath.xml.IntStack;
  
  /**
   * Tracks multiple stacks of opcodes positions.
   */
  public class UnionContext
  {
    static final int MAXPATHS = 32;
    IntStack[] m_stacks = new IntStack[MAXPATHS];
    IntStack[] m_posStacks = new IntStack[MAXPATHS];
    int m_stackCount;
  
    public static final int PSUEDO_POS_FOUNDNODE = -10000;
    public static final int PSUEDO_OP_FOUNDNODE = -10000;
  
    /**
     * Construct the stacks by going through and 
     * pushing the first step opcode position of each location 
     * path.
     */
    UnionContext(int[] opMap, int opPos)
    {
      int op = opMap[opPos];
      if(XPath.OP_UNION == op)
      {
        pushUnionPath(opMap, opPos);
      }
      else if(XPath.OP_LOCATIONPATH == op)
      {
        pushLocationPath(0, opMap, opPos);
      }
      else
      {
        System.out.println("Programmers Error! Op must be OP_UNION or 
OP_LOCATIONPATH");
      }
    }
  
    /**
     * Get the number of valid stacks in the stack array.
     */
    public final int getLocationPathCount()
    {
      return m_stackCount;
    }
    
    /**
     * Set the number of valid stacks in the array.
     */
    private final void setLocationPathCount(int i)
    {
      m_stackCount = i;
    }
    
    /**
     * Add a new stack and set the stack count 
     * to which+1.
     */
    private final void addNewLocationPath(int which)
    {
      m_stacks[which] = new IntStack();
      m_posStacks[which] = new IntStack();
      setLocationPathCount(which+1);
    }
    
    /**
     * Push the 
     */
    void pushLocationPath(int which, int[] opMap, int opPos)
    {
      addNewLocationPath(which);
      opPos = XPath.getFirstChildPos(opPos);
      push(which, opPos, 1);
      /*
      while(opPos < posOfLastOp)
      {
        // step
        int stepType = xpath.m_opMap[opPos];
        
        switch(stepType)
        {
        case xpath.FROM_ATTRIBUTES: // ?
          m_shouldWalkAttributes = true;
        case xpath.FROM_CHILDREN:
        case xpath.FROM_DESCENDANTS:
          break;
        case xpath.FROM_SELF:
        case xpath.FROM_DESCENDANTS_OR_SELF:
          // case xpath.FROM_FOLLOWING:  ...might do these later
          // case xpath.FROM_FOLLOWING_SIBLINGS: ...might do these later
          break;
        default:
          System.out.println("ERROR! Should only find forward axes!");
        }
  
        opPos = XPath.getNextOpPos(opMap, opPos);
      }
      if(xpath.m_opMap[opPos] != xpath.ENDOP)
      {
        System.out.println("ERROR! Could not find ENDOP after OP_LOCATIONPATH");
      }
      */
    }
    
    /**
     * Walk a union pattern and push each of the positions 
     * of the first child of the location steps.
     */
    private void pushUnionPath(int[] opMap, int opPos)
    {
      opPos+=2;
      
      for(int i = 0; opMap[opPos] == XPath.OP_LOCATIONPATH; i++)
      {
        int nextOpPos = XPath.getNextOpPos(opMap, opPos);
        pushLocationPath(i, opMap, opPos);
        opPos = nextOpPos;
      }
    }
    
    /**
     * Set the index position for a node, associated with 
     * the given LocationPath.
     */
    void setNodePosition(int which, int nodePos)
    {
      m_posStacks[which].setTop(nodePos);
    }
  
    /**
     * Set the index position for a node, associated with 
     * the given LocationPath.
     */
    void incrementNodePosition(int which)
    {
      m_posStacks[which].setTop(getNodePosition(which)+1);
    }
  
    /**
     * Set the index position for a node, associated with 
     * the given LocationPath.
     */
    int getNodePosition(int which)
    {
      return m_posStacks[which].peek();
    }
    
    /**
     * Pushes an opcode position onto the top of this stack. 
     *
     * @param   which   which stack to perform the operation on.
     * @param   opCodePos   an opcode position.
     * @return  the <code>opCodePos</code> argument.
     */
    public int push(int which, int opCodePos, int nodePos) 
    {
      m_posStacks[which].push(nodePos);
      return m_stacks[which].push(opCodePos);
    }
  
    /**
     * Removes the object at the top of the given stack and returns that 
     * object as the value of this function. 
     *
     * @param   which   which stack to perform the operation on.
     * @return     The opcode position at the top of this stack.
     * @exception  EmptyStackException  if this stack is empty.
     */
    public int pop(int which) 
    {
      m_posStacks[which].pop();
      return m_stacks[which].pop();
    }
  
  /**
     * Pop all stacks by one. 
     *
     * @exception  EmptyStackException  if this stack is empty.
     */
    public void pop() 
    {
      int n = m_stackCount;
      for(int i = 0; i < n; i++)
      {
        pop(i);
      }
    }
  
    /**
     * Looks at the object at the top of this stack without removing it 
     * from the stack. 
     *
     * @param   which   which stack to perform the operation on.
     * @return     The opcode position at the top of this stack.
     * @exception  EmptyStackException  if this stack is empty.
     */
    public int peek(int which) 
    {
      return m_stacks[which].peek();
    }
  
    /**
     * Tests if this stack is empty.
     *
     * @param   which   which stack to perform the operation on.
     * @return  <code>true</code> if this stack is empty;
     *          <code>false</code> otherwise.
     */
    public boolean empty(int which) 
    {
      return m_stacks[which].empty();
    }
  
    /**
     * Tests if all stacks are empty.
     *
     * @return  <code>true</code> if all stacks are empty;
     *          <code>false</code> otherwise.
     */
    public boolean empty() 
    {
      int n = m_stackCount;
      for(int i = 0; i < n; i++)
      {
        if(!empty(i))
          return false;
      }
      return true;
    }
  }
  
  
  

Reply via email to