KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > dom > AbstractParentNode


1 /*
2
3    Copyright 2000-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.dom;
19
20 import java.io.Serializable JavaDoc;
21
22 import org.w3c.dom.DOMException JavaDoc;
23 import org.w3c.dom.Node JavaDoc;
24 import org.w3c.dom.NodeList JavaDoc;
25 import org.w3c.dom.events.DocumentEvent JavaDoc;
26 import org.w3c.dom.events.MutationEvent JavaDoc;
27
28 /**
29  * This class implements the Node interface with support for children.
30  *
31  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
32  * @version $Id: AbstractParentNode.java,v 1.27 2005/03/18 00:38:12 deweese Exp $
33  */

34
35 public abstract class AbstractParentNode extends AbstractNode {
36
37     /**
38      * The children.
39      */

40     protected ChildNodes childNodes;
41
42     /**
43      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getChildNodes()}.
44      * @return {@link #childNodes}
45      */

46     public NodeList JavaDoc getChildNodes() {
47     return (childNodes == null)
48             ? childNodes = new ChildNodes()
49             : childNodes;
50     }
51
52     /**
53      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getFirstChild()}.
54      * @return {@link #childNodes}.firstChild
55      */

56     public Node JavaDoc getFirstChild() {
57     return (childNodes == null) ? null : childNodes.firstChild;
58     }
59
60     /**
61      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getLastChild()}.
62      * @return {@link #childNodes}.lastChild
63      */

64     public Node JavaDoc getLastChild() {
65     return (childNodes == null) ? null : childNodes.lastChild;
66     }
67
68     /**
69      * <b>DOM</b>: Implements {@link
70      * org.w3c.dom.Node#insertBefore(Node, Node)}.
71      */

72     public Node JavaDoc insertBefore(Node JavaDoc newChild, Node JavaDoc refChild)
73         throws DOMException JavaDoc {
74     if ((refChild != null) && ((childNodes == null) ||
75                                    (refChild.getParentNode() != this)))
76         throw createDOMException
77         (DOMException.NOT_FOUND_ERR,
78          "child.missing",
79          new Object JavaDoc[] { new Integer JavaDoc(refChild.getNodeType()),
80                 refChild.getNodeName() });
81
82     checkAndRemove(newChild, false);
83
84     if (newChild.getNodeType() == DOCUMENT_FRAGMENT_NODE) {
85         Node JavaDoc n = newChild.getFirstChild();
86         while (n != null) {
87                 Node JavaDoc ns = n.getNextSibling();
88         insertBefore(n, refChild);
89         n = ns;
90         }
91         return newChild;
92     } else {
93         // Node modification
94
if (childNodes == null) {
95             childNodes = new ChildNodes();
96         }
97         ExtendedNode n = childNodes.insert((ExtendedNode)newChild,
98                            (ExtendedNode)refChild);
99         n.setParentNode(this);
100
101             nodeAdded(n);
102
103         // Mutation event
104
fireDOMNodeInsertedEvent(n);
105         fireDOMSubtreeModifiedEvent();
106         return n;
107     }
108     }
109
110     /**
111      * <b>DOM</b>: Implements {@link
112      * org.w3c.dom.Node#replaceChild(Node, Node)}.
113      */

114     public Node JavaDoc replaceChild(Node JavaDoc newChild, Node JavaDoc oldChild)
115         throws DOMException JavaDoc {
116     if ((childNodes == null) || (oldChild.getParentNode() != this) )
117         throw createDOMException
118         (DOMException.NOT_FOUND_ERR,
119          "child.missing",
120          new Object JavaDoc[] { new Integer JavaDoc(oldChild.getNodeType()),
121                 oldChild.getNodeName() });
122
123     checkAndRemove(newChild, true);
124
125     if (newChild.getNodeType() == DOCUMENT_FRAGMENT_NODE) {
126         Node JavaDoc n = newChild.getLastChild();
127         if (n == null)
128                 return newChild;
129
130             Node JavaDoc ps = n.getPreviousSibling();
131             replaceChild(n, oldChild);
132         Node JavaDoc ns = n;
133             n = ps;
134             while (n != null) {
135                 ps = n.getPreviousSibling();
136                 insertBefore(n, ns);
137                 ns = n;
138                 n = ps;
139             }
140
141         return newChild;
142     }
143
144         // Mutation event
145
fireDOMNodeRemovedEvent(oldChild);
146         
147         getCurrentDocument().nodeToBeRemoved(oldChild);
148         nodeToBeRemoved(oldChild);
149         
150         // Node modification
151
ExtendedNode n = (ExtendedNode)newChild;
152         ExtendedNode o = childNodes.replace(n, (ExtendedNode)oldChild);
153         n.setParentNode(this);
154         o.setParentNode(null);
155         
156         nodeAdded(n);
157         
158         // Mutation event
159
fireDOMNodeInsertedEvent(n);
160         fireDOMSubtreeModifiedEvent();
161         return n;
162     }
163
164     /**
165      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#removeChild(Node)}.
166      */

167     public Node JavaDoc removeChild(Node JavaDoc oldChild) throws DOMException JavaDoc {
168     if (childNodes == null || oldChild.getParentNode() != this) {
169         throw createDOMException
170         (DOMException.NOT_FOUND_ERR,
171          "child.missing",
172          new Object JavaDoc[] { new Integer JavaDoc(oldChild.getNodeType()),
173                 oldChild.getNodeName() });
174     }
175     if (isReadonly()) {
176         throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
177                      "readonly.node",
178                      new Object JavaDoc[] { new Integer JavaDoc(getNodeType()),
179                             getNodeName() });
180     }
181
182     // Mutation event
183
fireDOMNodeRemovedEvent(oldChild);
184
185         getCurrentDocument().nodeToBeRemoved(oldChild);
186         nodeToBeRemoved(oldChild);
187
188     // Node modification
189
ExtendedNode result = childNodes.remove((ExtendedNode)oldChild);
190     result.setParentNode(null);
191
192     // Mutation event
193
fireDOMSubtreeModifiedEvent();
194     return result;
195     }
196
197     /**
198      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#appendChild(Node)}.
199      */

