View Javadoc
1   /*
2    * Copyright 2007 Edward Kuns
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   * $Id: Element.java 0000 2007-01-11 00:00:00Z ekuns $
17   */
18  package org.castor.xmlctf.xmldiff.xml.nodes;
19  
20  import java.util.Iterator;
21  import java.util.LinkedList;
22  
23  import org.castor.xmlctf.xmldiff.xml.Location;
24  
25  /**
26   * A representation of an Element XML node.
27   *
28   * @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
29   * @version $Revision: 0000 $ $Date: 2007-01-11 00:00:00 -0600 (Thu, 11 Jan 2007) $
30   * @since Castor 1.1
31   */
32  public class Element extends ParentNode {
33  
34      /** Serial Version UID. */
35      private static final long serialVersionUID = 7995110660306473483L;
36      /** Our list of Attributes. */
37      private final LinkedList  _attributes      = new LinkedList();
38      /** Our list of Namespaces. */
39      private final LinkedList  _namespaces      = new LinkedList();
40      /** Our location */
41      private Location          _location        = null;
42  
43      /**
44       * Creates a new Element.
45       *
46       * @param namespace the namespace URI for this node. (May be null.)
47       * @param localName the localname of this node. (Cannot be null.)
48       */
49      public Element(final String namespace, final String localName) {
50          super(namespace, localName, XMLNode.ELEMENT);
51      }
52  
53      /**
54       * Returns an Iterator over the List of Attributes.
55       * @return an Iterator over the List of Attributes.
56       */
57      public Iterator getAttributeIterator() {
58          return _attributes.iterator();
59      }
60  
61      /**
62       * Returns the value of the named attribute, or null if the node has no such
63       * attribute. If the argument <tt>uri</tt> is null, the node's namespace
64       * URI will be used.
65       *
66       * @param uri The attribute's namespace URI, or null
67       * @param localName The attribute's local name
68       * @return The attribute's value, or null if no such attribute exists
69       */
70      public String getAttribute(final String uri, final String localName) {
71          for (Iterator i = _attributes.iterator(); i.hasNext();) {
72              Attribute attr = (Attribute) i.next();
73              if (namespacesEqual(uri, attr.getNamespaceURI())
74                  && attr.getLocalName().equals(localName)) {
75                  return attr.getStringValue();
76              }
77          }
78          return null;
79      }
80  
81      /**
82       * Returns the namespace URI associated with this namespace prefix, as
83       * defined in the context of this node. Returns null if the prefix is
84       * undefined. Returns an empty String if the prefix is defined and
85       * associated with no namespace.
86       *
87       * @param prefix The namespace prefix
88       * @return The namespace URI, or null.
89       */
90      public String getNamespaceURI(final String prefix) {
91          String desiredPrefix = (prefix == null) ? "" : prefix;
92  
93          for (Iterator i = _namespaces.iterator(); i.hasNext(); ) {
94              Namespace ns = (Namespace) i.next();
95              if (desiredPrefix.equals(ns.getPrefix())) {
96                  return ns.getNamespaceUri();
97              }
98          }
99  
100         // If we didn't find it, search our parent
101         return super.getNamespaceURI(desiredPrefix);
102     }
103 
104     /**
105      * Returns the namespace prefix associated with this namespace URI, as
106      * defined in the context of this node. Returns null if no prefix is defined
107      * for this namespace URI. Returns an empty string if the default prefix is
108      * associated with this namespace URI.
109      *
110      * @param uri The namespace URI
111      * @return The namespace prefix, or null
112      */
113     public String getNamespacePrefix(final String uri) {
114         String desiredUri = (uri == null) ? "" : uri;
115 
116         for (Iterator i = _namespaces.iterator(); i.hasNext(); ) {
117             Namespace ns = (Namespace) i.next();
118             if (desiredUri.equals(ns.getNamespaceUri())) {
119                 return ns.getPrefix();
120             }
121         }
122 
123         // If we didn't find it locally, search our parent
124         ParentNode parent = getParentNode();
125         if (parent != null && parent instanceof Element) {
126             return ((Element)parent).getNamespacePrefix(desiredUri);
127         }
128 
129         // If no parent, return null
130         return null;
131     }
132 
133     /**
134      * Adds the given Attribute to this Element.
135      *
136      * @param attr the Attribute to add
137      */
138     public void addAttribute(final Attribute attr) {
139         if (attr == null) {
140             return;
141         }
142 
143         attr.setParent(this);
144         _attributes.add(attr);
145     }
146 
147     /**
148      * Adds the given Namespace to this Element.
149      *
150      * @param namespace the Namespace to add
151      */
152     public void addNamespace(final Namespace namespace) {
153         if (namespace == null) {
154             return;
155         }
156 
157         _namespaces.add(namespace);
158     }
159 
160     /**
161      * Returns true if the given two namespace URI strings are equal.
162      *
163      * @param ns1 The first namespace URI to compare
164      * @param ns2 The second namespace URI to compare
165      * @return true if the given two namespace URI strings are equal.
166      */
167     private boolean namespacesEqual(final String ns1, final String ns2) {
168         final String namespace1 = (ns1 == null) ? "" : ns1;
169         final String namespace2 = (ns2 == null) ? "" : ns2;
170 
171         return namespace1.equals(namespace2);
172     }
173 
174     /**
175      * Sets the location of this Element in the document.
176      * @param location the location of this Element in the document.
177      */
178     public void setLocation(final Location location) {
179         _location = location;
180     }
181 
182     /**
183      * Returns the location of this Element in the document.
184      * @return the location of this Element in the document.
185      */
186     public Location getLocation() {
187         return _location;
188     }
189 
190 }