comparison NGSrich_0.5.5/src/org/jdom/AttributeList.java @ 0:89ad0a9cca52 default tip

Uploaded
author pfrommolt
date Mon, 21 Nov 2011 08:12:19 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:89ad0a9cca52
1 /*--
2
3 $Id: AttributeList.java,v 1.24 2007/11/10 05:28:58 jhunter Exp $
4
5 Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 1. Redistributions of source code must retain the above copyright
13 notice, this list of conditions, and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions, and the disclaimer that follows
17 these conditions in the documentation and/or other materials
18 provided with the distribution.
19
20 3. The name "JDOM" must not be used to endorse or promote products
21 derived from this software without prior written permission. For
22 written permission, please contact <request_AT_jdom_DOT_org>.
23
24 4. Products derived from this software may not be called "JDOM", nor
25 may "JDOM" appear in their name, without prior written permission
26 from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
28 In addition, we request (but do not require) that you include in the
29 end-user documentation provided with the redistribution and/or in the
30 software itself an acknowledgement equivalent to the following:
31 "This product includes software developed by the
32 JDOM Project (http://www.jdom.org/)."
33 Alternatively, the acknowledgment may be graphical using the logos
34 available at http://www.jdom.org/images/logos.
35
36 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 SUCH DAMAGE.
48
49 This software consists of voluntary contributions made by many
50 individuals on behalf of the JDOM Project and was originally
51 created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52 Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
53 on the JDOM Project, please see <http://www.jdom.org/>.
54
55 */
56
57 package org.jdom;
58
59 import java.util.*;
60
61 /**
62 * <code>AttributeList</code> represents legal JDOM <code>Attribute</code>
63 * content. This class is NOT PUBLIC; users should see it as a simple List
64 * implementation.
65 *
66 * @author Alex Rosen
67 * @author Philippe Riand
68 * @author Bradley S. Huffman
69 * @version $Revision: 1.24 $, $Date: 2007/11/10 05:28:58 $
70 * @see CDATA
71 * @see Comment
72 * @see Element
73 * @see EntityRef
74 * @see ProcessingInstruction
75 * @see Text
76 */
77 class AttributeList extends AbstractList
78 implements List, java.io.Serializable {
79
80 private static final String CVS_ID =
81 "@(#) $RCSfile: AttributeList.java,v $ $Revision: 1.24 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1_1 $";
82
83 private static final int INITIAL_ARRAY_SIZE = 5;
84
85 /** The backing list */
86 private Attribute elementData[];
87 private int size;
88
89 /** The parent Element */
90 private Element parent;
91
92 /** Force an Element parent */
93 private AttributeList() {}
94
95 /**
96 * Create a new instance of the AttributeList representing
97 * Element content
98 *
99 * @param parent element whose attributes are to be held
100 */
101 AttributeList(Element parent) {
102 this.parent = parent;
103 }
104
105 /**
106 * Package internal method to support building from sources that are
107 * 100% trusted.
108 *
109 * @param a attribute to add without any checks
110 */
111 final void uncheckedAddAttribute(Attribute a) {
112 a.parent = parent;
113 ensureCapacity(size + 1);
114 elementData[size++] = a;
115 modCount++;
116 }
117
118 /**
119 * Add a attribute to the end of the list or replace a existing
120 * attribute with the same name and <code>Namespace</code>.
121 *
122 * @param obj The object to insert into the list.
123 * @return true (as per the general contract of Collection.add).
124 * @throws IndexOutOfBoundsException if index < 0 || index > size()
125 */
126 public boolean add(Object obj) {
127 if (obj instanceof Attribute) {
128 Attribute attribute = (Attribute) obj;
129 int duplicate = indexOfDuplicate(attribute);
130 if (duplicate < 0) {
131 add(size(), attribute);
132 }
133 else {
134 set(duplicate, attribute);
135 }
136 }
137 else if (obj == null) {
138 throw new IllegalAddException("Cannot add null attribute");
139 }
140 else {
141 throw new IllegalAddException("Class " +
142 obj.getClass().getName() +
143 " is not an attribute");
144 }
145 return true;
146 }
147
148 /**
149 * Inserts the specified attribute at the specified position in this list.
150 * Shifts the attribute currently at that position (if any) and any
151 * subsequent attributes to the right (adds one to their indices).
152 *
153 * @param index The location to set the value to.
154 * @param obj The object to insert into the list.
155 * throws IndexOutOfBoundsException if index < 0 || index > size()
156 */
157 public void add(int index, Object obj) {
158 if (obj instanceof Attribute) {
159 Attribute attribute = (Attribute) obj;
160 int duplicate = indexOfDuplicate(attribute);
161 if (duplicate >= 0) {
162 throw new IllegalAddException("Cannot add duplicate attribute");
163 }
164 add(index, attribute);
165 }
166 else if (obj == null) {
167 throw new IllegalAddException("Cannot add null attribute");
168 }
169 else {
170 throw new IllegalAddException("Class " +
171 obj.getClass().getName() +
172 " is not an attribute");
173 }
174 modCount++;
175 }
176
177 /**
178 * Check and add the <code>Attribute</code> to this list at
179 * the given index. Note: does not check for duplicate
180 * attributes.
181 *
182 * @param index index where to add <code>Attribute</code>
183 * @param attribute <code>Attribute</code> to add
184 */
185 void add(int index, Attribute attribute) {
186 if (attribute.getParent() != null) {
187 throw new IllegalAddException(
188 "The attribute already has an existing parent \"" +
189 attribute.getParent().getQualifiedName() + "\"");
190 }
191
192 String reason = Verifier.checkNamespaceCollision(attribute, parent);
193 if (reason != null) {
194 throw new IllegalAddException(parent, attribute, reason);
195 }
196
197 if (index<0 || index>size) {
198 throw new IndexOutOfBoundsException("Index: " + index +
199 " Size: " + size());
200 }
201
202 attribute.setParent(parent);
203
204 ensureCapacity(size+1);
205 if( index==size ) {
206 elementData[size++] = attribute;
207 } else {
208 System.arraycopy(elementData, index, elementData, index + 1, size - index);
209 elementData[index] = attribute;
210 size++;
211 }
212 modCount++;
213 }
214
215 /**
216 * Add all the objects in the specified collection.
217 *
218 * @param collection The collection containing all the objects to add.
219 * @return <code>true</code> if the list was modified as a result of
220 * the add.
221 */
222 public boolean addAll(Collection collection) {
223 return addAll(size(), collection);
224 }
225
226 /**
227 * Inserts the specified collecton at the specified position in this list.
228 * Shifts the attribute currently at that position (if any) and any
229 * subsequent attributes to the right (adds one to their indices).
230 *
231 * @param index The offset to start adding the data in the collection
232 * @param collection The collection to insert into the list.
233 * @return <code>true</code> if the list was modified as a result of
234 * the add.
235 * throws IndexOutOfBoundsException if index < 0 || index > size()
236 */
237 public boolean addAll(int index, Collection collection) {
238 if (index<0 || index>size) {
239 throw new IndexOutOfBoundsException("Index: " + index +
240 " Size: " + size());
241 }
242
243 if ((collection == null) || (collection.size() == 0)) {
244 return false;
245 }
246 ensureCapacity(size() + collection.size());
247
248 int count = 0;
249
250 try {
251 Iterator i = collection.iterator();
252 while (i.hasNext()) {
253 Object obj = i.next();
254 add(index + count, obj);
255 count++;
256 }
257 }
258 catch (RuntimeException exception) {
259 for (int i = 0; i < count; i++) {
260 remove(index);
261 }
262 throw exception;
263 }
264
265 return true;
266 }
267
268 /**
269 * Clear the current list.
270 */
271 public void clear() {
272 if (elementData != null) {
273 for (int i = 0; i < size; i++) {
274 Attribute attribute = elementData[i];
275 attribute.setParent(null);
276 }
277 elementData = null;
278 size = 0;
279 }
280 modCount++;
281 }
282
283 /**
284 * Clear the current list and set it to the contents
285 * of the <code>Collection</code>.
286 * object.
287 *
288 * @param collection The collection to use.
289 */
290 void clearAndSet(Collection collection) {
291 Attribute[] old = elementData;
292 int oldSize = size;
293
294 elementData = null;
295 size = 0;
296
297 if ((collection != null) && (collection.size() != 0)) {
298 ensureCapacity(collection.size());
299 try {
300 addAll(0, collection);
301 }
302 catch (RuntimeException exception) {
303 elementData = old;
304 size = oldSize;
305 throw exception;
306 }
307 }
308
309 if (old != null) {
310 for (int i = 0; i < oldSize; i++) {
311 Attribute attribute = old[i];
312 attribute.setParent(null);
313 }
314 }
315 modCount++;
316 }
317
318 /**
319 * Increases the capacity of this <code>AttributeList</code> instance,
320 * if necessary, to ensure that it can hold at least the number of
321 * items specified by the minimum capacity argument.
322 *
323 * @param minCapacity the desired minimum capacity.
324 */
325 private void ensureCapacity(int minCapacity) {
326 if (elementData == null) {
327 elementData = new Attribute[Math.max(minCapacity, INITIAL_ARRAY_SIZE)];
328 }
329 else {
330 int oldCapacity = elementData.length;
331 if (minCapacity > oldCapacity) {
332 Attribute oldData[] = elementData;
333 int newCapacity = (oldCapacity * 3)/2 + 1;
334 if (newCapacity < minCapacity)
335 newCapacity = minCapacity;
336 elementData = new Attribute[newCapacity];
337 System.arraycopy(oldData, 0, elementData, 0, size);
338 }
339 }
340 }
341
342 /**
343 * Return the object at the specified offset.
344 *
345 * @param index The offset of the object.
346 * @return The Object which was returned.
347 */
348 public Object get(int index) {
349 if (index<0 || index>=size) {
350 throw new IndexOutOfBoundsException("Index: " + index +
351 " Size: " + size());
352 }
353
354 return elementData[index];
355 }
356
357 /**
358 * Return the <code>Attribute</code> with the
359 * given name and <code>Namespace</code>.
360 *
361 * @param name name of attribute to return
362 * @param namespace <code>Namespace</code> to match
363 * @return the <code>Attribute</code>, or null if one doesn't exist.
364 */
365 Object get(String name, Namespace namespace) {
366 int index = indexOf(name, namespace);
367 if (index < 0) {
368 return null;
369 }
370 return elementData[index];
371 }
372
373 /**
374 * Return index of the <code>Attribute</code> with the
375 * given name and uri.
376 */
377 int indexOf(String name, Namespace namespace) {
378 String uri = namespace.getURI();
379 if (elementData != null) {
380 for (int i = 0; i < size; i++) {
381 Attribute old = elementData[i];
382 String oldURI = old.getNamespaceURI();
383 String oldName = old.getName();
384 if (oldURI.equals(uri) && oldName.equals(name)) {
385 return i;
386 }
387 }
388 }
389 return -1;
390 }
391
392 /**
393 * Remove the object at the specified offset.
394 *
395 * @param index The offset of the object.
396 * @return The Object which was removed.
397 */
398 public Object remove(int index) {
399 if (index<0 || index>=size)
400 throw new IndexOutOfBoundsException("Index: " + index +
401 " Size: " + size());
402
403 Attribute old = elementData[index];
404 old.setParent(null);
405 int numMoved = size - index - 1;
406 if (numMoved > 0)
407 System.arraycopy(elementData, index+1, elementData, index,numMoved);
408 elementData[--size] = null; // Let gc do its work
409 modCount++;
410 return old;
411 }
412
413 /**
414 * Remove the <code>Attribute</code> with the
415 * given name and <code>Namespace</code>.
416 *
417 * @param namespace <code>Namespace</code> to match
418 * @return the <code>true</code> if attribute was removed,
419 * <code>false</code> otherwise
420 */
421 boolean remove(String name, Namespace namespace) {
422 int index = indexOf(name, namespace);
423 if (index < 0) {
424 return false;
425 }
426 remove(index);
427 return true;
428 }
429
430 /**
431 * Set the object at the specified location to the supplied
432 * object.
433 *
434 * @param index The location to set the value to.
435 * @param obj The location to set the value to.
436 * @return The object which was replaced.
437 * throws IndexOutOfBoundsException if index < 0 || index >= size()
438 */
439 public Object set(int index, Object obj) {
440 if (obj instanceof Attribute) {
441 Attribute attribute = (Attribute) obj;
442 int duplicate = indexOfDuplicate(attribute);
443 if ((duplicate >= 0) && (duplicate != index)) {
444 throw new IllegalAddException("Cannot set duplicate attribute");
445 }
446 return set(index, attribute);
447 }
448 else if (obj == null) {
449 throw new IllegalAddException("Cannot add null attribute");
450 }
451 else {
452 throw new IllegalAddException("Class " +
453 obj.getClass().getName() +
454 " is not an attribute");
455 }
456 }
457
458 /**
459 * Set the object at the specified location to the supplied
460 * object. Note: does not check for duplicate attributes.
461 *
462 * @param index The location to set the value to.
463 * @param attribute The attribute to set.
464 * @return The object which was replaced.
465 * throws IndexOutOfBoundsException if index < 0 || index >= size()
466 */
467 Object set(int index, Attribute attribute) {
468 if (index < 0 || index >= size)
469 throw new IndexOutOfBoundsException("Index: " + index +
470 " Size: " + size());
471
472 if (attribute.getParent() != null) {
473 throw new IllegalAddException(
474 "The attribute already has an existing parent \"" +
475 attribute.getParent().getQualifiedName() + "\"");
476 }
477
478 String reason = Verifier.checkNamespaceCollision(attribute, parent);
479 if (reason != null) {
480 throw new IllegalAddException(parent, attribute, reason);
481 }
482
483 Attribute old = (Attribute) elementData[index];
484 old.setParent(null);
485
486 elementData[index] = attribute;
487 attribute.setParent(parent);
488 return old;
489 }
490
491 /**
492 * Return index of attribute with same name and Namespace, or
493 * -1 if one doesn't exist
494 */
495 private int indexOfDuplicate(Attribute attribute) {
496 int duplicate = -1;
497 String name = attribute.getName();
498 Namespace namespace = attribute.getNamespace();
499 duplicate = indexOf(name, namespace);
500 return duplicate;
501 }
502
503 /**
504 * Return the number of items in this list
505 *
506 * @return The number of items in this list.
507 */
508 public int size() {
509 return size;
510 }
511
512 /**
513 * Return this list as a <code>String</code>
514 */
515 public String toString() {
516 return super.toString();
517 }
518 }