org.getwheat.harvest.library.dom.DomHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.getwheat.harvest.library.dom.DomHelper.java

Source

package org.getwheat.harvest.library.dom;

import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/*
 * Copyright 2011 by Christopher Smith
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

/**
 * DomHelper is a utility class that provides common functionality for DOM processing.
 * 
 * @author Christopher Smith
 */
public class DomHelper {
    private static final Logger LOG = LoggerFactory.getLogger(DomHelper.class);
    private static final String VALUE_BOOLEAN = "boolean";
    private static final String VALUE_DECIMAL = "decimal";
    private static final String VALUE_INTEGER = "integer";
    private static final String VALUE_NIL = "nil";
    private static final String VALUE_TRUE = "true";
    private static final String VALUE_TYPE = "type";
    public static final String DTP_FULL = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    public static final String DTP_DATE = "yyyy-MM-dd";

    /**
     * Creates an empty {@link Document}.
     * 
     * @return a DOM Document
     * @throws ParserConfigurationException
     */
    public Document create() throws ParserConfigurationException {
        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        final DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.newDocument();
    }

    /**
     * Adds a root {@link Element} to the {@link Document}.
     * 
     * @param document
     * @param tag
     * @return the created {@link Element}
     */
    public Element addRootElement(final Document document, final XmlTag tag) {
        final Element element = document.createElement(tag.getElementName());
        document.appendChild(element);
        return element;
    }

    /**
     * Adds an {@link Element} to the parent if the value is not null.
     * 
     * @param document
     * @param parent
     * @param tag
     * @param value
     * @return the created {@link Element}
     */
    public Element addElement(final Document document, final Element parent, final XmlTag tag, final String value) {
        Element element = null;
        if (value != null) {
            element = document.createElement(tag.getElementName());
            element.appendChild(document.createTextNode(value));
            parent.appendChild(element);
        }
        return element;
    }

    /**
     * Adds an {@link Element} to the parent if the value is not null.
     * <p />
     * A type attribute is also added to the {@link Element}.
     * 
     * @param document
     * @param parent
     * @param tag
     * @param value
     */
    public void addElement(final Document document, final Element parent, final XmlTag tag,
            final BigDecimal value) {
        if (value != null) {
            final Element element = addElement(document, parent, tag, value.toString());
            element.setAttribute(VALUE_TYPE, VALUE_DECIMAL);
        }
    }

    /**
     * Adds an {@link Element} to the parent if the value is not null.
     * <p />
     * A type attribute is also added to the {@link Element}.
     * 
     * @param document
     * @param parent
     * @param tag
     * @param value
     */
    public void addElement(final Document document, final Element parent, final XmlTag tag, final Integer value) {
        if (value != null) {
            final Element element = addElement(document, parent, tag, value.toString());
            element.setAttribute(VALUE_TYPE, VALUE_INTEGER);
        }
    }

    /**
     * Adds an {@link Element} to the parent.
     * <p />
     * A type attribute is also added to the {@link Element}.
     * 
     * @param document
     * @param parent
     * @param tag
     * @param value
     */
    public void addElement(final Document document, final Element parent, final XmlTag tag, final boolean value) {
        final Element element = addElement(document, parent, tag, Boolean.toString(value));
        element.setAttribute(VALUE_TYPE, VALUE_BOOLEAN);
    }

    /**
     * Converts the {@link Document} to a string.
     * 
     * @param document
     * @return XML string
     * @throws TransformerException
     */
    public String convertToString(final Document document) throws TransformerException {
        final TransformerFactory factory = TransformerFactory.newInstance();
        final Transformer transformer = factory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        final StringWriter writer = new StringWriter();
        final StreamResult result = new StreamResult(writer);
        final DOMSource source = new DOMSource(document);
        transformer.transform(source, result);
        return writer.toString();
    }

