View Javadoc

1   /*
2    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    *
7    * $Id: DOMElement.java,v 1.21 2004/06/25 08:03:35 maartenc Exp $
8    */
9   
10  package org.dom4j.dom;
11  
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import org.dom4j.Attribute;
16  import org.dom4j.DocumentFactory;
17  import org.dom4j.Namespace;
18  import org.dom4j.QName;
19  import org.dom4j.tree.DefaultElement;
20  import org.w3c.dom.DOMException;
21  import org.w3c.dom.Document;
22  import org.w3c.dom.NamedNodeMap;
23  import org.w3c.dom.Node;
24  import org.w3c.dom.NodeList;
25  
26  /*** <p><code>DOMElement</code> implements an XML element which
27    * supports the W3C DOM API.</p>
28    *
29    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
30    * @version $Revision: 1.21 $
31    */
32  public class DOMElement extends DefaultElement implements org.w3c.dom.Element {
33  
34      /*** The <code>DocumentFactory</code> instance used by default */
35      private static final DocumentFactory DOCUMENT_FACTORY = DOMDocumentFactory.getInstance();
36  
37  
38      public DOMElement(String name) {
39          super(name);
40      }
41  
42      public DOMElement(QName qname) {
43          super(qname);
44      }
45  
46      public DOMElement(QName qname, int attributeCount) {
47          super(qname, attributeCount);
48      }
49  
50      public DOMElement(String name, Namespace namespace) {
51          super(name, namespace);
52      }
53  
54  
55  
56      // org.w3c.dom.Node interface
57      //-------------------------------------------------------------------------
58      public boolean supports(String feature, String version) {
59          return DOMNodeHelper.supports(this, feature, version);
60      }
61  
62      public String getNamespaceURI() {
63          return getQName().getNamespaceURI();
64      }
65  
66      public String getPrefix() {
67          return getQName().getNamespacePrefix();
68      }
69  
70      public void setPrefix(String prefix) throws DOMException {
71          DOMNodeHelper.setPrefix(this, prefix);
72      }
73  
74      public String getLocalName() {
75          return getQName().getName();
76      }
77  
78      public String getNodeName() {
79          return getName();
80      }
81  
82      //already part of API
83      //
84      //public short getNodeType();
85  
86  
87  
88      public String getNodeValue() throws DOMException {
89          return null;
90      }
91  
92      public void setNodeValue(String nodeValue) throws DOMException {
93      }
94  
95  
96      public org.w3c.dom.Node getParentNode() {
97          return DOMNodeHelper.getParentNode(this);
98      }
99  
100     public NodeList getChildNodes() {
101         return DOMNodeHelper.createNodeList( content() );
102     }
103 
104     public org.w3c.dom.Node getFirstChild() {
105         return DOMNodeHelper.asDOMNode( node(0) );
106     }
107 
108     public org.w3c.dom.Node getLastChild() {
109         return DOMNodeHelper.asDOMNode( node( nodeCount() - 1 ) );
110     }
111 
112     public org.w3c.dom.Node getPreviousSibling() {
113         return DOMNodeHelper.getPreviousSibling(this);
114     }
115 
116     public org.w3c.dom.Node getNextSibling() {
117         return DOMNodeHelper.getNextSibling(this);
118     }
119 
120     public NamedNodeMap getAttributes() {
121         return new DOMAttributeNodeMap( this );
122     }
123 
124     public Document getOwnerDocument() {
125         return DOMNodeHelper.getOwnerDocument(this);
126     }
127 
128     public org.w3c.dom.Node insertBefore(
129         org.w3c.dom.Node newChild,
130         org.w3c.dom.Node refChild
131     ) throws DOMException {
132         checkNewChildNode(newChild);
133         return DOMNodeHelper.insertBefore(this, newChild, refChild);
134     }
135 
136     public org.w3c.dom.Node replaceChild(
137         org.w3c.dom.Node newChild,
138         org.w3c.dom.Node oldChild
139     ) throws DOMException {
140         checkNewChildNode(newChild);
141         return DOMNodeHelper.replaceChild(this, newChild, oldChild);
142     }
143 
144     public org.w3c.dom.Node removeChild(org.w3c.dom.Node oldChild) throws DOMException {
145         return DOMNodeHelper.removeChild(this, oldChild);
146     }
147 
148     public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild) throws DOMException {
149         checkNewChildNode(newChild);
150         return DOMNodeHelper.appendChild(this, newChild);
151     }
152     
153     private void checkNewChildNode(org.w3c.dom.Node newChild) throws DOMException {
154         final int nodeType = newChild.getNodeType();
155         if (!(nodeType == Node.ELEMENT_NODE ||
156               nodeType == Node.TEXT_NODE ||
157               nodeType == Node.COMMENT_NODE ||
158               nodeType == Node.PROCESSING_INSTRUCTION_NODE ||
159               nodeType == Node.CDATA_SECTION_NODE ||
160               nodeType == Node.ENTITY_REFERENCE_NODE)) {
161             throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
162                "Specified node cannot be a child of element");
163         }
164     }
165 
166     public boolean hasChildNodes() {
167         return nodeCount() > 0;
168     }
169 
170     public org.w3c.dom.Node cloneNode(boolean deep) {
171         return DOMNodeHelper.cloneNode(this, deep);
172     }
173 
174     public boolean isSupported(String feature, String version) {
175         return DOMNodeHelper.isSupported(this, feature, version);
176     }
177 
178     public boolean hasAttributes() {
179         return DOMNodeHelper.hasAttributes(this);
180     }
181 
182 
183     // org.w3c.dom.Element interface
184     //-------------------------------------------------------------------------
185     public String getTagName() {
186         return getName();
187     }
188 
189     public String getAttribute(String name) {
190         String answer = attributeValue(name);
191         return (answer != null) ? answer : "";
192     }
193 
194     public void setAttribute(String name, String value) throws DOMException {
195         addAttribute(name, value);
196     }
197 
198     public void removeAttribute(String name) throws DOMException {
199         Attribute attribute = attribute(name);
200         if ( attribute != null ) {
201             remove(attribute);
202         }
203     }
204 
205     public org.w3c.dom.Attr getAttributeNode(String name) {
206         return DOMNodeHelper.asDOMAttr( attribute( name ) );
207     }
208 
209     public org.w3c.dom.Attr setAttributeNode(org.w3c.dom.Attr newAttr) throws DOMException {
210         if (this.isReadOnly()) {
211            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
212               "No modification allowed");
213         }
214         Attribute attribute = attribute(newAttr);
215         if (attribute != newAttr) {
216           if (newAttr.getOwnerElement() != null) {
217                 throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR,
218                    "Attribute is already in use");
219           }
220           Attribute newAttribute = createAttribute(newAttr);
221           if (attribute != null) {
222             attribute.detach();
223           }
224           add(newAttribute);
225         }
226         return DOMNodeHelper.asDOMAttr(attribute);
227     }
228 
229     public org.w3c.dom.Attr removeAttributeNode(org.w3c.dom.Attr oldAttr) throws DOMException {
230         Attribute attribute = attribute(oldAttr);
231         if ( attribute != null ) {
232             attribute.detach();
233             return DOMNodeHelper.asDOMAttr( attribute );
234         }
235         else {
236             throw new DOMException(
237                 DOMException.NOT_FOUND_ERR,
238                 "No such attribute"
239             );
240         }
241     }
242 
243     public String getAttributeNS(String namespaceURI,  String localName) {
244         Attribute attribute = attribute( namespaceURI, localName );
245         if ( attribute != null ) {
246             String answer = attribute.getValue();
247             if ( answer != null ) {
248                 return answer;
249             }
250         }
251         return "";
252     }
253 
254     public void setAttributeNS(
255         String namespaceURI,
256         String qualifiedName,
257         String value
258     ) throws DOMException {
259         Attribute attribute = attribute( namespaceURI, qualifiedName );
260         if ( attribute != null ) {
261             attribute.setValue(value);
262         }
263         else {
264             QName qname = getQName( namespaceURI, qualifiedName );
265             addAttribute( qname, value );
266         }
267     }
268 
269     public void removeAttributeNS(
270         String namespaceURI,
271         String localName
272     ) throws DOMException {
273         Attribute attribute = attribute( namespaceURI, localName );
274         if ( attribute != null ) {
275             remove( attribute );
276         }
277     }
278 
279     public org.w3c.dom.Attr getAttributeNodeNS(String namespaceURI,  String localName) {
280         Attribute attribute = attribute( namespaceURI, localName );
281         if ( attribute != null ) {
282             DOMNodeHelper.asDOMAttr( attribute );
283         }
284         return null;
285     }
286 
287     public org.w3c.dom.Attr setAttributeNodeNS(org.w3c.dom.Attr newAttr) throws DOMException {
288         Attribute attribute = attribute(
289             newAttr.getNamespaceURI(), newAttr.getLocalName()
290         );
291         if ( attribute != null ) {
292             attribute.setValue( newAttr.getValue() );
293         }
294         else {
295             attribute = createAttribute( newAttr );
296             add( attribute );
297         }
298         return DOMNodeHelper.asDOMAttr( attribute );
299     }
300 
301     public NodeList getElementsByTagName(String name) {
302         ArrayList list = new ArrayList();
303         DOMNodeHelper.appendElementsByTagName( list, this, name );
304         return DOMNodeHelper.createNodeList( list );
305     }
306 
307     public NodeList getElementsByTagNameNS(
308         String namespaceURI, String localName
309     ) {
310         ArrayList list = new ArrayList();
311         DOMNodeHelper.appendElementsByTagNameNS(list, this, namespaceURI, localName );
312         return DOMNodeHelper.createNodeList( list );
313     }
314 
315     public boolean hasAttribute(String name) {
316         return attribute(name) != null;
317     }
318 
319     public boolean hasAttributeNS(String namespaceURI, String localName) {
320         return attribute(namespaceURI, localName) != null;
321     }
322 
323 
324     // Implementation methods
325     //-------------------------------------------------------------------------
326     protected DocumentFactory getDocumentFactory() {
327         DocumentFactory factory = getQName().getDocumentFactory();
328         return ( factory != null ) ? factory : DOCUMENT_FACTORY;
329     }
330 
331     protected Attribute attribute(org.w3c.dom.Attr attr) {
332         return attribute(
333             DOCUMENT_FACTORY.createQName(
334                 attr.getLocalName(),
335                 attr.getPrefix(),
336                 attr.getNamespaceURI()
337             )
338         );
339     }
340 
341     protected Attribute attribute(String namespaceURI,  String localName) {
342         List attributes = attributeList();
343         int size = attributes.size();
344         for ( int i = 0; i < size; i++ ) {
345             Attribute attribute = (Attribute) attributes.get(i);
346             if ( localName.equals( attribute.getName() ) &&
347                 (((namespaceURI == null || namespaceURI.length() == 0) && 
348                       (attribute.getNamespaceURI() == null || attribute.getNamespaceURI().length() == 0)) ||
349                 (namespaceURI != null && namespaceURI.equals(attribute.getNamespaceURI()))))  {
350                 return attribute;
351             }
352         }
353         return null;
354     }
355 
356     protected Attribute createAttribute(org.w3c.dom.Attr newAttr) {
357         QName qname = null;
358         String name = newAttr.getLocalName();
359         if (name != null) {
360             String prefix = newAttr.getPrefix();
361             String uri = newAttr.getNamespaceURI();
362             qname = getDocumentFactory().createQName(name, prefix, uri);
363         } else {
364             name = newAttr.getName();
365             qname = getDocumentFactory().createQName(name);
366         }
367 
368         return new DOMAttribute(qname, newAttr.getValue());
369     }
370 
371     protected QName getQName( String namespaceURI, String qualifiedName ) {
372         int index = qualifiedName.indexOf( ':' );
373         String prefix = "";
374         String localName = qualifiedName;
375         if ( index >= 0 ) {
376             prefix = qualifiedName.substring(0, index);
377             localName = qualifiedName.substring(index+1);
378         }
379         return getDocumentFactory().createQName( localName, prefix, namespaceURI );
380     }
381 }
382 
383 
384 
385 
386 /*
387  * Redistribution and use of this software and associated documentation
388  * ("Software"), with or without modification, are permitted provided
389  * that the following conditions are met:
390  *
391  * 1. Redistributions of source code must retain copyright
392  *    statements and notices.  Redistributions must also contain a
393  *    copy of this document.
394  *
395  * 2. Redistributions in binary form must reproduce the
396  *    above copyright notice, this list of conditions and the
397  *    following disclaimer in the documentation and/or other
398  *    materials provided with the distribution.
399  *
400  * 3. The name "DOM4J" must not be used to endorse or promote
401  *    products derived from this Software without prior written
402  *    permission of MetaStuff, Ltd.  For written permission,
403  *    please contact dom4j-info@metastuff.com.
404  *
405  * 4. Products derived from this Software may not be called "DOM4J"
406  *    nor may "DOM4J" appear in their names without prior written
407  *    permission of MetaStuff, Ltd. DOM4J is a registered
408  *    trademark of MetaStuff, Ltd.
409  *
410  * 5. Due credit should be given to the DOM4J Project - 
411  *    http://www.dom4j.org
412  *
413  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
414  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
415  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
416  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
417  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
418  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
419  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
420  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
421  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
422  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
423  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
424  * OF THE POSSIBILITY OF SUCH DAMAGE.
425  *
426  * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
427  *
428  * $Id: DOMElement.java,v 1.21 2004/06/25 08:03:35 maartenc Exp $
429  */