ch.javasoft.xml.config.XmlUtil.java Source code

Java tutorial

Introduction

Here is the source code for ch.javasoft.xml.config.XmlUtil.java

Source

/*
 * =============================================================================
 * Simplified BSD License, see http://www.opensource.org/licenses/
 * -----------------------------------------------------------------------------
 * Copyright (c) 2008-2009, Marco Terzer, Zurich, Switzerland
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice, 
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Swiss Federal Institute of Technology Zurich 
 *       nor the names of its contributors may be used to endorse or promote 
 *       products derived from this software without specific prior written 
 *       permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 * =============================================================================
 */
package ch.javasoft.xml.config;

import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.Node;

import ch.javasoft.xml.config.XmlConfig.XmlAttribute;

public class XmlUtil {

    /**
     * Returns the child element of the given type which has the desired 
     * attribute value in the given attribute. In xpath, this would be somewhat
     * like <code>/child[@attribute=$attributeValue]</code>
     * <p>
     * If multiple children match the criteria, an exception is thrown. If no
     * child matching the criteria is found, then either <code>null</code> is
     * returned (if <code>throwExceptionIfNull==false</code>), or an exception
     * is thrown (otherwise).
     * 
     * @param element            the parent element containing the desired 
     *                         child element
     * @param child               specifies the name of the child element
     * @param attribute            specifies the name of the identifying attribute
     * @param attributeValue      the desired attribute value
     * @param throwExceptionIfNull   if <code>true</code>, an exception is thrown 
     *                         if no child matches the criteria
     * @return                  the desired child element, or 
     *                         <code>null</code> if 
     *                         <code>throwExceptionIfNull==false</code> and
     *                         no child element matched the criteria
     * @throws XmlConfigException   If multiple matches occur, or if no match
     *                         was found and exception throwing is desired
     *                         for this case (see <code>throwExceptionIfNull</code>)
     */
    @SuppressWarnings("unchecked")
    public static Element getChildElementByAttributeValue(Element element, XmlNode child, XmlNode attribute,
            String attributeValue, boolean throwExceptionIfNull) throws XmlConfigException {
        Element res = null;
        Iterator<Element> it = element.elementIterator(child.getXmlName());
        while (it.hasNext()) {
            Element el = it.next();
            String attValue = el.attributeValue(attribute.getXmlName());
            if (attributeValue.equals(attValue)) {
                if (res == null)
                    res = el;
                else {
                    throw new XmlConfigException("multiple matches for " + child.getXmlName()
                            + " children with attribute " + attribute.getXmlName() + "='" + attributeValue + "'",
                            element);
                }
            }
        }
        if (res == null && throwExceptionIfNull) {
            throw new XmlConfigException("missing " + child.getXmlName() + " child with attribute "
                    + attribute.getXmlName() + "='" + attributeValue + "'", element);
        }
        return res;
    }

    /**
     * Returns a typed iterator for child elements of a certain type
     * 
     * @param element    parent of which certain child elements are desired
     * @param childType node defining the name of the desired child elements
     */
    @SuppressWarnings("unchecked")
    public static Iterator<Element> getChildElements(Element element, XmlNode childType) throws XmlConfigException {
        return element.elementIterator(childType.getXmlName());
    }

    /**
     * Returns the desired single child element, or throws an exception if none
     * or multiple are found.
     * 
     * @param element            the parent of the desired child
     * @param child               specifies the desired child element name
     * @return                  the child element
     * @throws XmlConfigException   if no or multiple children match the 
     *                         criteria
     */
    public static Element getRequiredSingleChildElement(Element element, XmlNode child) throws XmlConfigException {
        final Element result = getOptionalSingleChildElement(element, child);
        if (result == null) {
            throw new XmlConfigException("missing " + child.getXmlName() + " child element", element);
        }
        return result;
    }

    /**
     * Returns the desired single child element, or throws an exception if none
     * or multiple are found.
     * 
     * @param element            the parent of the desired child
     * @param child               specifies the desired child element name
     * @return                  the child element
     * @throws XmlConfigException   if no or multiple children match the 
     *                         criteria
     */
    public static Element getOptionalSingleChildElement(Element element, XmlNode child) throws XmlConfigException {
        @SuppressWarnings("unchecked")
        List<Element> list = element.elements(child.getXmlName());
        if (list.isEmpty()) {
            return null;
        } else if (list.size() > 1) {
            throw new XmlConfigException(
                    "expected single " + child.getXmlName() + " child, but found " + list.size(), element);
        }
        return list.get(0);
    }

