1 /*
2 * Copyright (C) 2002 Carsten Krebs (Team-Konzept GmbH & Co.KG)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 package com.teamkonzept.dom4jb.dom;
19
20 import com.teamkonzept.dom4jb.schema.ContentIterator;
21
22 public class NodeList implements org.w3c.dom.NodeList {
23
24 public static final NodeList EMPTY = new EmptyNodeList();
25
26 protected static final int initialCapacity = 8;
27 /***
28 * The array buffer into which the elements of the NodeList are stored.
29 * The capacity of the ArrayList is the length of this array buffer.
30 */
31 protected Node nodeData[];
32 protected ContentIterator nodeIterator;
33
34 /***
35 * The size of the NodeList (the number of elements it contains).
36 *
37 * @serial
38 */
39 protected int size;
40
41 /***
42 * The parent node of all nodes stored in this nodelist
43 */
44 protected Node parent;
45
46 public NodeList(final Node parent) {
47 this(parent, null);
48 }
49
50 /***
51 * Constructs an node list
52 */
53 public NodeList(final ContentIterator iterator) {
54 this(null, iterator);
55 }
56
57 /***
58 * Constructs an node list
59 */
60 public NodeList(final Node parent, final ContentIterator iterator) {
61 this.parent = parent;
62 this.nodeData = null;
63 this.nodeIterator = iterator;
64 this.size = 0;
65 }
66
67 /***
68 * Trims the capacity of this <tt>NodeList</tt> instance to be the
69 * list's current size. An application can use this operation to minimize
70 * the storage of an <tt>NodeList</tt> instance.
71 */
72 public void trimToSize() {
73 final int oldCapacity = nodeData.length;
74 if (size < oldCapacity) {
75 Node oldData[] = nodeData;
76 nodeData = new Node[size];
77 System.arraycopy(oldData, 0, nodeData, 0, size);
78 }
79 }
80
81 /***
82 * Increases the capacity of this <tt>NodeList</tt> instance, if
83 * necessary, to ensure that it can hold at least the number of elements
84 * specified by the minimum capacity argument.
85 *
86 * @param minCapacity the desired minimum capacity.
87 */
88 public void ensureCapacity(final int minCapacity) {
89 if (nodeData == null) {
90 nodeData = new Node[initialCapacity];
91 }
92 final int oldCapacity = nodeData.length;
93 if (minCapacity > oldCapacity) {
94 final Object oldData[] = nodeData;
95 int newCapacity = (oldCapacity * 3) / 2 + 1;
96 if (newCapacity < minCapacity)
97 newCapacity = minCapacity;
98 nodeData = new Node[newCapacity];
99 System.arraycopy(oldData, 0, nodeData, 0, size);
100 }
101 }
102
103 /***
104 * Returns the number of elements in this list.
105 *
106 * @return the number of elements in this list.
107 */
108 public int getLength() {
109 if (nodeIterator == null) {
110 return size;
111 }
112 while (nodeIterator.hasNext()) {
113 add(nodeIterator.next());
114 }
115 nodeIterator = null;
116 return size;
117 }
118
119 /***
120 * The number of nodes in the list. The range of valid child node indices
121 * is 0 to <code>length-1</code> inclusive.
122 */
123 public int size() {
124 return getLength();
125 }
126
127 /***
128 * Tests if this list has no elements.
129 *
130 * @return <tt>true</tt> if this list has no elements;
131 * <tt>false</tt> otherwise.
132 */
133 public boolean isEmpty() {
134 if (size > 0) {
135 return false;
136 }
137 if (nodeIterator == null) {
138 return true;
139 }
140 if (nodeIterator.hasNext()) {
141 add(nodeIterator.next());
142 return false;
143 }
144 nodeIterator = null;
145 return true;
146 }
147
148 // Positional Access Operations
149
150 /***
151 * Returns the <code>index</code>th item in the collection. If
152 * <code>index</code> is greater than or equal to the number of nodes in
153 * the list, this returns <code>null</code>.
154 * @param index Index into the collection.
155 * @return The node at the <code>index</code>th position in the
156 * <code>NodeList</code>, or <code>null</code> if that is not a valid
157 * index.
158 */
159 public Node get(final int index) {
160 if (index < 0) {
161 return null;
162 }
163 if (index < size) {
164 return nodeData[index];
165 }
166 if (nodeIterator != null) {
167 for (ContentIterator iter = nodeIterator;
168 index >= size && iter.hasNext();
169 ) {
170 add(iter.next());
171 }
172 if (index < size) {
173 return nodeData[index];
174 }
175 nodeIterator = null;
176 }
177 return null;
178 }
179
180 /***
181 * Returns the <code>index</code>th item in the collection. If
182 * <code>index</code> is greater than or equal to the number of nodes in
183 * the list, this returns <code>null</code>.
184 * @param index Index into the collection.
185 * @return The node at the <code>index</code>th position in the
186 * <code>NodeList</code>, or <code>null</code> if that is not a valid
187 * index.
188 */
189 public org.w3c.dom.Node item(final int index) {
190 return get(index);
191 }
192
193 /***
194 * Appends the specified element to the end of this list.
195 *
196 * @param o element to be appended to this list.
197 * @return <tt>true</tt> (as per the general contract of Collection.add).
198 */
199 public boolean add(final Node o) {
200 ensureCapacity(size + 1);
201 nodeData[size] = o;
202 o.attach(size++, (Node) this);
203 return true;
204 }
205
206 /***
207 * Removes all of the elements from this list. The list will
208 * be empty after this call returns.
209 */
210 public void clear() {
211
212 // Let gc do its work
213 for (int i = 0; i < size; i++) {
214 nodeData[i] = null;
215 }
216
217 if (nodeIterator != null) {
218 nodeIterator = null;
219 }
220
221 size = 0;
222 }
223
224 public void setParentNode(final Node parent) {
225 this.parent = parent;
226 }
227
228 /***
229 * The parent of this nodes. All nodes, except <code>Attr</code>,
230 * <code>Document</code>, <code>DocumentFragment</code>,
231 * <code>Entity</code>, and <code>Notation</code> may have a parent.
232 * However, if a node has just been created and not yet added to the
233 * tree, or if it has been removed from the tree, this is
234 * <code>null</code>.
235 */
236 public org.w3c.dom.Node getParentNode() {
237 return parent;
238 }
239
240 protected void setIterator(final ContentIterator iterator) {
241 this.nodeIterator = iterator;
242 }
243 }
244
245 final class EmptyNodeList extends NodeList {
246 EmptyNodeList() {
247 super(null, null);
248 }
249
250 /***
251 * Returns the <code>index</code>th item in the collection. If
252 * <code>index</code> is greater than or equal to the number of nodes in
253 * the list, this returns <code>null</code>.
254 * @param index Index into the collection.
255 * @return The node at the <code>index</code>th position in the
256 * <code>NodeList</code>, or <code>null</code> if that is not a valid
257 * index.
258 */
259 public org.w3c.dom.Node item(final int index) {
260 return null;
261 }
262
263 /***
264 * The number of nodes in the list. The range of valid child node indices
265 * is 0 to <code>length-1</code> inclusive.
266 */
267 public int getLength() {
268 return 0;
269 }
270
271 /***
272 * Appends the specified element to the end of this list.
273 *
274 * @param o element to be appended to this list.
275 * @return <tt>true</tt> (as per the general contract of Collection.add).
276 */
277 public boolean add(final Node o) {
278 throw new UnsupportedOperationException(
279 "NodeList instance" + " is read-only!");
280 }
281 }
This page was automatically generated by Maven