/* * 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; } }