
org.purl.sword.base.XmlElement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dspace-sword Show documentation
Show all versions of dspace-sword Show documentation
DSpace SWORD Deposit Service Provider Extension
The newest version!
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.purl.sword.base;
import java.util.List;
import java.util.Properties;
import nu.xom.Attribute;
import nu.xom.Element;
import nu.xom.Node;
import org.apache.logging.log4j.Logger;
/**
* Parent class for all classes that represent an XML element. This provides
* some common utility methods that are useful for marshalling and
* unmarshalling data.
*
* @author Neil Taylor
*/
public abstract class XmlElement {
/**
* Logger
*/
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlElement.class);
/**
*
*/
protected XmlName xmlName;
public XmlName getXmlName() {
// FIXME - should this be a clone?
return xmlName;
}
/**
* The name to use for the prefix. E.g. atom:title, atom is the prefix.
*/
//protected String prefix;
/**
* The local name of the element. E.g. atom:title, title is the local name.
*/
//protected String localName;
/**
* Create a new instance. Set the local name that will be used.
*
* @param localName The local name for the element.
*/
public XmlElement(String localName) {
this("", localName);
}
/**
* Create a new instance. Set the prefix and local name.
*
* @param prefix The prefix for the element.
* @param localName The local name for the element.
*/
public XmlElement(String prefix, String localName) {
this.xmlName = new XmlName(prefix, localName, "");
}
/**
* Create a new insatnce. Set the prefix, local name and the namespace URI.
*
* @param prefix The prefix.
* @param localName The element's local name.
* @param namespaceUri The namespace URI.
*/
public XmlElement(String prefix, String localName, String namespaceUri) {
this.xmlName = new XmlName(prefix, localName, namespaceUri);
}
/**
* Set the name of this XML element.
*
* @param name name to set
*/
public XmlElement(XmlName name) {
xmlName = name;
}
/**
* The Date format that is used to parse dates to and from the ISO format
* in the XML data.
*/
protected static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
/**
* Array of possible date formats that are permitted for date elements.
*/
protected static final String[] DATE_FORMATS = {
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SZ",
"yyyy-MM-dd'T'HH:mm:ss.Sz",
"yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ssz",
"yyyy-MM-dd'T'HH:mmZZZZ",
"yyyy-MM-dd'T'HH:mmzzzz",
"yyyy-MM-dd'T'HHZZZZ",
"yyyy-MM-dd'T'HHzzzz",
"yyyy-MM-dd'T'HH:mm:ss.S",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd'T'HH:mm",
"yyyy-MM-dd'T'HH",
"yyyy-MM-dd",
"yyyy-MM",
"yyyy"
};
/**
* Extract a boolean value from the specified element. The boolean value
* is represented as the string 'true' or 'false' as the only child
* of the specified element.
*
* @param element The element that contains the boolean value.
* @return True or false, based on the string in the element's content.
* @throws UnmarshallException If the element does not contain a single child, or if
* the child does not contain the value 'true' or 'false'.
*/
protected boolean unmarshallBoolean(Element element)
throws UnmarshallException {
if (element.getChildCount() != 1) {
throw new UnmarshallException("Missing Boolean Value", null);
}
// ok to get the single child element. This should be a text element.
try {
Node child = element.getChild(0);
String value = child.getValue();
if ("true".equals(value)) {
return true;
} else if ("false".equals(value)) {
return false;
} else {
throw new UnmarshallException("Illegal Value");
}
} catch (IndexOutOfBoundsException ex) {
throw new UnmarshallException("Error accessing Boolean element", ex);
}
}
/**
* Extract a string value from the specified element. The value
* is the only child of the specified element.
*
* @param element The element that contains the string value.
* @return The string.
* @throws UnmarshallException If the element does not contain a single child.
*/
protected String unmarshallString(Element element)
throws UnmarshallException {
if (element.getChildCount() != 1) {
throw new UnmarshallException("Missing String Value", null);
}
// ok to get the single child element. This should be a text element.
try {
Node child = element.getChild(0);
return child.getValue();
} catch (IndexOutOfBoundsException ex) {
throw new UnmarshallException("Error accessing String element", ex);
}
}
/**
* Extract an integer value from the specified element. The integer value
* is represented as a string in the only child
* of the specified element.
*
* @param element The element that contains the integer.
* @return The integer.
* @throws UnmarshallException If the element does not contain a single child, or if
* the child does not contain the valid integer.
*/
protected int unmarshallInteger(Element element)
throws UnmarshallException {
if (element.getChildCount() != 1) {
throw new UnmarshallException("Missing Integer Value", null);
}
// ok to get the single child element. This should be a text element.
try {
Node child = element.getChild(0);
return Integer.parseInt(child.getValue());
} catch (IndexOutOfBoundsException ex) {
throw new UnmarshallException("Error accessing Integer", ex);
} catch (NumberFormatException nfex) {
throw new UnmarshallException("Error formatting the number", nfex);
}
}
/**
* Determines if the specified element is an instance of the element name. If
* you are checking the name title in the ATOM namespace, then the local name
* should be 'title' and the namespaceURI is the URI for the ATOM namespace.
*
* @param element The specified element.
* @param localName The local name for the element.
* @param namespaceURI The namespace for the element.
* @return True if the element matches the localname and namespace URI. Otherwise, false.
*/
protected boolean isInstanceOf(Element element, String localName, String namespaceURI) {
return (localName.equals(element.getLocalName()) &&
namespaceURI.equals(element.getNamespaceURI()));
}
/**
* Checks XML element local name and namespace URI.
*
* @param element XML element to check
* @param xmlName XML element name
* @return True if the element matches the localname and namespace URI. Otherwise, false.
*/
protected boolean isInstanceOf(Element element, XmlName xmlName) {
return (xmlName.getLocalName().equals(element.getLocalName()) &&
xmlName.getNamespace().equals(element.getNamespaceURI()));
}
/**
* Retrieve the qualified name for this object. This uses the
* prefix and local name stored in this object.
*
* @return A string of the format 'prefix:localName'
*/
public String getQualifiedName() {
return getQualifiedName(xmlName.getLocalName());
}
/**
* Retrieve the qualified name. The prefix for this object is prepended
* onto the specified local name.
*
* @param name the specified local name.
* @return A string of the format 'prefix:name'
*/
public String getQualifiedName(String name) {
return xmlName.getQualifiedName();
}
/**
* Get the qualified name for the given prefix and name
*
* @param prefix the prefix
* @param name the name
* @return the qualified name
*/
public String getQualifiedNameWithPrefix(String prefix, String name) {
return prefix + ":" + name;
}
public abstract SwordValidationInfo validate(Properties validationContext);
protected void processUnexpectedAttributes(Element element, List attributeItems) {
int attributeCount = element.getAttributeCount();
Attribute attribute = null;
for (int i = 0; i < attributeCount; i++) {
attribute = element.getAttribute(i);
XmlName attributeName = new XmlName(attribute.getNamespacePrefix(),
attribute.getLocalName(),
attribute.getNamespaceURI());
SwordValidationInfo info = new SwordValidationInfo(xmlName, attributeName,
SwordValidationInfo.UNKNOWN_ATTRIBUTE,
SwordValidationInfoType.INFO);
info.setContentDescription(attribute.getValue());
attributeItems.add(info);
}
}
/**
* Add the information to the unmarshall attribute section of the specified
* info object.
*
* @param element XML element to process
* @param info validation information item about elements/attributes
*/
protected void processUnexpectedAttributes(Element element, SwordValidationInfo info) {
int attributeCount = element.getAttributeCount();
Attribute attribute = null;
for (int i = 0; i < attributeCount; i++) {
attribute = element.getAttribute(i);
XmlName attributeName = new XmlName(attribute.getNamespacePrefix(),
attribute.getLocalName(),
attribute.getNamespaceURI());
SwordValidationInfo item = new SwordValidationInfo(xmlName, attributeName,
SwordValidationInfo.UNKNOWN_ATTRIBUTE,
SwordValidationInfoType.INFO);
item.setContentDescription(attribute.getValue());
info.addUnmarshallAttributeInfo(item);
}
}
protected SwordValidationInfo handleIncorrectElement(Element element, Properties validationProperties)
throws UnmarshallException {
log.error(
"Unexpected element. Expected: " + getQualifiedName() + ". Got: " +
((element != null) ? element.getQualifiedName() : "null"));
if (validationProperties != null) {
SwordValidationInfo info = new SwordValidationInfo(
new XmlName(element.getNamespacePrefix(), element.getLocalName(),
element.getNamespaceURI()),
"This is not the expected element. Received: " +
element.getQualifiedName() + " for namespaceUri: " +
element.getNamespaceURI(), SwordValidationInfoType.ERROR
);
return info;
} else {
throw new UnmarshallException("Not a " + getQualifiedName() + " element");
}
}
protected SwordValidationInfo createValidAttributeInfo(String name, String content) {
XmlName attributeName = new XmlName(xmlName.getPrefix(),
name,
xmlName.getNamespace());
SwordValidationInfo item = new SwordValidationInfo(xmlName, attributeName);
item.setContentDescription(content);
//attributeItems.add(item);
return item;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy