/** * 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 Hashtable index = (Hashtable) _rootToIndexMap.get(new Integer(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 = (IntegerArray) 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; }
/** * 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()); Hashtable index = (Hashtable) _rootToIndexMap.get(root); if (index == null) { index = new Hashtable(); _rootToIndexMap.put(root, index); } else { nodes = (IntegerArray) index.get(id); } if (nodes == null) { nodes = new IntegerArray(); index.put(id, nodes); } nodes.add(_enhancedDOM.getNodeHandle(ident)); } } return nodes; }
/** * Callers should not call next() after it returns END. * * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is <b>deprecated.</b></em> * * @deprecated */ public int next() { if (_nodes == null) return DTMAxisIterator.END; return (_position < _nodes.cardinality()) ? _dom.getNodeHandle(_nodes.at(_position++)) : DTMAxisIterator.END; }
/** * 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; }
public DTMAxisIterator setStartNode(int node) { if (_isRestartable) { _source.setStartNode(_startNode = node); _nodes.clear(); while ((node = _source.next()) != END) { _nodes.add(node); } _currentIndex = 0; resetPosition(); } return this; }
public int getNode(int index) { if (index < _numCachedNodes) { return _nodes.at(index); } else if (!_isEnded) { int node = _source.next(); if (node != END) { _nodes.add(node); _numCachedNodes++; } else { _isEnded = true; } return node; } else return END; }
private int computePositionOfLast() { final int last = _nodes.cardinality(); final int currNode = _currentNode; final AbstractTranslet translet = _translet; int lastPosition = _position; for (int index = _currentIndex; index < last; ) { final int position = _docOrder ? index + 1 : last - index; int nodeIndex = _nodes.at(index++); // note increment if (_filter.test(nodeIndex, position, last, currNode, translet, this)) { lastPosition++; } } return lastPosition; }
/** * 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>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. * * @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 Hashtable index = (Hashtable) _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 = (IntegerArray) index.get(value); return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0; } // The particular key name identifies no nodes in this document return 0; }
public int next() { final int last = _nodes.cardinality(); final int currentNode = _currentNode; final AbstractTranslet translet = _translet; for (int index = _currentIndex; index < last; ) { final int position = _docOrder ? index + 1 : last - index; final int node = _nodes.at(index++); // note increment if (_filter.test(node, position, last, currentNode, translet, this)) { _currentIndex = index; return returnNode(node); } } return END; }
/** * 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 Hashtable index = (Hashtable) _rootToIndexMap.get(new Integer(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 = (IntegerArray) 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 = (IntegerArray) index.get(keyValue); } return result; }
/** * Adds a node to the node list for a given value. Nodes will always be added in document order. */ public void add(Object value, int node, int rootNode) { if (_currentDocumentNode != rootNode) { _currentDocumentNode = rootNode; _index = new Hashtable(); _rootToIndexMap.put(new Integer(rootNode), _index); } IntegerArray nodes = (IntegerArray) _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); } }
/** * 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; }
/** * 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); } } }
public DTMAxisIterator cloneIterator() { try { final CurrentNodeListIterator clone = (CurrentNodeListIterator) super.clone(); clone._nodes = (IntegerArray) _nodes.clone(); clone._source = _source.cloneIterator(); clone._isRestartable = false; return clone.reset(); } catch (CloneNotSupportedException e) { BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, e.toString()); return null; } }
/** * 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; }
/** * 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 = (IntegerArray) _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); } } }
/** * 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(); }
/** * Returns the number of elements in this iterator. * * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is <b>deprecated.</b></em> * * @deprecated */ public int getLast() { return (_nodes == null) ? 0 : _nodes.cardinality(); }
/** * This method must be called by the code generated by the key() function prior to returning the * node iterator. * * <p><em>Use of an instance of this class as a {@link DTMAxisIterator} is <b>deprecated.</b></em> * * @deprecated */ public void lookupKey(Object value) { IntegerArray nodes = (IntegerArray) _index.get(value); _nodes = (nodes != null) ? (IntegerArray) nodes.clone() : null; _position = 0; }