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