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 }