1 /*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5 /*
6 * Copyright 1999-2004 The Apache Software Foundation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 /*
21 * $Id: DTMAxisIterNodeList.java,v 1.2.4.1 2005/09/15 08:14:59 suresh_emailid Exp $
22 */
23 package com.sun.org.apache.xml.internal.dtm.ref;
24
25 import com.sun.org.apache.xml.internal.dtm.DTM;
26 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
27 import com.sun.org.apache.xml.internal.utils.IntVector;
28
29 import org.w3c.dom.Node;
30
31 /**
32 * <code>DTMAxisNodeList</code> gives us an implementation of the DOM's
33 * NodeList interface wrapped around a DTM Iterator. The author
34 * considers this something of an abominations, since NodeList was not
35 * intended to be a general purpose "list of nodes" API and is
36 * generally considered by the DOM WG to have be a mistake... but I'm
37 * told that some of the XPath/XSLT folks say they must have this
38 * solution.
39 *
40 * Please note that this is not necessarily equivlaent to a DOM
41 * NodeList operating over the same document. In particular:
42 * <ul>
43 *
44 * <li>If there are several Text nodes in logical succession (ie,
45 * across CDATASection and EntityReference boundaries), we will return
46 * only the first; the caller is responsible for stepping through
47 * them.
48 * (%REVIEW% Provide a convenience routine here to assist, pending
49 * proposed DOM Level 3 getAdjacentText() operation?) </li>
50 *
51 * <li>Since the whole XPath/XSLT architecture assumes that the source
52 * document is not altered while we're working with it, we do not
53 * promise to implement the DOM NodeList's "live view" response to
54 * document mutation. </li>
55 *
56 * </ul>
57 *
58 * <p>State: In progress!!</p>
59 * */
60 public class DTMAxisIterNodeList extends DTMNodeListBase {
61 private DTM m_dtm;
62 private DTMAxisIterator m_iter;
63 private IntVector m_cachedNodes;
64 private int m_last = -1;
65 //================================================================
66 // Methods unique to this class
67 private DTMAxisIterNodeList() {
68 }
69
70 /**
71 * Public constructor: Wrap a DTMNodeList around an existing
72 * and preconfigured DTMAxisIterator
73 */
74 public DTMAxisIterNodeList(DTM dtm, DTMAxisIterator dtmAxisIterator) {
75 if (dtmAxisIterator == null) {
76 m_last = 0;
77 } else {
78 m_cachedNodes = new IntVector();
79 m_dtm = dtm;
80 }
81 m_iter = dtmAxisIterator;
82 }
83
84 /**
85 * Access the wrapped DTMIterator. I'm not sure whether anyone will
86 * need this or not, but let's write it and think about it.
87 *
88 */
89 public DTMAxisIterator getDTMAxisIterator() {
90 return m_iter;
91 }
92
93
94 //================================================================
95 // org.w3c.dom.NodeList API follows
96
97 /**
98 * Returns the <code>index</code>th item in the collection. If
99 * <code>index</code> is greater than or equal to the number of nodes in
100 * the list, this returns <code>null</code>.
101 * @param index Index into the collection.
102 * @return The node at the <code>index</code>th position in the
103 * <code>NodeList</code>, or <code>null</code> if that is not a valid
104 * index.
105 */
106 public Node item(int index) {
107 if (m_iter != null) {
108 int node;
109 int count = m_cachedNodes.size();
110
111 if (count > index) {
112 node = m_cachedNodes.elementAt(index);
113 return m_dtm.getNode(node);
114 } else if (m_last == -1) {
115 while (((node = m_iter.next()) != DTMAxisIterator.END)
116 && count <= index) {
117 m_cachedNodes.addElement(node);
118 count++;
119 }
120 if (node == DTMAxisIterator.END) {
121 m_last = count;
122 } else {
123 return m_dtm.getNode(node);
124 }
125 }
126 }
127 return null;
128 }
129
130 /**
131 * The number of nodes in the list. The range of valid child node indices
132 * is 0 to <code>length-1</code> inclusive.
133 */
134 public int getLength() {
135 if (m_last == -1) {
136 int node;
137 while ((node = m_iter.next()) != DTMAxisIterator.END) {
138 m_cachedNodes.addElement(node);
139 }
140 m_last = m_cachedNodes.size();
141 }
142 return m_last;
143 }
144 }