200     public Node JavaDoc appendChild(Node JavaDoc newChild) throws DOMException JavaDoc {
201     checkAndRemove(newChild, false);
202
203     if (newChild.getNodeType() == DOCUMENT_FRAGMENT_NODE) {
204         Node JavaDoc n = newChild.getFirstChild();
205         while (n != null) {
206                 Node JavaDoc ns = n.getNextSibling();
207         appendChild(n);
208         n = ns;
209         }
210         return newChild;
211     } else {
212         if (childNodes == null)
213         childNodes = new ChildNodes();
214
215         // Node modification
216
ExtendedNode n = childNodes.append((ExtendedNode)newChild);
217         n.setParentNode(this);
218
219             nodeAdded(n);
220
221         // Mutation event
222
fireDOMNodeInsertedEvent(n);
223         fireDOMSubtreeModifiedEvent();
224         return n;
225     }
226     }
227
228     /**
229      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#hasChildNodes()}.
230      * @return true if this node has children, false otherwise.
231      */

232     public boolean hasChildNodes() {
233     return childNodes != null && childNodes.getLength() != 0;
234     }
235
236     /**
237      * <b>DOM</b>: Implements {@link org.w3c.dom.Node#normalize()}.
238      */

239     public void normalize() {
240     Node JavaDoc p = getFirstChild();
241     if (p != null) {
242         p.normalize();
243         Node JavaDoc n = p.getNextSibling();
244         while (n != null) {
245         if (p.getNodeType() == TEXT_NODE &&
246                     n.getNodeType() == TEXT_NODE) {
247             String JavaDoc s = p.getNodeValue() + n.getNodeValue();
248             AbstractText at = (AbstractText)p;
249             at.setNodeValue(s);
250             removeChild(n);
251             n = p.getNextSibling();
252         } else {
253             n.normalize();
254             p = n;
255             n = n.getNextSibling();
256         }
257         }
258     }
259     }
260
261     /**
262      * <b>DOM</b>: Implements {@link
263      * org.w3c.dom.Element#getElementsByTagName(String)}.
264      */

