19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: NodeSequence.java 469367 2006-10-31 04:41:08Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath.axes;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMFilter;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMIterator;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMManager;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.NodeVector;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.NodeSetDTM;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathContext;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class is the dynamic wrapper for a Xalan DTMIterator instance, and
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * provides random access capabilities.
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class NodeSequence extends XObject
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  implements DTMIterator, Cloneable, PathComponent
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 3866261934726581044L;
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The index of the last node in the iteration. */
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int m_last = -1;
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The index of the next node to be fetched.  Useful if this
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is a cached iterator, and is being used as random access
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * NodeList.
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int m_next = 0;
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * A cache of a list of nodes obtained from the iterator so far.
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This list is appended to until the iterator is exhausted and
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the cache is complete.
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Multiple NodeSequence objects may share the same cache.
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private IteratorCache m_cache;
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If this iterator needs to cache nodes that are fetched, they
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * are stored in the Vector in the generic object.
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected NodeVector getVector() {
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NodeVector nv = (m_cache != null) ?  m_cache.getVector() : null;
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return nv;
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the cache (if any) of nodes obtained from
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the iterator so far. Note that the cache keeps
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * growing until the iterator is walked to exhaustion,
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * at which point the cache is "complete".
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private IteratorCache getCache() {
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_cache;
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the vector where nodes will be cached.
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void SetVector(NodeVector v)
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	setObject(v);
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If the iterator needs to cache nodes as they are fetched,
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * then this method returns true.
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean hasCache()
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    final NodeVector nv = getVector();
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	return (nv != null);
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If this NodeSequence has a cache, and that cache is
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * fully populated then this method returns true, otherwise
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if there is no cache or it is not complete it returns false.
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private boolean cacheComplete() {
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final boolean complete;
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (m_cache != null) {
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          complete = m_cache.isComplete();
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      } else {
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          complete = false;
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return complete;
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If this NodeSequence has a cache, mark that it is complete.
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This method should be called after the iterator is exhausted.
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void markCacheComplete() {
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NodeVector nv = getVector();
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nv != null) {
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_cache.setCacheComplete(true);
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The functional iterator that fetches nodes.
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected DTMIterator m_iter;
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the functional iterator that fetches nodes.
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param iter The iterator that is to be contained.
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void setIter(DTMIterator iter)
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	m_iter = iter;
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the functional iterator that fetches nodes.
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The contained iterator.
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final DTMIterator getContainedIter()
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	return m_iter;
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The DTMManager to use if we're using a NodeVector only.
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * We may well want to do away with this, and store it in the NodeVector.
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected DTMManager m_dtmMgr;
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // ==== Constructors ====
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new NodeSequence from a (already cloned) iterator.
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param iter Cloned (not static) DTMIterator.
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param context The initial context node.
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The execution context.
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param shouldCacheNodes True if this sequence can random access.
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes)
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	setIter(iter);
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	setRoot(context, xctxt);
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	setShouldCacheNodes(shouldCacheNodes);
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new NodeSequence from a (already cloned) iterator.
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeVector
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public NodeSequence(Object nodeVector)
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	super(nodeVector);
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (nodeVector instanceof NodeVector) {
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SetVector((NodeVector) nodeVector);
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != nodeVector)
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		assertion(nodeVector instanceof NodeVector,
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			"Must have a NodeVector as the object for NodeSequence!");
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if(nodeVector instanceof DTMIterator)
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		{
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			setIter((DTMIterator)nodeVector);
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			m_last = ((DTMIterator)nodeVector).getLength();
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		}
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct an empty XNodeSet object.  This is used to create a mutable
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * nodeset to which random nodes may be added.
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private NodeSequence(DTMManager dtmMgr)
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super(new NodeVector());
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_last = 0;
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_dtmMgr = dtmMgr;
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new NodeSequence in an invalid (null) state.
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public NodeSequence()
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getDTM(int)
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM getDTM(int nodeHandle)
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	DTMManager mgr = getDTMManager();
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != mgr)
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return getDTMManager().getDTM(nodeHandle);
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	assertion(false, "Can not get a DTM Unless a DTMManager has been set!");
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return null;
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getDTMManager()
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMManager getDTMManager()
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmMgr;
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getRoot()
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getRoot()
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return m_iter.getRoot();
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// NodeSetDTM will call this, and so it's not a good thing to throw
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// an assertion here.
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// assertion(false, "Can not get the root from a non-iterated NodeSequence!");
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return DTM.NULL;
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#setRoot(int, Object)
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setRoot(int nodeHandle, Object environment)
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		XPathContext xctxt = (XPathContext)environment;
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_dtmMgr = xctxt.getDTMManager();
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_iter.setRoot(nodeHandle, environment);
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if(!m_iter.isDocOrdered())
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		{
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			if(!hasCache())
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  				setShouldCacheNodes(true);
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			runTo(-1);
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			m_next=0;
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		}
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		assertion(false, "Can not setRoot on a non-iterated NodeSequence!");
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#reset()
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void reset()
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	m_next = 0;
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// not resetting the iterator on purpose!!!
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getWhatToShow()
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getWhatToShow()
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE)
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	: m_iter.getWhatToShow();
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getExpandEntityReferences()
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean getExpandEntityReferences()
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return m_iter.getExpandEntityReferences();
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return true;
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#nextNode()
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int nextNode()
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // If the cache is on, and the node has already been found, then
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // just return from the list.
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NodeVector vec = getVector();
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != vec)
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // There is a cache
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	if(m_next < vec.size())
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	{
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // The node is in the cache, so just return it.
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			int next = vec.elementAt(m_next);
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    	m_next++;
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    	return next;
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	}
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	else if(cacheComplete() || (-1 != m_last) || (null == m_iter))
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	{
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		m_next++;
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		return DTM.NULL;
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	}
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (null == m_iter)
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return DTM.NULL;
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 	int next = m_iter.nextNode();
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(DTM.NULL != next)
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	if(hasCache())
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	{
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		if(m_iter.isDocOrdered())
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	    {
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    			getVector().addElement(next);
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    			m_next++;
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		}
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		else
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		{
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    			int insertIndex = addNodeInDocOrder(next);
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    			if(insertIndex >= 0)
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    				m_next++;
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		}
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	}
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	else
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    		m_next++;
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // We have exhausted the iterator, and if there is a cache
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // it must have all nodes in it by now, so let the cache
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // know that it is complete.
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        markCacheComplete();
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	m_last = m_next;
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	m_next++;
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return next;
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#previousNode()
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int previousNode()
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(hasCache())
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if(m_next <= 0)
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			return DTM.NULL;
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		else
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		{
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			m_next--;
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			return item(m_next);
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		}
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    int n = m_iter.previousNode();
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    m_next = m_iter.getCurrentPos();
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    return m_next;
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#detach()
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void detach()
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_iter.detach();
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	super.detach();
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Calling this with a value of false will cause the nodeset
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to be cached.
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#allowDetachToRelease(boolean)
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void allowDetachToRelease(boolean allowRelease)
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if((false == allowRelease) && !hasCache())
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		setShouldCacheNodes(true);
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_iter.allowDetachToRelease(allowRelease);
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	super.allowDetachToRelease(allowRelease);
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getCurrentNode()
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getCurrentNode()
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(hasCache())
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		int currentIndex = m_next-1;
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		NodeVector vec = getVector();
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if((currentIndex >= 0) && (currentIndex < vec.size()))
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			return vec.elementAt(currentIndex);
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		else
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  			return DTM.NULL;
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return m_iter.getCurrentNode();
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return DTM.NULL;
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#isFresh()
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean isFresh()
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 == m_next);
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#setShouldCacheNodes(boolean)
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setShouldCacheNodes(boolean b)
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (b)
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(!hasCache())
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SetVector(new NodeVector());
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//	  else
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//	    getVector().RemoveAllNoClear();  // Is this good?
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SetVector(null);
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#isMutable()
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean isMutable()
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return hasCache(); // though may be surprising if it also has an iterator!
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getCurrentPos()
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getCurrentPos()
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_next;
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#runTo(int)
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void runTo(int index)
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int n;
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (-1 == index)
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int pos = m_next;
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != (n = nextNode()));
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_next = pos;
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(m_next == index)
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(hasCache() && m_next < getVector().size())
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_next = index;
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if((null == getVector()) && (index < m_next))
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((m_next >= index) && DTM.NULL != (n = previousNode()));
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((m_next < index) && DTM.NULL != (n = nextNode()));
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#setCurrentPos(int)
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setCurrentPos(int i)
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	runTo(i);
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#item(int)
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int item(int index)
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	setCurrentPos(index);
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	int n = nextNode();
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	m_next = index;
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	return n;
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#setItem(int, int)
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setItem(int node, int index)
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	NodeVector vec = getVector();
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != vec)
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int oldNode = vec.elementAt(index);
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (oldNode != node && m_cache.useCount() > 1) {
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* If we are going to set the node at the given index
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * to a different value, and the cache is shared
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * (has a use count greater than 1)
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * then make a copy of the cache and use it
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * so we don't overwrite the value for other
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * users of the cache.
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            IteratorCache newCache = new IteratorCache();
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            final NodeVector nv;
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try {
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                nv = (NodeVector) vec.clone();
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            } catch (CloneNotSupportedException e) {
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                // This should never happen
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                e.printStackTrace();
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                RuntimeException rte = new RuntimeException(e.getMessage());
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                throw rte;
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            newCache.setVector(nv);
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            newCache.setCacheComplete(true);
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_cache = newCache;
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            vec = nv;
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Keep our superclass informed of the current NodeVector
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            super.setObject(nv);
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            /* When we get to here the new cache has
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * a use count of 1 and when setting a
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * bunch of values on the same NodeSequence,
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * such as when sorting, we will keep setting
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             * values in that same copy which has a use count of 1.
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             */
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		vec.setElementAt(node, index);
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_last = vec.size();
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_iter.setItem(node, index);
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getLength()
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getLength()
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    IteratorCache cache = getCache();
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(cache != null)
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Nodes from the iterator are cached
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (cache.isComplete()) {
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // All of the nodes from the iterator are cached
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // so just return the number of nodes in the cache
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            NodeVector nv = cache.getVector();
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return nv.size();
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // If this NodeSequence wraps a mutable nodeset, then
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // m_last will not reflect the size of the nodeset if
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // it has been mutated...
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (m_iter instanceof NodeSetDTM)
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return m_iter.getLength();
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(-1 == m_last)
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	{
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		int pos = m_next;
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		runTo(-1);
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_next = pos;
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	}
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	    return m_last;
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return (-1 == m_last) ? (m_last = m_iter.getLength()) : m_last;
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note: Not a deep clone.
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#cloneWithReset()
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMIterator cloneWithReset() throws CloneNotSupportedException
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	NodeSequence seq = (NodeSequence)super.clone();
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    seq.m_next = 0;
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_cache != null) {
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // In making this clone of an iterator we are making
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // another NodeSequence object it has a reference
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // to the same IteratorCache object as the original
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // so we need to remember that more than one
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // NodeSequence object shares the cache.
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_cache.increaseUseCount();
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return seq;
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a clone of this iterator, but don't reset the iteration in the
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * process, so that it may be used from the current position.
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note: Not a deep clone.
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A clone of this object.
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws CloneNotSupportedException
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Object clone() throws CloneNotSupportedException
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          NodeSequence clone = (NodeSequence) super.clone();
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (null != m_iter) clone.m_iter = (DTMIterator) m_iter.clone();
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (m_cache != null) {
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // In making this clone of an iterator we are making
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // another NodeSequence object it has a reference
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // to the same IteratorCache object as the original
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // so we need to remember that more than one
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // NodeSequence object shares the cache.
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              m_cache.increaseUseCount();
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return clone;
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#isDocOrdered()
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean isDocOrdered()
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return m_iter.isDocOrdered();
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return true; // can't be sure?
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DTMIterator#getAxis()
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getAxis()
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null != m_iter)
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return m_iter.getAxis();
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	assertion(false, "Can not getAxis from a non-iterated node sequence!");
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return 0;
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see PathComponent#getAnalysisBits()
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getAnalysisBits()
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if((null != m_iter) && (m_iter instanceof PathComponent))
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return ((PathComponent)m_iter).getAnalysisBits();
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	return 0;
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.apache.xpath.Expression#fixupVariables(Vector, int)
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void fixupVariables(Vector vars, int globalsSize)
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	super.fixupVariables(vars, globalsSize);
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Add the node into a vector of nodes where it should occur in
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * document order.
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node The node to be added.
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return insertIndex.
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws RuntimeException thrown if this NodeSetDTM is not of
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a mutable type.
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   protected int addNodeInDocOrder(int node)
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   {
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      assertion(hasCache(), "addNodeInDocOrder must be done on a mutable sequence!");
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int insertIndex = -1;
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NodeVector vec = getVector();
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // This needs to do a binary search, but a binary search
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // is somewhat tough because the sequence test involves
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // two nodes.
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int size = vec.size(), i;
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (i = size - 1; i >= 0; i--)
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int child = vec.elementAt(i);
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (child == node)
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          i = -2; // Duplicate, suppress insert
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DTM dtm = m_dtmMgr.getDTM(node);
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!dtm.isNodeAfter(node, child))
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (i != -2)
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertIndex = i + 1;
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        vec.insertElementAt(node, insertIndex);
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // checkDups();
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return insertIndex;
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    } // end addNodeInDocOrder(Vector v, Object obj)
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   /**
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * It used to be that many locations in the code simply
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * did an assignment to this.m_obj directly, rather than
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * calling the setObject(Object) method. The problem is
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * that our super-class would be updated on what the
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * cache associated with this NodeSequence, but
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * we wouldn't know ourselves.
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * <p>
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * All setting of m_obj is done through setObject() now,
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * and this method over-rides the super-class method.
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * So now we are in the loop have an opportunity
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * to update some caching information.
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    *
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    */
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   protected void setObject(Object obj) {
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       if (obj instanceof NodeVector) {
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           // Keep our superclass informed of the current NodeVector
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           // ... if we don't the smoketest fails (don't know why).
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           super.setObject(obj);
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           // A copy of the code of what SetVector() would do.
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           NodeVector v = (NodeVector)obj;
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           if (m_cache != null) {
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               m_cache.setVector(v);
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           } else if (v!=null) {
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               m_cache = new IteratorCache();
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               m_cache.setVector(v);
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           }
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       } else if (obj instanceof IteratorCache) {
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           IteratorCache cache = (IteratorCache) obj;
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           m_cache = cache;
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           m_cache.increaseUseCount();
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           // Keep our superclass informed of the current NodeVector
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           super.setObject(cache.getVector());
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       } else {
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           super.setObject(obj);
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       }
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   }
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   /**
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * Each NodeSequence object has an iterator which is "walked".
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * As an iterator is walked one obtains nodes from it.
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * As those nodes are obtained they may be cached, making
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * the next walking of a copy or clone of the iterator faster.
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * This field (m_cache) is a reference to such a cache,
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * which is populated as the iterator is walked.
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * <p>
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * Note that multiple NodeSequence objects may hold a
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * reference to the same cache, and also
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * (and this is important) the same iterator.
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * The iterator and its cache may be shared among
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * many NodeSequence objects.
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * <p>
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * If one of the NodeSequence objects walks ahead
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * of the others it fills in the cache.
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * As the others NodeSequence objects catch up they
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * get their values from
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * the cache rather than the iterator itself, so
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * the iterator is only ever walked once and everyone
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * benefits from the cache.
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * <p>
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * At some point the cache may be
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * complete due to walking to the end of one of
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * the copies of the iterator, and the cache is
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * then marked as "complete".
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * and the cache will have no more nodes added to it.
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * <p>
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    * Its use-count is the number of NodeSequence objects that use it.
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    */
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   private final static class IteratorCache {
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       /**
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * A list of nodes already obtained from the iterator.
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * As the iterator is walked the nodes obtained from
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * it are appended to this list.
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * Both an iterator and its corresponding cache can
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * be shared by multiple NodeSequence objects.
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * For example, consider three NodeSequence objects
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * ns1, ns2 and ns3 doing such sharing, and the
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * nodes to be obtaind from the iterator being
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * the sequence { 33, 11, 44, 22, 55 }.
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * If ns3.nextNode() is called 3 times the the
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * underlying iterator will have walked through
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * 33, 11, 55 and these three nodes will have been put
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * in the cache.
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * If ns2.nextNode() is called 2 times it will return
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * 33 and 11 from the cache, leaving the iterator alone.
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * If ns1.nextNode() is called 6 times it will return
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * 33 and 11 from the cache, then get 44, 22, 55 from
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * the iterator, and appending 44, 22, 55 to the cache.
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * On the sixth call it is found that the iterator is
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * exhausted and the cache is marked complete.
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * Should ns2 or ns3 have nextNode() called they will
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * know that the cache is complete, and they will
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * obtain all subsequent nodes from the cache.
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * <p>
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * Note that the underlying iterator, though shared
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        * is only ever walked once.
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        */
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private NodeVector m_vec2;
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * true if the associated iterator is exhausted and
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * all nodes obtained from it are in the cache.
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private boolean m_isComplete2;
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private int m_useCount2;
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        IteratorCache() {
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_vec2 = null;
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_isComplete2 = false;
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_useCount2 = 1;
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return;
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Returns count of how many NodeSequence objects share this
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * IteratorCache object.
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private int useCount() {
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return m_useCount2;
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * This method is called when yet another
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * NodeSequence object uses, or shares
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * this same cache.
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         *
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private void increaseUseCount() {
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (m_vec2 != null)
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_useCount2++;
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Sets the NodeVector that holds the
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * growing list of nodes as they are appended
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * to the cached list.
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private void setVector(NodeVector nv) {
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_vec2 = nv;
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_useCount2 = 1;
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Get the cached list of nodes obtained from
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * the iterator so far.
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private NodeVector getVector() {
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return m_vec2;
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Call this method with 'true' if the
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * iterator is exhausted and the cached list
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * is complete, or no longer growing.
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private void setCacheComplete(boolean b) {
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            m_isComplete2 = b;
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * Returns true if no cache is complete
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * and immutable.
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        private boolean isComplete() {
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return m_isComplete2;
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the cached list of nodes appended with
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * values obtained from the iterator as
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * a NodeSequence is walked when its
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * nextNode() method is called.
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    protected IteratorCache getIteratorCache() {
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_cache;
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
954