]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/document/DOMXMLElement.java
remove mediastreamer2 and add it as a submodule instead.
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / document / DOMXMLElement.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56
57 package net.jxta.impl.document;
58
59
60 import net.jxta.document.Attribute;
61 import net.jxta.document.XMLElement;
62
63 import org.w3c.dom.Element;
64 import org.w3c.dom.NamedNodeMap;
65 import org.w3c.dom.Node;
66
67 import java.util.ArrayList;
68 import java.util.Collections;
69 import java.util.Enumeration;
70 import java.util.List;
71
72
73 /**
74  * This class represent an element of an XML document. XML Documents are formed
75  * as a hierarchy of elements. Each element provides a proxy for DOM elements
76  * and the text nodes containing values.
77  */
78 public class DOMXMLElement implements XMLElement<DOMXMLElement> {
79
80     protected DOMXMLDocument root;
81
82     /**
83      * The DOM node for which this element is a proxy.
84      */
85     protected Node domNode;
86
87     /**
88      * Constructor for associating a DOM node with a StructuredDocument Element.
89      *
90      * @param root the DOM not which is to be associated with this element.
91      * @param node the DOM node
92      */
93     protected DOMXMLElement(DOMXMLDocument root, Node node) {
94         this.root = root;
95         domNode = node;
96     }
97
98     /**
99      * Get the name associated with an element.
100      *
101      * @return A string containing the key of this element.
102      */
103     public String getKey() {
104         return getName();
105     }
106
107     /**
108      * Get the value (if any) associated with an element.
109      *
110      * @return A string containing the value of this element, if any, otherwise null.
111      */
112     public String getValue() {
113         return getTextValue();
114     }
115
116     /**
117      * Get the name associated with an element.
118      *
119      * @return A string containing the name of this element.
120      */
121     public String getName() {
122         return getAssocNode().getNodeName();
123     }
124
125     /**
126      * Get the value (if any) associated with an element.
127      *
128      * @return A string containing the value of this element, if any, otherwise null.
129      */
130     public String getTextValue() {
131         StringBuilder itsValue = new StringBuilder();
132         
133         for (Node eachChild = getAssocNode().getFirstChild(); eachChild != null; eachChild = eachChild.getNextSibling()) {
134             if (Node.TEXT_NODE == eachChild.getNodeType()) {
135                 itsValue.append(eachChild.getNodeValue());
136             }
137         }
138
139         if (0 == itsValue.length()) {
140             return null;
141         } else {
142             return itsValue.toString();
143         }
144     }
145
146     /**
147      * Get the root element of the hierarchy this element belongs to.
148      *
149      * @return StructuredDocument root of this element's hierarchy.
150      */
151     public DOMXMLDocument getRoot() {
152         return root;
153     }
154
155     /**
156      * Get the parent of this element. If the element has not been inserted into
157      * the Document then null is returned. If this element is the root of the
158      * Document then it returns itself.
159      */
160     public DOMXMLElement getParent() {
161         Node node = getAssocNode();
162
163         if (node.getOwnerDocument().equals(node)) {
164             return new DOMXMLElement(root, node);
165         } else {
166             return new DOMXMLElement(root, node.getParentNode());
167         }
168     }
169
170     /**
171      * Add a child element to this element
172      *
173      * @param element the element to be added as a child
174      */
175     public void appendChild(DOMXMLElement element) {
176         getAssocNode().appendChild(element.getAssocNode());
177     }
178
179     /**
180      * Returns an enumeration of the immediate children of this element
181      *
182      * @return An enumeration containing all of the children of this element.
183      */
184     public Enumeration<DOMXMLElement> getChildren() {
185         List<DOMXMLElement> children = new ArrayList<DOMXMLElement>();
186
187         for (Node eachChild = getAssocNode().getFirstChild(); eachChild != null; eachChild = eachChild.getNextSibling()) {
188             if (Node.ELEMENT_NODE == eachChild.getNodeType()) {
189                 children.add(new DOMXMLElement(root, eachChild));
190             }
191         }
192
193         return Collections.enumeration(children);
194     }
195
196     /**
197      * Returns an enumeration of the immediate children of this element whose
198      * name match the specified string.
199      *
200      * @param key The key which will be matched against.
201      * @return enumeration containing all of the children of this element.
202      */
203     public Enumeration<DOMXMLElement> getChildren(Object key) {
204         if (key instanceof String)
205             return getChildren((String) key);
206         else
207             throw new ClassCastException(key.getClass().getName() + " not supported by getChildren.");
208     }
209
210     /**
211      * Returns an enumeration of the immediate children of this element whose
212      * name match the specified string.
213      *
214      * @param name The name which will be matched against.
215      * @return An enumeration containing all of the children of this element.
216      */
217     public Enumeration<DOMXMLElement> getChildren(String name) {
218         List<DOMXMLElement> children = new ArrayList<DOMXMLElement>();
219
220         for (Node eachChild = getAssocNode().getFirstChild(); eachChild != null; eachChild = eachChild.getNextSibling()) {
221             if ((Node.ELEMENT_NODE == eachChild.getNodeType()) && (name.equals(eachChild.getNodeName()))) {
222                 children.add(new DOMXMLElement(root, eachChild));
223             }
224         }
225
226         return Collections.enumeration(children);
227     }
228
229     /**
230      * Tests two elements for equality. For the XML document the definition of
231      * equality is:
232      * <p/>
233      * <p/><ul>
234      * <li>the item compared against must be an XML Element.</li>
235      * <p/>
236      * <li>The items must belong to the same document.</li>
237      * <p/>
238      * <li>The items must have the same name.</li>
239      * <p/>
240      * <li>The items must have the save textual value.</li>
241      * </ul>
242      *
243      * @param element the element to be compared against.
244      * @return true if the elements are equal
245      */
246     @Override
247     public boolean equals(Object element) {
248         if (this == element) {
249             return true;
250         }
251
252         if (!(element instanceof DOMXMLElement)) {
253             return false;
254         }
255
256         DOMXMLElement xmlElement = (DOMXMLElement) element;
257
258         Node me = getAssocNode();
259         Node it = xmlElement.getAssocNode();
260
261         if (me == it) {
262             return true;
263         }
264
265         if (me.getOwnerDocument() != it.getOwnerDocument()) {
266             return false;
267         }
268
269         if (!getName().equals(xmlElement.getName())) {
270             return false;
271         }
272
273         String val1 = getTextValue();
274         String val2 = xmlElement.getTextValue();
275
276         return (null == val1) && (null == val2) || null != val1 && null != val2 && val1.equals(val2);
277
278     }
279
280     /**
281      * Returns the DOM Node associated with this StructuredDocument element.
282      *
283      * @return Node    The DOM Node associated with this StructuredDocument element.
284      */
285     protected Node getAssocNode() {
286         return domNode;
287     }
288
289     // Attributable methods
290
291     /**
292      * Adds an attribute with the given name and value. Some implementations
293      * may support only a single value for each distinct name. Others may
294      * support multiple values for each name. If the value being provided
295      * replaces some other value then that value is returned otherwise null
296      * is returned.
297      *
298      * @param name  name of the attribute.
299      * @param value value for the attribute.
300      * @return String  containing previous value for this name if the value
301      *         is being replaced otherwise null.
302      */
303     public String addAttribute(String name, String value) {
304         String oldAttrValue = ((Element) getAssocNode()).getAttribute(name);
305
306         ((Element) getAssocNode()).setAttribute(name, value);
307         return (0 == oldAttrValue.length()) ? null : oldAttrValue;
308     }
309
310     /**
311      * Adds an attribute with the given name and value. Some implementations
312      * may support only a single value for each distinct name. Others may
313      * support multiple values for each name. If the value being provided
314      * replaces some other value then that value is returned otherwise null
315      * is returned.
316      *
317      * @param newAttrib new attribute.
318      * @return String  containing previous value for this name if the value
319      *         is being replaced otherwise null.
320      */
321     public String addAttribute(Attribute newAttrib) {
322         String oldAttrValue = ((Element) getAssocNode()).getAttribute(newAttrib.getName());
323
324         ((Element) getAssocNode()).setAttribute(newAttrib.getName(), newAttrib.getValue());
325         return (0 == oldAttrValue.length()) ? null : oldAttrValue;
326     }
327
328     /**
329      * Returns an enumerations of the attributes assosicated with this object.
330      * Each element is of type Attribute.
331      *
332      * @return Enumeration the attributes associated with this object.
333      */
334     public Enumeration<Attribute> getAttributes() {
335         NamedNodeMap nmap = getAssocNode().getAttributes();
336
337         if (nmap == null) {
338             List<Attribute> noAttrs = Collections.emptyList();
339
340             return Collections.enumeration(noAttrs);
341         }
342
343         List<Attribute> attrs = new ArrayList<Attribute>();
344
345         for (int i = 0; i < nmap.getLength(); i++) {
346             Node domAttr = nmap.item(i);
347             Attribute attr = new Attribute(this, domAttr.getNodeName(), domAttr.getNodeValue());
348
349             attrs.add(attr);
350         }
351
352         return Collections.enumeration(attrs);
353     }
354
355     /**
356      * returns a single attribute which matches the name provided. If no such
357      * named attribute exists then null is returned. For impelementations of
358      * this interface which support multiple values for each name only the
359      * first value will be returned. To access all values for a name you must
360      * use getAttributes.
361      *
362      * @return Attribute the attributes matching the given name.
363      */
364     public Attribute getAttribute(String name) {
365         NamedNodeMap nmap = (getAssocNode()).getAttributes();
366
367         if (nmap == null) {
368             return null;
369         }
370
371         for (int i = 0; i < nmap.getLength(); i++) {
372             Node domAttr = nmap.item(i);
373
374             if (name.equals(domAttr.getNodeName())) {
375                 Attribute attr = new Attribute(this, domAttr.getNodeName(), domAttr.getNodeValue());
376
377                 return attr;
378             }
379         }
380
381         return null;
382     }
383 }