📄 axeswalker.java
字号:
/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: AxesWalker.java,v 1.2.4.1 2005/09/14 19:45:22 jeffsuttor Exp $ */package com.sun.org.apache.xpath.internal.axes;import java.util.Vector;import com.sun.org.apache.xalan.internal.res.XSLMessages;import com.sun.org.apache.xml.internal.dtm.DTM;import com.sun.org.apache.xml.internal.dtm.DTMAxisTraverser;import com.sun.org.apache.xml.internal.dtm.DTMIterator;import com.sun.org.apache.xpath.internal.Expression;import com.sun.org.apache.xpath.internal.ExpressionOwner;import com.sun.org.apache.xpath.internal.XPathContext;import com.sun.org.apache.xpath.internal.XPathVisitor;import com.sun.org.apache.xpath.internal.compiler.Compiler;import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;/** * Serves as common interface for axes Walkers, and stores common * state variables. */public class AxesWalker extends PredicatedNodeTest implements Cloneable, PathComponent, ExpressionOwner{ static final long serialVersionUID = -2966031951306601247L; /** * Construct an AxesWalker using a LocPathIterator. * * @param locPathIterator non-null reference to the parent iterator. */ public AxesWalker(LocPathIterator locPathIterator, int axis) { super( locPathIterator ); m_axis = axis; } public final WalkingIterator wi() { return (WalkingIterator)m_lpi; } /** * Initialize an AxesWalker during the parse of the XPath expression. * * @param compiler The Compiler object that has information about this * walker in the op map. * @param opPos The op code position of this location step. * @param stepType The type of location step. * * @throws javax.xml.transform.TransformerException */ public void init(Compiler compiler, int opPos, int stepType) throws javax.xml.transform.TransformerException { initPredicateInfo(compiler, opPos); // int testType = compiler.getOp(nodeTestOpPos); } /** * Get a cloned AxesWalker. * * @return A new AxesWalker that can be used without mutating this one. * * @throws CloneNotSupportedException */ public Object clone() throws CloneNotSupportedException { // Do not access the location path itterator during this operation! AxesWalker clone = (AxesWalker) super.clone(); //clone.setCurrentNode(clone.m_root); // clone.m_isFresh = true; return clone; } /** * Do a deep clone of this walker, including next and previous walkers. * If the this AxesWalker is on the clone list, don't clone but * return the already cloned version. * * @param cloneOwner non-null reference to the cloned location path * iterator to which this clone will be added. * @param cloneList non-null vector of sources in odd elements, and the * corresponding clones in even vectors. * * @return non-null clone, which may be a new clone, or may be a clone * contained on the cloneList. */ AxesWalker cloneDeep(WalkingIterator cloneOwner, Vector cloneList) throws CloneNotSupportedException { AxesWalker clone = findClone(this, cloneList); if(null != clone) return clone; clone = (AxesWalker)this.clone(); clone.setLocPathIterator(cloneOwner); if(null != cloneList) { cloneList.addElement(this); cloneList.addElement(clone); } if(wi().m_lastUsedWalker == this) cloneOwner.m_lastUsedWalker = clone; if(null != m_nextWalker) clone.m_nextWalker = m_nextWalker.cloneDeep(cloneOwner, cloneList); // If you don't check for the cloneList here, you'll go into an // recursive infinate loop. if(null != cloneList) { if(null != m_prevWalker) clone.m_prevWalker = m_prevWalker.cloneDeep(cloneOwner, cloneList); } else { if(null != m_nextWalker) clone.m_nextWalker.m_prevWalker = clone; } return clone; } /** * Find a clone that corresponds to the key argument. * * @param key The original AxesWalker for which there may be a clone. * @param cloneList vector of sources in odd elements, and the * corresponding clones in even vectors, may be null. * * @return A clone that corresponds to the key, or null if key not found. */ static AxesWalker findClone(AxesWalker key, Vector cloneList) { if(null != cloneList) { // First, look for clone on list. int n = cloneList.size(); for (int i = 0; i < n; i+=2) { if(key == cloneList.elementAt(i)) return (AxesWalker)cloneList.elementAt(i+1); } } return null; } /** * 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() { m_currentNode = DTM.NULL; m_dtm = null; m_traverser = null; m_isFresh = true; m_root = DTM.NULL; } //=============== TreeWalker Implementation =============== /** * The root node of the TreeWalker, as specified in setRoot(int root). * Note that this may actually be below the current node. * * @return The context node of the step. */ public int getRoot() { return m_root; } /** * Get the analysis bits for this walker, as defined in the WalkerFactory. * @return One of WalkerFactory#BIT_DESCENDANT, etc. */ public int getAnalysisBits() { int axis = getAxis(); int bit = WalkerFactory.getAnalysisBitFromAxes(axis); return bit; } /** * Set the root node of the TreeWalker. * (Not part of the DOM2 TreeWalker interface). * * @param root The context node of this step. */ public void setRoot(int root) { // %OPT% Get this directly from the lpi. XPathContext xctxt = wi().getXPathContext(); m_dtm = xctxt.getDTM(root); m_traverser = m_dtm.getAxisTraverser(m_axis); m_isFresh = true; m_foundLast = false; m_root = root; m_currentNode = root; if (DTM.NULL == root) { throw new RuntimeException( XSLMessages.createXPATHMessage(XPATHErrorResources.ER_SETTING_WALKER_ROOT_TO_NULL, null)); //"\n !!!! Error! Setting the root of a walker to null!!!"); } resetProximityPositions(); } /** * The node at which the TreeWalker is currently positioned. * <br> The value must not be null. Alterations to the DOM tree may cause * the current node to no longer be accepted by the TreeWalker's * associated filter. currentNode may also be explicitly set to any node, * whether or not it is within the subtree specified by the root node or * would be accepted by the filter and whatToShow flags. Further * traversal occurs relative to currentNode even if it is not part of the * current view by applying the filters in the requested direction (not * changing currentNode where no traversal is possible). * * @return The node at which the TreeWalker is currently positioned, only null * if setRoot has not yet been called. */ public final int getCurrentNode() { return m_currentNode; } /** * Set the next walker in the location step chain. * * * @param walker Reference to AxesWalker derivative, or may be null. */ public void setNextWalker(AxesWalker walker) { m_nextWalker = walker; } /** * Get the next walker in the location step chain. * * * @return Reference to AxesWalker derivative, or null. */ public AxesWalker getNextWalker() { return m_nextWalker; } /** * Set or clear the previous walker reference in the location step chain. * * * @param walker Reference to previous walker reference in the location * step chain, or null. */ public void setPrevWalker(AxesWalker walker) { m_prevWalker = walker; } /** * Get the previous walker reference in the location step chain. * * * @return Reference to previous walker reference in the location * step chain, or null. */ public AxesWalker getPrevWalker() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -