2 * @(#)DOMNodeImpl.java 1.11 2000/08/16
8 import org.w3c.dom.DOMException;
14 * (c) 1998-2000 (W3C) MIT, INRIA, Keio University
15 * See Tidy.java for the copyright notice.
16 * Derived from <a href="http://www.w3.org/People/Raggett/tidy">
17 * HTML Tidy Release 4 Aug 2000</a>
19 * @author Dave Raggett <dsr@w3.org>
20 * @author Andy Quick <ac.quick@sympatico.ca> (translation to Java)
21 * @version 1.4, 1999/09/04 DOM Support
22 * @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
23 * @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
24 * @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
25 * @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
26 * @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
27 * @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
28 * @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
31 public class DOMNodeImpl implements org.w3c.dom.Node {
33 protected Node adaptee;
35 protected DOMNodeImpl(Node adaptee)
37 this.adaptee = adaptee;
41 /* --------------------- DOM ---------------------------- */
44 * @see org.w3c.dom.Node#getNodeValue
46 public String getNodeValue() throws DOMException
48 String value = ""; //BAK 10/10/2000 replaced null
49 if (adaptee.type == Node.TextNode ||
50 adaptee.type == Node.CDATATag ||
51 adaptee.type == Node.CommentTag ||
52 adaptee.type == Node.ProcInsTag)
55 if (adaptee.textarray != null && adaptee.start < adaptee.end)
57 value = Lexer.getString(adaptee.textarray,
59 adaptee.end - adaptee.start);
66 * @see org.w3c.dom.Node#setNodeValue
68 public void setNodeValue(String nodeValue) throws DOMException
70 if (adaptee.type == Node.TextNode ||
71 adaptee.type == Node.CDATATag ||
72 adaptee.type == Node.CommentTag ||
73 adaptee.type == Node.ProcInsTag)
75 byte[] textarray = Lexer.getBytes(nodeValue);
76 adaptee.textarray = textarray;
78 adaptee.end = textarray.length;
83 * @see org.w3c.dom.Node#getNodeName
85 public String getNodeName()
87 return adaptee.element;
91 * @see org.w3c.dom.Node#getNodeType
93 public short getNodeType()
96 switch (adaptee.type) {
98 result = org.w3c.dom.Node.DOCUMENT_NODE;
100 case Node.DocTypeTag:
101 result = org.w3c.dom.Node.DOCUMENT_TYPE_NODE;
103 case Node.CommentTag:
104 result = org.w3c.dom.Node.COMMENT_NODE;
106 case Node.ProcInsTag:
107 result = org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE;
110 result = org.w3c.dom.Node.TEXT_NODE;
113 result = org.w3c.dom.Node.CDATA_SECTION_NODE;
116 case Node.StartEndTag:
117 result = org.w3c.dom.Node.ELEMENT_NODE;
124 * @see org.w3c.dom.Node#getParentNode
126 public org.w3c.dom.Node getParentNode()
128 if (adaptee.parent != null)
129 return adaptee.parent.getAdapter();
135 * @see org.w3c.dom.Node#getChildNodes
137 public org.w3c.dom.NodeList getChildNodes()
139 return new DOMNodeListImpl(adaptee);
143 * @see org.w3c.dom.Node#getFirstChild
145 public org.w3c.dom.Node getFirstChild()
147 if (adaptee.content != null)
148 return adaptee.content.getAdapter();
154 * @see org.w3c.dom.Node#getLastChild
156 public org.w3c.dom.Node getLastChild()
158 if (adaptee.last != null)
159 return adaptee.last.getAdapter();
165 * @see org.w3c.dom.Node#getPreviousSibling
167 public org.w3c.dom.Node getPreviousSibling()
169 if (adaptee.prev != null)
170 return adaptee.prev.getAdapter();
176 * @see org.w3c.dom.Node#getNextSibling
178 public org.w3c.dom.Node getNextSibling()
180 if (adaptee.next != null)
181 return adaptee.next.getAdapter();
187 * @see org.w3c.dom.Node#getAttributes
189 public org.w3c.dom.NamedNodeMap getAttributes()
191 return new DOMAttrMapImpl(adaptee.attributes);
195 * @see org.w3c.dom.Node#getOwnerDocument
197 public org.w3c.dom.Document getOwnerDocument()
202 if (node != null && node.type == Node.RootNode)
205 for (node = this.adaptee;
206 node != null && node.type != Node.RootNode; node = node.parent);
209 return (org.w3c.dom.Document)node.getAdapter();
215 * @see org.w3c.dom.Node#insertBefore
217 public org.w3c.dom.Node insertBefore(org.w3c.dom.Node newChild,
218 org.w3c.dom.Node refChild)
221 // TODO - handle newChild already in tree
223 if (newChild == null)
225 if (!(newChild instanceof DOMNodeImpl)) {
226 throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
227 "newChild not instanceof DOMNodeImpl");
229 DOMNodeImpl newCh = (DOMNodeImpl)newChild;
231 if (this.adaptee.type == Node.RootNode) {
232 if (newCh.adaptee.type != Node.DocTypeTag &&
233 newCh.adaptee.type != Node.ProcInsTag) {
234 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
235 "newChild cannot be a child of this node");
237 } else if (this.adaptee.type == Node.StartTag) {
238 if (newCh.adaptee.type != Node.StartTag &&
239 newCh.adaptee.type != Node.StartEndTag &&
240 newCh.adaptee.type != Node.CommentTag &&
241 newCh.adaptee.type != Node.TextNode &&
242 newCh.adaptee.type != Node.CDATATag) {
243 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
244 "newChild cannot be a child of this node");
247 if (refChild == null) {
248 Node.insertNodeAtEnd(this.adaptee, newCh.adaptee);
249 if (this.adaptee.type == Node.StartEndTag) {
250 this.adaptee.setType(Node.StartTag);
253 Node ref = this.adaptee.content;
254 while (ref != null) {
255 if (ref.getAdapter() == refChild) break;
259 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
260 "refChild not found");
262 Node.insertNodeBeforeElement(ref, newCh.adaptee);
268 * @see org.w3c.dom.Node#replaceChild
270 public org.w3c.dom.Node replaceChild(org.w3c.dom.Node newChild,
271 org.w3c.dom.Node oldChild)
274 // TODO - handle newChild already in tree
276 if (newChild == null)
278 if (!(newChild instanceof DOMNodeImpl)) {
279 throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
280 "newChild not instanceof DOMNodeImpl");
282 DOMNodeImpl newCh = (DOMNodeImpl)newChild;
284 if (this.adaptee.type == Node.RootNode) {
285 if (newCh.adaptee.type != Node.DocTypeTag &&
286 newCh.adaptee.type != Node.ProcInsTag) {
287 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
288 "newChild cannot be a child of this node");
290 } else if (this.adaptee.type == Node.StartTag) {
291 if (newCh.adaptee.type != Node.StartTag &&
292 newCh.adaptee.type != Node.StartEndTag &&
293 newCh.adaptee.type != Node.CommentTag &&
294 newCh.adaptee.type != Node.TextNode &&
295 newCh.adaptee.type != Node.CDATATag) {
296 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
297 "newChild cannot be a child of this node");
300 if (oldChild == null) {
301 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
302 "oldChild not found");
305 Node ref = this.adaptee.content;
306 while (ref != null) {
307 if (ref.getAdapter() == oldChild) break;
311 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
312 "oldChild not found");
314 newCh.adaptee.next = ref.next;
315 newCh.adaptee.prev = ref.prev;
316 newCh.adaptee.last = ref.last;
317 newCh.adaptee.parent = ref.parent;
318 newCh.adaptee.content = ref.content;
319 if (ref.parent != null) {
320 if (ref.parent.content == ref)
321 ref.parent.content = newCh.adaptee;
322 if (ref.parent.last == ref)
323 ref.parent.last = newCh.adaptee;
325 if (ref.prev != null) {
326 ref.prev.next = newCh.adaptee;
328 if (ref.next != null) {
329 ref.next.prev = newCh.adaptee;
331 for (n = ref.content; n != null; n = n.next) {
333 n.parent = newCh.adaptee;
340 * @see org.w3c.dom.Node#removeChild
342 public org.w3c.dom.Node removeChild(org.w3c.dom.Node oldChild)
345 if (oldChild == null)
348 Node ref = this.adaptee.content;
349 while (ref != null) {
350 if (ref.getAdapter() == oldChild) break;
354 throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
355 "refChild not found");
357 Node.discardElement(ref);
359 if (this.adaptee.content == null
360 && this.adaptee.type == Node.StartTag) {
361 this.adaptee.setType(Node.StartEndTag);
368 * @see org.w3c.dom.Node#appendChild
370 public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild)
373 // TODO - handle newChild already in tree
375 if (newChild == null)
377 if (!(newChild instanceof DOMNodeImpl)) {
378 throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
379 "newChild not instanceof DOMNodeImpl");
381 DOMNodeImpl newCh = (DOMNodeImpl)newChild;
383 if (this.adaptee.type == Node.RootNode) {
384 if (newCh.adaptee.type != Node.DocTypeTag &&
385 newCh.adaptee.type != Node.ProcInsTag) {
386 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
387 "newChild cannot be a child of this node");
389 } else if (this.adaptee.type == Node.StartTag) {
390 if (newCh.adaptee.type != Node.StartTag &&
391 newCh.adaptee.type != Node.StartEndTag &&
392 newCh.adaptee.type != Node.CommentTag &&
393 newCh.adaptee.type != Node.TextNode &&
394 newCh.adaptee.type != Node.CDATATag) {
395 throw new DOMExceptionImpl(DOMException.HIERARCHY_REQUEST_ERR,
396 "newChild cannot be a child of this node");
399 Node.insertNodeAtEnd(this.adaptee, newCh.adaptee);
401 if (this.adaptee.type == Node.StartEndTag) {
402 this.adaptee.setType(Node.StartTag);
409 * @see org.w3c.dom.Node#hasChildNodes
411 public boolean hasChildNodes()
413 return (adaptee.content != null);
417 * @see org.w3c.dom.Node#cloneNode
419 public org.w3c.dom.Node cloneNode(boolean deep)
421 Node node = adaptee.cloneNode(deep);
423 return node.getAdapter();
427 * DOM2 - not implemented.
429 public void normalize()
434 * DOM2 - not implemented.
436 public boolean supports(String feature, String version)
438 return isSupported(feature, version);
442 * DOM2 - not implemented.
444 public String getNamespaceURI()
450 * DOM2 - not implemented.
452 public String getPrefix()
458 * DOM2 - not implemented.
460 public void setPrefix(String prefix)
466 * DOM2 - not implemented.
468 public String getLocalName()
474 * DOM2 - not implemented.
476 public boolean isSupported(String feature,String version) {
481 * DOM2 - @see org.w3c.dom.Node#hasAttributes
482 * contributed by dlp@users.sourceforge.net
484 public boolean hasAttributes()
486 return adaptee.attributes != null;