misc changes
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.jtidy / src / net / sourceforge / phpdt / tidy / w3c / DOMNodeImpl.java
1 /*
2  * @(#)DOMNodeImpl.java   1.11 2000/08/16
3  *
4  */
5
6 package net.sourceforge.phpdt.tidy.w3c;
7
8 import org.w3c.dom.DOMException;
9 import sun.security.krb5.internal.n;
10
11 /**
12  *
13  * DOMNodeImpl
14  *
15  * (c) 1998-2000 (W3C) MIT, INRIA, Keio University
16  * See Tidy.java for the copyright notice.
17  * Derived from <a href="http://www.w3.org/People/Raggett/tidy">
18  * HTML Tidy Release 4 Aug 2000</a>
19  *
20  * @author  Dave Raggett <dsr@w3.org>
21  * @author  Andy Quick <ac.quick@sympatico.ca> (translation to Java)
22  * @version 1.4, 1999/09/04 DOM Support
23  * @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
24  * @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
25  * @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
26  * @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
27  * @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
28  * @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
29  * @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
30  */
31
32 public class DOMNodeImpl implements org.w3c.dom.Node {
33
34     protected Node adaptee;
35
36     protected DOMNodeImpl(Node adaptee)
37     {
38         this.adaptee = adaptee;
39     }
40
41
42     /* --------------------- DOM ---------------------------- */
43
44     /**
45      * @see org.w3c.dom.Node#getNodeValue
46      */
47     public String getNodeValue() throws DOMException
48     {
49         String value = ""; //BAK 10/10/2000 replaced null
50         if (adaptee.type == Node.TextNode ||
51             adaptee.type == Node.CDATATag ||
52             adaptee.type == Node.CommentTag ||
53             adaptee.type == Node.ProcInsTag)
54         {
55
56             if (adaptee.textarray != null && adaptee.start < adaptee.end)
57             {
58                 value = Lexer.getString(adaptee.textarray,
59                                         adaptee.start,
60                                         adaptee.end - adaptee.start);
61             }
62         }
63         return value;
64     }
65
66     /**
67      * @see org.w3c.dom.Node#setNodeValue
68      */
69     public void setNodeValue(String nodeValue) throws DOMException
70     {
71         if (adaptee.type == Node.TextNode ||
72             adaptee.type == Node.CDATATag ||
73             adaptee.type == Node.CommentTag ||
74             adaptee.type == Node.ProcInsTag)
75         {
76             byte[] textarray = Lexer.getBytes(nodeValue);
77             adaptee.textarray = textarray;
78             adaptee.start = 0;
79             adaptee.end = textarray.length;
80         }
81     }
82
83     /**
84      * @see org.w3c.dom.Node#getNodeName
85      */
86     public String getNodeName()
87     {
88         return adaptee.element;
89     }
90
91     /**
92      * @see org.w3c.dom.Node#getNodeType
93      */
94     public short getNodeType()
95     {
96         short result = -1;
97         switch (adaptee.type) {
98         case Node.RootNode:
99             result = org.w3c.dom.Node.DOCUMENT_NODE;
100             break;
101         case Node.DocTypeTag:
102             result = org.w3c.dom.Node.DOCUMENT_TYPE_NODE;
103             break;
104         case Node.CommentTag:
105             result = org.w3c.dom.Node.COMMENT_NODE;
106             break;
107         case Node.ProcInsTag:
108             result = org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE;
109             break;
110         case Node.TextNode:
111             result = org.w3c.dom.Node.TEXT_NODE;
112             break;
113         case Node.CDATATag:
114             result = org.w3c.dom.Node.CDATA_SECTION_NODE;
115             break;
116         case Node.StartTag:
117         case Node.StartEndTag:
118             result = org.w3c.dom.Node.ELEMENT_NODE;
119             break;
120         }
121         return result;
122     }
123
124     /**
125      * @see org.w3c.dom.Node#getParentNode
126      */
127     public org.w3c.dom.Node getParentNode()
128     {
129         if (adaptee.parent != null)
130             return adaptee.parent.getAdapter();
131         else
132             return null;
133     }
134
135     /**
136      * @see org.w3c.dom.Node#getChildNodes
137      */
138     public org.w3c.dom.NodeList getChildNodes()
139     {
140         return new DOMNodeListImpl(adaptee);
141     }
142
143     /**
144      * @see org.w3c.dom.Node#getFirstChild
145      */
146     public org.w3c.dom.Node getFirstChild()
147     {
148         if (adaptee.content != null)
149             return adaptee.content.getAdapter();
150         else
151             return null;
152     }
153
154     /**
155      * @see org.w3c.dom.Node#getLastChild
156      */
157     public org.w3c.dom.Node getLastChild()
158     {
159         if (adaptee.last != null)
160             return adaptee.last.getAdapter();
161         else
162             return null;
163     }
164
165     /**
166      * @see org.w3c.dom.Node#getPreviousSibling
167      */
168     public org.w3c.dom.Node getPreviousSibling()
169     {
170         if (adaptee.prev != null)
171             return adaptee.prev.getAdapter();
172         else
173             return null;
174     }
175
176     /**
177      * @see org.w3c.dom.Node#getNextSibling
178      */
179     public org.w3c.dom.Node getNextSibling()
180     {
181         if (adaptee.next != null)
182             return adaptee.next.getAdapter();
183         else
184             return null;
185     }
186
187     /**
188      * @see org.w3c.dom.Node#getAttributes
189      */
190     public org.w3c.dom.NamedNodeMap getAttributes()
191     {
192         return new DOMAttrMapImpl(adaptee.attributes);
193     }
194
195     /**
196      * @see org.w3c.dom.Node#getOwnerDocument
197      */
198     public org.w3c.dom.Document getOwnerDocument()
199     {
200         Node node;
201
202         node = this.adaptee;
203         if (node != null && node.type == Node.RootNode)
204             return null;
205
206         for (node = this.adaptee;
207             node != null && node.type != Node.RootNode; node = node.parent);
208
209         if (node != null)
210             return (org.w3c.dom.Document)node.getAdapter();
211         else
212             return null;
213     }
214
215     /**
216      * @see org.w3c.dom.Node#insertBefore
217      */
218     public org.w3c.dom.Node insertBefore(org.w3c.dom.Node newChild,
219                                          org.w3c.dom.Node refChild)
220                                              throws DOMException
221     {
222         // TODO - handle newChild already in tree
223
224         if (newChild == null)
225             return null;
226         if (!(newChild instanceof DOMNodeImpl)) {
227             throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
228                                        "newChild not instanceof DOMNodeImpl");
229         }
230         DOMNodeImpl newCh = (DOMNodeImpl)newChild;
231
232         if (this.adaptee.type == Node.RootNode) {
233             if (newCh.adaptee.type != Node.DocTypeTag &&
234                 newCh.adaptee.type != Node.ProcInsTag) {
235                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
236                                        "newChild cannot be a child of this node");
237             }
238         } else if (this.adaptee.type == Node.StartTag) {
239             if (newCh.adaptee.type != Node.StartTag &&
240                 newCh.adaptee.type != Node.StartEndTag &&
241                 newCh.adaptee.type != Node.CommentTag &&
242                 newCh.adaptee.type != Node.TextNode &&
243                 newCh.adaptee.type != Node.CDATATag) {
244                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
245                                        "newChild cannot be a child of this node");
246             }
247         }
248         if (refChild == null) {
249             Node.insertNodeAtEnd(this.adaptee, newCh.adaptee);
250             if (this.adaptee.type == Node.StartEndTag) {
251               this.adaptee.setType(Node.StartTag);
252             }
253         } else {
254             Node ref = this.adaptee.content;
255             while (ref != null) {
256                 if (ref.getAdapter() == refChild) break;
257                 ref = ref.next;
258             }
259             if (ref == null) {
260                 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
261                                            "refChild not found");
262             }
263             Node.insertNodeBeforeElement(ref, newCh.adaptee);
264         }
265         return newChild;
266     }
267
268     /**
269      * @see org.w3c.dom.Node#replaceChild
270      */
271     public org.w3c.dom.Node replaceChild(org.w3c.dom.Node newChild,
272                                          org.w3c.dom.Node oldChild)
273                                              throws DOMException
274     {
275         // TODO - handle newChild already in tree
276
277         if (newChild == null)
278             return null;
279         if (!(newChild instanceof DOMNodeImpl)) {
280             throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
281                                        "newChild not instanceof DOMNodeImpl");
282         }
283         DOMNodeImpl newCh = (DOMNodeImpl)newChild;
284
285         if (this.adaptee.type == Node.RootNode) {
286             if (newCh.adaptee.type != Node.DocTypeTag &&
287                 newCh.adaptee.type != Node.ProcInsTag) {
288                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
289                                        "newChild cannot be a child of this node");
290             }
291         } else if (this.adaptee.type == Node.StartTag) {
292             if (newCh.adaptee.type != Node.StartTag &&
293                 newCh.adaptee.type != Node.StartEndTag &&
294                 newCh.adaptee.type != Node.CommentTag &&
295                 newCh.adaptee.type != Node.TextNode &&
296                 newCh.adaptee.type != Node.CDATATag) {
297                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
298                                        "newChild cannot be a child of this node");
299             }
300         }
301         if (oldChild == null) {
302             throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
303                                        "oldChild not found");
304         } else {
305             Node n;
306             Node ref = this.adaptee.content;
307             while (ref != null) {
308                 if (ref.getAdapter() == oldChild) break;
309                 ref = ref.next;
310             }
311             if (ref == null) {
312                 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
313                                            "oldChild not found");
314             }
315             newCh.adaptee.next = ref.next;
316             newCh.adaptee.prev = ref.prev;
317             newCh.adaptee.last = ref.last;
318             newCh.adaptee.parent = ref.parent;
319             newCh.adaptee.content = ref.content;
320             if (ref.parent != null) {
321                 if (ref.parent.content == ref)
322                     ref.parent.content = newCh.adaptee;
323                 if (ref.parent.last == ref)
324                     ref.parent.last = newCh.adaptee;
325             }
326             if (ref.prev != null) {
327                 ref.prev.next = newCh.adaptee;
328             }
329             if (ref.next != null) {
330                 ref.next.prev = newCh.adaptee;
331             }
332             for (n = ref.content; n != null; n = n.next) {
333                 if (n.parent == ref)
334                     n.parent = newCh.adaptee;
335             }
336         }
337         return oldChild;
338     }
339
340     /**
341      * @see org.w3c.dom.Node#removeChild
342      */
343     public org.w3c.dom.Node removeChild(org.w3c.dom.Node oldChild)
344                                             throws DOMException
345     {
346         if (oldChild == null)
347             return null;
348
349         Node ref = this.adaptee.content;
350         while (ref != null) {
351             if (ref.getAdapter() == oldChild) break;
352             ref = ref.next;
353         }
354         if (ref == null) {
355             throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
356                                        "refChild not found");
357         }
358         Node.discardElement(ref);
359
360         if (this.adaptee.content == null
361         &&  this.adaptee.type == Node.StartTag) {
362           this.adaptee.setType(Node.StartEndTag);
363         }
364
365         return oldChild;
366     }
367
368     /**
369      * @see org.w3c.dom.Node#appendChild
370      */
371     public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild)
372                                             throws DOMException
373     {
374         // TODO - handle newChild already in tree
375
376         if (newChild == null)
377             return null;
378         if (!(newChild instanceof DOMNodeImpl)) {
379             throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
380                                        "newChild not instanceof DOMNodeImpl");
381         }
382         DOMNodeImpl newCh = (DOMNodeImpl)newChild;
383
384         if (this.adaptee.type == Node.RootNode) {
385             if (newCh.adaptee.type != Node.DocTypeTag &&
386                 newCh.adaptee.type != Node.ProcInsTag) {
387                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
388                                        "newChild cannot be a child of this node");
389             }
390         } else if (this.adaptee.type == Node.StartTag) {
391             if (newCh.adaptee.type != Node.StartTag &&
392                 newCh.adaptee.type != Node.StartEndTag &&
393                 newCh.adaptee.type != Node.CommentTag &&
394                 newCh.adaptee.type != Node.TextNode &&
395                 newCh.adaptee.type != Node.CDATATag) {
396                 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
397                                        "newChild cannot be a child of this node");
398             }
399         }
400         Node.insertNodeAtEnd(this.adaptee, newCh.adaptee);
401
402         if (this.adaptee.type == Node.StartEndTag) {
403           this.adaptee.setType(Node.StartTag);
404         }
405
406         return newChild;
407     }
408
409     /**
410      * @see org.w3c.dom.Node#hasChildNodes
411      */
412     public boolean hasChildNodes()
413     {
414         return (adaptee.content != null);
415     }
416
417     /**
418      * @see org.w3c.dom.Node#cloneNode
419      */
420     public org.w3c.dom.Node cloneNode(boolean deep)
421     {
422         Node node = adaptee.cloneNode(deep);
423         node.parent = null;
424         return node.getAdapter();
425     }
426
427     /**
428      * DOM2 - not implemented.
429      */
430     public void normalize()
431     {
432     }
433
434     /**
435      * DOM2 - not implemented.
436      */
437     public boolean supports(String feature, String version)
438     {
439         return isSupported(feature, version);
440     }
441
442     /**
443      * DOM2 - not implemented.
444      */
445     public String getNamespaceURI()
446     {
447         return null;
448     }
449
450     /**
451      * DOM2 - not implemented.
452      */
453     public String getPrefix()
454     {
455         return null;
456     }
457
458     /**
459      * DOM2 - not implemented.
460      */
461     public void setPrefix(String prefix)
462                             throws DOMException
463     {
464     }
465
466     /**
467      * DOM2 - not implemented.
468      */
469     public String getLocalName()
470     {
471       return null;
472     }
473
474     /**
475      * DOM2 - not implemented.
476      */
477     public boolean isSupported(String feature,String version) {
478         return false;
479     }
480
481     /**
482      * DOM2 - @see org.w3c.dom.Node#hasAttributes
483      * contributed by dlp@users.sourceforge.net
484      */
485     public boolean hasAttributes()
486     {
487         return adaptee.attributes != null;
488     }
489 }