com.onespatial.jrc.tns.oml_to_rif.fixture.DomBasedUnitTest.java Source code

Java tutorial

Introduction

Here is the source code for com.onespatial.jrc.tns.oml_to_rif.fixture.DomBasedUnitTest.java

Source

/*
 * Copyright (c) 2012 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     1Spatial PLC <http://www.1spatial.com>
 *     HUMBOLDT EU Integrated Project #030962
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */
package com.onespatial.jrc.tns.oml_to_rif.fixture;

import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.hamcrest.CoreMatchers;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.BeforeClass;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * Test fixture class for facilitating tests requiring to manipulate DOM
 * documents.
 * 
 * @author Simon Payne (Simon.Payne@1spatial.com) / 1Spatial Group Ltd.
 * @author Richard Sunderland (Richard.Sunderland@1spatial.com) / 1Spatial Group Ltd.
 */
public abstract class DomBasedUnitTest {
    /**
     * For logging of test output by child classes.
     */
    protected Log log = LogFactory.getLog(DomBasedUnitTest.class);

    /**
     * Document builder to parse test artifacts into DOM.
     */
    private static DocumentBuilder builder;

    /**
     * Transform used to dump DOMs.
     */
    private static Transformer transformer;

    /**
     * Run once, before any tests are run.
     * 
     * @throws FactoryConfigurationError
     *             if any errors occurred configuring the
     *             {@link DocumentBuilderFactory}
     * @throws ParserConfigurationException
     *             if any errors occurred creating a {@link DocumentBuilder}
     * @throws TransformerConfigurationException
     *             if any errors occurred configuring the
     *             {@link TransformerFactory}
     */
    @BeforeClass
    public static void beforeAnyTest()
            throws ParserConfigurationException, FactoryConfigurationError, TransformerConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        builder = factory.newDocumentBuilder();

        TransformerFactory tFactory = TransformerFactory.newInstance();
        transformer = tFactory.newTransformer();
    }

    /**
     * Load a DOM from the class path.
     * 
     * @param path
     *            the name of the XML file.
     * @return the DOM of the XML file.
     * @throws IOException
     *             if any errors occurred acquiring an {@link InputStream} to
     *             read the given XML file
     * @throws SAXException
     *             if any errors occurred parsing the XML file
     */
    protected Document loadDom(String path) throws SAXException, IOException {
        InputStream rifStream = getClass().getResourceAsStream(path);
        if (rifStream == null) {
            throw new IllegalArgumentException("Could not find " + path + " on class path."); //$NON-NLS-1$ //$NON-NLS-2$
        }

        return builder.parse(rifStream);
    }

    /**
     * @param actualDom
     *            {@link Document}
     * @param expectedContent
     *            String
     * @throws SAXException
     *             if any errors occurred parsing the content
     * @throws IOException
     *             if any errors occurred acquiring an {@link InputStream} to
     *             read the content
     */
    protected void testDom(Document actualDom, String expectedContent) throws SAXException, IOException {
        Document expectedDom = loadDom(expectedContent);

        XMLUnit.setIgnoreWhitespace(true);
        XMLUnit.setIgnoreComments(true);
        Diff diff = new Diff(expectedDom, actualDom);

        if (!diff.similar()) {
            log.debug("Expected:"); //$NON-NLS-1$
            writeDom(expectedDom, System.out);
            log.debug("\n\nActual:"); //$NON-NLS-1$
            writeDom(actualDom, System.out);
            log.debug(diff);
        }

        assertThat(diff.similar(), CoreMatchers.is(true));
        // assertThat(diff.identical(), is(true));
    }

    /**
     * Pretty Print a DOM to a stream.
     * 
     * @param document
     *            the DOM to print.
     * @param dest
     *            the stream to write to.
     */
    protected void writeDom(Document document, OutputStream dest) {
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(dest);
        try {
            transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
            transformer.transform(source, result);
        } catch (TransformerException e) {
            e.printStackTrace();
            fail();
        }
    }

    /**
     * @param rifDocument
     *            {@link org.w3._2007.rif.Document}
     * @return {@link Document}
     * @throws JAXBException
     *             if any errors occurred trying to marshall the RIF content to
     *             an DOM document
     * @throws ParserConfigurationException
     */
    protected org.w3c.dom.Document getDomFromRif(org.w3._2007.rif.Document rifDocument) throws JAXBException {
        org.w3c.dom.Document domDocument = builder.newDocument();
        JAXBContext jc = JAXBContext.newInstance("org.w3._2007.rif", getClass().getClassLoader()); //$NON-NLS-1$
        jc.createMarshaller()
                .marshal(new JAXBElement<org.w3._2007.rif.Document>(new QName("http://www.w3.org/2007/rif#", //$NON-NLS-1$
                        "Document", "rif"), org.w3._2007.rif.Document.class, rifDocument), //$NON-NLS-1$ //$NON-NLS-2$
                        domDocument);
        return domDocument;
    }
}