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 }