001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: DTMNodeList.java,v 1.12 2005/01/24 00:34:35 mcnamara Exp $
018: */
019: package org.apache.xml.dtm.ref;
020:
021: import org.apache.xml.dtm.DTM;
022: import org.apache.xml.dtm.DTMIterator;
023: import org.w3c.dom.Node;
024:
025: /**
026: * <code>DTMNodeList</code> gives us an implementation of the DOM's
027: * NodeList interface wrapped around a DTM Iterator. The author
028: * considers this something of an abominations, since NodeList was not
029: * intended to be a general purpose "list of nodes" API and is
030: * generally considered by the DOM WG to have be a mistake... but I'm
031: * told that some of the XPath/XSLT folks say they must have this
032: * solution.
033: *
034: * Please note that this is not necessarily equivlaent to a DOM
035: * NodeList operating over the same document. In particular:
036: * <ul>
037: *
038: * <li>If there are several Text nodes in logical succession (ie,
039: * across CDATASection and EntityReference boundaries), we will return
040: * only the first; the caller is responsible for stepping through
041: * them.
042: * (%REVIEW% Provide a convenience routine here to assist, pending
043: * proposed DOM Level 3 getAdjacentText() operation?) </li>
044: *
045: * <li>Since the whole XPath/XSLT architecture assumes that the source
046: * document is not altered while we're working with it, we do not
047: * promise to implement the DOM NodeList's "live view" response to
048: * document mutation. </li>
049: *
050: * </ul>
051: *
052: * <p>State: In progress!!</p>
053: * */
054: public class DTMNodeList extends DTMNodeListBase {
055: private DTMIterator m_iter;
056:
057: //================================================================
058: // Methods unique to this class
059: private DTMNodeList() {
060: }
061:
062: /**
063: * Public constructor: Wrap a DTMNodeList around an existing
064: * and preconfigured DTMIterator
065: *
066: * WARNING: THIS HAS THE SIDE EFFECT OF ISSUING setShouldCacheNodes(true)
067: * AGAINST THE DTMIterator.
068: *
069: */
070: public DTMNodeList(DTMIterator dtmIterator) {
071: if (dtmIterator != null) {
072: int pos = dtmIterator.getCurrentPos();
073: try {
074: m_iter = (DTMIterator) dtmIterator.cloneWithReset();
075: } catch (CloneNotSupportedException cnse) {
076: m_iter = dtmIterator;
077: }
078: m_iter.setShouldCacheNodes(true);
079: m_iter.runTo(-1);
080: m_iter.setCurrentPos(pos);
081: }
082: }
083:
084: /**
085: * Access the wrapped DTMIterator. I'm not sure whether anyone will
086: * need this or not, but let's write it and think about it.
087: *
088: */
089: public DTMIterator getDTMIterator() {
090: return m_iter;
091: }
092:
093: //================================================================
094: // org.w3c.dom.NodeList API follows
095:
096: /**
097: * Returns the <code>index</code>th item in the collection. If
098: * <code>index</code> is greater than or equal to the number of nodes in
099: * the list, this returns <code>null</code>.
100: * @param index Index into the collection.
101: * @return The node at the <code>index</code>th position in the
102: * <code>NodeList</code>, or <code>null</code> if that is not a valid
103: * index.
104: */
105: public Node item(int index) {
106: if (m_iter != null) {
107: int handle = m_iter.item(index);
108: if (handle == DTM.NULL) {
109: return null;
110: }
111: return m_iter.getDTM(handle).getNode(handle);
112: } else {
113: return null;
114: }
115: }
116:
117: /**
118: * The number of nodes in the list. The range of valid child node indices
119: * is 0 to <code>length-1</code> inclusive.
120: */
121: public int getLength() {
122: return (m_iter != null) ? m_iter.getLength() : 0;
123: }
124: }
|