/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */ /* $Id$ */ package org.apache.fop.intermediate; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.xml.transform.ErrorListener; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMSource; import org.custommonkey.xmlunit.XMLAssert; import org.junit.After; import org.junit.Before; import org.w3c.dom.Document; import org.xml.sax.SAXException; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.NullOutputStream; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; import org.apache.fop.events.model.EventSeverity; import org.apache.fop.util.ConsoleEventListenerForTests; /** * Abstract base class for intermediate format tests. */ public abstract class AbstractIntermediateTest { /** the test environment */ protected static TestAssistant testAssistant = new TestAssistant(); /** the FOP factory */ protected FopFactory fopFactory; /** the directory containing the tests */ protected File testDir = new File("test/layoutengine/standard-testcases"); /** the output directory for any files generated by the tests */ protected File outputDir; /** the test file */ protected File testFile; /** the test document as DOM */ protected Document testDoc; /** the intermediate format document as DOM */ protected Document intermediate; /** * Constructor for the test suite that is used for each test file. * @param testFile the test file to run * @throws IOException if an I/O error occurs while loading the test case */ public AbstractIntermediateTest(File testFile) throws IOException { this.testFile = testFile; } @Before public void setUp() throws Exception { setupOutputDirectory(); this.testDoc = testAssistant.loadTestCase(testFile); this.fopFactory = testAssistant.getFopFactory(testDoc); intermediate = buildIntermediateDocument(testAssistant.getTestcase2FOStylesheet()); if (outputDir != null) { testAssistant.saveDOM(intermediate, new File(outputDir, testFile.getName() + ".1" + getIntermediateFileExtension())); } } @After public void tearDown() throws Exception { //Release memory this.intermediate = null; this.fopFactory = null; this.testDoc = null; } /** * Returns the file extension for the intermediate file format. * @return the file extension */ protected abstract String getIntermediateFileExtension(); /** * Returns the MIME type for which to test or to mimic for the intermediate format. * @return the MIME type */ protected String getTargetMIME() { return MimeConstants.MIME_PDF; } /** * Validates the intermediate format file. * @param doc the intermediate file * @throws IOException if an IO error occurs while loading the schema * @throws SAXException if a SAX-related exception (including a validation error) occurs */ protected void validate(Document doc) throws SAXException, IOException { //nop by default } /** * Builds an intermediate format document from a source file. * @param templates the (optional) stylesheet * @return the intermediate format document as a DOM * @throws Exception if an error occurs while processing the document */ protected abstract Document buildIntermediateDocument(Templates templates) throws Exception; /** * Creates a new FOP user agent. * @return the user agent */ protected FOUserAgent createUserAgent() { FOUserAgent userAgent = fopFactory.newFOUserAgent(); userAgent.getEventBroadcaster().addEventListener( new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.FATAL)); return userAgent; } /** * Sets up the output directory. */ protected void setupOutputDirectory() { String s = System.getProperty("fop.intermediate.outdir"); if (s != null && s.length() > 0) { outputDir = new File(s); outputDir.mkdirs(); } } /** * Tests the area tree parser by running the parsed area tree again through the area tree * renderer. The source and result documents are compared to each other. * @throws Exception if the test fails */ public void testParserToIntermediateFormat() throws Exception { validate(intermediate); Source src = new DOMSource(intermediate); Document doc = parseAndRenderToIntermediateFormat(src); if (outputDir != null) { File tgtFile = new File(outputDir, testFile.getName() + ".2" + getIntermediateFileExtension()); testAssistant.saveDOM(doc, tgtFile); } XMLAssert.assertXMLEqual(testFile.toString(), intermediate, doc); } /** * Parses the intermediate file and renders it back to the intermediate format. * @param src the source for the intermediate file * @return a DOM Document with the re-created intermediate file * @throws Exception if an error occurs while processing the document */ protected abstract Document parseAndRenderToIntermediateFormat(Source src) throws Exception; /** * Tests the area tree parser by sending the parsed area tree to the PDF Renderer. Some * errors might be caught by the PDFRenderer. * @throws Exception if the test fails */ public void testParserToPDF() throws Exception { OutputStream out; if (outputDir != null) { File tgtFile = new File(outputDir, testFile.getName() + ".pdf"); out = new FileOutputStream(tgtFile); out = new BufferedOutputStream(out); } else { out = new NullOutputStream(); } try { Source src = new DOMSource(intermediate); parseAndRender(src, out); } finally { IOUtils.closeQuietly(out); } } /** * Parses and renders an intermediate format document to a final format. * @param src the source document * @param out the target output stream * @throws Exception if an error occurs while rendering the document */ protected abstract void parseAndRender(Source src, OutputStream out) throws Exception; /** * Run the test. * * @throws Exception if an error occurs during the test */ public abstract void runTest() throws Exception; /** * Sets an error listener which doesn't swallow errors like Xalan's default one. * @param transformer the transformer to set the error listener on */ protected void setErrorListener(Transformer transformer) { transformer.setErrorListener(new ErrorListener() { public void error(TransformerException exception) throws TransformerException { throw exception; } public void fatalError(TransformerException exception) throws TransformerException { throw exception; } public void warning(TransformerException exception) throws TransformerException { //ignore } }); } }