    /**
     * Returns the desired attribute value, or throws an exception no such
     * attribute exists.
     * 
     * @param element            the element to get the attribute value from
     * @param attribute            specifies the desired attribute name
     * @return                  the attribute value
     * @throws XmlConfigException   if no such attribute value is defined
     */
    public static String getRequiredAttributeValue(Element element, XmlNode attribute) throws XmlConfigException {
        Attribute att = element.attribute(attribute.getXmlName());
        if (att == null) {
            throw new XmlConfigException(
                    "missing " + attribute.getXmlName() + " attribute for " + element.getName() + " element",
                    element);
        }
        return att.getValue();
    }

    /**
     * Returns the desired attribute value, or the given default value if no 
     * such attribute exists.
     * 
     * @param element            the element to get the attribute value from
     * @param attribute            specifies the desired attribute name
     * @param defaultValue         the default value to use if no such 
     *                         attribute exists
     * @return                  the attribute value, or the default if no
     *                         such attribute exists
     */
    public static String getOptionalAttributeValue(Element element, XmlNode attribute, String defaultValue)
            throws XmlConfigException {
        Attribute att = element.attribute(attribute.getXmlName());
        if (att == null) {
            return defaultValue;
        }
        return att.getValue();
    }

    /**
     * Check whether the given element has the desired name. Throws an exception
     * otherwise.
     * 
     * @param element            the element to check
     * @param expected            specifies the expected element name
     * @throws XmlConfigException   if the check fails
     */
    public static void checkExpectedElementName(Element element, XmlNode expected) throws XmlConfigException {
        if (!isExpectedElementName(element, expected)) {
            throw new XmlConfigException(
                    expected.getXmlName() + " element expected, but " + element.getName() + " found", element);
        }
    }

    /**
     * Returns true if the given element has the desired name.
     * 
     * @param element            the element to check
     * @param expected            specifies the expected element name
     * @return true if the check is successful
     */
    public static boolean isExpectedElementName(Element element, XmlNode expected) {
        return expected.getXmlName().equals(element.getName());
    }

    /**
     * Check whether the given element has the desired value for a specific
     * attribute. Throws an exception otherwise.
     * 
     * @param element            the element to check
     * @param attribute            specifies the attribute name
     * @param expectedValue         the desired attribute value
     * @throws XmlConfigException   if the check fails
     */
    public static void checkExpectedAttributeValue(Element element, XmlNode attribute, String expectedValue)
            throws XmlConfigException {
        String value = element.attributeValue(attribute.getXmlName());
        if (!expectedValue.equals(value)) {
            throw new XmlConfigException("expected value '" + expectedValue + "' for attribute '"
                    + attribute.getXmlName() + "', but found '" + value + "'", element);
        }
    }

    /**
     * Returns an xpath like string for the given xml node
     * 
     * @param node            the node to convert to a string
     * @param recurseParents   true if parents should be included
     * 
     * @return an xpath like string for the given node
     */
    public static String getNodePath(Node node, boolean recurseParents) {
        if (node instanceof Element) {
            return getElementPath((Element) node, recurseParents);
        }
        final StringBuilder sb = new StringBuilder(node.getName());
        if (recurseParents && node.getParent() != null) {
            sb.insert(0, node instanceof Attribute ? '@' : '/');
            sb.insert(0, getElementPath(node.getParent(), recurseParents));
        }
        return sb.toString();
    }

    /**
     * Returns an xpath like string for the given xml element
     * 
     * @param elem            the element to convert to a string
     * @param recurseParents   true if parents should be included
     * 
     * @return an xpath like string for the given element
     */
    public static String getElementPath(Element elem, boolean recurseParents) {
        StringBuilder sb = new StringBuilder(elem.getName());
        String name = elem.attributeValue(XmlAttribute.name.getXmlName());
        if (name != null) {
            sb.append("[" + name + "]");
        }
        if (recurseParents && !elem.isRootElement() && elem.getParent() != null) {
            sb.insert(0, '/');
            sb.insert(0, getElementPath(elem.getParent(), recurseParents));
        }
        return sb.toString();
    }

    //no instances
    private XmlUtil() {
    }
}