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: DTMChildIterNodeList.java,v 1.4 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.w3c.dom.Node;
023:
024: /**
025: * <code>DTMNodeList</code> gives us an implementation of the DOM's
026: * NodeList interface wrapped around a DTM Iterator. The author
027: * considers this something of an abominations, since NodeList was not
028: * intended to be a general purpose "list of nodes" API and is
029: * generally considered by the DOM WG to have be a mistake... but I'm
030: * told that some of the XPath/XSLT folks say they must have this
031: * solution.
032: *
033: * Please note that this is not necessarily equivlaent to a DOM
034: * NodeList operating over the same document. In particular:
035: * <ul>
036: *
037: * <li>If there are several Text nodes in logical succession (ie,
038: * across CDATASection and EntityReference boundaries), we will return
039: * only the first; the caller is responsible for stepping through
040: * them.
041: * (%REVIEW% Provide a convenience routine here to assist, pending
042: * proposed DOM Level 3 getAdjacentText() operation?) </li>
043: *
044: * <li>Since the whole XPath/XSLT architecture assumes that the source
045: * document is not altered while we're working with it, we do not
046: * promise to implement the DOM NodeList's "live view" response to
047: * document mutation. </li>
048: *
049: * </ul>
050: *
051: * <p>State: In progress!!</p>
052: * */
053: public class DTMChildIterNodeList extends DTMNodeListBase {
054: private int m_firstChild;
055: private DTM m_parentDTM;
056:
057: //================================================================
058: // Methods unique to this class
059: private DTMChildIterNodeList() {
060: }
061:
062: /**
063: * Public constructor: Create a NodeList to support
064: * DTMNodeProxy.getChildren().
065: *
066: * Unfortunately AxisIterators and DTMIterators don't share an API,
067: * so I can't use the existing Axis.CHILD iterator. Rather than
068: * create Yet Another Class, let's set up a special case of this
069: * one.
070: *
071: * @param parentDTM The DTM containing this node
072: * @param parentHandle DTM node-handle integer
073: *
074: */
075: public DTMChildIterNodeList(DTM parentDTM, int parentHandle) {
076: m_parentDTM = parentDTM;
077: m_firstChild = parentDTM.getFirstChild(parentHandle);
078: }
079:
080: //================================================================
081: // org.w3c.dom.NodeList API follows
082:
083: /**
084: * Returns the <code>index</code>th item in the collection. If
085: * <code>index</code> is greater than or equal to the number of nodes in
086: * the list, this returns <code>null</code>.
087: * @param index Index into the collection.
088: * @return The node at the <code>index</code>th position in the
089: * <code>NodeList</code>, or <code>null</code> if that is not a valid
090: * index.
091: */
092: public Node item(int index) {
093: int handle = m_firstChild;
094: while (--index >= 0 && handle != DTM.NULL) {
095: handle = m_parentDTM.getNextSibling(handle);
096: }
097: if (handle == DTM.NULL) {
098: return null;
099: }
100: return m_parentDTM.getNode(handle);
101: }
102:
103: /**
104: * The number of nodes in the list. The range of valid child node indices
105: * is 0 to <code>length-1</code> inclusive.
106: */
107: public int getLength() {
108: int count = 0;
109: for (int handle = m_firstChild; handle != DTM.NULL; handle = m_parentDTM
110: .getNextSibling(handle)) {
111: ++count;
112: }
113: return count;
114: }
115: }
|