
net.n3.nanoxml.XMLElement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jhotdraw Show documentation
Show all versions of jhotdraw Show documentation
JHotDraw 7 with openTCS-specific modifications
The newest version!
/* Werner Randelshofer 2009-06-01
* Removed finalize method. Added dispose method.
/* Werner Randelshofer 2006-11-28
* Added method getDoubleAttribue(String name, Map valueSet, String defaultKey, boolean allowLiterals);
/* Werner Randelshofer 2006-11-26
* Added method getAttribute(String name, String namespace, Map valueSet, String defaultKey, boolean allowLiterals);
*/
/* XMLElement.java NanoXML/Java
*
* $Revision: 1.5 $
* $Date: 2002/02/06 18:50:12 $
* $Name: RELEASE_2_2_1 $
*
* This file is part of NanoXML 2 for Java.
* Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
* use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/
package net.n3.nanoxml;
import java.io.CharArrayWriter;
import java.io.Serializable;
import java.util.*;
/**
* XMLElement is an XML element. The standard NanoXML builder generates a
* tree of such elements.
*
* @see net.n3.nanoxml.StdXMLBuilder
*
* @author Marc De Scheemaecker
* @version $Name: RELEASE_2_2_1 $, $Revision: 1.5 $
*/
@SuppressWarnings("unchecked")
public class XMLElement implements IXMLElement, Serializable {
/**
* Necessary for serialization.
*/
static final long serialVersionUID = -2383376380548624920L;
/**
* No line number defined.
*/
public static final int NO_LINE = -1;
/**
* The parent element.
*/
private IXMLElement parent;
/**
* The attributes of the element.
*/
private ArrayList attributes;
/**
* The child iterator.
*/
private ArrayList children;
/**
* The name of the element.
*/
private String name;
/**
* The full name of the element.
*/
private String fullName;
/**
* The namespace URI.
*/
private String namespace;
/**
* The content of the element.
*/
private String content;
/**
* The system ID of the source data where this element is located.
*/
private String systemID;
/**
* The line in the source data where this element starts.
*/
private int lineNr;
/**
* Creates an empty element to be used for #PCDATA content.
*/
public XMLElement() {
this(null, null, null, NO_LINE);
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
*/
public XMLElement(String fullName) {
this(fullName, null, null, NO_LINE);
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
public XMLElement(String fullName,
String systemID,
int lineNr) {
this(fullName, null, systemID, lineNr);
}
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
*/
public XMLElement(String fullName,
String namespace) {
this(fullName, namespace, null, NO_LINE);
}
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
public XMLElement(String fullName,
String namespace,
String systemID,
int lineNr) {
this.attributes = new ArrayList();
this.children = new ArrayList(8);
this.fullName = fullName;
if (namespace == null) {
this.name = fullName;
} else {
int index = fullName.indexOf(':');
if (index >= 0) {
this.name = fullName.substring(index + 1);
} else {
this.name = fullName;
}
}
this.namespace = namespace;
this.content = null;
this.lineNr = lineNr;
this.systemID = systemID;
this.parent = null;
}
/**
* Creates an element to be used for #PCDATA content.
*/
public IXMLElement createPCDataElement() {
return new XMLElement();
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
*/
public IXMLElement createElement(String fullName) {
return new XMLElement(fullName);
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
public IXMLElement createElement(String fullName,
String systemID,
int lineNr) {
return new XMLElement(fullName, systemID, lineNr);
}
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
*/
public IXMLElement createElement(String fullName,
String namespace) {
return new XMLElement(fullName, namespace);
}
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
public IXMLElement createElement(String fullName,
String namespace,
String systemID,
int lineNr) {
return new XMLElement(fullName, namespace, systemID, lineNr);
}
/**
* Cleans up the object when it's destroyed.
* /
protected void finalize() throws Throwable {
this.attributes.clear();
this.attributes = null;
this.children = null;
this.fullName = null;
this.name = null;
this.namespace = null;
this.content = null;
this.systemID = null;
this.parent = null;
super.finalize();
}*/
/**
* Returns the parent element. This method returns null for the root
* element.
*/
public IXMLElement getParent() {
return this.parent;
}
/**
* Returns the full name (i.e. the name including an eventual namespace
* prefix) of the element.
*
* @return the name, or null if the element only contains #PCDATA.
*/
public String getFullName() {
return this.fullName;
}
/**
* Returns the name of the element.
*
* @return the name, or null if the element only contains #PCDATA.
*/
public String getName() {
return this.name;
}
/**
* Returns the namespace of the element.
*
* @return the namespace, or null if no namespace is associated with the
* element.
*/
public String getNamespace() {
return this.namespace;
}
/**
* Sets the full name. This method also sets the short name and clears the
* namespace URI.
*
* @param name the non-null name.
*/
public void setName(String name) {
this.name = name;
this.fullName = name;
this.namespace = null;
}
/**
* Sets the name.
*
* @param fullName the non-null full name.
* @param namespace the namespace URI, which may be null.
*/
public void setName(String fullName,
String namespace) {
int index = fullName.indexOf(':');
if ((namespace == null) || (index < 0)) {
this.name = fullName;
} else {
this.name = fullName.substring(index + 1);
}
this.fullName = fullName;
this.namespace = namespace;
}
/**
* Adds a child element.
*
* @param child the non-null child to add.
*/
public void addChild(IXMLElement child) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
if ((child.getName() == null) && (! this.children.isEmpty())) {
IXMLElement lastChild = (IXMLElement) this.children.get(this.children.size() - 1);
if (lastChild.getName() == null) {
lastChild.setContent(lastChild.getContent()
+ child.getContent());
return;
}
}
((XMLElement)child).parent = this;
this.children.add(child);
}
/**
* Inserts a child element.
*
* @param child the non-null child to add.
* @param index where to put the child.
*/
public void insertChild(IXMLElement child,
int index) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
if ((child.getName() == null) && (! this.children.isEmpty())) {
IXMLElement lastChild = (IXMLElement) this.children.get(this.children.size() - 1);
if (lastChild.getName() == null) {
lastChild.setContent(lastChild.getContent()
+ child.getContent());
return;
}
}
((XMLElement) child).parent = this;
this.children.add(index, child);
}
/**
* Removes a child element.
*
* @param child the non-null child to remove.
*/
public void removeChild(IXMLElement child) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
this.children.remove(child);
}
/**
* Removes the child located at a certain index.
*
* @param index the index of the child, where the first child has index 0.
*/
public void removeChildAtIndex(int index) {
this.children.remove(index);
}
/**
* Returns an enumeration of all child iterator.
*
* @return the non-null enumeration
*/
public Iterator iterateChildren() {
return this.children.iterator();
}
/**
* Returns whether the element is a leaf element.
*
* @return true if the element has no children.
*/
public boolean isLeaf() {
return this.children.isEmpty();
}
/**
* Returns whether the element has children.
*
* @return true if the element has children.
*/
public boolean hasChildren() {
return (! this.children.isEmpty());
}
/**
* Returns the number of children.
*
* @return the count.
*/
public int getChildrenCount() {
return this.children.size();
}
/**
* Returns a vector containing all the child iterator.
*
* @return the vector.
*/
public ArrayList getChildren() {
return this.children;
}
/**
* Returns the child at a specific index.
*
* @param index the index of the child
*
* @return the non-null child
*
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds.
*/
public IXMLElement getChildAtIndex(int index)
throws ArrayIndexOutOfBoundsException {
return (IXMLElement) this.children.get(index);
}
/**
* Searches a child element.
*
* @param name the full name of the child to search for.
*
* @return the child element, or null if no such child was found.
*/
public IXMLElement getFirstChildNamed(String name) {
Iterator enm = this.children.iterator();
while (enm.hasNext()) {
IXMLElement child = (IXMLElement) enm.next();
String childName = child.getFullName();
if ((childName != null) && childName.equals(name)) {
return child;
}
}
return null;
}
/**
* Searches a child element.
*
* @param name the name of the child to search for.
* @param namespace the namespace, which may be null.
*
* @return the child element, or null if no such child was found.
*/
public IXMLElement getFirstChildNamed(String name,
String namespace) {
Iterator enm = this.children.iterator();
while (enm.hasNext()) {
IXMLElement child = (IXMLElement) enm.next();
String str = child.getName();
boolean found = (str != null) && (str.equals(name));
str = child.getNamespace();
if (str == null) {
found &= (name == null);
} else {
found &= str.equals(namespace);
}
if (found) {
return child;
}
}
return null;
}
/**
* Returns a vector of all child iterator named name.
*
* @param name the full name of the children to search for.
*
* @return the non-null vector of child iterator.
*/
public ArrayList getChildrenNamed(String name) {
ArrayList result = new ArrayList(this.children.size());
Iterator enm = this.children.iterator();
while (enm.hasNext()) {
IXMLElement child = (IXMLElement) enm.next();
String childName = child.getFullName();
if ((childName != null) && childName.equals(name)) {
result.add(child);
}
}
return result;
}
/**
* Returns a vector of all child iterator named name.
*
* @param name the name of the children to search for.
* @param namespace the namespace, which may be null.
*
* @return the non-null vector of child iterator.
*/
public ArrayList getChildrenNamed(String name,
String namespace) {
ArrayList result = new ArrayList(this.children.size());
Iterator enm = this.children.iterator();
while (enm.hasNext()) {
IXMLElement child = (IXMLElement) enm.next();
String str = child.getName();
boolean found = (str != null) && (str.equals(name));
str = child.getNamespace();
if (str == null) {
found &= (name == null);
} else {
found &= str.equals(namespace);
}
if (found) {
result.add(child);
}
}
return result;
}
/**
* Searches an attribute.
*
* @param fullName the non-null full name of the attribute.
*
* @return the attribute, or null if the attribute does not exist.
*/
private XMLAttribute findAttribute(String fullName) {
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
if (attr.getFullName().equals(fullName)) {
return attr;
}
}
return null;
}
/**
* Searches an attribute.
*
* @param name the non-null short name of the attribute.
* @param namespace the name space, which may be null.
*
* @return the attribute, or null if the attribute does not exist.
*/
private XMLAttribute findAttribute(String name,
String namespace) {
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
boolean found = attr.getName().equals(name);
if (namespace == null) {
found &= (attr.getNamespace() == null);
} else {
found &= namespace.equals(attr.getNamespace());
}
if (found) {
return attr;
}
}
return null;
}
/**
* Returns the number of attributes.
*/
public int getAttributeCount() {
return this.attributes.size();
}
/**
* @deprecated As of NanoXML/Java 2.1, replaced by
* {@link #getAttribute(java.lang.String,java.lang.String)}
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
*
* @return the value, or null if the attribute does not exist.
*/
public String getAttribute(String name) {
return this.getAttribute(name, null);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null full name of the attribute.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public String getAttribute(String name,
String defaultValue) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return defaultValue;
} else {
return attr.getValue();
}
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public String getAttribute(String name,
String namespace,
String defaultValue) {
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
return defaultValue;
} else {
return attr.getValue();
}
}
/**
* Returns an attribute of the element.
* If the attribute doesn't exist, defaultValue
is returned.
*
* @param name The name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue Key to use if the attribute is missing.
*
*/
public double getDoubleAttribute(String name,
String namespace,
double defaultValue) {
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
return defaultValue;
} else {
try {
return Double.parseDouble(attr.getValue());
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
/**
* Returns the value of an attribute.
*
* @param name the non-null full name of the attribute.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public int getAttribute(String name,
int defaultValue) {
String value = this.getAttribute(name, Integer.toString(defaultValue));
return Integer.parseInt(value);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public int getAttribute(String name,
String namespace,
int defaultValue) {
String value = this.getAttribute(name, namespace,
Integer.toString(defaultValue));
return Integer.parseInt(value);
}
/**
* Returns an attribute by looking up a key in a hashtable.
* If the attribute doesn't exist, the value corresponding to defaultKey
* is returned.
*
* As an example, if valueSet contains the mapping "one" =>
* "1"
* and the element contains the attribute attr="one"
, then
* getAttribute("attr", mapping, defaultKey, false)
returns
* "1"
.
*
* @param name
* The name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param valueSet
* HashMap mapping keySet().iterator to values.
* @param defaultKey
* Key to use if the attribute is missing.
*
*
- Preconditions:
-
*
name != null
* name
is a valid XML identifier
* valueSet
!= null
* - the keySet().iterator of
valueSet
are strings
*
*
*/
public Object getAttribute(String name, String namespace,
Map valueSet,
String defaultKey) {
String key = this.getAttribute(name, namespace, null);
if (key == null || ! valueSet.containsKey(key)) {
return valueSet.get(defaultKey);
}
return valueSet.get(key);
}
/**
* Returns the type of an attribute.
*
* @param name the non-null full name of the attribute.
*
* @return the type, or null if the attribute does not exist.
*/
public String getAttributeType(String name) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return null;
} else {
return attr.getType();
}
}
/**
* Returns the namespace of an attribute.
*
* @param name the non-null full name of the attribute.
*
* @return the namespace, or null if there is none associated.
*/
public String getAttributeNamespace(String name) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return null;
} else {
return attr.getNamespace();
}
}
/**
* Returns the type of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
*
* @return the type, or null if the attribute does not exist.
*/
public String getAttributeType(String name,
String namespace) {
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
return null;
} else {
return attr.getType();
}
}
/**
* Sets an attribute.
*
* @param name the non-null full name of the attribute.
* @param value the non-null value of the attribute.
*/
public void setAttribute(String name,
String value) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
attr = new XMLAttribute(name, name, null, value, "CDATA");
this.attributes.add(attr);
} else {
attr.setValue(value);
}
}
/**
* Sets an attribute.
*
* @param fullName the non-null full name of the attribute.
* @param namespace the namespace URI of the attribute, which may be null.
* @param value the non-null value of the attribute.
*/
public void setAttribute(String fullName,
String namespace,
String value) {
int index = fullName.indexOf(':');
String name = fullName.substring(index + 1);
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
attr = new XMLAttribute(fullName, name, namespace, value, "CDATA");
this.attributes.add(attr);
} else {
attr.setValue(value);
}
}
/**
* Removes an attribute.
*
* @param name the non-null name of the attribute.
*/
public void removeAttribute(String name) {
for (int i = 0; i < this.attributes.size(); i++) {
XMLAttribute attr = (XMLAttribute) this.attributes.get(i);
if (attr.getFullName().equals(name)) {
this.attributes.remove(i);
return;
}
}
}
/**
* Removes an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI of the attribute, which may be null.
*/
public void removeAttribute(String name,
String namespace) {
for (int i = 0; i < this.attributes.size(); i++) {
XMLAttribute attr = (XMLAttribute) this.attributes.get(i);
boolean found = attr.getName().equals(name);
if (namespace == null) {
found &= (attr.getNamespace() == null);
} else {
found &= attr.getNamespace().equals(namespace);
}
if (found) {
this.attributes.remove(i);
return;
}
}
}
/**
* Returns an enumeration of all attribute names.
*
* @return the non-null enumeration.
*/
public Iterator iterateAttributeNames() {
ArrayList result = new ArrayList();
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
result.add(attr.getFullName());
}
return result.iterator();
}
/**
* Returns whether an attribute exists.
*
* @return true if the attribute exists.
*/
public boolean hasAttribute(String name) {
return this.findAttribute(name) != null;
}
/**
* Returns whether an attribute exists.
*
* @return true if the attribute exists.
*/
public boolean hasAttribute(String name,
String namespace) {
return this.findAttribute(name, namespace) != null;
}
/**
* Returns all attributes as a Properties object.
*
* @return the non-null set.
*/
public Properties getAttributes() {
Properties result = new Properties();
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
result.put(attr.getFullName(), attr.getValue());
}
return result;
}
/**
* Returns all attributes in a specific namespace as a Properties object.
*
* @param namespace the namespace URI of the attributes, which may be null.
*
* @return the non-null set.
*/
public Properties getAttributesInNamespace(String namespace) {
Properties result = new Properties();
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
if (namespace == null) {
if (attr.getNamespace() == null) {
result.put(attr.getName(), attr.getValue());
}
} else {
if (namespace.equals(attr.getNamespace())) {
result.put(attr.getName(), attr.getValue());
}
}
}
return result;
}
/**
* Returns the system ID of the data where the element started.
*
* @return the system ID, or null if unknown.
*
* @see #getLineNr
*/
public String getSystemID() {
return this.systemID;
}
/**
* Returns the line number in the data where the element started.
*
* @return the line number, or NO_LINE if unknown.
*
* @see #NO_LINE
* @see #getSystemID
*/
public int getLineNr() {
return this.lineNr;
}
/**
* Return the #PCDATA content of the element. If the element has a
* combination of #PCDATA content and child iterator, the #PCDATA
* sections can be retrieved as unnamed child objects. In this case,
* this method returns null.
*
* @return the content.
*/
public String getContent() {
return this.content;
}
/**
* Sets the #PCDATA content. It is an error to call this method with a
* non-null value if there are child objects.
*
* @param content the (possibly null) content.
*/
public void setContent(String content) {
this.content = content;
}
/**
* Returns true if the element equals another element.
*
* @param rawElement the element to compare to
*/
public boolean equals(Object rawElement) {
try {
return this.equalsXMLElement((IXMLElement) rawElement);
} catch (ClassCastException e) {
return false;
}
}
/**
* Returns true if the element equals another element.
*
* @param elt the element to compare to
*/
public boolean equalsXMLElement(IXMLElement elt) {
if (! this.name.equals(elt.getName())) {
return false;
}
if (this.attributes.size() != elt.getAttributeCount()) {
return false;
}
Iterator enm = this.attributes.iterator();
while (enm.hasNext()) {
XMLAttribute attr = (XMLAttribute) enm.next();
if (! elt.hasAttribute(attr.getName(), attr.getNamespace())) {
return false;
}
String value = elt.getAttribute(attr.getName(),
attr.getNamespace(),
null);
if (! attr.getValue().equals(value)) {
return false;
}
String type = elt.getAttributeType(attr.getName(),
attr.getNamespace());
if (! attr.getType().equals(type)) {
return false;
}
}
if (this.children.size() != elt.getChildrenCount()) {
return false;
}
for (int i = 0; i < this.children.size(); i++) {
IXMLElement child1 = this.getChildAtIndex(i);
IXMLElement child2 = elt.getChildAtIndex(i);
if (! child1.equalsXMLElement(child2)) {
return false;
}
}
return true;
}
// BEGIN PATCH Werner Randelshofer
public String toString() {
CharArrayWriter buf = new CharArrayWriter();
XMLWriter w = new XMLWriter(buf);
try {
w.write(this);
} catch (java.io.IOException e) {
InternalError error = new InternalError("toString failed");
error.initCause(e);
throw error;
}
return buf.toString();
}
/** Gets rid of the XMLElement and of all its children. */
public void dispose() {
if (children != null) {
for (IXMLElement c : children) {
c.dispose();
}
}
this.attributes.clear();
this.attributes = null;
this.children = null;
this.fullName = null;
this.name = null;
this.namespace = null;
this.content = null;
this.systemID = null;
this.parent = null;
}
// END PATCH Werner Randelshofer
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy