package org.gwtoolbox.commons.xml.client;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.NodeList;
import org.gwtoolbox.commons.collections.client.FilteredIterator;
import org.gwtoolbox.commons.collections.client.ReadOnlyIterator;
import org.gwtoolbox.commons.conversion.client.TextConverterManager;
import org.gwtoolbox.commons.predicate.client.AbstractPredicate;
import java.util.Iterator;
import java.util.Date;
/**
* @author Uri Boness
*/
public final class DOMUtils {
/**
* Returns a single child element of the given parent.
*
* @param parent The parent.
* @param childName The name of the child (tag name).
* @return A single child element of the given parent, or {@code null} if none was found.
* @throws XmlException When more than one child was found.
*/
public static Element getSingleChild(Element parent, String childName) throws XmlException {
NodeList nodes = parent.getElementsByTagName(childName);
if (nodes.getLength() == 0) {
return null;
}
if (nodes.getLength() > 1) {
throw new XmlException("Found more than one <" + childName + "> element");
}
return (Element) nodes.item(0);
}
/**
* Returns the text value of a child of the given parent or {@code null} if no child was found.
*
* @param parent The parent.
* @param childName The name of the child.
* @return The text value of a child of the given parent or {@code null} if no child was found.
* @see #getSingleChildValue(com.google.gwt.xml.client.Element, String, String)
*/
public static String getSingleChildValue(Element parent, String childName) {
return getSingleChildValue(parent, childName, null);
}
/**
* Returns the text value of a child of the given parent.
* <p>
* Example:
* <code><pre>
* <parent>
* <child>Value</child>
* </parent>
* </pre></code>
*
* Calling {@code getSingleChildValue(parent, "childe")} on the above element will result in {@code "Value").
*
* @param parent The parent.
* @param childName The name of the child to inspect (tag name).
* @param defaultValue The value that will be returned if the child element was not found.
* @return The text value of the requested child, or {@code null} if the child doesn't exist or if it doesn't hold any text.
*/
public static String getSingleChildValue(Element parent, String childName, String defaultValue) {
Element child = getSingleChild(parent, childName);
if (child == null) {
return defaultValue;
}
return getTextValue(child, "");
}
public static String getTextValue(Element element) {
return getTextValue(element, null);
}
public static String getTextValue(Element element, String defaultValue) {
NodeList nodes = element.getChildNodes();
for (int i=0; i<nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.TEXT_NODE) {
return node.getNodeValue();
}
}
return defaultValue;
}
public static boolean getBooleanValue(Element element, boolean defaultValue) {
Boolean value = getBooleanValue(element);
return value == null ? defaultValue : value;
}
public static Boolean getBooleanValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Boolean.class, value);
}
public static int getIntValue(Element element, int defaultValue) {
Integer value = getIntValue(element);
return value == null ? defaultValue : value;
}
public static Integer getIntValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Integer.class, value);
}
public static long getLongValue(Element element, long defaultValue) {
Long value = getLongValue(element);
return value == null ? defaultValue : value;
}
public static Long getLongValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Long.class, value);
}
public static float getDoubleValue(Element element, float defaultValue) {
Float value = getFloatValue(element);
return value == null ? defaultValue : value;
}
public static Float getFloatValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Float.class, value);
}
public static Date getDateValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Date.class, value);
}
public static double getDoubleValue(Element element, double defaultValue) {
Double value = getDoubleValue(element);
return value == null ? defaultValue : value;
}
public static Double getDoubleValue(Element element) {
String value = getTextValue(element);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Double.class, value);
}
/**
* Returns the integer value of the child of the given parent.
*
* @param parent The parent.
* @param childName The name of the child to inspect (tag name).
* @return The integer value of the child of the given parent, or {@code null} if there is not value.
* @see #getSingleChildValue(com.google.gwt.xml.client.Element, String)
*/
public static Integer getSingleChildIntegerValue(Element parent, String childName) {
String value = getSingleChildValue(parent, childName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Integer.class, value);
}
/**
* Returns the integer value of the child of the given parent. If no value is defined the given default value will
* be returned.
*
* @param parent The parent.
* @param childName The name of the child to inspect (tag name).
* @return The integer value of the child of the given parent, or the given default value if no value is found.
* @see #getSingleChildIntegerValue(com.google.gwt.xml.client.Element, String)
*/
public static int getSingleChildIntegerValue(Element parent, String childName, int defaultValue) {
Integer value = getSingleChildIntegerValue(parent, childName);
return value == null ? defaultValue : value;
}
public static Long getSingleChildLongValue(Element parent, String childName) {
String value = getSingleChildValue(parent, childName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Long.class, value);
}
public static long getSingleChildLongValue(Element parent, String childName, long defaultValue) {
Long value = getSingleChildLongValue(parent, childName);
return value == null ? defaultValue : value;
}
public static Iterable<Element> children(Element parent) {
return new NodeListIterable(parent.getChildNodes());
}
public static Iterable<Element> children(Element parent, String childTagName) {
return new NodeListIterable(parent.getElementsByTagName(childTagName));
}
public static Double getSingleChildDoubleValue(Element parent, String childName) {
String value = getSingleChildValue(parent, childName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Double.class, value);
}
public static double getSingleChildDoubleValue(Element parent, String childName, double defaultValue) {
Double value = getSingleChildDoubleValue(parent, childName);
return value == null ? defaultValue : value;
}
public static Boolean getSingleChildBooleanValue(Element parent, String childName) {
String value = getSingleChildValue(parent, childName);
if (value == null) {
return null;
}
return Boolean.valueOf(value);
}
public static boolean getSingleChildBooleanValue(Element parent, String childName, boolean defaultValue) {
Boolean value = getSingleChildBooleanValue(parent, childName);
return value == null ? defaultValue : value;
}
public static String getSingleChildAttribute(Element parent, String childName, String attributeName) {
Element child = getSingleChild(parent, childName);
if (child == null) {
return null;
}
return child.getAttribute(attributeName);
}
public static boolean getBooleanAttribute(Element element, String attributeName, boolean defaultValue) {
Boolean value = getBooleanAttribute(element, attributeName);
return value == null ? defaultValue : value;
}
public static Boolean getBooleanAttribute(Element element, String attributeName) {
String value = element.getAttribute(attributeName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Boolean.class, value);
}
public static int getIntegerAttribute(Element element, String attributeName, int defaultValue) {
Integer value = getIntegerAttribute(element, attributeName);
return value == null ? defaultValue : value;
}
public static Integer getIntegerAttribute(Element element, String attributeName) {
String value = element.getAttribute(attributeName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Integer.class, value);
}
public static long getLongAttribute(Element element, String attributeName, long defaultValue) {
Long value = getLongAttribute(element, attributeName);
return value == null ? defaultValue : value;
}
public static Long getLongAttribute(Element element, String attributeName) {
String value = element.getAttribute(attributeName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Long.class, value);
}
public static double getDoubleAttribute(Element element, String attributeName, double defaultValue) {
Double value = getDoubleAttribute(element, attributeName);
return value == null ? defaultValue : value;
}
public static Double getDoubleAttribute(Element element, String attributeName) {
String value = element.getAttribute(attributeName);
if (value == null) {
return null;
}
return TextConverterManager.getGlobalConverter().toValue(Double.class, value);
}
//================================================= Inner Classes ==================================================
private static class NodeListIterable implements Iterable<Element> {
private final NodeList nodes;
private NodeListIterable(NodeList nodes) {
this.nodes = nodes;
}
@SuppressWarnings("unchecked")
public Iterator<Element> iterator() {
return new FilteredIterator(new NodeListIterator(nodes), new AbstractPredicate<Node>() {
public boolean eval(Node node) {
return node.getNodeType() == Node.ELEMENT_NODE;
}
});
}
}
private static class NodeListIterator extends ReadOnlyIterator<Node> {
private final NodeList nodes;
private int index = 0;
private NodeListIterator(NodeList nodes) {
this.nodes = nodes;
}
public boolean hasNext() {
return index < nodes.getLength();
}
public Node next() {
return nodes.item(index++);
}
}
}