KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > message > NodeImpl


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

16
17 package org.apache.axis.message;
18
19 import org.apache.axis.components.logger.LogFactory;
20 import org.apache.axis.encoding.SerializationContext;
21 import org.apache.axis.i18n.Messages;
22 import org.apache.commons.logging.Log;
23 import org.w3c.dom.Attr JavaDoc;
24 import org.w3c.dom.CDATASection JavaDoc;
25 import org.w3c.dom.CharacterData JavaDoc;
26 import org.w3c.dom.Comment JavaDoc;
27 import org.w3c.dom.DOMException JavaDoc;
28 import org.w3c.dom.Document JavaDoc;
29 import org.w3c.dom.NamedNodeMap JavaDoc;
30 import org.w3c.dom.Node JavaDoc;
31 import org.w3c.dom.NodeList JavaDoc;
32 import org.w3c.dom.Text JavaDoc;
33 import org.xml.sax.Attributes JavaDoc;
34 import org.xml.sax.helpers.AttributesImpl JavaDoc;
35
36 import javax.xml.soap.SOAPElement JavaDoc;
37 import javax.xml.soap.SOAPException JavaDoc;
38 import java.io.Serializable JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Iterator JavaDoc;
41
42 /**
43  * This is our implementation of the DOM node
44  */