265     public NodeList JavaDoc getElementsByTagName(String JavaDoc name) {
266     if (name == null) {
267         return EMPTY_NODE_LIST;
268     }
269         AbstractDocument ad = getCurrentDocument();
270         ElementsByTagName result = ad.getElementsByTagName(this, name);
271         if (result == null) {
272             result = new ElementsByTagName(name);
273             ad.putElementsByTagName(this, name, result);
274         }
275         return result;
276     }
277
278     /**
279      * <b>DOM</b>: Implements {@link
280      * org.w3c.dom.Element#getElementsByTagNameNS(String,String)}.
281      */

282     public NodeList JavaDoc getElementsByTagNameNS(String JavaDoc namespaceURI,
283                                            String JavaDoc localName) {
284     if (localName == null) {
285         return EMPTY_NODE_LIST;
286     }
287         AbstractDocument ad = getCurrentDocument();
288         ElementsByTagNameNS result =
289             ad.getElementsByTagNameNS(this, namespaceURI,
290                                       localName);
291         if (result == null) {
292             result = new ElementsByTagNameNS(namespaceURI, localName);
293             ad.putElementsByTagNameNS(this, namespaceURI, localName, result);
294         }
295         return result;
296     }
297
298     /**
299      * Recursively fires a DOMNodeInsertedIntoDocument event.
300      */

301     public void fireDOMNodeInsertedIntoDocumentEvent() {
302     AbstractDocument doc = getCurrentDocument();
303     if (doc.getEventsEnabled()) {
304         super.fireDOMNodeInsertedIntoDocumentEvent();
305         for (Node JavaDoc n = getFirstChild(); n != null; n = n.getNextSibling()) {
306         ((AbstractNode)n).fireDOMNodeInsertedIntoDocumentEvent();
307         }
308     }
309     }
310
311     /**
312      * Recursively fires a DOMNodeRemovedFromDocument event.
313      */

314     public void fireDOMNodeRemovedFromDocumentEvent() {
315     AbstractDocument doc = getCurrentDocument();
316     if (doc.getEventsEnabled()) {
317         super.fireDOMNodeRemovedFromDocumentEvent();
318         for (Node JavaDoc n = getFirstChild(); n != null; n = n.getNextSibling()) {
319         ((AbstractNode)n).fireDOMNodeRemovedFromDocumentEvent();
320         }
321     }
322     }
323
324     /**
325      * Called when a child node has been added.
326      */

327     protected void nodeAdded(Node JavaDoc n) {
328     }
329
330     /**
331      * Called when a child node is going to be removed.
332      */

333     protected void nodeToBeRemoved(Node JavaDoc n) {
334     }
335
336     /**
337      * Deeply exports this node to the given document.
338      */

339     protected Node JavaDoc deepExport(Node JavaDoc n, AbstractDocument d) {
340     super.deepExport(n, d);
341     for (Node JavaDoc p = getFirstChild(); p != null; p = p.getNextSibling()) {
342         Node JavaDoc t = ((AbstractNode)p).deepExport(p.cloneNode(false), d);
343         n.appendChild(t);
344     }
345     return n;
346     }
347
348     /**
349      * Deeply copy the fields of the current node into the given node.
350      * @param n a node of the type of this.
351      */

352     protected Node JavaDoc deepCopyInto(Node JavaDoc n) {
353     super.deepCopyInto(n);
354     for (Node JavaDoc p = getFirstChild(); p != null; p = p.getNextSibling()) {
355         Node JavaDoc t = p.cloneNode(true);
356         n.appendChild(t);
357     }
358     return n;
359     }
360
361     /**
362      * Fires a DOMSubtreeModified event.
363      */

