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 }