view flys-aft/src/main/java/de/intevation/utils/XML.java @ 4070:d09adfa90942

Added XML/XPath support. flys-aft/trunk@3397 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 13 Dec 2011 10:01:44 +0000
parents
children 88f801888d85
line wrap: on
line source
package de.intevation.utils;

import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathVariableResolver;

public final class XML
{
    /** Logger for this class. */
    private static Logger log = Logger.getLogger(XML.class);

    public static class MapXPathVariableResolver
    implements          XPathVariableResolver 
    {
        protected Map<String, String> variables;


        public MapXPathVariableResolver() {
            this.variables = new HashMap<String, String>();
        }


        public MapXPathVariableResolver(Map<String, String> variables) {
            this.variables = variables;
        }


        public void addVariable(String name, String value) {
            variables.put(name, value);
        }


        @Override
        public Object resolveVariable(QName variableName) {
            String key = variableName.getLocalPart();
            return variables.get(key);
        }
    } // class MapXPathVariableResolver

    private XML() {
    }

    /**
     * Loads a XML document namespace aware from a file
     * @param file The file to load.
     * @return the XML document or null if something went wrong
     * during loading.
     */
    public static final Document parseDocument(File file) {
        InputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(file));
            return parseDocument(inputStream);
        }
        catch (IOException ioe) {
            log.error(ioe.getLocalizedMessage(), ioe);
        }
        finally {
            if (inputStream != null) {
                try { inputStream.close(); }
                catch (IOException ioe) {}
            }
        }
        return null;
    }


    public static final Document parseDocument(InputStream inputStream) {
        return parseDocument(inputStream, Boolean.TRUE);
    }

    public static final Document parseDocument(
        InputStream inputStream,
        Boolean     namespaceAware
    ) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        if (namespaceAware != null) {
            factory.setNamespaceAware(namespaceAware.booleanValue());
        }

        try {
            return factory.newDocumentBuilder().parse(inputStream);
        }
        catch (ParserConfigurationException pce) {
            log.error(pce.getLocalizedMessage(), pce);
        }
        catch (SAXException se) {
            log.error(se.getLocalizedMessage(), se);
        }
        catch (IOException ioe) {
            log.error(ioe.getLocalizedMessage(), ioe);
        }
        return null;
    }


    /**
     * Creates a new XPath without a namespace context.
     * @return the new XPath.
     */
    public static final XPath newXPath() {
        return newXPath(null, null);
    }

    /**
     * Creates a new XPath with a given namespace context.
     * @param namespaceContext The namespace context to be used or null
     * if none should be used.
     * @return The new XPath
     */
    public static final XPath newXPath(
        NamespaceContext      namespaceContext,
        XPathVariableResolver resolver)
    {
        XPathFactory factory = XPathFactory.newInstance();
        XPath        xpath   = factory.newXPath();
        if (namespaceContext != null) {
            xpath.setNamespaceContext(namespaceContext);
        }

        if (resolver != null) {
            xpath.setXPathVariableResolver(resolver);
        }
        return xpath;
    }

    /**
     * Evaluates an XPath query on a given object and returns the result
     * as a given type. No namespace context is used.
     * @param root  The object which is used as the root of the tree to
     * be searched in.
     * @param query The XPath query
     * @param returnTyp The type of the result.
     * @return The result of type 'returnTyp' or null if something
     * went wrong during XPath evaluation.
     */
    public static final Object xpath(
        Object root,
        String query,
        QName  returnTyp
    ) {
        return xpath(root, query, returnTyp, null);
    }

    /**
     * Evaluates an XPath query on a given object and returns the result
     * as a given type. Optionally a namespace context is used.
     * @param root The object which is used as the root of the tree to
     * be searched in.
     * @param query The XPath query
     * @param returnType The type of the result.
     * @param namespaceContext The namespace context to be used or null
     * if none should be used.
     * @return The result of type 'returnTyp' or null if something
     * went wrong during XPath evaluation.
     */
    public static final Object xpath(
        Object           root,
        String           query,
        QName            returnType,
        NamespaceContext namespaceContext
    ) {
        return xpath(root, query, returnType, namespaceContext, null);
    }

    public static final Object xpath(
        Object           root,
        String           query,
        QName            returnType,
        NamespaceContext namespaceContext,
        Map<String, String> variables)
    {
        if (root == null) {
            return null;
        }

        XPathVariableResolver resolver = variables != null
            ? new MapXPathVariableResolver(variables)
            : null;

        try {
            XPath xpath = newXPath(namespaceContext, resolver);
            if (xpath != null) {
                return xpath.evaluate(query, root, returnType);
            }
        }
        catch (XPathExpressionException xpee) {
            log.error(xpee.getLocalizedMessage(), xpee);
        }

        return null;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org