364     protected void fireDOMSubtreeModifiedEvent() {
365     AbstractDocument doc = getCurrentDocument();
366     if (doc.getEventsEnabled()) {
367         DocumentEvent JavaDoc de = (DocumentEvent JavaDoc)doc;
368         MutationEvent JavaDoc ev = (MutationEvent JavaDoc)de.createEvent("MutationEvents");
369         ev.initMutationEvent("DOMSubtreeModified",
370                  true, // canBubbleArg
371
false, // cancelableArg
372
null, // relatedNodeArg
373
null, // prevValueArg
374
null, // newValueArg
375
null, // attrNameArg
376
MutationEvent.MODIFICATION);
377         dispatchEvent(ev);
378     }
379     }
380
381     /**
382      * Fires a DOMNodeInserted event.
383      */

384     protected void fireDOMNodeInsertedEvent(Node JavaDoc node) {
385     AbstractDocument doc = getCurrentDocument();
386     if (doc.getEventsEnabled()) {
387         DocumentEvent JavaDoc de = (DocumentEvent JavaDoc)doc;
388         MutationEvent JavaDoc ev = (MutationEvent JavaDoc)de.createEvent("MutationEvents");
389         ev.initMutationEvent("DOMNodeInserted",
390                  true, // canBubbleArg
391
false, // cancelableArg
392
this, // relatedNodeArg
393
null, // prevValueArg
394
null, // newValueArg
395
null, // attrNameArg
396
MutationEvent.ADDITION);
397         AbstractNode n = (AbstractNode)node;
398         n.dispatchEvent(ev);
399         n.fireDOMNodeInsertedIntoDocumentEvent();
400     }
401     }
402
403     /**
404      * Fires a DOMNodeRemoved event.
405      */

406     protected void fireDOMNodeRemovedEvent(Node JavaDoc node) {
407     AbstractDocument doc = getCurrentDocument();
408     if (doc.getEventsEnabled()) {
409         DocumentEvent JavaDoc de = (DocumentEvent JavaDoc)doc;
410         MutationEvent JavaDoc ev = (MutationEvent JavaDoc)de.createEvent("MutationEvents");
411         ev.initMutationEvent("DOMNodeRemoved",
412                  true, // canBubbleArg
413
false, // cancelableArg
414
this, // relatedNodeArg
415
null, // prevValueArg
416
null, // newValueArg
417
null, // attrNameArg
418
MutationEvent.REMOVAL);
419         AbstractNode n = (AbstractNode)node;
420         n.dispatchEvent(ev);
421         n.fireDOMNodeRemovedFromDocumentEvent();
422     }
423     }
424
425     /**
426      * Checks the validity of a node to be inserted, and removes it from
427      * the document if needed.
428      */

429     protected void checkAndRemove(Node JavaDoc n, boolean replace) {
430     checkChildType(n, replace);
431
432     if (isReadonly())
433         throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
434                      "readonly.node",
435                      new Object JavaDoc[] { new Integer JavaDoc(getNodeType()),
436                             getNodeName() });
437
438     if (n.getOwnerDocument() != getCurrentDocument())
439         throw createDOMException(DOMException.WRONG_DOCUMENT_ERR,
440                      "node.from.wrong.document",
441                      new Object JavaDoc[] { new Integer JavaDoc(getNodeType()),
442                             getNodeName() });
443         if (this == n)
444             throw createDOMException
445                 (DOMException.HIERARCHY_REQUEST_ERR,
446                  "add.self", new Object JavaDoc[] { getNodeName() });
447
448     Node JavaDoc np = n.getParentNode();
449         if (np == null)
450             return; // Already removed from tree, do nothing.
451

452         for (Node JavaDoc pn = getParentNode(); pn != null; pn = pn.getParentNode()) {
453             if (pn == n)
454                 throw createDOMException
455                     (DOMException.HIERARCHY_REQUEST_ERR,
456                      "add.ancestor",
457                      new Object JavaDoc[] { new Integer JavaDoc(getNodeType()),
458                                     getNodeName() });
459         }
460
461     // Remove the node from the tree
462
np.removeChild(n);
463     }
464
465     /**
466      * To manage a list of nodes.
467      */

468     protected class ElementsByTagName implements NodeList JavaDoc {
469
470     /**
471      * The table.
472      */

473     protected Node JavaDoc[] table;
474
475     /**
476      * The number of nodes.
477      */

478     protected int size = -1;
479
480         /**
481          * The name identifier.
482          */

483         protected String JavaDoc name;
484
485     /**
486      * Creates a new ElementsByTagName object.
487      */

488     public ElementsByTagName(String JavaDoc n) {
489             name = n;
490     }
491
492     /**
493      * <b>DOM</b>: Implements {@link NodeList#item(int)}.
494      */

495     public Node JavaDoc item(int index) {
496             if (size == -1) {
497                 initialize();
498             }
499         if (table == null || index < 0 || index >= size) {
500         return null;
501         }
502         return table[index];
503     }
504
505     /**
506      * <b>DOM</b>: Implements {@link NodeList#getLength()}.
507      * @return {@link #size}.
508      */

509     public int getLength() {
510             if (size == -1) {
511                 initialize();
512             }
513         return size;
514     }
515
516         /**
517          * Invalidates the list.
518          */

519         public void invalidate() {
520             size = -1;
521         }
522
523     /**
524      * Appends a node to the list.
525      */

526     protected void append(Node JavaDoc n) {
527         if (table == null) {
528         table = new Node JavaDoc[11];
529         } else if (size == table.length - 1) {
530         Node JavaDoc[] t = new Node JavaDoc[table.length * 2 + 1];
531         for (int i = 0; i < size; i++) {
532             t[i] = table[i];
533         }
534         table = t;
535         }
536         table[size++] = n;
537     }
538
539         /**
540          * Initializes the list.
541          */

542         protected void initialize() {
543             size = 0;
544             for (Node JavaDoc n = AbstractParentNode.this.getFirstChild();
545                  n != null;
546                  n = n.getNextSibling()) {
547                 initialize(n);
548             }
549         }
550
551         private void initialize(Node JavaDoc node) {
552             if (node.getNodeType() == ELEMENT_NODE) {
553                 String JavaDoc nm = node.getNodeName();
554                 if (name.equals("*") || name.equals(nm)) {
555                     append(node);
556                 }
557             }
558             for (Node JavaDoc n = node.getFirstChild();
559                  n != null;
560                  n = n.getNextSibling()) {
561                 initialize(n);
562             }
563         }
564     }
565
566     /**
567      * To manage a list of nodes.
568      */

569     protected class ElementsByTagNameNS implements NodeList JavaDoc {
570
571     /**
572      * The table.
573      */

574     protected Node JavaDoc[] table;
575
576     /**
577      * The number of nodes.
578      */

579     protected int size = -1;
580
581         /**
582          * The namespace URI identifier.
583          */

584         protected String JavaDoc namespaceURI;
585
586         /**
587          * The local name identifier.
588          */

589         protected String JavaDoc localName;
590
591     /**
592      * Creates a new ElementsByTagNameNS object.
593      */

594     public ElementsByTagNameNS(String JavaDoc ns, String JavaDoc ln) {
595             namespaceURI = ns;
596             localName = ln;
597     }
598
599     /**
600      * <b>DOM</b>: Implements {@link NodeList#item(int)}.
601      */

602     public Node JavaDoc item(int index) {
603             if (size == -1) {
604                 initialize();
605             }
606         if (table == null || index < 0 || index > size) {
607         return null;
608         }
609         return table[index];
610     }
611
612     /**
613      * <b>DOM</b>: Implements {@link NodeList#getLength()}.
614      * @return {@link #size}.
615      */

616     public int getLength() {
617             if (size == -1) {
618                 initialize();
619             }
620         return size;
621     }
622
623         /**
624          * Invalidates the list.
625          */

626         public void invalidate() {
627             size = -1;
628         }
629
630     /**
631      * Appends a node to the list.
632      */

633     protected void append(Node JavaDoc n) {
634         if (table == null) {
635         table = new Node JavaDoc[11];
636         } else if (size == table.length - 1) {
637         Node JavaDoc[] t = new Node JavaDoc[table.length * 2 + 1];
638         for (int i = 0; i < size; i++) {
639             t[i] = table[i];
640         }
641         table = t;
642         }
643         table[size++] = n;
644     }
645
646         /**
647          * Initializes the list.
648          */

649         protected void initialize() {
650             size = 0;
651             for (Node JavaDoc n = AbstractParentNode.this.getFirstChild();
652                  n != null;
653                  n = n.getNextSibling()) {
654                 initialize(n);
655             }
656         }
657
658         private void initialize(Node JavaDoc node) {
659             if (node.getNodeType() == ELEMENT_NODE) {
660                 String JavaDoc ns = node.getNamespaceURI();
661                 String JavaDoc nm = (ns == null)
662                     ? node.getNodeName()
663                     : node.getLocalName();
664                 if (nsMatch(namespaceURI, node.getNamespaceURI()) &&
665                     (localName.equals("*") || localName.equals(nm))) {
666                     append(node);
667                 }
668             }
669             for (Node JavaDoc n = node.getFirstChild();
670                  n != null;
671                  n = n.getNextSibling()) {
672                 initialize(n);
673             }
674         }
675
676         private boolean nsMatch(String JavaDoc s1, String JavaDoc s2) {
677             if (s1 == null && s2 == null) {
678                 return true;
679             }
680             if (s1 == null || s2 == null) {
681                 return false;
682             }
683             if (s1.equals("*")) {
684                 return true;
685             }
686             return s1.equals(s2);
687         }
688     }
689
690     /**
691      * To manage the children of this node.
692      */

693     protected class ChildNodes implements NodeList JavaDoc, Serializable JavaDoc {
694     /**
695      * The first child.
696      */

697     protected ExtendedNode firstChild;
698
699     /**
700      * The last child.
701      */

702     protected ExtendedNode lastChild;
703
704     /**
705      * The number of children.
706      */

707     protected int children;
708
709     /**
710      * Creates a new ChildNodes object.
711      */

712     public ChildNodes() {
713     }
714
715     /**
716      * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#item(int)}.
717      */

718     public Node JavaDoc item(int index) {
719         if (index < 0 || index >= children) {
720         return null;
721         }
722         if (index < (children >> 1)) {
723         Node JavaDoc n = firstChild;
724         for (int i = 0; i < index; i++) {
725             n = n.getNextSibling();
726         }
727         return n;
728         } else {
729         Node JavaDoc n = lastChild;
730         for (int i = children - 1; i > index; i--) {
731             n = n.getPreviousSibling();
732         }
733         return n;
734         }
735     }
736
737     /**
738      * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#getLength()}.
739      * @return {@link #children}.
740      */

741     public int getLength() {
742         return children;
743     }
744
745     /**
746      * Appends a node to the tree.
747      * The node is assumed not to be a DocumentFragment instance.
748      */

749     public ExtendedNode append(ExtendedNode n) {
750         if (lastChild == null) {
751         firstChild = n;
752         } else {
753           lastChild.setNextSibling(n);
754               n.setPreviousSibling(lastChild);
755             }
756         lastChild = n;
757         children++;
758         return n;
759     }
760
761     /**
762      * Inserts a node in the tree.
763      */

764     public ExtendedNode insert(ExtendedNode n, ExtendedNode r) {
765         if (r == null) {
766         return append(n);
767         }
768
769         if (r == firstChild) {
770         firstChild.setPreviousSibling(n);
771         n.setNextSibling(firstChild);
772         firstChild = n;
773         children++;
774         return n;
775         }
776         if (r == lastChild) {
777                 ExtendedNode ps = (ExtendedNode)r.getPreviousSibling();
778                 ps.setNextSibling(n);
779                 r.setPreviousSibling(n);
780                 n.setNextSibling(r);
781                 n.setPreviousSibling(ps);
782                 children++;
783                 return n;
784         }
785
786             ExtendedNode ps = (ExtendedNode)r.getPreviousSibling();
787             if ((ps.getNextSibling() == r) &&
788                 (ps.getParentNode() == r.getParentNode())) {
789                 ps.setNextSibling(n);
790                 n.setPreviousSibling(ps);
791                 n.setNextSibling(r);
792                 r.setPreviousSibling(n);
793                 children++;
794                 return n;
795             }
796
797         throw createDOMException
798         (DOMException.NOT_FOUND_ERR,
799          "child.missing",
800          new Object JavaDoc[] { new Integer JavaDoc(r.getNodeType()),
801                 r.getNodeName() });
802     }
803
804     /**
805      * Replaces a node in the tree by an other.
806      */

807     public ExtendedNode replace(ExtendedNode n, ExtendedNode o) {
808         if (o == firstChild) {
809                 ExtendedNode t = (ExtendedNode)firstChild.getNextSibling();
810         n.setNextSibling(t);
811                 if (o == lastChild) {
812                     lastChild = n;
813                 } else {
814                     t.setPreviousSibling(n);
815                 }
816         firstChild.setNextSibling(null);
817         firstChild = n;
818         return o;
819         }
820
821         if (o == lastChild) {
822                 ExtendedNode t = (ExtendedNode)lastChild.getPreviousSibling();
823         n.setPreviousSibling(t);
824                 t.setNextSibling(n);
825         lastChild.setPreviousSibling(null);
826         lastChild = n;
827         return o;
828         }
829
830             ExtendedNode ps = (ExtendedNode)o.getPreviousSibling();
831             ExtendedNode ns = (ExtendedNode)o.getNextSibling();
832             if ((ps.getNextSibling() == o) &&
833                 (ns.getPreviousSibling() == o) &&
834                 (ps.getParentNode() == o.getParentNode()) &&
835                 (ns.getParentNode() == o.getParentNode())) {
836
837                 ps.setNextSibling(n);
838                 n.setPreviousSibling(ps);
839                 n.setNextSibling(ns);
840                 ns.setPreviousSibling(n);
841                 o.setPreviousSibling(null);
842                 o.setNextSibling(null);
843                 return o;
844             }
845         throw createDOMException
846         (DOMException.NOT_FOUND_ERR,
847          "child.missing",
848          new Object JavaDoc[] { new Integer JavaDoc(o.getNodeType()),
849                 o.getNodeName() });
850     }
851
852         /**
853      * Removes the given node from the tree.
854      */

855         public ExtendedNode remove(ExtendedNode n) {
856         if (n == firstChild) {
857         if (n == lastChild) {
858             firstChild = null;
859             lastChild = null;
860             children--;
861             return n;
862         }
863         firstChild = (ExtendedNode)firstChild.getNextSibling();
864         firstChild.setPreviousSibling(null);
865         n.setNextSibling(null);
866         children--;
867         return n;
868         }
869
870         if (n == lastChild) {
871         lastChild = (ExtendedNode)lastChild.getPreviousSibling();
872         lastChild.setNextSibling(null);
873         n.setPreviousSibling(null);
874         children--;
875         return n;
876         }
877
878             ExtendedNode ps = (ExtendedNode)n.getPreviousSibling();
879             ExtendedNode ns = (ExtendedNode)n.getNextSibling();
880             if ((ps.getNextSibling() == n) &&
881                 (ns.getPreviousSibling() == n) &&
882                 (ps.getParentNode() == n.getParentNode()) &&
883                 (ns.getParentNode() == n.getParentNode())) {
884                 ps.setNextSibling(ns);
885                 ns.setPreviousSibling(ps);
886                 n.setPreviousSibling(null);
887                 n.setNextSibling(null);
888                 children--;
889                 return n;
890             }
891         throw createDOMException
892         (DOMException.NOT_FOUND_ERR,
893          "child.missing",
894          new Object JavaDoc[] { new Integer JavaDoc(n.getNodeType()),
895                 n.getNodeName() });
896     }
897     }
898 }
899
Popular Tags