dtmdefaultbaseiterators.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,931 行 · 第 1/4 页

JAVA
1,931
字号
/* * 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.xml.dtm.ref;import org.apache.xml.dtm.*;import javax.xml.transform.Source;import org.apache.xml.utils.XMLStringFactory;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xalan.res.XSLMessages;/** * This class implements the traversers for DTMDefaultBase. */public abstract class DTMDefaultBaseIterators extends DTMDefaultBaseTraversers{  /**   * Construct a DTMDefaultBaseTraversers object from a DOM node.   *   * @param mgr The DTMManager who owns this DTM.   * @param domSource the DOM source that this DTM will wrap.   * @param source The object that is used to specify the construction source.   * @param dtmIdentity The DTM identity ID for this DTM.   * @param whiteSpaceFilter The white space filter for this DTM, which may   *                         be null.   * @param xstringfactory The factory to use for creating XMLStrings.   * @param doIndexing true if the caller considers it worth it to use    *                   indexing schemes.   */  public DTMDefaultBaseIterators(DTMManager mgr, Source source,                                 int dtmIdentity,                                 DTMWSFilter whiteSpaceFilter,                                 XMLStringFactory xstringfactory,                                 boolean doIndexing)  {    super(mgr, source, dtmIdentity, whiteSpaceFilter,           xstringfactory, doIndexing);  }  /**   * Get an iterator that can navigate over an XPath Axis, predicated by   * the extended type ID.   * Returns an iterator that must be initialized   * with a start node (using iterator.setStartNode()).   *   * @param axis One of Axes.ANCESTORORSELF, etc.   * @param type An extended type ID.   *   * @return A DTMAxisIterator, or null if the given axis isn't supported.   */  public DTMAxisIterator getTypedAxisIterator(int axis, int type)  {    DTMAxisIterator iterator = null;    /* This causes an error when using patterns for elements that       do not exist in the DOM (translet types which do not correspond       to a DOM type are mapped to the DOM.ELEMENT type).    */    //        if (type == NO_TYPE) {    //            return(EMPTYITERATOR);    //        }    //        else if (type == ELEMENT) {    //            iterator = new FilterIterator(getAxisIterator(axis),    //                                          getElementFilter());    //        }    //        else     {      switch (axis)      {      case Axis.SELF :        iterator = new TypedSingletonIterator(type);        break;      case Axis.CHILD :        iterator = new TypedChildrenIterator(type);        break;      case Axis.PARENT :        return (new ParentIterator().setNodeType(type));      case Axis.ANCESTOR :        return (new TypedAncestorIterator(type));      case Axis.ANCESTORORSELF :        return ((new TypedAncestorIterator(type)).includeSelf());      case Axis.ATTRIBUTE :        return (new TypedAttributeIterator(type));      case Axis.DESCENDANT :        iterator = new TypedDescendantIterator(type);        break;      case Axis.DESCENDANTORSELF :        iterator = (new TypedDescendantIterator(type)).includeSelf();        break;      case Axis.FOLLOWING :        iterator = new TypedFollowingIterator(type);        break;      case Axis.PRECEDING :        iterator = new TypedPrecedingIterator(type);        break;      case Axis.FOLLOWINGSIBLING :        iterator = new TypedFollowingSiblingIterator(type);        break;      case Axis.PRECEDINGSIBLING :        iterator = new TypedPrecedingSiblingIterator(type);        break;      case Axis.NAMESPACE :        iterator = new TypedNamespaceIterator(type);        break;      case Axis.ROOT :        iterator = new TypedRootIterator(type);        break;      default :        throw new DTMException(XSLMessages.createMessage(XSLTErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED, new Object[]{Axis.names[axis]})); //"Error: typed iterator for axis "                               //+ Axis.names[axis] + "not implemented");      }    }    return (iterator);  }  /**   * This is a shortcut to the iterators that implement the   * XPath axes.   * Returns a bare-bones iterator that must be initialized   * with a start node (using iterator.setStartNode()).   *   * @param axis One of Axes.ANCESTORORSELF, etc.   *   * @return A DTMAxisIterator, or null if the given axis isn't supported.   */  public DTMAxisIterator getAxisIterator(final int axis)  {    DTMAxisIterator iterator = null;    switch (axis)    {    case Axis.SELF :      iterator = new SingletonIterator();      break;    case Axis.CHILD :      iterator = new ChildrenIterator();      break;    case Axis.PARENT :      return (new ParentIterator());    case Axis.ANCESTOR :      return (new AncestorIterator());    case Axis.ANCESTORORSELF :      return ((new AncestorIterator()).includeSelf());    case Axis.ATTRIBUTE :      return (new AttributeIterator());    case Axis.DESCENDANT :      iterator = new DescendantIterator();      break;    case Axis.DESCENDANTORSELF :      iterator = (new DescendantIterator()).includeSelf();      break;    case Axis.FOLLOWING :      iterator = new FollowingIterator();      break;    case Axis.PRECEDING :      iterator = new PrecedingIterator();      break;    case Axis.FOLLOWINGSIBLING :      iterator = new FollowingSiblingIterator();      break;    case Axis.PRECEDINGSIBLING :      iterator = new PrecedingSiblingIterator();      break;    case Axis.NAMESPACE :      iterator = new NamespaceIterator();      break;    case Axis.ROOT :      iterator = new RootIterator();      break;    default :      throw new DTMException(XSLMessages.createMessage(XSLTErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED, new Object[]{Axis.names[axis]})); //"Error: iterator for axis '" + Axis.names[axis]                             //+ "' not implemented");    }    return (iterator);  }  /**   * Abstract superclass defining behaviors shared by all DTMDefault's   * internal implementations of DTMAxisIterator. Subclass this (and   * override, if necessary) to implement the specifics of an   * individual axis iterator.   *   * Currently there isn't a lot here   */  private abstract class InternalAxisIteratorBase extends DTMAxisIteratorBase  {    // %REVIEW% We could opt to share _nodeType and setNodeType() as    // well, and simply ignore them in iterators which don't use them.    // But Scott's worried about the overhead involved in cloning    // these, and wants them to have as few fields as possible. Note    // that we can't create a TypedInternalAxisIteratorBase because    // those are often based on the untyped versions and Java doesn't    // support multiple inheritance. <sigh/>    /**     * Current iteration location. Usually this is the last location     * returned (starting point for the next() search); for single-node     * iterators it may instead be initialized to point to that single node.     */    protected int _currentNode;    /**     * Remembers the current node for the next call to gotoMark().     *     * %REVIEW% Should this save _position too?     */    public void setMark()    {      _markedNode = _currentNode;    }    /**     * Restores the current node remembered by setMark().     *     * %REVEIW% Should this restore _position too?     */    public void gotoMark()    {      _currentNode = _markedNode;    }  }  // end of InternalAxisIteratorBase   /**   * Iterator that returns all immediate children of a given node   */  private final class ChildrenIterator extends InternalAxisIteratorBase  {    /**     * Setting start to END should 'close' the iterator,     * i.e. subsequent call to next() should return END.     *     * If the iterator is not restartable, this has no effect.     * %REVIEW% Should it return/throw something in that case,     * or set current node to END, to indicate request-not-honored?     *     * @param node Sets the root of the iteration.     *     * @return A DTMAxisIterator set to the start of the iteration.     */    public DTMAxisIterator setStartNode(final int node)    {      if (_isRestartable)      {        _startNode = node;        _currentNode = NOTPROCESSED;        return resetPosition();      }      return this;    }    /**     * Get the next node in the iteration.     *     * @return The next node handle in the iteration, or END if no more     * are available.     */    public int next()    {      _currentNode = (NOTPROCESSED == _currentNode)                     ? getFirstChild(_startNode)                     : getNextSibling(_currentNode);      return returnNode(_currentNode);    }  }  // end of ChildrenIterator  /**   * Iterator that returns the parent of a given node. Note that   * this delivers only a single node; if you want all the ancestors,   * see AncestorIterator.   */  private final class ParentIterator extends InternalAxisIteratorBase  {    /** The extended type ID that was requested. */    private int _nodeType = -1;    /**     * Set start to END should 'close' the iterator,     * i.e. subsequent call to next() should return END.     *     * @param node Sets the root of the iteration.     *     * @return A DTMAxisIterator set to the start of the iteration.     */    public DTMAxisIterator setStartNode(int node)    {      if (_isRestartable)      {        _startNode = node;        _currentNode = getParent(node);        return resetPosition();      }      return this;    }    /**     * Set the node type of the parent that we're looking for.     * Note that this does _not_ mean "find the nearest ancestor of     * this type", but "yield the parent if it is of this type".     *     *     * @param type extended type ID.     *     * @return ParentIterator configured with the type filter set.     */    public DTMAxisIterator setNodeType(final int type)    {      _nodeType = type;      return this;    }    /**     * Get the next node in the iteration. In this case, we return     * only the immediate parent, _if_ it matches the requested nodeType.     *     * @return The next node handle in the iteration, or END.     */    public int next()    {      int result = _currentNode;      if ((_nodeType != -1) && (getExpandedTypeID(_currentNode) != _nodeType))        result = END;      else        result = _currentNode;      _currentNode = END;      return returnNode(result);    }  }  // end of ParentIterator  /**   * Iterator that returns children of a given type for a given node.   * The functionality chould be achieved by putting a filter on top   * of a basic child iterator, but a specialised iterator is used   * for efficiency (both speed and size of translet).   */  private final class TypedChildrenIterator extends InternalAxisIteratorBase  {    /** The extended type ID that was requested. */    private final int _nodeType;    /**     * Constructor TypedChildrenIterator     *     *     * @param nodeType The extended type ID being requested.     */    public TypedChildrenIterator(int nodeType)    {      _nodeType = nodeType;    }    /**     * Set start to END should 'close' the iterator,     * i.e. subsequent call to next() should return END.     *     * @param node Sets the root of the iteration.     *     * @return A DTMAxisIterator set to the start of the iteration.     */    public DTMAxisIterator setStartNode(int node)    {      if (_isRestartable)      {        _startNode = node;        _currentNode = NOTPROCESSED;        return resetPosition();      }      return this;    }    /**     * Get the next node in the iteration.     *     * @return The next node handle in the iteration, or END.     */    public int next()    {      for (int node = (NOTPROCESSED == _currentNode)                      ? getFirstChild(_startNode)                      : getNextSibling(_currentNode); node                        != END; node = getNextSibling(node))      {        if (getExpandedTypeID(node) == _nodeType)        {          _currentNode = node;          return returnNode(node);        }      }      return END;    }  }  // end of TypedChildrenIterator  /**   * Iterator that returns children within a given namespace for a   * given node. The functionality chould be achieved by putting a   * filter on top of a basic child iterator, but a specialised   * iterator is used for efficiency (both speed and size of translet).

⌨️ 快捷键说明

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