|
Java example source code file (KeyIndex.java)
The KeyIndex.java Java example source code/* * reserved comment block * DO NOT REMOVE OR ALTER! */ /* * Copyright 2001-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: KeyIndex.java,v 1.6 2006/06/19 19:49:02 spericas Exp $ */ package com.sun.org.apache.xalan.internal.xsltc.dom; import java.util.StringTokenizer; 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.runtime.Hashtable; 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; /** * 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. * @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 Hashtable _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 Hashtable _rootToIndexMap = new Hashtable(); /** * 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(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); } } /** * 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 = (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); } } } /** * 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; } /** * <p>This method must be called by the code generated by the key() function * prior to returning the node iterator.</p> * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public void lookupKey(Object value) { IntegerArray nodes = (IntegerArray) _index.get(value); _nodes = (nodes != null) ? (IntegerArray) nodes.clone() : null; _position = 0; } /** * <p>Callers should not call next() after it returns END. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @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 * function, checks whether the context node is in the set of nodes that * results from that reference to the <code>id function. This is * used in the implementation of <code>id patterns. * * @param node The context node * @param value The argument to the <code>id function * @return <code>1 if the context node is in the set of nodes * returned by the reference to the <code>id function; * <code>0, 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; } /** * <p>Given a context node and the second argument to the XSLT * <code>key function, checks whether the context node is in the * set of nodes that results from that reference to the <code>key * 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 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 function * @return <code>1 if and only if the context node is in the set of * nodes returned by the reference to the <code>key function; * <code>0, 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; } /** * <p>Resets the iterator to the last start node. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public DTMAxisIterator reset() { _position = 0; return this; } /** * <p>Returns the number of elements in this iterator. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public int getLast() { return (_nodes == null) ? 0 : _nodes.cardinality(); } /** * <p>Returns the position of the current node in the set. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public int getPosition() { return _position; } /** * <p>Remembers the current node for the next call to gotoMark(). * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public void setMark() { _markedPosition = _position; } /** * <p>Restores the current node remembered by setMark(). * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @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>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @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>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public int getStartNode() { return 0; } /** * <p>True if this iterator has a reversed axis. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @deprecated */ public boolean isReverse() { return(false); } /** * <p>Returns a deep copy of this iterator. * <p>Use of an instance of this class as a {@link DTMAxisIterator} is * <b>deprecated. * @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 function or * XPath <code>id function. * * @param keyValue A string or iterator representing the key values or id * references * @param isKeyCall A <code>boolean indicating whether the iterator * is being created for a reference <code>key or * <code>id */ 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 function or * XPath <code>id function. * * @param keyValue A string representing the key values or id * references * @param isKeyCall A <code>boolean indicating whether the iterator * is being created for a reference <code>key or * <code>id */ 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 function or * XPath <code>id function. * * @param keyValue An iterator representing the key values or id * references * @param isKeyCall A <code>boolean indicating whether the iterator * is being created for a reference <code>key or * <code>id */ 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 function or the XPath Other Java examples (source code examples)Here is a short list of links related to this Java KeyIndex.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.