    /**
     * Parses the entity content and returns a DOM Document.
     * <p />
     * This method uses the default system DocumentBuilderFactory to parse the entity's content
     * stream.
     * 
     * @param entity
     * @return a DOM Document
     * @throws ParserConfigurationException
     * @throws IllegalStateException
     * @throws IOException
     * @throws SAXException
     * @see DocumentBuilderFactory
     */
    public Document getDomDocument(final HttpEntity entity)
            throws ParserConfigurationException, IllegalStateException, IOException, SAXException {
        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        final DocumentBuilder builder = factory.newDocumentBuilder();
        final InputSource input = new InputSource();
        input.setByteStream(entity.getContent());
        return builder.parse(input);
    }

    /**
     * Converts the value of the specified tag to a Date object.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @param parsePattern the Joda Time format to use for converting the Date
     * @return a Date object or null if not found
     */
    public Date getDateValue(final Element element, final XmlTag tag, final String parsePattern) {
        Date value = null;
        final String nodeValue = getStringValue(element, tag);
        if (nodeValue != null) {
            final DateTimeFormatter formatter = DateTimeFormat.forPattern(parsePattern);
            try {
                value = formatter.parseDateTime(nodeValue).toDate();
            } catch (Exception ex) {
                LOG.warn("", ex);
            }
        }
        return value;
    }

    /**
     * Converts the value of the specified tag to a boolean.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @return boolean
     */
    public boolean getBooleanValue(final Element element, final XmlTag tag) {
        return Boolean.parseBoolean(getStringValue(element, tag));
    }

    /**
     * Converts the value of the specified tag to an int.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @return int
     */
    public int getIntValue(final Element element, final XmlTag tag) {
        int value = 0;
        final String nodeValue = getStringValue(element, tag);
        if (nodeValue != null) {
            try {
                value = Integer.parseInt(nodeValue);
            } catch (Exception ex) {
                LOG.warn("", ex);
            }
        }
        return value;
    }

    /**
     * Extracts the value for the specified tag.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @return a String or null if not found
     */
    public String getStringValue(final Element element, final XmlTag tag) {
        String value = null;
        final Element item = getElementByTagName(element, tag);
        if (isValid(item)) {
            value = item.getFirstChild().getNodeValue();
        }
        return value;
    }

    private boolean isValid(final Element element) {
        boolean value = false;
        if (element != null) {
            if (element.hasAttribute(VALUE_NIL)
                    && VALUE_TRUE.equals(element.getAttributeNode(VALUE_NIL).getNodeValue())) {
                value = false;
            } else {
                final Node child = element.getFirstChild();
                value = child != null;
            }
        }
        return value;
    }

    private Element getElementByTagName(final Element element, final XmlTag tag) {
        Element child = null;
        if (element != null) {
            final NodeList list = element.getElementsByTagName(tag.getElementName());
            if (list.getLength() > 0) {
                child = (Element) list.item(0);
            }
        }
        return child;
    }

    /**
     * Converts the value of the specified tag to an Integer.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @return an Integer or null if not found
     */
    public Integer getIntegerValue(final Element element, final XmlTag tag) {
        Integer value = null;
        final String nodeValue = getStringValue(element, tag);
        if (nodeValue != null) {
            try {
                value = Integer.valueOf(nodeValue);
            } catch (Exception ex) {
                LOG.warn("", ex);
            }
        }
        return value;
    }

    /**
     * Converts the value of the specified tag to a BigDecimal.
     * 
     * @param element the Element to search
     * @param tag the XML Tag to find
     * @return a BigDecimal or null if not found
     */
    public BigDecimal getBigDecimalValue(final Element element, final XmlTag tag) {
        BigDecimal value = null;
        final String nodeValue = getStringValue(element, tag);
        if (nodeValue != null) {
            try {
                value = BigDecimal.valueOf(Double.valueOf(nodeValue));
            } catch (Exception ex) {
                LOG.warn("", ex);
            }
        }
        return value;
    }

    /**
     * Retrieves the Location HTTP Header identifier that matches the pattern.
     * 
     * @param headers
     * @param pattern
     * @return the identifier
     */
    public int getIdentifier(final Header[] headers, final String pattern) {
        int identifier = 0;
        if (headers != null && headers.length > 0) {
            final Matcher matcher = Pattern.compile(pattern).matcher(headers[0].getValue());
            if (matcher.find()) {
                identifier = Integer.parseInt(matcher.group(1));
            }
        }
        return identifier;
    }
}