|  | /* | 
|  | * 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; | 
|  |  | 
|  | import java.io.File; | 
|  | import java.io.FileInputStream; | 
|  | import java.io.IOException; | 
|  | import java.io.OutputStream; | 
|  | import java.net.URI; | 
|  |  | 
|  | import javax.xml.transform.Result; | 
|  | import javax.xml.transform.Source; | 
|  | import javax.xml.transform.Transformer; | 
|  | import javax.xml.transform.TransformerException; | 
|  | import javax.xml.transform.dom.DOMResult; | 
|  | import javax.xml.transform.dom.DOMSource; | 
|  | import javax.xml.transform.sax.SAXResult; | 
|  | import javax.xml.transform.sax.SAXTransformerFactory; | 
|  | import javax.xml.transform.sax.TransformerHandler; | 
|  | import javax.xml.transform.stream.StreamResult; | 
|  | import javax.xml.transform.stream.StreamSource; | 
|  |  | 
|  | import org.junit.BeforeClass; | 
|  | import org.junit.Test; | 
|  | import org.w3c.dom.Document; | 
|  |  | 
|  | import static org.junit.Assert.assertEquals; | 
|  | import static org.junit.Assert.assertTrue; | 
|  |  | 
|  | import org.apache.commons.io.IOUtils; | 
|  | import org.apache.commons.io.output.ByteArrayOutputStream; | 
|  | import org.apache.xpath.XPathAPI; | 
|  | import org.apache.xpath.objects.XObject; | 
|  |  | 
|  | import org.apache.xmlgraphics.io.Resource; | 
|  | import org.apache.xmlgraphics.io.ResourceResolver; | 
|  |  | 
|  | import org.apache.fop.apps.FOPException; | 
|  | import org.apache.fop.apps.FOUserAgent; | 
|  | import org.apache.fop.apps.Fop; | 
|  | import org.apache.fop.apps.FopFactory; | 
|  | import org.apache.fop.apps.FopFactoryBuilder; | 
|  | import org.apache.fop.apps.MimeConstants; | 
|  | import org.apache.fop.apps.io.ResourceResolverFactory; | 
|  | import org.apache.fop.render.xml.XMLRenderer; | 
|  |  | 
|  | import static org.apache.fop.FOPTestUtils.getBaseDir; | 
|  |  | 
|  | /** | 
|  | * Tests URI resolution facilities. | 
|  | */ | 
|  | public class URIResolutionTestCase { | 
|  |  | 
|  | private SAXTransformerFactory tfactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); | 
|  |  | 
|  | private static final File BACKUP_DIR = new File(getBaseDir(), "build/test-results"); | 
|  |  | 
|  | private static FopFactory fopFactory; | 
|  |  | 
|  | @BeforeClass | 
|  | public static void makeDirs() { | 
|  | BACKUP_DIR.mkdirs(); | 
|  | fopFactory = new FopFactoryBuilder(new File(".").getAbsoluteFile().toURI(), | 
|  | new CustomURIResolver()).build(); | 
|  | } | 
|  |  | 
|  | private static File getTestDir() { | 
|  | return new File(getBaseDir(), "test/xml/uri-testing/"); | 
|  | } | 
|  |  | 
|  | @Test | 
|  | public void innerTestFO1() throws Exception { | 
|  | File foFile = new File(getTestDir(), "custom-scheme/only-scheme-specific-part.fo"); | 
|  |  | 
|  | FOUserAgent ua = fopFactory.newFOUserAgent(); | 
|  |  | 
|  | Document doc = createAreaTree(foFile, ua); | 
|  |  | 
|  | // XPath checking on the area tree | 
|  | assertEquals("viewport for external-graphic is missing", | 
|  | "true", evalXPath(doc, "boolean(//flow/block[1]/lineArea/viewport)")); | 
|  | assertEquals("46080", evalXPath(doc, "//flow/block[1]/lineArea/viewport/@ipd")); | 
|  | assertEquals("46080", evalXPath(doc, "//flow/block[1]/lineArea/viewport/@bpd")); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test custom URI resolution with a hand-written URIResolver. | 
|  | * @throws Exception if anything fails | 
|  | */ | 
|  | @Test | 
|  | public void testFO2() throws Exception { | 
|  | File foFile = new File(getTestDir(), "custom-scheme/only-scheme-specific-part-svg.fo"); | 
|  |  | 
|  | FOUserAgent ua = fopFactory.newFOUserAgent(); | 
|  |  | 
|  | ByteArrayOutputStream baout = new ByteArrayOutputStream(); | 
|  |  | 
|  | Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, ua, baout); | 
|  |  | 
|  | Transformer transformer = tfactory.newTransformer(); //Identity transf. | 
|  | Source src = new StreamSource(foFile); | 
|  | Result res = new SAXResult(fop.getDefaultHandler()); | 
|  | transformer.transform(src, res); | 
|  |  | 
|  | OutputStream out = new java.io.FileOutputStream( | 
|  | new File(BACKUP_DIR, foFile.getName() + ".pdf")); | 
|  | try { | 
|  | baout.writeTo(out); | 
|  | } finally { | 
|  | IOUtils.closeQuietly(out); | 
|  | } | 
|  |  | 
|  | //Test using PDF as the area tree doesn't invoke Batik so we could check | 
|  | //if the resolver is actually passed to Batik by FOP | 
|  | assertTrue("Generated PDF has zero length", baout.size() > 0); | 
|  | } | 
|  |  | 
|  | private Document createAreaTree(File fo, FOUserAgent ua) | 
|  | throws TransformerException, FOPException { | 
|  | DOMResult domres = new DOMResult(); | 
|  | //Setup Transformer to convert the area tree to a DOM | 
|  | TransformerHandler athandler = tfactory.newTransformerHandler(); | 
|  | athandler.setResult(domres); | 
|  |  | 
|  | XMLRenderer atrenderer = new XMLRenderer(ua); | 
|  | atrenderer.setContentHandler(athandler); | 
|  | ua.setRendererOverride(atrenderer); | 
|  |  | 
|  | Fop fop = fopFactory.newFop(ua); | 
|  |  | 
|  | Transformer transformer = tfactory.newTransformer(); //Identity transf. | 
|  | Source src = new StreamSource(fo); | 
|  | Result res = new SAXResult(fop.getDefaultHandler()); | 
|  | transformer.transform(src, res); | 
|  |  | 
|  | Document doc = (Document) domres.getNode(); | 
|  | saveAreaTreeXML(doc, new File(BACKUP_DIR, fo.getName() + ".at.xml")); | 
|  | return doc; | 
|  | } | 
|  |  | 
|  | private String evalXPath(Document doc, String xpath) { | 
|  | XObject res; | 
|  | try { | 
|  | res = XPathAPI.eval(doc, xpath); | 
|  | } catch (TransformerException e) { | 
|  | throw new RuntimeException("XPath evaluation failed: " + e.getMessage()); | 
|  | } | 
|  | return res.str(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Save the area tree XML for later inspection. | 
|  | * @param doc area tree as a DOM document | 
|  | * @param target target file | 
|  | * @throws TransformerException if a problem occurs during serialization | 
|  | */ | 
|  | protected void saveAreaTreeXML(Document doc, File target) throws TransformerException { | 
|  | Transformer transformer = tfactory.newTransformer(); | 
|  | Source src = new DOMSource(doc); | 
|  | Result res = new StreamResult(target); | 
|  | transformer.transform(src, res); | 
|  | } | 
|  |  | 
|  | private static final class CustomURIResolver implements ResourceResolver { | 
|  | private final ResourceResolver defaultImpl =  ResourceResolverFactory.createDefaultResourceResolver(); | 
|  |  | 
|  | public Resource getResource(URI uri) throws IOException { | 
|  | if (uri.getScheme().equals("funky") && uri.getSchemeSpecificPart().equals("myimage123")) { | 
|  | return new Resource("", new FileInputStream("test/resources/images/bgimg300dpi.jpg")); | 
|  | } | 
|  |  | 
|  | return defaultImpl.getResource(uri); | 
|  | } | 
|  |  | 
|  | public OutputStream getOutputStream(URI uri) throws IOException { | 
|  | return defaultImpl.getOutputStream(uri); | 
|  | } | 
|  |  | 
|  | } | 
|  | } |