- /*
- * 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.axes;
-
- import java.util.Stack;
-
- import org.apache.xpath.Expression;
- import org.apache.xpath.objects.XObject;
- import org.apache.xpath.XPathContext;
- import org.apache.xml.utils.PrefixResolver;
- import org.apache.xpath.axes.SubContextList;
- import org.apache.xpath.compiler.PsuedoNames;
- import org.apache.xpath.compiler.Compiler;
- import org.apache.xpath.patterns.StepPattern;
- import org.apache.xpath.VariableStack;
- import org.apache.xpath.patterns.NodeTest;
- import org.apache.xml.dtm.DTM;
- import org.apache.xml.dtm.DTMIterator;
- import org.apache.xml.dtm.DTMFilter;
- import org.apache.xml.dtm.DTMManager;
- import org.apache.xml.dtm.Axis;
- import org.apache.xml.dtm.DTMAxisTraverser;
-
- /**
- * This class treats a
- * <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a> as a
- * filtered iteration over the tree, evaluating each node in a super axis
- * traversal against the LocationPath interpreted as a match pattern. This
- * class is useful to find nodes in document order that are complex paths
- * whose steps probably criss-cross each other.
- */
- public class MatchPatternIterator extends LocPathIterator
- {
-
- /** This is the select pattern, translated into a match pattern. */
- protected StepPattern m_pattern;
-
- /** The traversal axis from where the nodes will be filtered. */
- protected int m_superAxis = -1;
-
- /** The DTM inner traversal class, that corresponds to the super axis. */
- protected DTMAxisTraverser m_traverser;
-
- /** DEBUG flag for diagnostic dumps. */
- private static final boolean DEBUG = false;
-
- // protected int m_nsElemBase = DTM.NULL;
-
- /**
- * Create a LocPathIterator object, including creation
- * of step walkers from the opcode list, and call back
- * into the Compiler to create predicate expressions.
- *
- * @param compiler The Compiler which is creating
- * this expression.
- * @param opPos The position of this iterator in the
- * opcode list from the compiler.
- * @param analysis Analysis bits that give general information about the
- * LocationPath.
- *
- * @throws javax.xml.transform.TransformerException
- */
- MatchPatternIterator(Compiler compiler, int opPos, int analysis)
- throws javax.xml.transform.TransformerException
- {
-
- super(compiler, opPos, analysis, false);
-
- int firstStepPos = compiler.getFirstChildPos(opPos);
-
- m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0);
-
- boolean fromRoot = false;
- boolean walkBack = false;
- boolean walkDescendants = false;
- boolean walkAttributes = false;
-
- if (0 != (analysis & (WalkerFactory.BIT_ROOT |
- WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT)))
- fromRoot = true;
-
- if (0 != (analysis
- & (WalkerFactory.BIT_ANCESTOR
- | WalkerFactory.BIT_ANCESTOR_OR_SELF
- | WalkerFactory.BIT_PRECEDING
- | WalkerFactory.BIT_PRECEDING_SIBLING
- | WalkerFactory.BIT_FOLLOWING
- | WalkerFactory.BIT_FOLLOWING_SIBLING
- | WalkerFactory.BIT_PARENT | WalkerFactory.BIT_FILTER)))
- walkBack = true;
-
- if (0 != (analysis
- & (WalkerFactory.BIT_DESCENDANT_OR_SELF
- | WalkerFactory.BIT_DESCENDANT
- | WalkerFactory.BIT_CHILD)))
- walkDescendants = true;
-
- if (0 != (analysis
- & (WalkerFactory.BIT_ATTRIBUTE | WalkerFactory.BIT_NAMESPACE)))
- walkAttributes = true;
-
- if(false || DEBUG)
- {
- System.out.print("analysis: "+Integer.toBinaryString(analysis));
- System.out.println(", "+WalkerFactory.getAnalysisString(analysis));
- }
-
- if(fromRoot || walkBack)
- {
- if(walkAttributes)
- {
- m_superAxis = Axis.ALL;
- }
- else
- {
- m_superAxis = Axis.DESCENDANTSFROMROOT;
- }
- }
- else if(walkDescendants)
- {
- if(walkAttributes)
- {
- m_superAxis = Axis.ALLFROMNODE;
- }
- else
- {
- m_superAxis = Axis.DESCENDANTORSELF;
- }
- }
- else
- {
- m_superAxis = Axis.ALL;
- }
- if(false || DEBUG)
- {
- System.out.println("axis: "+Axis.names[m_superAxis]);
- }
-
- }
-
-
- /**
- * Initialize the context values for this expression
- * after it is cloned.
- *
- * @param execContext The XPath runtime context for this
- * transformation.
- */
- public void setRoot(int context, Object environment)
- {
- super.setRoot(context, environment);
- m_traverser = m_cdtm.getAxisTraverser(m_superAxis);
- }
-
- /**
- * Get the next node via getNextXXX. Bottlenecked for derived class override.
- * @return The next node on the axis, or DTM.NULL.
- */
- protected int getNextNode()
- {
- m_lastFetched = (DTM.NULL == m_lastFetched)
- ? m_traverser.first(m_context)
- : m_traverser.next(m_context, m_lastFetched);
- return m_lastFetched;
- }
-
- /**
- * Returns the next node in the set and advances the position of the
- * iterator in the set. After a NodeIterator is created, the first call
- * to nextNode() returns the first node in the set.
- * @return The next <code>Node</code> in the set being iterated over, or
- * <code>null</code> if there are no more members in that set.
- */
- public int nextNode()
- {
- if(m_foundLast)
- return DTM.NULL;
-
- int next;
-
- org.apache.xpath.VariableStack vars;
- int savedStart;
- if (-1 != m_stackFrame)
- {
- vars = m_execContext.getVarStack();
-
- // These three statements need to be combined into one operation.
- savedStart = vars.getStackFrame();
-
- vars.setStackFrame(m_stackFrame);
- }
- else
- {
- // Yuck. Just to shut up the compiler!
- vars = null;
- savedStart = 0;
- }
-
- try
- {
- if(DEBUG)
- System.out.println("m_pattern"+m_pattern.toString());
-
- do
- {
- next = getNextNode();
-
- if (DTM.NULL != next)
- {
- if(DTMIterator.FILTER_ACCEPT == acceptNode(next, m_execContext))
- break;
- else
- continue;
- }
- else
- break;
- }
- while (next != DTM.NULL);
-
- if (DTM.NULL != next)
- {
- if(DEBUG)
- {
- System.out.println("next: "+next);
- System.out.println("name: "+m_cdtm.getNodeName(next));
- }
- incrementCurrentPos();
-
- return next;
- }
- else
- {
- m_foundLast = true;
-
- return DTM.NULL;
- }
- }
- finally
- {
- if (-1 != m_stackFrame)
- {
- // These two statements need to be combined into one operation.
- vars.setStackFrame(savedStart);
- }
- }
-
- }
-
- /**
- * Test whether a specified node is visible in the logical view of a
- * TreeWalker or NodeIterator. This function will be called by the
- * implementation of TreeWalker and NodeIterator; it is not intended to
- * be called directly from user code.
- * @param n The node to check to see if it passes the filter or not.
- * @return a constant to determine whether the node is accepted,
- * rejected, or skipped, as defined above .
- */
- public short acceptNode(int n, XPathContext xctxt)
- {
-
- try
- {
- xctxt.pushCurrentNode(n);
- xctxt.pushIteratorRoot(m_context);
- if(DEBUG)
- {
- System.out.println("traverser: "+m_traverser);
- System.out.print("node: "+n);
- System.out.println(", "+m_cdtm.getNodeName(n));
- // if(m_cdtm.getNodeName(n).equals("near-east"))
- System.out.println("pattern: "+m_pattern.toString());
- m_pattern.debugWhatToShow(m_pattern.getWhatToShow());
- }
-
- XObject score = m_pattern.execute(xctxt);
-
- if(DEBUG)
- {
- // System.out.println("analysis: "+Integer.toBinaryString(m_analysis));
- System.out.println("score: "+score);
- System.out.println("skip: "+(score == NodeTest.SCORE_NONE));
- }
-
- // System.out.println("\n::acceptNode - score: "+score.num()+"::");
- return (score == NodeTest.SCORE_NONE) ? DTMIterator.FILTER_SKIP
- : DTMIterator.FILTER_ACCEPT;
- }
- catch (javax.xml.transform.TransformerException se)
- {
-
- // TODO: Fix this.
- throw new RuntimeException(se.getMessage());
- }
- finally
- {
- xctxt.popCurrentNode();
- xctxt.popIteratorRoot();
- }
-
- }
-
- }