| /* |
| * 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.layoutengine; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMResult; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.sax.SAXResult; |
| import javax.xml.transform.sax.TransformerHandler; |
| |
| import org.apache.fop.DebugHelper; |
| import org.apache.fop.apps.FOUserAgent; |
| import org.apache.fop.apps.Fop; |
| import org.apache.fop.apps.FopFactory; |
| import org.apache.fop.apps.FormattingResults; |
| import org.apache.fop.area.AreaTreeModel; |
| import org.apache.fop.area.AreaTreeParser; |
| import org.apache.fop.area.RenderPagesModel; |
| import org.apache.fop.events.model.EventSeverity; |
| import org.apache.fop.fonts.FontInfo; |
| import org.apache.fop.intermediate.IFTester; |
| import org.apache.fop.intermediate.TestAssistant; |
| import org.apache.fop.layoutmgr.ElementListObserver; |
| import org.apache.fop.render.intermediate.IFContext; |
| import org.apache.fop.render.intermediate.IFRenderer; |
| import org.apache.fop.render.intermediate.IFSerializer; |
| import org.apache.fop.render.xml.XMLRenderer; |
| import org.apache.fop.util.ConsoleEventListenerForTests; |
| import org.apache.fop.util.DelegatingContentHandler; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Parameterized; |
| import org.junit.runners.Parameterized.Parameters; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * Class for testing the FOP's layout engine using testcases specified in XML |
| * files. |
| */ |
| @RunWith(Parameterized.class) |
| public class LayoutEngineTester { |
| private static File areaTreeBackupDir; |
| /** |
| * Sets up the class, this is invoked only once. |
| */ |
| @BeforeClass |
| public static void makeDirAndRegisterDebugHelper() { |
| DebugHelper.registerStandardElementListObservers(); |
| areaTreeBackupDir = new File("build/test-results/layoutengine"); |
| areaTreeBackupDir.mkdirs(); |
| } |
| |
| /** |
| * Creates the parameters for this test. |
| * |
| * @return the list of file arrays populated with test files |
| * @throws IOException if an I/O error occurs while reading the test file |
| */ |
| @Parameters |
| public static Collection<File[]> getParameters() throws IOException { |
| return LayoutEngineTestUtils.getTestFiles(); |
| } |
| |
| private TestAssistant testAssistant = new TestAssistant(); |
| |
| private LayoutEngineChecksFactory layoutEngineChecksFactory = new LayoutEngineChecksFactory(); |
| |
| private IFTester ifTester; |
| private File testFile; |
| |
| private TransformerFactory tfactory = TransformerFactory.newInstance(); |
| |
| /** |
| * Constructs a new instance. |
| * |
| * @param testFile the test file |
| */ |
| public LayoutEngineTester(File testFile) { |
| this.ifTester = new IFTester(tfactory, areaTreeBackupDir); |
| this.testFile = testFile; |
| } |
| |
| /** |
| * Runs a single layout engine test case. |
| * @throws TransformerException In case of an XSLT/JAXP problem |
| * @throws IOException In case of an I/O problem |
| * @throws SAXException In case of a problem during SAX processing |
| * @throws ParserConfigurationException In case of a problem with the XML parser setup |
| */ |
| @Test |
| public void runTest() throws TransformerException, SAXException, IOException, |
| ParserConfigurationException { |
| |
| DOMResult domres = new DOMResult(); |
| |
| ElementListCollector elCollector = new ElementListCollector(); |
| ElementListObserver.addObserver(elCollector); |
| |
| Fop fop; |
| FopFactory effFactory; |
| try { |
| Document testDoc = testAssistant.loadTestCase(testFile); |
| effFactory = testAssistant.getFopFactory(testDoc); |
| |
| //Setup Transformer to convert the testcase XML to XSL-FO |
| Transformer transformer = testAssistant.getTestcase2FOStylesheet().newTransformer(); |
| Source src = new DOMSource(testDoc); |
| |
| //Setup Transformer to convert the area tree to a DOM |
| TransformerHandler athandler; |
| athandler = testAssistant.getTransformerFactory().newTransformerHandler(); |
| athandler.setResult(domres); |
| |
| //Setup FOP for area tree rendering |
| FOUserAgent ua = effFactory.newFOUserAgent(); |
| ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString()); |
| ua.getEventBroadcaster().addEventListener( |
| new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); |
| |
| XMLRenderer atrenderer = new XMLRenderer(); |
| atrenderer.setUserAgent(ua); |
| atrenderer.setContentHandler(athandler); |
| ua.setRendererOverride(atrenderer); |
| fop = effFactory.newFop(ua); |
| |
| SAXResult fores = new SAXResult(fop.getDefaultHandler()); |
| transformer.transform(src, fores); |
| } finally { |
| ElementListObserver.removeObserver(elCollector); |
| } |
| |
| Document doc = (Document)domres.getNode(); |
| if (this.areaTreeBackupDir != null) { |
| testAssistant.saveDOM(doc, |
| new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml")); |
| } |
| FormattingResults results = fop.getResults(); |
| LayoutResult result = new LayoutResult(doc, elCollector, results); |
| checkAll(effFactory, testFile, result); |
| } |
| |
| /** |
| * Perform all checks on the area tree and, optionally, on the intermediate format. |
| * @param testFile Test case XML file |
| * @param result The layout results |
| * @throws TransformerException if a problem occurs in XSLT/JAXP |
| */ |
| protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result) |
| throws TransformerException { |
| Element testRoot = testAssistant.getTestRoot(testFile); |
| |
| NodeList nodes; |
| //AT tests only when checks are available |
| nodes = testRoot.getElementsByTagName("at-checks"); |
| if (nodes.getLength() > 0) { |
| Element atChecks = (Element)nodes.item(0); |
| doATChecks(atChecks, result); |
| } |
| |
| //IF tests only when checks are available |
| nodes = testRoot.getElementsByTagName("if-checks"); |
| if (nodes.getLength() > 0) { |
| Element ifChecks = (Element)nodes.item(0); |
| Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree()); |
| ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument); |
| } |
| } |
| |
| private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML) |
| throws TransformerException { |
| try { |
| FOUserAgent ua = fopFactory.newFOUserAgent(); |
| ua.setBaseURL(testFile.getParentFile().toURI().toURL().toExternalForm()); |
| ua.getEventBroadcaster().addEventListener( |
| new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); |
| |
| IFRenderer ifRenderer = new IFRenderer(); |
| ifRenderer.setUserAgent(ua); |
| |
| IFSerializer serializer = new IFSerializer(); |
| serializer.setContext(new IFContext(ua)); |
| DOMResult result = new DOMResult(); |
| serializer.setResult(result); |
| ifRenderer.setDocumentHandler(serializer); |
| |
| ua.setRendererOverride(ifRenderer); |
| FontInfo fontInfo = new FontInfo(); |
| //Construct the AreaTreeModel that will received the individual pages |
| final AreaTreeModel treeModel = new RenderPagesModel(ua, |
| null, fontInfo, null); |
| |
| //Iterate over all intermediate files |
| AreaTreeParser parser = new AreaTreeParser(); |
| ContentHandler handler = parser.getContentHandler(treeModel, ua); |
| |
| DelegatingContentHandler proxy = new DelegatingContentHandler() { |
| |
| public void endDocument() throws SAXException { |
| super.endDocument(); |
| //Signal the end of the processing. |
| //The renderer can finalize the target document. |
| treeModel.endDocument(); |
| } |
| |
| }; |
| proxy.setDelegateContentHandler(handler); |
| |
| Transformer transformer = tfactory.newTransformer(); |
| transformer.transform(new DOMSource(areaTreeXML), new SAXResult(proxy)); |
| |
| return (Document)result.getNode(); |
| } catch (Exception e) { |
| throw new TransformerException( |
| "Error while generating intermediate format file: " + e.getMessage(), e); |
| } |
| } |
| |
| private void doATChecks(Element checksRoot, LayoutResult result) { |
| List<LayoutEngineCheck> checks = layoutEngineChecksFactory.createCheckList(checksRoot); |
| if (checks.size() == 0) { |
| throw new RuntimeException("No available area tree check"); |
| } |
| for (LayoutEngineCheck check : checks) { |
| check.check(result); |
| } |
| } |
| |
| } |