45 public class NodeImpl implements org.w3c.dom.Node JavaDoc, javax.xml.soap.Node JavaDoc,
46         Serializable JavaDoc, Cloneable JavaDoc {
47
48     protected static Log log =
49             LogFactory.getLog(NodeImpl.class.getName());
50
51     protected String JavaDoc name;
52     protected String JavaDoc prefix;
53     protected String JavaDoc namespaceURI;
54     protected transient Attributes JavaDoc attributes = NullAttributes.singleton;
55
56     protected Document JavaDoc document = null;
57     protected NodeImpl parent = null;
58     protected ArrayList JavaDoc children = null;
59
60     // ...or as DOM
61
protected CharacterData JavaDoc textRep = null;
62
63     protected boolean _isDirty = false;
64     private static final String JavaDoc NULL_URI_NAME = "intentionalNullURI";
65
66     /**
67      * empty constructor
68      */

69     public NodeImpl() {
70     }
71
72     /**
73      * constructor which adopts the name and NS of the char data, and its text
74      * @param text
75      */

76     public NodeImpl(CharacterData JavaDoc text) {
77         textRep = text;
78         namespaceURI = text.getNamespaceURI();
79         name = text.getLocalName();
80     }
81
82     /**
83      * A code representing the type of the underlying object, as defined above.
84      */

85     public short getNodeType() {
86         if (this.textRep != null) {
87             if (textRep instanceof Comment JavaDoc) {
88                 return COMMENT_NODE;
89             } else if (textRep instanceof CDATASection JavaDoc) {
90                 return CDATA_SECTION_NODE;
91             } else {
92                 return TEXT_NODE;
93             }
94         } else if (false) {
95             return DOCUMENT_FRAGMENT_NODE;
96         } else if (false) {
97             return Node.ELEMENT_NODE;
98         } else { // most often but we cannot give prioeity now
99
return Node.ELEMENT_NODE;
100         }
101     }
102
103     /**
104      * Puts all <code>Text</code> nodes in the full depth of the sub-tree
105      * underneath this <code>Node</code>, including attribute nodes, into a
106      * "normal" form where only structure (e.g., elements, comments,
107      * processing instructions, CDATA sections, and entity references)
108      * separates <code>Text</code> nodes, i.e., there are neither adjacent
109      * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can
110      * be used to ensure that the DOM view of a document is the same as if
111      * it were saved and re-loaded, and is useful when operations (such as
112      * XPointer lookups) that depend on a particular document tree
113      * structure are to be used.In cases where the document contains
114      * <code>CDATASections</code>, the normalize operation alone may not be
115      * sufficient, since XPointers do not differentiate between
116      * <code>Text</code> nodes and <code>CDATASection</code> nodes.
117      */

118     public void normalize() {
119         //TODO: Fix this for SAAJ 1.2 Implementation
120
}
121
122     /**
123      * Returns whether this node (if it is an element) has any attributes.
124      *
125      * @return <code>true</code> if this node has any attributes,
126      * <code>false</code> otherwise.
127      * @since DOM Level 2
128      */

129     public boolean hasAttributes() {
130         return attributes.getLength() > 0;
131     }
132
133     /**
134      * Returns whether this node has any children.
135      *
136      * @return <code>true</code> if this node has any children,
137      * <code>false</code> otherwise.
138      */

139     public boolean hasChildNodes() {
140         return (children != null && !children.isEmpty());
141     }
142
143     /**
144      * Returns the local part of the qualified name of this node.
145      * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
146      * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
147      * method, such as <code>createElement</code> from the
148      * <code>Document</code> interface, this is always <code>null</code>.
149      *
150      * @since DOM Level 2
151      */

152     public String JavaDoc getLocalName() {
153         return name;
154     }
155
156     /**
157      * The namespace URI of this node, or <code>null</code> if it is
158      * unspecified.
159      * <br>This is not a computed value that is the result of a namespace
160      * lookup based on an examination of the namespace declarations in
161      * scope. It is merely the namespace URI given at creation time.
162      * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
163      * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
164      * method, such as <code>createElement</code> from the
165      * <code>Document</code> interface, this is always <code>null</code>.Per
166      * the Namespaces in XML Specification an attribute does not inherit
167      * its namespace from the element it is attached to. If an attribute is
168      * not explicitly given a namespace, it simply has no namespace.
169      *
170      * @since DOM Level 2
171      */

172     public String JavaDoc getNamespaceURI() {
173         return (namespaceURI);
174     }
175
176     /**
177      * The name of this node, depending on its type; see the table above.
178      */

179     public String JavaDoc getNodeName() {
180         return (prefix != null && prefix.length() > 0) ?
181                 prefix + ":" + name : name;
182     }
183
184     /**
185      * The value of this node, depending on its type; see the table above.
186      * When it is defined to be <code>null</code>, setting it has no effect.
187      *
188      * @throws org.w3c.dom.DOMException NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
189      * @throws org.w3c.dom.DOMException DOMSTRING_SIZE_ERR: Raised when it would return more characters than
190      * fit in a <code>DOMString</code> variable on the implementation
191      * platform.
192      */

193     public String JavaDoc getNodeValue() throws DOMException JavaDoc {
194         if (textRep == null) {
195             return null;
196         } else {
197             return textRep.getData();
198         }
199     }
200
201     /**
202      * The namespace prefix of this node, or <code>null</code> if it is
203      * unspecified.
204      * <br>Note that setting this attribute, when permitted, changes the
205      * <code>nodeName</code> attribute, which holds the qualified name, as
206      * well as the <code>tagName</code> and <code>name</code> attributes of
207      * the <code>Element</code> and <code>Attr</code> interfaces, when
208      * applicable.
209      * <br>Note also that changing the prefix of an attribute that is known to
210      * have a default value, does not make a new attribute with the default
211      * value and the original prefix appear, since the
212      * <code>namespaceURI</code> and <code>localName</code> do not change.
213      * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
214      * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
215      * method, such as <code>createElement</code> from the
216      * <code>Document</code> interface, this is always <code>null</code>.
217      *
218      * @throws org.w3c.dom.DOMException INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
219      * illegal character, per the XML 1.0 specification .
220      * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
221      * <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is
222      * malformed per the Namespaces in XML specification, if the
223      * <code>namespaceURI</code> of this node is <code>null</code>, if the
224      * specified prefix is "xml" and the <code>namespaceURI</code> of this
225      * node is different from "http://www.w3.org/XML/1998/namespace", if
226      * this node is an attribute and the specified prefix is "xmlns" and
227      * the <code>namespaceURI</code> of this node is different from "
228      * http://www.w3.org/2000/xmlns/", or if this node is an attribute and
229      * the <code>qualifiedName</code> of this node is "xmlns" .
230      * @since DOM Level 2
231      */

232     public String JavaDoc getPrefix() {
233         return (prefix);
234     }
235
236     /**
237      * The value of this node, depending on its type; see the table above.
238      * When it is defined to be <code>null</code>, setting it has no effect.
239      *
240      * @throws org.w3c.dom.DOMException NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
241      * @throws org.w3c.dom.DOMException DOMSTRING_SIZE_ERR: Raised when it would return more characters than
242      * fit in a <code>DOMString</code> variable on the implementation
243      * platform.
244      */

245     public void setNodeValue(String JavaDoc nodeValue) throws DOMException JavaDoc {
246         throw new DOMException JavaDoc(DOMException.NO_DATA_ALLOWED_ERR,
247                 "Cannot use TextNode.set in " + this);
248     }
249
250     /**
251      * The namespace prefix of this node, or <code>null</code> if it is
252      * unspecified.
253      * <br>Note that setting this attribute, when permitted, changes the
254      * <code>nodeName</code> attribute, which holds the qualified name, as
255      * well as the <code>tagName</code> and <code>name</code> attributes of
256      * the <code>Element</code> and <code>Attr</code> interfaces, when
257      * applicable.
258      * <br>Note also that changing the prefix of an attribute that is known to
259      * have a default value, does not make a new attribute with the default
260      * value and the original prefix appear, since the
261      * <code>namespaceURI</code> and <code>localName</code> do not change.
262      * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
263      * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
264      * method, such as <code>createElement</code> from the
265      * <code>Document</code> interface, this is always <code>null</code>.
266      *
267      * @throws org.w3c.dom.DOMException INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
268      * illegal character, per the XML 1.0 specification .
269      * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
270      * <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is
271      * malformed per the Namespaces in XML specification, if the
272      * <code>namespaceURI</code> of this node is <code>null</code>, if the
273      * specified prefix is "xml" and the <code>namespaceURI</code> of this
274      * node is different from "http://www.w3.org/XML/1998/namespace", if
275      * this node is an attribute and the specified prefix is "xmlns" and
276      * the <code>namespaceURI</code> of this node is different from "
277      * http://www.w3.org/2000/xmlns/", or if this node is an attribute and
278      * the <code>qualifiedName</code> of this node is "xmlns" .
279      * @since DOM Level 2
280      */

281     public void setPrefix(String JavaDoc prefix) {
282         this.prefix = prefix;
283     }
284
285     /**
286      * Set the owner document
287      *
288      * @param doc
289      */

290     public void setOwnerDocument(Document JavaDoc doc) {
291         document = doc;
292     }
293
294     /**
295      * The <code>Document</code> object associated with this node. This is
296      * also the <code>Document</code> object used to create new nodes. When
297      * this node is a <code>Document</code> or a <code>DocumentType</code>
298      * which is not used with any <code>Document</code> yet, this is
299      * <code>null</code>.
300      */

301     public Document JavaDoc getOwnerDocument() {
302         if(document == null) {
303             NodeImpl node = getParent();
304             if (node != null) {
305               return node.getOwnerDocument();
306             }
307         }
308         return document;
309     }
310
311     /**
312      * A <code>NamedNodeMap</code> containing the attributes of this node (if
313      * it is an <code>Element</code>) or <code>null</code> otherwise.
314      */

315     public NamedNodeMap JavaDoc getAttributes() {
316         // make first it is editable.
317
makeAttributesEditable();
318         return convertAttrSAXtoDOM(attributes);
319     }
320
321     /**
322      * The first child of this node. If there is no such node, this returns
323      * <code>null</code>.
324      */

325     public Node JavaDoc getFirstChild() {
326         if (children != null && !children.isEmpty()) {
327             return (Node JavaDoc) children.get(0);
328         } else {
329             return null;
330         }
331     }
332
333     /**
334      * The last child of this node. If there is no such node, this returns
335      * <code>null</code>.
336      */

337     public Node JavaDoc getLastChild() {
338         if (children != null && !children.isEmpty()) {
339             return (Node JavaDoc) children.get(children.size() - 1);
340         } else {
341             return null;
342         }
343     }
344
345     /**
346      * The node immediately following this node. If there is no such node,
347      * this returns <code>null</code>.
348      */

349     public Node JavaDoc getNextSibling() {
350         SOAPElement JavaDoc parent = getParentElement();
351         if (parent == null) {
352             return null;
353         }
354         Iterator JavaDoc iter = parent.getChildElements();
355         Node JavaDoc nextSibling = null;
356         while (iter.hasNext()) {
357             if (iter.next() == this) {
358                 if (iter.hasNext()) {
359                     return (Node JavaDoc) iter.next();
360                 } else {
361                     return null;
362                 }
363             }
364         }
365         return nextSibling; // should be null.
366
}
367
368     /**
369      * The parent of this node. All nodes, except <code>Attr</code>,
370      * <code>Document</code>, <code>DocumentFragment</code>,
371      * <code>Entity</code>, and <code>Notation</code> may have a parent.
372      * However, if a node has just been created and not yet added to the
373      * tree, or if it has been removed from the tree, this is
374      * <code>null</code>.
375      */

376     public Node JavaDoc getParentNode() {
377         return (Node JavaDoc) getParent();
378     }
379
380     /**
381      * The node immediately preceding this node. If there is no such node,
382      * this returns <code>null</code>.
383      */

384     public Node JavaDoc getPreviousSibling() {
385         SOAPElement JavaDoc parent = getParentElement();
386         if (parent == null) {
387             return null;
388         }
389         NodeList JavaDoc nl = parent.getChildNodes();
390         int len = nl.getLength();
391         int i = 0;
392         Node JavaDoc previousSibling = null;
393         while (i < len) {
394             if (nl.item(i) == this) {
395                 return previousSibling;
396             }
397             previousSibling = nl.item(i);
398             i++;
399         }
400         return previousSibling; // should be null.
401
}
402
403     /**
404      * Returns a duplicate of this node, i.e., serves as a generic copy
405      * constructor for nodes. The duplicate node has no parent; (
406      * <code>parentNode</code> is <code>null</code>.).
407      * <br>Cloning an <code>Element</code> copies all attributes and their
408      * values, including those generated by the XML processor to represent
409      * defaulted attributes, but this method does not copy any text it
410      * contains unless it is a deep clone, since the text is contained in a
411      * child <code>Text</code> node. Cloning an <code>Attribute</code>
412      * directly, as opposed to be cloned as part of an <code>Element</code>
413      * cloning operation, returns a specified attribute (
414      * <code>specified</code> is <code>true</code>). Cloning any other type
415      * of node simply returns a copy of this node.
416      * <br>Note that cloning an immutable subtree results in a mutable copy,
417      * but the children of an <code>EntityReference</code> clone are readonly
418      * . In addition, clones of unspecified <code>Attr</code> nodes are
419      * specified. And, cloning <code>Document</code>,
420      * <code>DocumentType</code>, <code>Entity</code>, and
421      * <code>Notation</code> nodes is implementation dependent.
422      *
423      * @param deep If <code>true</code>, recursively clone the subtree under
424      * the specified node; if <code>false</code>, clone only the node
425      * itself (and its attributes, if it is an <code>Element</code>).
426      * @return The duplicate node.
427      */

428     public Node JavaDoc cloneNode(boolean deep) {
429         return new NodeImpl(textRep);
430     }
431
432     /**
433      * A <code>NodeList</code> that contains all children of this node. If
434      * there are no children, this is a <code>NodeList</code> containing no
435      * nodes.
436      */

437     public NodeList JavaDoc getChildNodes() {
438         if (children == null) {
439             return NodeListImpl.EMPTY_NODELIST;
440         } else {
441             return new NodeListImpl(children);
442         }
443     }
444
445     /**
446      * Tests whether the DOM implementation implements a specific feature and
447      * that feature is supported by this node.
448      *
449      * @param feature The name of the feature to test. This is the same name
450      * which can be passed to the method <code>hasFeature</code> on
451      * <code>DOMImplementation</code>.
452      * @param version This is the version number of the feature to test. In
453      * Level 2, version 1, this is the string "2.0". If the version is not
454      * specified, supporting any version of the feature will cause the
455      * method to return <code>true</code>.
456      * @return Returns <code>true</code> if the specified feature is
457      * supported on this node, <code>false</code> otherwise.
458      * @since DOM Level 2
459      */

460     public boolean isSupported(String JavaDoc feature, String JavaDoc version) {
461         return false; //TODO: Fix this for SAAJ 1.2 Implementation
462
}
463
464     /**
465      * Adds the node <code>newChild</code> to the end of the list of children
466      * of this node. If the <code>newChild</code> is already in the tree, it
467      * is first removed.
468      *
469      * @param newChild The node to add.If it is a
470      * <code>DocumentFragment</code> object, the entire contents of the
471      * document fragment are moved into the child list of this node
472      * @return The node added.
473      * @throws org.w3c.dom.DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
474      * allow children of the type of the <code>newChild</code> node, or if
475      * the node to append is one of this node's ancestors or this node
476      * itself.
477      * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
478      * from a different document than the one that created this node.
479      * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or
480      * if the previous parent of the node being inserted is readonly.
481      *
482      */

483     public Node JavaDoc appendChild(Node JavaDoc newChild) throws DOMException JavaDoc {
484         if (newChild == null) {
485             throw new DOMException JavaDoc
486                     (DOMException.HIERARCHY_REQUEST_ERR,
487                             "Can't append a null node.");
488         }
489         initializeChildren();
490         // per DOM spec - must remove from tree. If newChild.parent == null,
491
// detachNode() does nothing. So this shouldn't hurt performace of
492
// serializers.
493
((NodeImpl) newChild).detachNode();
494         children.add(newChild);
495         ((NodeImpl) newChild).parent = this;
496         setDirty(true);
497         return newChild;
498     }
499
500     /**
501      * Removes the child node indicated by <code>oldChild</code> from the list
502      * of children, and returns it.
503      *
504      * @param oldChild The node being removed.
505      * @return The node removed.
506      * @throws org.w3c.dom.DOMException NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
507      * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
508      * this node.
509      */

510     public Node JavaDoc removeChild(Node JavaDoc oldChild) throws DOMException JavaDoc {
511         if (removeNodeFromChildList((NodeImpl) oldChild)) {
512             setDirty(true);
513             return oldChild;
514         }
515         throw new DOMException JavaDoc(DOMException.NOT_FOUND_ERR,
516                 "NodeImpl Not found");
517     }
518
519     private boolean removeNodeFromChildList(NodeImpl n) {
520         boolean removed = false;
521         initializeChildren();
522         final Iterator JavaDoc itr = children.iterator();
523         while (itr.hasNext()) {
524             final NodeImpl node = (NodeImpl) itr.next();
525             if (node == n) {
526                 removed = true;
527                 itr.remove();
528             }
529         }
530         return removed;
531     }
532
533     /**
534      * Inserts the node <code>newChild</code> before the existing child node
535      * <code>refChild</code>. If <code>refChild</code> is <code>null</code>,
536      * insert <code>newChild</code> at the end of the list of children.
537      * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
538      * all of its children are inserted, in the same order, before
539      * <code>refChild</code>. If the <code>newChild</code> is already in the
540      * tree, it is first removed.
541      *
542      * @param newChild The node to insert.
543      * @param refChild The reference node, i.e., the node before which the
544      * new node must be inserted.
545      * @return The node being inserted.
546      * @throws org.w3c.dom.DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
547      * allow children of the type of the <code>newChild</code> node, or if
548      * the node to insert is one of this node's ancestors or this node
549      * itself.
550      * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
551      * from a different document than the one that created this node.
552      * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or
553      * if the parent of the node being inserted is readonly.
554      * <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of
555      * this node.
556      */

557     public Node JavaDoc insertBefore(Node JavaDoc newChild, Node JavaDoc refChild) throws DOMException JavaDoc {
558         initializeChildren();
559         int position = children.indexOf(refChild);
560         if (position < 0) {
561             position = 0;
562         }
563         children.add(position, newChild);
564         setDirty(true);
565         return newChild;
566     }
567
568     /**
569      * Replaces the child node <code>oldChild</code> with <code>newChild</code>
570      * in the list of children, and returns the <code>oldChild</code> node.
571      * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
572      * <code>oldChild</code> is replaced by all of the
573      * <code>DocumentFragment</code> children, which are inserted in the
574      * same order. If the <code>newChild</code> is already in the tree, it
575      * is first removed.
576      *
577      * @param newChild The new node to put in the child list.
578      * @param oldChild The node being replaced in the list.
579      * @return The node replaced.
580      * @throws org.w3c.dom.DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
581      * allow children of the type of the <code>newChild</code> node, or if
582      * the node to put in is one of this node's ancestors or this node
583      * itself.
584      * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
585      * from a different document than the one that created this node.
586      * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of
587      * the new node is readonly.
588      * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
589      * this node.
590      */

591     public Node JavaDoc replaceChild(Node JavaDoc newChild, Node JavaDoc oldChild) throws DOMException JavaDoc {
592         initializeChildren();
593         int position = children.indexOf(oldChild);
594         if (position < 0) {
595             throw new DOMException JavaDoc(DOMException.NOT_FOUND_ERR,
596                     "NodeImpl Not found");
597         }
598         children.remove(position);
599         children.add(position, newChild);
600         setDirty(true);
601         return oldChild;
602     }
603
604     /**
605      * Returns the the value of the immediate child of this <code>Node</code>
606      * object if a child exists and its value is text.
607      *
608      * @return a <code>String</code> with the text of the immediate child of
609      * this <code>Node</code> object if (1) there is a child and
610      * (2) the child is a <code>Text</code> object;
611      * <code>null</code> otherwise
612      */

613     public String JavaDoc getValue() {
614         return textRep.getNodeValue();
615     }
616
617     /**
618      * Sets the parent of this <code>Node</code> object to the given
619      * <code>SOAPElement</code> object.
620      *
621      * @param parent the <code>SOAPElement</code> object to be set as
622      * the parent of this <code>Node</code> object
623      * @throws javax.xml.soap.SOAPException if there is a problem in setting the
624      * parent to the given element
625      * @see #getParentElement() getParentElement()
626      */

627     public void setParentElement(SOAPElement JavaDoc parent) throws SOAPException JavaDoc {
628         if (parent == null)
629             throw new IllegalArgumentException JavaDoc(
630                     Messages.getMessage("nullParent00"));
631         try {
632             setParent((NodeImpl) parent);
633         } catch (Throwable JavaDoc t) {
634             throw new SOAPException JavaDoc(t);
635         }
636     }
637
638     /**
639      * Returns the parent element of this <code>Node</code> object.
640      * This method can throw an <code>UnsupportedOperationException</code>
641      * if the tree is not kept in memory.
642      *
643      * @return the <code>SOAPElement</code> object that is the parent of
644      * this <code>Node</code> object or <code>null</code> if this
645      * <code>Node</code> object is root
646      * @throws UnsupportedOperationException if the whole tree is not kept in memory
647      * @see #setParentElement(javax.xml.soap.SOAPElement) setParentElement(javax.xml.soap.SOAPElement)
648      */

649     public SOAPElement JavaDoc getParentElement() {
650         return (SOAPElement JavaDoc) getParent();
651     }
652
653     /**
654      * Removes this <code>Node</code> object from the tree. Once
655      * removed, this node can be garbage collected if there are no
656      * application references to it.
657      */

658     public void detachNode() {
659         if (parent != null) {
660             parent.removeChild(this);
661             parent = null;
662         }
663     }
664
665     /**
666      * Notifies the implementation that this <code>Node</code>
667      * object is no longer being used by the application and that the
668      * implementation is free to reuse this object for nodes that may
669      * be created later.
670      * <P>
671      * Calling the method <code>recycleNode</code> implies that the method
672      * <code>detachNode</code> has been called previously.
673      */

674     public void recycleNode() {
675         //TODO: Fix this for SAAJ 1.2 Implementation
676
}
677
678     /**
679      * If this is a Text node then this method will set its value, otherwise it
680      * sets the value of the immediate (Text) child of this node. The value of
681      * the immediate child of this node can be set only if, there is one child
682      * node and that node is a Text node, or if there are no children in which
683      * case a child Text node will be created.
684      *
685      * @param value the text to set
686      * @throws IllegalStateException if the node is not a Text node and
687      * either has more than one child node or has a child node that
688      * is not a Text node
689      */

690     public void setValue(String JavaDoc value) {
691         if (this instanceof org.apache.axis.message.Text) {
692             setNodeValue(value);
693         } else if (children != null) {
694             if (children.size() != 1) {
695                 throw new IllegalStateException JavaDoc( "setValue() may not be called on a non-Text node with more than one child." );
696             }
697             javax.xml.soap.Node JavaDoc child = (javax.xml.soap.Node JavaDoc) children.get(0);
698             if (!(child instanceof org.apache.axis.message.Text)) {
699                 throw new IllegalStateException JavaDoc( "setValue() may not be called on a non-Text node with a non-Text child." );
700             }
701             ((javax.xml.soap.Text JavaDoc)child).setNodeValue(value);
702         } else {
703             appendChild(new org.apache.axis.message.Text(value));
704         }
705     }
706
707     /**
708      * make the attributes editable
709      *
710      * @return AttributesImpl
711      */

712     protected AttributesImpl JavaDoc makeAttributesEditable() {
713         if (attributes == null || attributes instanceof NullAttributes) {
714             attributes = new AttributesImpl JavaDoc();
715         } else if (!(attributes instanceof AttributesImpl JavaDoc)) {
716             attributes = new AttributesImpl JavaDoc(attributes);
717         }
718         return (AttributesImpl JavaDoc) attributes;
719     }
720
721     /**
722      * The internal representation of Attributes cannot help being changed
723      * It is because Attribute is not immutible Type, so if we keep out value and
724      * just return it in another form, the application may chnae it, which we cannot
725      * detect without some kind back track method (call back notifying the chnage.)
726      * I am not sure which approach is better.
727      */

728     protected NamedNodeMap JavaDoc convertAttrSAXtoDOM(Attributes JavaDoc saxAttr) {
729         try {
730             org.w3c.dom.Document JavaDoc doc = org.apache.axis.utils.XMLUtils.newDocument();
731             AttributesImpl JavaDoc saxAttrs = (AttributesImpl JavaDoc) saxAttr;
732             NamedNodeMap JavaDoc domAttributes = new NamedNodeMapImpl();
733             for (int i = 0; i < saxAttrs.getLength(); i++) {
734                 String JavaDoc uri = saxAttrs.getURI(i);
735                 String JavaDoc qname = saxAttrs.getQName(i);
736                 String JavaDoc value = saxAttrs.getValue(i);
737                 if (uri != null && uri.trim().length() > 0) {
738                     // filterring out the tricky method to differentiate the null namespace
739
// -ware case
740
if (NULL_URI_NAME.equals(uri)) {
741                         uri = null;
742                     }
743                     Attr JavaDoc attr = doc.createAttributeNS(uri, qname);
744                     attr.setValue(value);
745                     domAttributes.setNamedItemNS(attr);
746                 } else {
747                     Attr JavaDoc attr = doc.createAttribute(qname);
748                     attr.setValue(value);
749                     domAttributes.setNamedItem(attr);
750                 }
751             }
752             return domAttributes;
753         } catch (Exception JavaDoc ex) {
754             log.error(Messages.getMessage("saxToDomFailed00"),ex);
755
756             return null;
757         }
758     }
759
760     /**
761      * Initialize the children array
762      */

763     protected void initializeChildren() {
764         if (children == null) {
765             children = new ArrayList JavaDoc();
766         }
767     }
768
769     /**
770      * get the parent node
771      * @return parent node
772      */

773     protected NodeImpl getParent() {
774         return parent;
775     }
776
777     /**
778      * Set the parent node and invoke appendChild(this) to
779      * add this node to the parent's list of children.
780      * @param parent
781      * @throws SOAPException
782      */

783     protected void setParent(NodeImpl parent) throws SOAPException JavaDoc {
784         if (this.parent == parent) {
785             return;
786         }
787         if (this.parent != null) {
788             this.parent.removeChild(this);
789         }
790         if (parent != null) {
791             parent.appendChild(this);
792         }
793         this.parent = parent;
794     }
795
796     /**
797      * print the contents of this node
798      * @param context
799      * @throws Exception
800      */

801     public void output(SerializationContext context) throws Exception JavaDoc {
802         if (textRep == null)
803             return;
804         boolean oldPretty = context.getPretty();
805         context.setPretty(false);
806         if (textRep instanceof CDATASection JavaDoc) {
807             context.writeString("<![CDATA[");
808             context.writeString(((org.w3c.dom.Text JavaDoc) textRep).getData());
809             context.writeString("]]>");
810         } else if (textRep instanceof Comment JavaDoc) {
811             context.writeString("<!--");
812             context.writeString(((CharacterData JavaDoc) textRep).getData());
813             context.writeString("-->");
814         } else if (textRep instanceof Text) {
815             context.writeSafeString(((Text) textRep).getData());
816         }
817         context.setPretty(oldPretty);
818     }
819
820     /**
821      * get the dirty bit
822      * @return
823      */

824     public boolean isDirty() {
825         return _isDirty;
826     }
827
828     /**
829      * set the dirty bit. will also set our parent as dirty, if there is one.
830      * Note that clearing the dirty bit does <i>not</i> propagate upwards.
831      * @param dirty new value of the dirty bit
832      */

833     public void setDirty(boolean dirty)
834     {
835         _isDirty = dirty;
836         if (_isDirty && parent != null) {
837             ((NodeImpl) parent).setDirty(true);
838         }
839     }
840 }
841
Popular Tags