aboutsummaryrefslogtreecommitdiff
path: root/src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java')
-rw-r--r--src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java900
1 files changed, 0 insertions, 900 deletions
diff --git a/src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java b/src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java
deleted file mode 100644
index 5eb17d7..0000000
--- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/KeyIndex.java
+++ /dev/null
@@ -1,900 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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: KeyIndex.java,v 1.6 2006/06/19 19:49:02 spericas Exp $
- */
-
-package com.sun.org.apache.xalan.internal.xsltc.dom;
-
-import com.sun.org.apache.xalan.internal.xsltc.DOM;
-import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
-import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
-import com.sun.org.apache.xalan.internal.xsltc.util.IntegerArray;
-import com.sun.org.apache.xml.internal.dtm.Axis;
-import com.sun.org.apache.xml.internal.dtm.DTM;
-import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
-import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Stores mappings of key values or IDs to DTM nodes.
- * <em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em>
- * @author Morten Jorgensen
- * @author Santiago Pericas-Geertsen
- */
-public class KeyIndex extends DTMAxisIteratorBase {
-
- /**
- * A mapping between values and nodesets for the current document. Used
- * only while building keys.
- */
- private Map<String, IntegerArray> _index;
-
- /**
- * The document node currently being processed. Used only while building
- * keys.
- */
- private int _currentDocumentNode = DTM.NULL;
-
- /**
- * A mapping from a document node to the mapping between values and nodesets
- */
- private Map<Integer, Map> _rootToIndexMap = new HashMap<>();
-
- /**
- * The node set associated to the current value passed
- * to lookupKey();
- */
- private IntegerArray _nodes = null;
-
- /**
- * The XSLTC DOM object if this KeyIndex is being used to implement the
- * id() function.
- */
- private DOM _dom;
-
- private DOMEnhancedForDTM _enhancedDOM;
-
- /**
- * Store position after call to setMark()
- */
- private int _markedPosition = 0;
-
- public KeyIndex(int dummy) {
- }
-
- public void setRestartable(boolean flag) {
- }
-
- /**
- * Adds a node to the node list for a given value. Nodes will
- * always be added in document order.
- */
- public void add(String value, int node, int rootNode) {
- if (_currentDocumentNode != rootNode) {
- _currentDocumentNode = rootNode;
- _index = new HashMap<>();
- _rootToIndexMap.put(rootNode, _index);
- }
-
- IntegerArray nodes = _index.get(value);
-
- if (nodes == null) {
- nodes = new IntegerArray();
- _index.put(value, nodes);
- nodes.add(node);
-
- // Because nodes are added in document order,
- // duplicates can be eliminated easily at this stage.
- } else if (node != nodes.at(nodes.cardinality() - 1)) {
- nodes.add(node);
- }
- }
-
- /**
- * Merge the current value's nodeset set by lookupKey() with _nodes.
- * @deprecated
- */
- public void merge(KeyIndex other) {
- if (other == null) return;
-
- if (other._nodes != null) {
- if (_nodes == null) {
- _nodes = (IntegerArray)other._nodes.clone();
- }
- else {
- _nodes.merge(other._nodes);
- }
- }
- }
-
- /**
- * This method must be called by the code generated by the id() function
- * prior to returning the node iterator. The lookup code for key() and
- * id() differ in the way the lookup value can be whitespace separated
- * list of tokens for the id() function, but a single string for the
- * key() function.
- * @deprecated
- */
- public void lookupId(Object value) {
- // Clear _nodes array
- _nodes = null;
-
- final StringTokenizer values = new StringTokenizer((String) value,
- " \n\t");
- while (values.hasMoreElements()) {
- final String token = (String) values.nextElement();
- IntegerArray nodes = _index.get(token);
-
- if (nodes == null && _enhancedDOM != null
- && _enhancedDOM.hasDOMSource()) {
- nodes = getDOMNodeById(token);
- }
-
- if (nodes == null) continue;
-
- if (_nodes == null) {
- nodes = (IntegerArray)nodes.clone();
- _nodes = nodes;
- }
- else {
- _nodes.merge(nodes);
- }
- }
- }
-
- /**
- * Return an IntegerArray for the DOM Node which has the given id.
- *
- * @param id The id
- * @return A IntegerArray representing the Node whose id is the given value.
- */
- public IntegerArray getDOMNodeById(String id) {
- IntegerArray nodes = null;
-
- if (_enhancedDOM != null) {
- int ident = _enhancedDOM.getElementById(id);
-
- if (ident != DTM.NULL) {
- Integer root = new Integer(_enhancedDOM.getDocument());
- Map<String, IntegerArray> index = _rootToIndexMap.get(root);
-
- if (index == null) {
- index = new HashMap<>();
- _rootToIndexMap.put(root, index);
- } else {
- nodes = index.get(id);
- }
-
- if (nodes == null) {
- nodes = new IntegerArray();
- index.put(id, nodes);
- }
-
- nodes.add(_enhancedDOM.getNodeHandle(ident));
- }
- }
-
- return nodes;
- }
-
- /**
- * <p>This method must be called by the code generated by the key() function
- * prior to returning the node iterator.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public void lookupKey(Object value) {
- IntegerArray nodes = _index.get(value);
- _nodes = (nodes != null) ? (IntegerArray) nodes.clone() : null;
- _position = 0;
- }
-
- /**
- * <p>Callers should not call next() after it returns END.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public int next() {
- if (_nodes == null) return DTMAxisIterator.END;
-
- return (_position < _nodes.cardinality()) ?
- _dom.getNodeHandle(_nodes.at(_position++)) : DTMAxisIterator.END;
- }
-
- /**
- * Given a context node and the argument to the XPath <code>id</code>
- * function, checks whether the context node is in the set of nodes that
- * results from that reference to the <code>id</code> function. This is
- * used in the implementation of <code>id</code> patterns.
- *
- * @param node The context node
- * @param value The argument to the <code>id</code> function
- * @return <code>1</code> if the context node is in the set of nodes
- * returned by the reference to the <code>id</code> function;
- * <code>0</code>, otherwise
- */
- public int containsID(int node, Object value) {
- final String string = (String)value;
- int rootHandle = _dom.getAxisIterator(Axis.ROOT)
- .setStartNode(node).next();
-
- // Get the mapping table for the document containing the context node
- Map<String, IntegerArray> index =
- _rootToIndexMap.get(rootHandle);
-
- // Split argument to id function into XML whitespace separated tokens
- final StringTokenizer values = new StringTokenizer(string, " \n\t");
-
- while (values.hasMoreElements()) {
- final String token = (String) values.nextElement();
- IntegerArray nodes = null;
-
- if (index != null) {
- nodes = index.get(token);
- }
-
- // If input was from W3C DOM, use DOM's getElementById to do
- // the look-up.
- if (nodes == null && _enhancedDOM != null
- && _enhancedDOM.hasDOMSource()) {
- nodes = getDOMNodeById(token);
- }
-
- // Did we find the context node in the set of nodes?
- if (nodes != null && nodes.indexOf(node) >= 0) {
- return 1;
- }
- }
-
- // Didn't find the context node in the set of nodes returned by id
- return 0;
- }
-
- /**
- * <p>Given a context node and the second argument to the XSLT
- * <code>key</code> function, checks whether the context node is in the
- * set of nodes that results from that reference to the <code>key</code>
- * function. This is used in the implementation of key patterns.</p>
- * <p>This particular {@link KeyIndex} object is the result evaluating the
- * first argument to the <code>key</code> function, so it's not taken into
- * any further account.</p>
- *
- * @param node The context node
- * @param value The second argument to the <code>key</code> function
- * @return <code>1</code> if and only if the context node is in the set of
- * nodes returned by the reference to the <code>key</code> function;
- * <code>0</code>, otherwise
- */
- public int containsKey(int node, Object value) {
- int rootHandle = _dom.getAxisIterator(Axis.ROOT)
- .setStartNode(node).next();
-
- // Get the mapping table for the document containing the context node
- Map<String,IntegerArray> index =
- _rootToIndexMap.get(new Integer(rootHandle));
-
- // Check whether the context node is present in the set of nodes
- // returned by the key function
- if (index != null) {
- final IntegerArray nodes = index.get(value);
- return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
- }
-
- // The particular key name identifies no nodes in this document
- return 0;
- }
-
- /**
- * <p>Resets the iterator to the last start node.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public DTMAxisIterator reset() {
- _position = 0;
- return this;
- }
-
- /**
- * <p>Returns the number of elements in this iterator.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public int getLast() {
- return (_nodes == null) ? 0 : _nodes.cardinality();
- }
-
- /**
- * <p>Returns the position of the current node in the set.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public int getPosition() {
- return _position;
- }
-
- /**
- * <p>Remembers the current node for the next call to gotoMark().</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public void setMark() {
- _markedPosition = _position;
- }
-
- /**
- * <p>Restores the current node remembered by setMark().</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public void gotoMark() {
- _position = _markedPosition;
- }
-
- /**
- * <p>Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public DTMAxisIterator setStartNode(int start) {
- if (start == DTMAxisIterator.END) {
- _nodes = null;
- }
- else if (_nodes != null) {
- _position = 0;
- }
- return (DTMAxisIterator) this;
- }
-
- /**
- * <p>Get start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public int getStartNode() {
- return 0;
- }
-
- /**
- * <p>True if this iterator has a reversed axis.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public boolean isReverse() {
- return(false);
- }
-
- /**
- * <p>Returns a deep copy of this iterator.</p>
- * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is
- * <b>deprecated.</b></em></p>
- * @deprecated
- */
- public DTMAxisIterator cloneIterator() {
- KeyIndex other = new KeyIndex(0);
- other._index = _index;
- other._rootToIndexMap = _rootToIndexMap;
- other._nodes = _nodes;
- other._position = _position;
- return (DTMAxisIterator) other;
- }
-
- public void setDom(DOM dom, int node) {
- _dom = dom;
-
- // If a MultiDOM, ensure _enhancedDOM is correctly set
- // so that getElementById() works in lookupNodes below
- if (dom instanceof MultiDOM) {
- dom = ((MultiDOM) dom).getDTM(node);
- }
-
- if (dom instanceof DOMEnhancedForDTM) {
- _enhancedDOM = (DOMEnhancedForDTM)dom;
- }
- else if (dom instanceof DOMAdapter) {
- DOM idom = ((DOMAdapter)dom).getDOMImpl();
- if (idom instanceof DOMEnhancedForDTM) {
- _enhancedDOM = (DOMEnhancedForDTM)idom;
- }
- }
- }
-
- /**
- * Create a {@link KeyIndexIterator} that iterates over the nodes that
- * result from a reference to the XSLT <code>key</code> function or
- * XPath <code>id</code> function.
- *
- * @param keyValue A string or iterator representing the key values or id
- * references
- * @param isKeyCall A <code>boolean</code> indicating whether the iterator
- * is being created for a reference <code>key</code> or
- * <code>id</code>
- */
- public KeyIndexIterator getKeyIndexIterator(Object keyValue,
- boolean isKeyCall) {
- if (keyValue instanceof DTMAxisIterator) {
- return getKeyIndexIterator((DTMAxisIterator) keyValue, isKeyCall);
- } else {
- return getKeyIndexIterator(BasisLibrary.stringF(keyValue, _dom),
- isKeyCall);
- }
- }
-
- /**
- * Create a {@link KeyIndexIterator} that iterates over the nodes that
- * result from a reference to the XSLT <code>key</code> function or
- * XPath <code>id</code> function.
- *
- * @param keyValue A string representing the key values or id
- * references
- * @param isKeyCall A <code>boolean</code> indicating whether the iterator
- * is being created for a reference <code>key</code> or
- * <code>id</code>
- */
- public KeyIndexIterator getKeyIndexIterator(String keyValue,
- boolean isKeyCall) {
- return new KeyIndexIterator(keyValue, isKeyCall);
- }
-
- /**
- * Create a {@link KeyIndexIterator} that iterates over the nodes that
- * result from a reference to the XSLT <code>key</code> function or
- * XPath <code>id</code> function.
- *
- * @param keyValue An iterator representing the key values or id
- * references
- * @param isKeyCall A <code>boolean</code> indicating whether the iterator
- * is being created for a reference <code>key</code> or
- * <code>id</code>
- */
- public KeyIndexIterator getKeyIndexIterator(DTMAxisIterator keyValue,
- boolean isKeyCall) {
- return new KeyIndexIterator(keyValue, isKeyCall);
- }
-
- /**
- * Used to represent an empty node set.
- */
- final private static IntegerArray EMPTY_NODES = new IntegerArray(0);
-
-
- /**
- * An iterator representing the result of a reference to either the
- * XSLT <code>key</code> function or the XPath <code>id</code> function.
- */
- public class KeyIndexIterator extends MultiValuedNodeHeapIterator {
-
- /**
- * <p>A reference to the <code>key</code> function that only has one
- * key value or to the <code>id</code> function that has only one string
- * argument can be optimized to ignore the multi-valued heap. This
- * field will be <code>null</code> otherwise.
- */
- private IntegerArray _nodes;
-
- /**
- * <p>This field contains the iterator representing a node set key value
- * argument to the <code>key</code> function or a node set argument
- * to the <code>id</code> function.</p>
- *
- * <p>Exactly one of this field and {@link #_keyValue} must be
- * <code>null</code>.</p>
- */
- private DTMAxisIterator _keyValueIterator;
-
- /**
- * <p>This field contains the iterator representing a non-node-set key
- * value argument to the <code>key</code> function or a non-node-set
- * argument to the <code>id</code> function.</p>
- *
- * <p>Exactly one of this field and {@link #_keyValueIterator} must be
- * <code>null</code>.</p>
- */
- private String _keyValue;
-
- /**
- * Indicates whether this object represents the result of a reference
- * to the <code>key</code> function (<code>true</code>) or the
- * <code>id</code> function (<code>false</code>).
- */
- private boolean _isKeyIterator;
-
- /**
- * Represents the DTM nodes retrieved for one key value or one string
- * argument to <code>id</code> for use as one heap node in a
- * {@link MultiValuedNodeHeapIterator}.
- */
- protected class KeyIndexHeapNode
- extends MultiValuedNodeHeapIterator.HeapNode
- {
- /**
- * {@link IntegerArray} of DTM nodes retrieved for one key value.
- * Must contain no duplicates and be stored in document order.
- */
- private IntegerArray _nodes;
-
- /**
- * Position in {@link #_nodes} array of next node to return from
- * this heap node.
- */
- private int _position = 0;
-
- /**
- * Marked position. Used by {@link #setMark()} and
- * {@link #gotoMark()}
- */
- private int _markPosition = -1;
-
- /**
- * Create a heap node representing DTM nodes retrieved for one
- * key value in a reference to the <code>key</code> function
- * or string argument to the <code>id</code> function.
- */
- KeyIndexHeapNode(IntegerArray nodes) {
- _nodes = nodes;
- }
-
- /**
- * Advance to the next node represented by this {@link HeapNode}
- *
- * @return the next DTM node.
- */
- public int step() {
- if (_position < _nodes.cardinality()) {
- _node = _nodes.at(_position);
- _position++;
- } else {
- _node = DTMAxisIterator.END;
- }
-
- return _node;
- }
-
- /**
- * Creates a deep copy of this {@link HeapNode}. The clone is not
- * reset from the current position of the original.
- *
- * @return the cloned heap node
- */
- public HeapNode cloneHeapNode() {
- KeyIndexHeapNode clone =
- (KeyIndexHeapNode) super.cloneHeapNode();
-
- clone._nodes = _nodes;
- clone._position = _position;
- clone._markPosition = _markPosition;
-
- return clone;
- }
-
- /**
- * Remembers the current node for the next call to
- * {@link #gotoMark()}.
- */
- public void setMark() {
- _markPosition = _position;
- }
-
- /**
- * Restores the current node remembered by {@link #setMark()}.
- */
- public void gotoMark() {
- _position = _markPosition;
- }
-
- /**
- * Performs a comparison of the two heap nodes
- *
- * @param heapNode the heap node against which to compare
- * @return <code>true</code> if and only if the current node for
- * this heap node is before the current node of the
- * argument heap node in document order.
- */
- public boolean isLessThan(HeapNode heapNode) {
- return _node < heapNode._node;
- }
-
- /**
- * <p>Sets context with respect to which this heap node is
- * evaluated.</p>
- * <p>This has no real effect on this kind of heap node. Instead,
- * the {@link KeyIndexIterator#setStartNode(int)} method should
- * create new instances of this class to represent the effect of
- * changing the context.</p>
- */
- public HeapNode setStartNode(int node) {
- return this;
- }
-
- /**
- * Reset the heap node back to its beginning.
- */
- public HeapNode reset() {
- _position = 0;
- return this;
- }
- }
-
- /**
- * Constructor used when the argument to <code>key</code> or
- * <code>id</code> is not a node set.
- *
- * @param keyValue the argument to <code>key</code> or <code>id</code>
- * cast to a <code>String</code>
- * @param isKeyIterator indicates whether the constructed iterator
- * represents a reference to <code>key</code> or
- * <code>id</code>.
- */
- KeyIndexIterator(String keyValue, boolean isKeyIterator) {
- _isKeyIterator = isKeyIterator;
- _keyValue = keyValue;
- }
-
- /**
- * Constructor used when the argument to <code>key</code> or
- * <code>id</code> is a node set.
- *
- * @param keyValues the argument to <code>key</code> or <code>id</code>
- * @param isKeyIterator indicates whether the constructed iterator
- * represents a reference to <code>key</code> or
- * <code>id</code>.
- */
- KeyIndexIterator(DTMAxisIterator keyValues, boolean isKeyIterator) {
- _keyValueIterator = keyValues;
- _isKeyIterator = isKeyIterator;
- }
-
- /**
- * Retrieve nodes for a particular key value or a particular id
- * argument value.
- *
- * @param root The root node of the document containing the context node
- * @param keyValue The key value of id string argument value
- * @return an {@link IntegerArray} of the resulting nodes
- */
- protected IntegerArray lookupNodes(int root, String keyValue) {
- IntegerArray result = null;
-
- // Get mapping from key values/IDs to DTM nodes for this document
- Map<String, IntegerArray> index = _rootToIndexMap.get(root);
-
- if (!_isKeyIterator) {
- // For id function, tokenize argument as whitespace separated
- // list of values and look up nodes identified by each ID.
- final StringTokenizer values =
- new StringTokenizer(keyValue, " \n\t");
-
- while (values.hasMoreElements()) {
- final String token = (String) values.nextElement();
- IntegerArray nodes = null;
-
- // Does the ID map to any node in the document?
- if (index != null) {
- nodes = index.get(token);
- }
-
- // If input was from W3C DOM, use DOM's getElementById to do
- // the look-up.
- if (nodes == null && _enhancedDOM != null
- && _enhancedDOM.hasDOMSource()) {
- nodes = getDOMNodeById(token);
- }
-
- // If we found any nodes, merge them into the cumulative
- // result
- if (nodes != null) {
- if (result == null) {
- result = (IntegerArray)nodes.clone();
- } else {
- result.merge(nodes);
- }
- }
- }
- } else if (index != null) {
- // For key function, map key value to nodes
- result = index.get(keyValue);
- }
-
- return result;
- }
-
- /**
- * Set context node for the iterator. This will cause the iterator
- * to reset itself, reevaluate arguments to the function, look up
- * nodes in the input and reinitialize its internal heap.
- *
- * @param node the context node
- * @return A {@link DTMAxisIterator} set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node) {
- _startNode = node;
-
- // If the arugment to the function is a node set, set the
- // context node on it.
- if (_keyValueIterator != null) {
- _keyValueIterator = _keyValueIterator.setStartNode(node);
- }
-
- init();
-
- return super.setStartNode(node);
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next() {
- int nodeHandle;
-
- // If at most one key value or at most one string argument to id
- // resulted in nodes being returned, use the IntegerArray
- // stored at _nodes directly. This relies on the fact that the
- // IntegerArray never includes duplicate nodes and is always stored
- // in document order.
- if (_nodes != null) {
- if (_position < _nodes.cardinality()) {
- nodeHandle = returnNode(_nodes.at(_position));
- } else {
- nodeHandle = DTMAxisIterator.END;
- }
- } else {
- nodeHandle = super.next();
- }
-
- return nodeHandle;
- }
-
- /**
- * Resets the iterator to the last start node.
- *
- * @return A DTMAxisIterator, which may or may not be the same as this
- * iterator.
- */
- public DTMAxisIterator reset() {
- if (_nodes == null) {
- init();
- } else {
- super.reset();
- }
-
- return resetPosition();
- }
-
- /**
- * Evaluate the reference to the <code>key</code> or <code>id</code>
- * function with the context specified by {@link #setStartNode(int)}
- * and set up this iterator to iterate over the DTM nodes that are
- * to be returned.
- */
- protected void init() {
- super.init();
- _position = 0;
-
- // All nodes retrieved are in the same document
- int rootHandle = _dom.getAxisIterator(Axis.ROOT)
- .setStartNode(_startNode).next();
-
- // Is the argument not a node set?
- if (_keyValueIterator == null) {
- // Look up nodes returned for the single string argument
- _nodes = lookupNodes(rootHandle, _keyValue);
-
- if (_nodes == null) {
- _nodes = EMPTY_NODES;
- }
- } else {
- DTMAxisIterator keyValues = _keyValueIterator.reset();
- int retrievedKeyValueIdx = 0;
- boolean foundNodes = false;
-
- _nodes = null;
-
- // For each node in the node set argument, get the string value
- // and look up the nodes returned by key or id for that string
- // value. If at most one string value has nodes associated,
- // the nodes will be stored in _nodes; otherwise, the nodes
- // will be placed in a heap.
- for (int keyValueNode = keyValues.next();
- keyValueNode != DTMAxisIterator.END;
- keyValueNode = keyValues.next()) {
-
- String keyValue = BasisLibrary.stringF(keyValueNode, _dom);
-
- IntegerArray nodes = lookupNodes(rootHandle, keyValue);
-
- if (nodes != null) {
- if (!foundNodes) {
- _nodes = nodes;
- foundNodes = true;
- } else {
- if (_nodes != null) {
- addHeapNode(new KeyIndexHeapNode(_nodes));
- _nodes = null;
- }
- addHeapNode(new KeyIndexHeapNode(nodes));
- }
- }
- }
-
- if (!foundNodes) {
- _nodes = EMPTY_NODES;
- }
- }
- }
-
- /**
- * Returns the number of nodes in this iterator.
- *
- * @return the number of nodes
- */
- public int getLast() {
- // If nodes are stored in _nodes, take advantage of the fact that
- // there are no duplicates. Otherwise, fall back to the base heap
- // implementaiton and hope it does a good job with this.
- return (_nodes != null) ? _nodes.cardinality() : super.getLast();
- }
-
- /**
- * Return the node at the given position.
- *
- * @param position The position
- * @return The node at the given position.
- */
- public int getNodeByPosition(int position) {
- int node = DTMAxisIterator.END;
-
- // If nodes are stored in _nodes, take advantage of the fact that
- // there are no duplicates and they are stored in document order.
- // Otherwise, fall back to the base heap implementation to do a
- // good job with this.
- if (_nodes != null) {
- if (position > 0) {
- if (position <= _nodes.cardinality()) {
- _position = position;
- node = _nodes.at(position-1);
- } else {
- _position = _nodes.cardinality();
- }
- }
- } else {
- node = super.getNodeByPosition(position);
- }
-
- return node;
- }
- }
-}