Clover coverage report - dom4j - 1.6.1
Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00

file stats: | LOC: | 1.055 |  | Methods: | 49
| NCLOC: | 727 |  | Classes: | 1

Source file | Conditionals | Statements | Methods | TOTAL

DefaultElement.java

59,8%

68,3%

75,5%

65,5%

1 |  | /*
2 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3 |  | *
4 |  | * This software is open source.
5 |  | * See the bottom of this file for the licence.
6 |  | */
7 |  |
8 |  | package org.dom4j.tree;
9 |  |
10 |  | import java.util.ArrayList;
11 |  | import java.util.Iterator;
12 |  | import java.util.List;
13 |  |
14 |  | import org.dom4j.Attribute;
15 |  | import org.dom4j.Branch;
16 |  | import org.dom4j.Document;
17 |  | import org.dom4j.DocumentFactory;
18 |  | import org.dom4j.Element;
19 |  | import org.dom4j.IllegalAddException;
20 |  | import org.dom4j.Namespace;
21 |  | import org.dom4j.Node;
22 |  | import org.dom4j.ProcessingInstruction;
23 |  | import org.dom4j.QName;
24 |  |
25 |  | /**
26 |  | * <p>
27 |  | * <code>DefaultElement</code> is the default DOM4J default implementation of
28 |  | * an XML element.
29 |  | * </p>
30 |  | *
31 |  | * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
32 |  | * @version $Revision: 1.59 $
33 |  | */
34 |  | public class DefaultElement extends AbstractElement {
35 |  | /** The <code>DocumentFactory</code> instance used by default */
36 |  | private static final transient DocumentFactory DOCUMENT_FACTORY =
37 |  | DocumentFactory.getInstance();
38 |  |
39 |  | /** The <code>QName</code> for this element */
40 |  | private QName qname;
41 |  |
42 |  | /**
43 |  | * Stores the parent branch of this node which is either a Document if this
44 |  | * element is the root element in a document, or another Element if it is a
45 |  | * child of the root document, or null if it has not been added to a
46 |  | * document yet.
47 |  | */
48 |  | private Branch parentBranch;
49 |  |
50 |  | /**
51 |  | * Stores null for no content, a Node for a single content node or a List
52 |  | * for multiple content nodes. The List will be lazily constructed when
53 |  | * required.
54 |  | */
55 |  | private Object content;
56 |  |
57 |  | /** Lazily constructes list of attributes */
58 |  | private Object attributes;
59 |  |
60 | 1 | public DefaultElement(String name) {
61 | 1 | this.qname = DOCUMENT_FACTORY.createQName(name);
62 |  | }
63 |  |
64 | 96007 | public DefaultElement(QName qname) {
65 | 96007 | this.qname = qname;
66 |  | }
67 |  |
68 | 0 | public DefaultElement(QName qname, int attributeCount) {
69 | 0 | this.qname = qname;
70 |  |
71 | 0 | if (attributeCount > 1) {
72 | 0 | this.attributes = new ArrayList(attributeCount);
73 |  | }
74 |  | }
75 |  |
76 | 0 | public DefaultElement(String name, Namespace namespace) {
77 | 0 | this.qname = DOCUMENT_FACTORY.createQName(name, namespace);
78 |  | }
79 |  |
80 | 131539 | public Element getParent() {
81 | 131539 | Element result = null;
82 |  |
83 | 131539 | if (parentBranch instanceof Element) {
84 | 35288 | result = (Element) parentBranch;
85 |  | }
86 |  |
87 | 131539 | return result;
88 |  | }
89 |  |
90 | 94507 | public void setParent(Element parent) {
91 | 94507 | if (parentBranch instanceof Element || (parent != null)) {
92 | 92978 | parentBranch = parent;
93 |  | }
94 |  | }
95 |  |
96 | 13010 | public Document getDocument() {
97 | 13010 | if (parentBranch instanceof Document) {
98 | 6597 | return (Document) parentBranch;
99 | 6413 | } else if (parentBranch instanceof Element) {
100 | 117 | Element parent = (Element) parentBranch;
101 |  |
102 | 117 | return parent.getDocument();
103 |  | }
104 |  |
105 | 6296 | return null;
106 |  | }
107 |  |
108 | 15752 | public void setDocument(Document document) {
109 | 15752 | if (parentBranch instanceof Document || (document != null)) {
110 | 12600 | parentBranch = document;
111 |  | }
112 |  | }
113 |  |
114 | 10 | public boolean supportsParent() {
115 | 10 | return true;
116 |  | }
117 |  |
118 | 619575 | public QName getQName() {
119 | 619575 | return qname;
120 |  | }
121 |  |
122 | 1502 | public void setQName(QName name) {
123 | 1502 | this.qname = name;
124 |  | }
125 |  |
126 | 183 | public String getText() {
127 | 183 | final Object contentShadow = content;
128 |  |
129 | 183 | if (contentShadow instanceof List) {
130 | 80 | return super.getText();
131 |  | } else {
132 | 103 | if (contentShadow != null) {
133 | 93 | return getContentAsText(contentShadow);
134 |  | } else {
135 | 10 | return "";
136 |  | }
137 |  | }
138 |  | }
139 |  |
140 | 8 | public String getStringValue() {
141 | 8 | final Object contentShadow = content;
142 |  |
143 | 8 | if (contentShadow instanceof List) {
144 | 6 | List list = (List) contentShadow;
145 |  |
146 | 6 | int size = list.size();
147 |  |
148 | 6 | if (size > 0) {
149 | 6 | if (size == 1) {
150 |  | // optimised to avoid StringBuffer creation
151 | 4 | return getContentAsStringValue(list.get(0));
152 |  | } else {
153 | 2 | StringBuffer buffer = new StringBuffer();
154 |  |
155 | 2 | for (int i = 0; i < size; i++) {
156 | 9 | Object node = list.get(i);
157 |  |
158 | 9 | String string = getContentAsStringValue(node);
159 |  |
160 | 9 | if (string.length() > 0) {
161 | 7 | if (USE_STRINGVALUE_SEPARATOR) {
162 | 0 | if (buffer.length() > 0) {
163 | 0 | buffer.append(' ');
164 |  | }
165 |  | }
166 |  |
167 | 7 | buffer.append(string);
168 |  | }
169 |  | }
170 |  |
171 | 2 | return buffer.toString();
172 |  | }
173 |  | }
174 |  | } else {
175 | 2 | if (contentShadow != null) {
176 | 0 | return getContentAsStringValue(contentShadow);
177 |  | }
178 |  | }
179 |  |
180 | 2 | return "";
181 |  | }
182 |  |
183 | 129 | public Object clone() {
184 | 129 | DefaultElement answer = (DefaultElement) super.clone();
185 |  |
186 | 129 | if (answer != this) {
187 | 129 | answer.content = null;
188 |  |
189 | 129 | answer.attributes = null;
190 |  |
191 | 129 | answer.appendAttributes(this);
192 |  |
193 | 129 | answer.appendContent(this);
194 |  | }
195 |  |
196 | 129 | return answer;
197 |  | }
198 |  |
199 | 8764 | public Namespace getNamespaceForPrefix(String prefix) {
200 | 8764 | if (prefix == null) {
201 | 9 | prefix = "";
202 |  | }
203 |  |
204 | 8764 | if (prefix.equals(getNamespacePrefix())) {
205 | 3721 | return getNamespace();
206 | 5043 | } else if (prefix.equals("xml")) {
207 | 0 | return Namespace.XML_NAMESPACE;
208 |  | } else {
209 | 5043 | final Object contentShadow = content;
210 |  |
211 | 5043 | if (contentShadow instanceof List) {
212 | 5040 | List list = (List) contentShadow;
213 |  |
214 | 5040 | int size = list.size();
215 |  |
216 | 5040 | for (int i = 0; i < size; i++) {
217 | 5100 | Object object = list.get(i);
218 |  |
219 | 5100 | if (object instanceof Namespace) {
220 | 5055 | Namespace namespace = (Namespace) object;
221 |  |
222 | 5055 | if (prefix.equals(namespace.getPrefix())) {
223 | 5023 | return namespace;
224 |  | }
225 |  | }
226 |  | }
227 | 3 | } else if (contentShadow instanceof Namespace) {
228 | 0 | Namespace namespace = (Namespace) contentShadow;
229 |  |
230 | 0 | if (prefix.equals(namespace.getPrefix())) {
231 | 0 | return namespace;
232 |  | }
233 |  | }
234 |  | }
235 |  |
236 | 20 | Element parent = getParent();
237 |  |
238 | 20 | if (parent != null) {
239 | 19 | Namespace answer = parent.getNamespaceForPrefix(prefix);
240 |  |
241 | 19 | if (answer != null) {
242 | 19 | return answer;
243 |  | }
244 |  | }
245 |  |
246 | 1 | if ((prefix == null) || (prefix.length() <= 0)) {
247 | 0 | return Namespace.NO_NAMESPACE;
248 |  | }
249 |  |
250 | 1 | return null;
251 |  | }
252 |  |
253 | 9 | public Namespace getNamespaceForURI(String uri) {
254 | 9 | if ((uri == null) || (uri.length() <= 0)) {
255 | 0 | return Namespace.NO_NAMESPACE;
256 | 9 | } else if (uri.equals(getNamespaceURI())) {
257 | 0 | return getNamespace();
258 |  | } else {
259 | 9 | final Object contentShadow = content;
260 |  |
261 | 9 | if (contentShadow instanceof List) {
262 | 9 | List list = (List) contentShadow;
263 |  |
264 | 9 | int size = list.size();
265 |  |
266 | 9 | for (int i = 0; i < size; i++) {
267 | 21 | Object object = list.get(i);
268 |  |
269 | 21 | if (object instanceof Namespace) {
270 | 12 | Namespace namespace = (Namespace) object;
271 |  |
272 | 12 | if (uri.equals(namespace.getURI())) {
273 | 6 | return namespace;
274 |  | }
275 |  | }
276 |  | }
277 | 0 | } else if (contentShadow instanceof Namespace) {
278 | 0 | Namespace namespace = (Namespace) contentShadow;
279 |  |
280 | 0 | if (uri.equals(namespace.getURI())) {
281 | 0 | return namespace;
282 |  | }
283 |  | }
284 |  |
285 | 3 | Element parent = getParent();
286 |  |
287 | 3 | if (parent != null) {
288 | 3 | return parent.getNamespaceForURI(uri);
289 |  | }
290 |  |
291 | 0 | return null;
292 |  | }
293 |  | }
294 |  |
295 | 9903 | public List declaredNamespaces() {
296 | 9903 | BackedList answer = createResultList();
297 |  |
298 |  | // if (getNamespaceURI().length() > 0) {
299 |  | //
300 |  | // answer.addLocal(getNamespace());
301 |  | //
302 |  | // }
303 | 9903 | final Object contentShadow = content;
304 |  |
305 | 9903 | if (contentShadow instanceof List) {
306 | 9903 | List list = (List) contentShadow;
307 |  |
308 | 9903 | int size = list.size();
309 |  |
310 | 9903 | for (int i = 0; i < size; i++) {
311 | 31929 | Object object = list.get(i);
312 |  |
313 | 31929 | if (object instanceof Namespace) {
314 | 821 | answer.addLocal(object);
315 |  | }
316 |  | }
317 |  | } else {
318 | 0 | if (contentShadow instanceof Namespace) {
319 | 0 | answer.addLocal(contentShadow);
320 |  | }
321 |  | }
322 |  |
323 | 9903 | return answer;
324 |  | }
325 |  |
326 | 15 | public List additionalNamespaces() {
327 | 15 | final Object contentShadow = content;
328 |  |
329 | 15 | if (contentShadow instanceof List) {
330 | 13 | List list = (List) contentShadow;
331 |  |
332 | 13 | int size = list.size();
333 |  |
334 | 13 | BackedList answer = createResultList();
335 |  |
336 | 13 | for (int i = 0; i < size; i++) {
337 | 89 | Object object = list.get(i);
338 |  |
339 | 89 | if (object instanceof Namespace) {
340 | 25 | Namespace namespace = (Namespace) object;
341 |  |
342 | 25 | if (!namespace.equals(getNamespace())) {
343 | 13 | answer.addLocal(namespace);
344 |  | }
345 |  | }
346 |  | }
347 |  |
348 | 13 | return answer;
349 |  | } else {
350 | 2 | if (contentShadow instanceof Namespace) {
351 | 1 | Namespace namespace = (Namespace) contentShadow;
352 |  |
353 | 1 | if (namespace.equals(getNamespace())) {
354 | 1 | return createEmptyList();
355 |  | }
356 |  |
357 | 0 | return createSingleResultList(namespace);
358 |  | } else {
359 | 1 | return createEmptyList();
360 |  | }
361 |  | }
362 |  | }
363 |  |
364 | 0 | public List additionalNamespaces(String defaultNamespaceURI) {
365 | 0 | final Object contentShadow = content;
366 |  |
367 | 0 | if (contentShadow instanceof List) {
368 | 0 | List list = (List) contentShadow;
369 |  |
370 | 0 | BackedList answer = createResultList();
371 |  |
372 | 0 | int size = list.size();
373 |  |
374 | 0 | for (int i = 0; i < size; i++) {
375 | 0 | Object object = list.get(i);
376 |  |
377 | 0 | if (object instanceof Namespace) {
378 | 0 | Namespace namespace = (Namespace) object;
379 |  |
380 | 0 | if (!defaultNamespaceURI.equals(namespace.getURI())) {
381 | 0 | answer.addLocal(namespace);
382 |  | }
383 |  | }
384 |  | }
385 |  |
386 | 0 | return answer;
387 |  | } else {
388 | 0 | if (contentShadow instanceof Namespace) {
389 | 0 | Namespace namespace = (Namespace) contentShadow;
390 |  |
391 | 0 | if (!defaultNamespaceURI.equals(namespace.getURI())) {
392 | 0 | return createSingleResultList(namespace);
393 |  | }
394 |  | }
395 |  | }
396 |  |
397 | 0 | return createEmptyList();
398 |  | }
399 |  |
400 |  | // Processing instruction API
401 | 0 | public List processingInstructions() {
402 | 0 | final Object contentShadow = content;
403 |  |
404 | 0 | if (contentShadow instanceof List) {
405 | 0 | List list = (List) contentShadow;
406 |  |
407 | 0 | BackedList answer = createResultList();
408 |  |
409 | 0 | int size = list.size();
410 |  |
411 | 0 | for (int i = 0; i < size; i++) {
412 | 0 | Object object = list.get(i);
413 |  |
414 | 0 | if (object instanceof ProcessingInstruction) {
415 | 0 | answer.addLocal(object);
416 |  | }
417 |  | }
418 |  |
419 | 0 | return answer;
420 |  | } else {
421 | 0 | if (contentShadow instanceof ProcessingInstruction) {
422 | 0 | return createSingleResultList(contentShadow);
423 |  | }
424 |  |
425 | 0 | return createEmptyList();
426 |  | }
427 |  | }
428 |  |
429 | 0 | public List processingInstructions(String target) {
430 | 0 | final Object shadow = content;
431 |  |
432 | 0 | if (shadow instanceof List) {
433 | 0 | List list = (List) shadow;
434 |  |
435 | 0 | BackedList answer = createResultList();
436 |  |
437 | 0 | int size = list.size();
438 |  |
439 | 0 | for (int i = 0; i < size; i++) {
440 | 0 | Object object = list.get(i);
441 |  |
442 | 0 | if (object instanceof ProcessingInstruction) {
443 | 0 | ProcessingInstruction pi = (ProcessingInstruction) object;
444 |  |
445 | 0 | if (target.equals(pi.getName())) {
446 | 0 | answer.addLocal(pi);
447 |  | }
448 |  | }
449 |  | }
450 |  |
451 | 0 | return answer;
452 |  | } else {
453 | 0 | if (shadow instanceof ProcessingInstruction) {
454 | 0 | ProcessingInstruction pi = (ProcessingInstruction) shadow;
455 |  |
456 | 0 | if (target.equals(pi.getName())) {
457 | 0 | return createSingleResultList(pi);
458 |  | }
459 |  | }
460 |  |
461 | 0 | return createEmptyList();
462 |  | }
463 |  | }
464 |  |
465 | 0 | public ProcessingInstruction processingInstruction(String target) {
466 | 0 | final Object shadow = content;
467 |  |
468 | 0 | if (shadow instanceof List) {
469 | 0 | List list = (List) shadow;
470 |  |
471 | 0 | int size = list.size();
472 |  |
473 | 0 | for (int i = 0; i < size; i++) {
474 | 0 | Object object = list.get(i);
475 |  |
476 | 0 | if (object instanceof ProcessingInstruction) {
477 | 0 | ProcessingInstruction pi = (ProcessingInstruction) object;
478 |  |
479 | 0 | if (target.equals(pi.getName())) {
480 | 0 | return pi;
481 |  | }
482 |  | }
483 |  | }
484 |  | } else {
485 | 0 | if (shadow instanceof ProcessingInstruction) {
486 | 0 | ProcessingInstruction pi = (ProcessingInstruction) shadow;
487 |  |
488 | 0 | if (target.equals(pi.getName())) {
489 | 0 | return pi;
490 |  | }
491 |  | }
492 |  | }
493 |  |
494 | 0 | return null;
495 |  | }
496 |  |
497 | 0 | public boolean removeProcessingInstruction(String target) {
498 | 0 | final Object shadow = content;
499 |  |
500 | 0 | if (shadow instanceof List) {
501 | 0 | List list = (List) shadow;
502 |  |
503 | 0 | for (Iterator iter = list.iterator(); iter.hasNext();) {
504 | 0 | Object object = iter.next();
505 |  |
506 | 0 | if (object instanceof ProcessingInstruction) {
507 | 0 | ProcessingInstruction pi = (ProcessingInstruction) object;
508 |  |
509 | 0 | if (target.equals(pi.getName())) {
510 | 0 | iter.remove();
511 |  |
512 | 0 | return true;
513 |  | }
514 |  | }
515 |  | }
516 |  | } else {
517 | 0 | if (shadow instanceof ProcessingInstruction) {
518 | 0 | ProcessingInstruction pi = (ProcessingInstruction) shadow;
519 |  |
520 | 0 | if (target.equals(pi.getName())) {
521 | 0 | this.content = null;
522 |  |
523 | 0 | return true;
524 |  | }
525 |  | }
526 |  | }
527 |  |
528 | 0 | return false;
529 |  | }
530 |  |
531 | 125 | public Element element(String name) {
532 | 125 | final Object contentShadow = content;
533 |  |
534 | 125 | if (contentShadow instanceof List) {
535 | 30 | List list = (List) contentShadow;
536 |  |
537 | 30 | int size = list.size();
538 |  |
539 | 82 | for (int i = 0; i < size; i++) {
540 | 82 | Object object = list.get(i);
541 |  |
542 | 82 | if (object instanceof Element) {
543 | 36 | Element element = (Element) object;
544 |  |
545 | 36 | if (name.equals(element.getName())) {
546 | 30 | return element;
547 |  | }
548 |  | }
549 |  | }
550 |  | } else {
551 | 95 | if (contentShadow instanceof Element) {
552 | 6 | Element element = (Element) contentShadow;
553 |  |
554 | 6 | if (name.equals(element.getName())) {
555 | 6 | return element;
556 |  | }
557 |  | }
558 |  | }
559 |  |
560 | 89 | return null;
561 |  | }
562 |  |
563 | 2965 | public Element element(QName qName) {
564 | 2965 | final Object contentShadow = content;
565 |  |
566 | 2965 | if (contentShadow instanceof List) {
567 | 2705 | List list = (List) contentShadow;
568 |  |
569 | 2705 | int size = list.size();
570 |  |
571 | 2705 | for (int i = 0; i < size; i++) {
572 | 21262 | Object object = list.get(i);
573 |  |
574 | 21262 | if (object instanceof Element) {
575 | 11680 | Element element = (Element) object;
576 |  |
577 | 11680 | if (qName.equals(element.getQName())) {
578 | 2290 | return element;
579 |  | }
580 |  | }
581 |  | }
582 |  | } else {
583 | 260 | if (contentShadow instanceof Element) {
584 | 1 | Element element = (Element) contentShadow;
585 |  |
586 | 1 | if (qName.equals(element.getQName())) {
587 | 1 | return element;
588 |  | }
589 |  | }
590 |  | }
591 |  |
592 | 674 | return null;
593 |  | }
594 |  |
595 | 0 | public Element element(String name, Namespace namespace) {
596 | 0 | return element(getDocumentFactory().createQName(name, namespace));
597 |  | }
598 |  |
599 | 2 | public void setContent(List content) {
600 | 2 | contentRemoved();
601 |  |
602 | 2 | if (content instanceof ContentListFacade) {
603 | 2 | content = ((ContentListFacade) content).getBackingList();
604 |  | }
605 |  |
606 | 2 | if (content == null) {
607 | 0 | this.content = null;
608 |  | } else {
609 | 2 | int size = content.size();
610 |  |
611 | 2 | List newContent = createContentList(size);
612 |  |
613 | 2 | for (int i = 0; i < size; i++) {
614 | 7 | Object object = content.get(i);
615 |  |
616 | 7 | if (object instanceof Node) {
617 | 7 | Node node = (Node) object;
618 | 7 | Element parent = node.getParent();
619 |  |
620 | 7 | if ((parent != null) && (parent != this)) {
621 | 2 | node = (Node) node.clone();
622 |  | }
623 |  |
624 | 7 | newContent.add(node);
625 | 7 | childAdded(node);
626 | 0 | } else if (object != null) {
627 | 0 | String text = object.toString();
628 | 0 | Node node = getDocumentFactory().createText(text);
629 | 0 | newContent.add(node);
630 | 0 | childAdded(node);
631 |  | }
632 |  | }
633 |  |
634 | 2 | this.content = newContent;
635 |  | }
636 |  | }
637 |  |
638 | 0 | public void clearContent() {
639 | 0 | if (content != null) {
640 | 0 | contentRemoved();
641 |  |
642 | 0 | content = null;
643 |  | }
644 |  | }
645 |  |
646 | 355275 | public Node node(int index) {
647 | 355275 | if (index >= 0) {
648 | 355275 | final Object contentShadow = content;
649 | 355275 | Object node;
650 |  |
651 | 355275 | if (contentShadow instanceof List) {
652 | 333677 | List list = (List) contentShadow;
653 |  |
654 | 333677 | if (index >= list.size()) {
655 | 0 | return null;
656 |  | }
657 |  |
658 | 333677 | node = list.get(index);
659 |  | } else {
660 | 21598 | node = (index == 0) ? contentShadow : null;
661 |  | }
662 |  |
663 | 355275 | if (node != null) {
664 | 355275 | if (node instanceof Node) {
665 | 355275 | return (Node) node;
666 |  | } else {
667 | 0 | return new DefaultText(node.toString());
668 |  | }
669 |  | }
670 |  | }
671 |  |
672 | 0 | return null;
673 |  | }
674 |  |
675 | 0 | public int indexOf(Node node) {
676 | 0 | final Object contentShadow = content;
677 |  |
678 | 0 | if (contentShadow instanceof List) {
679 | 0 | List list = (List) contentShadow;
680 |  |
681 | 0 | return list.indexOf(node);
682 |  | } else {
683 | 0 | if ((contentShadow != null) && contentShadow.equals(node)) {
684 | 0 | return 0;
685 |  | } else {
686 | 0 | return -1;
687 |  | }
688 |  | }
689 |  | }
690 |  |
691 | 125606 | public int nodeCount() {
692 | 125606 | final Object contentShadow = content;
693 |  |
694 | 125606 | if (contentShadow instanceof List) {
695 | 103856 | List list = (List) contentShadow;
696 |  |
697 | 103856 | return list.size();
698 |  | } else {
699 | 21750 | return (contentShadow != null) ? 1 : 0;
700 |  | }
701 |  | }
702 |  |
703 | 94704 | public Iterator nodeIterator() {
704 | 94704 | final Object contentShadow = content;
705 |  |
706 | 94704 | if (contentShadow instanceof List) {
707 | 33208 | List list = (List) contentShadow;
708 |  |
709 | 33208 | return list.iterator();
710 |  | } else {
711 | 61496 | if (contentShadow != null) {
712 | 61120 | return createSingleIterator(contentShadow);
713 |  | } else {
714 | 376 | return EMPTY_ITERATOR;
715 |  | }
716 |  | }
717 |  | }
718 |  |
719 | 109 | public List attributes() {
720 | 109 | return new ContentListFacade(this, attributeList());
721 |  | }
722 |  |
723 | 0 | public void setAttributes(List attributes) {
724 | 0 | if (attributes instanceof ContentListFacade) {
725 | 0 | attributes = ((ContentListFacade) attributes).getBackingList();
726 |  | }
727 |  |
728 | 0 | this.attributes = attributes;
729 |  | }
730 |  |
731 | 5028 | public Iterator attributeIterator() {
732 | 5028 | final Object attributesShadow = this.attributes;
733 |  |
734 | 5028 | if (attributesShadow instanceof List) {
735 | 2596 | List list = (List) attributesShadow;
736 |  |
737 | 2596 | return list.iterator();
738 | 2432 | } else if (attributesShadow != null) {
739 | 998 | return createSingleIterator(attributesShadow);
740 |  | } else {
741 | 1434 | return EMPTY_ITERATOR;
742 |  | }
743 |  | }
744 |  |
745 | 24324 | public Attribute attribute(int index) {
746 | 24324 | final Object attributesShadow = this.attributes;
747 |  |
748 | 24324 | if (attributesShadow instanceof List) {
749 | 22129 | List list = (List) attributesShadow;
750 |  |
751 | 22129 | return (Attribute) list.get(index);
752 | 2195 | } else if ((attributesShadow != null) && (index == 0)) {
753 | 2195 | return (Attribute) attributesShadow;
754 |  | } else {
755 | 0 | return null;
756 |  | }
757 |  | }
758 |  |
759 | 110652 | public int attributeCount() {
760 | 110652 | final Object attributesShadow = this.attributes;
761 |  |
762 | 110652 | if (attributesShadow instanceof List) {
763 | 65626 | List list = (List) attributesShadow;
764 |  |
765 | 65626 | return list.size();
766 |  | } else {
767 | 45026 | return (attributesShadow != null) ? 1 : 0;
768 |  | }
769 |  | }
770 |  |
771 | 3958 | public Attribute attribute(String name) {
772 | 3958 | final Object attributesShadow = this.attributes;
773 |  |
774 | 3958 | if (attributesShadow instanceof List) {
775 | 1292 | List list = (List) attributesShadow;
776 |  |
777 | 1292 | int size = list.size();
778 |  |
779 | 1292 | for (int i = 0; i < size; i++) {
780 | 2294 | Attribute attribute = (Attribute) list.get(i);
781 |  |
782 | 2294 | if (name.equals(attribute.getName())) {
783 | 974 | return attribute;
784 |  | }
785 |  | }
786 | 2666 | } else if (attributesShadow != null) {
787 | 1729 | Attribute attribute = (Attribute) attributesShadow;
788 |  |
789 | 1729 | if (name.equals(attribute.getName())) {
790 | 575 | return attribute;
791 |  | }
792 |  | }
793 |  |
794 | 2409 | return null;
795 |  | }
796 |  |
797 | 20997 | public Attribute attribute(QName qName) {
798 | 20997 | final Object attributesShadow = this.attributes;
799 |  |
800 | 20997 | if (attributesShadow instanceof List) {
801 | 17846 | List list = (List) attributesShadow;
802 |  |
803 | 17846 | int size = list.size();
804 |  |
805 | 17846 | for (int i = 0; i < size; i++) {
806 | 20862 | Attribute attribute = (Attribute) list.get(i);
807 |  |
808 | 20862 | if (qName.equals(attribute.getQName())) {
809 | 17696 | return attribute;
810 |  | }
811 |  | }
812 | 3151 | } else if (attributesShadow != null) {
813 | 618 | Attribute attribute = (Attribute) attributesShadow;
814 |  |
815 | 618 | if (qName.equals(attribute.getQName())) {
816 | 231 | return attribute;
817 |  | }
818 |  | }
819 |  |
820 | 3070 | return null;
821 |  | }
822 |  |
823 | 0 | public Attribute attribute(String name, Namespace namespace) {
824 | 0 | return attribute(getDocumentFactory().createQName(name, namespace));
825 |  | }
826 |  |
827 | 10743 | public void add(Attribute attribute) {
828 | 10743 | if (attribute.getParent() != null) {
829 | 0 | String message = "The Attribute already has an existing parent \""
830 |  | + attribute.getParent().getQualifiedName() + "\"";
831 |  |
832 | 0 | throw new IllegalAddException(this, attribute, message);
833 |  | }
834 |  |
835 | 10743 | if (attribute.getValue() == null) {
836 |  | // try remove a previous attribute with the same
837 |  | // name since adding an attribute with a null value
838 |  | // is equivalent to removing it.
839 | 2 | Attribute oldAttribute = attribute(attribute.getQName());
840 |  |
841 | 2 | if (oldAttribute != null) {
842 | 1 | remove(oldAttribute);
843 |  | }
844 |  | } else {
845 | 10741 | if (attributes == null) {
846 | 9433 | attributes = attribute;
847 |  | } else {
848 | 1308 | attributeList().add(attribute);
849 |  | }
850 |  |
851 | 10741 | childAdded(attribute);
852 |  | }
853 |  | }
854 |  |
855 | 6 | public boolean remove(Attribute attribute) {
856 | 6 | boolean answer = false;
857 | 6 | final Object attributesShadow = this.attributes;
858 |  |
859 | 6 | if (attributesShadow instanceof List) {
860 | 3 | List list = (List) attributesShadow;
861 |  |
862 | 3 | answer = list.remove(attribute);
863 |  |
864 | 3 | if (!answer) {
865 |  | // we may have a copy of the attribute
866 | 0 | Attribute copy = attribute(attribute.getQName());
867 |  |
868 | 0 | if (copy != null) {
869 | 0 | list.remove(copy);
870 |  |
871 | 0 | answer = true;
872 |  | }
873 |  | }
874 | 3 | } else if (attributesShadow != null) {
875 | 3 | if (attribute.equals(attributesShadow)) {
876 | 3 | this.attributes = null;
877 |  |
878 | 3 | answer = true;
879 |  | } else {
880 |  | // we may have a copy of the attribute
881 | 0 | Attribute other = (Attribute) attributesShadow;
882 |  |
883 | 0 | if (attribute.getQName().equals(other.getQName())) {
884 | 0 | attributes = null;
885 |  |
886 | 0 | answer = true;
887 |  | }
888 |  | }
889 |  | }
890 |  |
891 | 6 | if (answer) {
892 | 6 | childRemoved(attribute);
893 |  | }
894 |  |
895 | 6 | return answer;
896 |  | }
897 |  |
898 |  | // Implementation methods
899 |  | // -------------------------------------------------------------------------
900 | 219990 | protected void addNewNode(Node node) {
901 | 219990 | final Object contentShadow = content;
902 |  |
903 | 219990 | if (contentShadow == null) {
904 | 92043 | this.content = node;
905 |  | } else {
906 | 127947 | if (contentShadow instanceof List) {
907 | 103858 | List list = (List) contentShadow;
908 |  |
909 | 103858 | list.add(node);
910 |  | } else {
911 | 24089 | List list = createContentList();
912 |  |
913 | 24089 | list.add(contentShadow);
914 |  |
915 | 24089 | list.add(node);
916 |  |
917 | 24089 | this.content = list;
918 |  | }
919 |  | }
920 |  |
921 | 219990 | childAdded(node);
922 |  | }
923 |  |
924 | 13545 | protected boolean removeNode(Node node) {
925 | 13545 | boolean answer = false;
926 | 13545 | final Object contentShadow = content;
927 |  |
928 | 13545 | if (contentShadow != null) {
929 | 13545 | if (contentShadow == node) {
930 | 1 | this.content = null;
931 |  |
932 | 1 | answer = true;
933 | 13544 | } else if (contentShadow instanceof List) {
934 | 13544 | List list = (List) contentShadow;
935 |  |
936 | 13544 | answer = list.remove(node);
937 |  | }
938 |  | }
939 |  |
940 | 13545 | if (answer) {
941 | 13545 | childRemoved(node);
942 |  | }
943 |  |
944 | 13545 | return answer;
945 |  | }
946 |  |
947 | 88171 | protected List contentList() {
948 | 88171 | final Object contentShadow = content;
949 |  |
950 | 88171 | if (contentShadow instanceof List) {
951 | 61297 | return (List) contentShadow;
952 |  | } else {
953 | 26874 | List list = createContentList();
954 |  |
955 | 26874 | if (contentShadow != null) {
956 | 23679 | list.add(contentShadow);
957 |  | }
958 |  |
959 | 26874 | this.content = list;
960 |  |
961 | 26874 | return list;
962 |  | }
963 |  | }
964 |  |
965 | 87124 | protected List attributeList() {
966 | 87124 | final Object attributesShadow = this.attributes;
967 |  |
968 | 87124 | if (attributesShadow instanceof List) {
969 | 58366 | return (List) attributesShadow;
970 | 28758 | } else if (attributesShadow != null) {
971 | 9093 | List list = createAttributeList();
972 |  |
973 | 9093 | list.add(attributesShadow);
974 |  |
975 | 9093 | this.attributes = list;
976 |  |
977 | 9093 | return list;
978 |  | } else {
979 | 19665 | List list = createAttributeList();
980 |  |
981 | 19665 | this.attributes = list;
982 |  |
983 | 19665 | return list;
984 |  | }
985 |  | }
986 |  |
987 | 1618 | protected List attributeList(int size) {
988 | 1618 | final Object attributesShadow = this.attributes;
989 |  |
990 | 1618 | if (attributesShadow instanceof List) {
991 | 0 | return (List) attributesShadow;
992 | 1618 | } else if (attributesShadow != null) {
993 | 0 | List list = createAttributeList(size);
994 |  |
995 | 0 | list.add(attributesShadow);
996 |  |
997 | 0 | this.attributes = list;
998 |  |
999 | 0 | return list;
1000 |  | } else {
1001 | 1618 | List list = createAttributeList(size);
1002 |  |
1003 | 1618 | this.attributes = list;
1004 |  |
1005 | 1618 | return list;
1006 |  | }
1007 |  | }
1008 |  |
1009 | 2 | protected void setAttributeList(List attributeList) {
1010 | 2 | this.attributes = attributeList;
1011 |  | }
1012 |  |
1013 | 228999 | protected DocumentFactory getDocumentFactory() {
1014 | 228999 | DocumentFactory factory = qname.getDocumentFactory();
1015 |  |
1016 | 228999 | return (factory != null) ? factory : DOCUMENT_FACTORY;
1017 |  | }
1018 |  | }
1019 |  |
1020 |  | /*
1021 |  | * Redistribution and use of this software and associated documentation
1022 |  | * ("Software"), with or without modification, are permitted provided that the
1023 |  | * following conditions are met:
1024 |  | *
1025 |  | * 1. Redistributions of source code must retain copyright statements and
1026 |  | * notices. Redistributions must also contain a copy of this document.
1027 |  | *
1028 |  | * 2. Redistributions in binary form must reproduce the above copyright notice,
1029 |  | * this list of conditions and the following disclaimer in the documentation
1030 |  | * and/or other materials provided with the distribution.
1031 |  | *
1032 |  | * 3. The name "DOM4J" must not be used to endorse or promote products derived
1033 |  | * from this Software without prior written permission of MetaStuff, Ltd. For
1034 |  | * written permission, please contact dom4j-info@metastuff.com.
1035 |  | *
1036 |  | * 4. Products derived from this Software may not be called "DOM4J" nor may
1037 |  | * "DOM4J" appear in their names without prior written permission of MetaStuff,
1038 |  | * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
1039 |  | *
1040 |  | * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
1041 |  | *
1042 |  | * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
1043 |  | * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1044 |  | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1045 |  | * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
1046 |  | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1047 |  | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1048 |  | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1049 |  | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1050 |  | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1051 |  | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1052 |  | * POSSIBILITY OF SUCH DAMAGE.
1053 |  | *
1054 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
1055 |  | */