filterexprwalker.java

来自「java jdk 1.4的源码」· Java 代码 · 共 390 行

JAVA
390
字号
/* * 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.Vector;import javax.xml.transform.TransformerException;import org.apache.xalan.templates.FuncKey;import org.apache.xml.dtm.Axis;import org.apache.xml.dtm.DTM;import org.apache.xml.dtm.DTMIterator;import org.apache.xml.utils.PrefixResolver;import org.apache.xpath.Expression;import org.apache.xpath.ExpressionOwner;import org.apache.xpath.VariableStack;import org.apache.xpath.XPathContext;import org.apache.xpath.XPathVisitor;import org.apache.xpath.compiler.Compiler;import org.apache.xpath.compiler.OpCodes;import org.apache.xpath.objects.XNodeSet;/** * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP, * op codes. * @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a> */public class FilterExprWalker extends AxesWalker{  /**   * Construct a FilterExprWalker using a LocPathIterator.   *   * @param locPathIterator non-null reference to the parent iterator.   */  public FilterExprWalker(WalkingIterator locPathIterator)  {    super(locPathIterator, Axis.FILTEREDLIST);  }  /**   * Init a FilterExprWalker.   *   * @param compiler non-null reference to the Compiler that is constructing.   * @param opPos positive opcode position for this step.   * @param stepType The type of step.   *   * @throws javax.xml.transform.TransformerException   */  public void init(Compiler compiler, int opPos, int stepType)          throws javax.xml.transform.TransformerException  {    super.init(compiler, opPos, stepType);    // Smooth over an anomily in the opcode map...    switch (stepType)    {    case OpCodes.OP_FUNCTION :    case OpCodes.OP_EXTFUNCTION :    	m_mustHardReset = true;    case OpCodes.OP_GROUP :    case OpCodes.OP_VARIABLE :      m_expr = compiler.compile(opPos);      m_expr.exprSetParent(this);      if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof org.apache.xalan.templates.FuncKey))      {      	// hack/temp workaround      	m_canDetachNodeset = false;      }      break;    default :      m_expr = compiler.compile(opPos + 2);      m_expr.exprSetParent(this);    }//    if(m_expr instanceof WalkingIterator)//    {//      WalkingIterator wi = (WalkingIterator)m_expr;//      if(wi.getFirstWalker() instanceof FilterExprWalker)//      {//      	FilterExprWalker fw = (FilterExprWalker)wi.getFirstWalker();//      	if(null == fw.getNextWalker())//      	{//      		m_expr = fw.m_expr;//      		m_expr.exprSetParent(this);//      	}//      }//      		//    }  }    /**   * Detaches the walker from the set which it iterated over, releasing   * any computational resources and placing the iterator in the INVALID   * state.   */  public void detach()  {    	super.detach();  	m_exprObj.detach();  	m_exprObj = null;  }  /**   *  Set the root node of the TreeWalker.   *   * @param root non-null reference to the root, or starting point of    *        the query.   */  public void setRoot(int root)  {    super.setRoot(root);  	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(root,   	                  m_lpi.getXPathContext(), m_lpi.getPrefixResolver(),   	                  m_lpi.getIsTopLevel(), m_lpi.m_stackFrame, m_expr);  }  /**   * Get a cloned FilterExprWalker.   *   * @return A new FilterExprWalker that can be used without mutating this one.   *   * @throws CloneNotSupportedException   */  public Object clone() throws CloneNotSupportedException  {    FilterExprWalker clone = (FilterExprWalker) super.clone();    // clone.m_expr = (Expression)((Expression)m_expr).clone();    if (null != m_exprObj)      clone.m_exprObj = (XNodeSet) m_exprObj.clone();    return clone;  }    /**   * This method needs to override AxesWalker.acceptNode because FilterExprWalkers   * don't need to, and shouldn't, do a node test.   * @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)  {    try    {      if (getPredicateCount() > 0)      {        countProximityPosition(0);        if (!executePredicates(n, m_lpi.getXPathContext()))          return DTMIterator.FILTER_SKIP;      }      return DTMIterator.FILTER_ACCEPT;    }    catch (javax.xml.transform.TransformerException se)    {      throw new RuntimeException(se.getMessage());    }  }  /**   *  Moves the <code>TreeWalker</code> to the next visible node in document   * order relative to the current node, and returns the new node. If the   * current node has no next node,  or if the search for nextNode attempts   * to step upward from the TreeWalker's root node, returns   * <code>null</code> , and retains the current node.   * @return  The new node, or <code>null</code> if the current node has no   *   next node  in the TreeWalker's logical view.   */  public int getNextNode()  {    if (null != m_exprObj)    {       int next = m_exprObj.nextNode();       return next;    }    else      return DTM.NULL;  }    /**   * Get the index of the last node that can be itterated to.   *   *   * @param xctxt XPath runtime context.   *   * @return the index of the last node that can be itterated to.   */  public int getLastPos(XPathContext xctxt)  {    return m_exprObj.getLength();  }    /** The contained expression. Should be non-null.   *  @serial   */  private Expression m_expr;  /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */  transient private XNodeSet m_exprObj;    private boolean m_mustHardReset = false;  private boolean m_canDetachNodeset = true;  /**   * This function is used to fixup variables from QNames to stack frame    * indexes at stylesheet build time.   * @param vars List of QNames that correspond to variables.  This list    * should be searched backwards for the first qualified name that    * corresponds to the variable reference qname.  The position of the    * QName in the vector from the start of the vector will be its position    * in the stack frame (but variables above the globalsTop value will need    * to be offset to the current stack frame).   */  public void fixupVariables(java.util.Vector vars, int globalsSize)  {    super.fixupVariables(vars, globalsSize);    m_expr.fixupVariables(vars, globalsSize);  }    /**   * Get the inner contained expression of this filter.   */  public Expression getInnerExpression()  {  	return m_expr;  }    /**   * Set the inner contained expression of this filter.   */  public void setInnerExpression(Expression expr)  {  	expr.exprSetParent(this);  	m_expr = expr;  }    /**    * Get the analysis bits for this walker, as defined in the WalkerFactory.   * @return One of WalkerFactory#BIT_DESCENDANT, etc.   */  public int getAnalysisBits()  {      if (null != m_expr && m_expr instanceof PathComponent)      {        return ((PathComponent) m_expr).getAnalysisBits();      }      return WalkerFactory.BIT_FILTER;  }    /**   * Returns true if all the nodes in the iteration well be returned in document    * order.   * Warning: This can only be called after setRoot has been called!   *    * @return true as a default.   */  public boolean isDocOrdered()  {    return m_exprObj.isDocOrdered();  }    /**   * Returns the axis being iterated, if it is known.   *    * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple    * types.   */  public int getAxis()  {    return m_exprObj.getAxis();  }    class filterExprOwner implements ExpressionOwner  {      /**     * @see ExpressionOwner#getExpression()     */    public Expression getExpression()    {      return m_expr;    }
    /**     * @see ExpressionOwner#setExpression(Expression)     */    public void setExpression(Expression exp)    {    	exp.exprSetParent(FilterExprWalker.this);    	m_expr = exp;    }
  }  	/**	 * This will traverse the heararchy, calling the visitor for 	 * each member.  If the called visitor method returns 	 * false, the subtree should not be called.	 * 	 * @param owner The owner of the visitor, where that path may be 	 *              rewritten if needed.	 * @param visitor The visitor whose appropriate method will be called.	 */	public void callPredicateVisitors(XPathVisitor visitor)	{	  m_expr.callVisitors(new filterExprOwner(), visitor);	  	  super.callPredicateVisitors(visitor);	}     /**     * @see Expression#deepEquals(Expression)     */    public boolean deepEquals(Expression expr)    {      if (!super.deepEquals(expr))                return false;      FilterExprWalker walker = (FilterExprWalker)expr;      if(!m_expr.deepEquals(walker.m_expr))      	return false;      return true;    }	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?