Mercurial > repos > pfrommolt > ngsrich
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 } |