/* * 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 embedding.events; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; import org.xml.sax.SAXException; import org.apache.commons.io.IOUtils; 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.MimeConstants; import org.apache.fop.events.Event; import org.apache.fop.events.EventFormatter; import org.apache.fop.events.EventListener; import org.apache.fop.events.model.EventSeverity; /** * This class demonstrates how to register an event listener with FOP so you can customize * FOP's error behaviour. */ public class ExampleEvents { // configure fopFactory as desired private final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); /** * Converts an FO file to a PDF file using FOP * @param fo the FO file * @param pdf the target PDF file * @throws IOException In case of an I/O problem * @throws FOPException In case of a FOP problem * @throws TransformerException In case of a problem with XSLT */ public void convertFO2PDF(URL fo, File pdf) throws IOException, FOPException, TransformerException { OutputStream out = null; try { //Create the user agent for this processing run FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); //Adding a simple logging listener that writes to stdout and stderr foUserAgent.getEventBroadcaster().addEventListener(new SysOutEventListener()); // Add your own event listener foUserAgent.getEventBroadcaster().addEventListener(new MyEventListener()); // configure foUserAgent further as desired // Setup output stream. Note: Using BufferedOutputStream // for performance reasons (helpful with FileOutputStreams). out = new FileOutputStream(pdf); out = new BufferedOutputStream(out); // Construct fop with desired output format Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); // Setup JAXP using identity transformer TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); // identity transformer // Setup input stream Source src = new StreamSource(fo.toExternalForm()); // Resulting SAX events (the generated FO) must be piped through to FOP Result res = new SAXResult(fop.getDefaultHandler()); // Start XSLT transformation and FOP processing transformer.transform(src, res); } finally { IOUtils.closeQuietly(out); } } private static class MyEventListener implements EventListener { public void processEvent(Event event) { if ("org.apache.fop.ResourceEventProducer.imageNotFound" .equals(event.getEventID())) { //Get the FileNotFoundException that's part of the event's parameters FileNotFoundException fnfe = (FileNotFoundException)event.getParam("fnfe"); System.out.println("---=== imageNotFound Event for " + event.getParam("uri") + "!!! ===---"); //Stop processing when an image could not be found. Otherwise, FOP would just //continue without the image! System.out.println("Throwing a RuntimeException..."); throw new RuntimeException(EventFormatter.format(event), fnfe); } else { //ignore all other events } } } /** A simple event listener that writes the events to stdout and sterr. */ private static class SysOutEventListener implements EventListener { /** {@inheritDoc} */ public void processEvent(Event event) { String msg = EventFormatter.format(event); EventSeverity severity = event.getSeverity(); if (severity == EventSeverity.INFO) { System.out.println("[INFO ] " + msg); } else if (severity == EventSeverity.WARN) { System.out.println("[WARN ] " + msg); } else if (severity == EventSeverity.ERROR) { System.err.println("[ERROR] " + msg); } else if (severity == EventSeverity.FATAL) { System.err.println("[FATAL] " + msg); } else { assert false; } } } /** * This method extracts the original exception from some exception. The exception * might be nested multiple levels deep. * @param t the Throwable to inspect * @return the original Throwable or the method parameter t if there are no nested Throwables. */ private static Throwable getOriginalThrowable(Throwable t) { if (t instanceof SAXException) { SAXException saxe = (SAXException)t; if (saxe.getException() != null) { return getOriginalThrowable(saxe.getException()); } else { return saxe; } } else { if (t.getCause() != null) { return getOriginalThrowable(t.getCause()); } else { return t; } } } /** * Main method. * @param args command-line arguments */ public static void main(String[] args) { try { System.out.println("FOP ExampleEvents\n"); System.out.println("Preparing..."); //Setup directories File baseDir = new File("."); File outDir = new File(baseDir, "out"); outDir.mkdirs(); //Setup input and output files URL fo = ExampleEvents.class.getResource("missing-image.fo"); File pdffile = new File(outDir, "out.pdf"); System.out.println("Input: XSL-FO (" + fo.toExternalForm() + ")"); System.out.println("Output: PDF (" + pdffile + ")"); System.out.println(); System.out.println("Transforming..."); ExampleEvents app = new ExampleEvents(); try { app.convertFO2PDF(fo, pdffile); } catch (TransformerException te) { //Note: We don't get the original exception here! //FOP needs to embed the exception in a SAXException and the TraX transformer //again wraps the SAXException in a TransformerException. Even our own //RuntimeException just wraps the original FileNotFoundException. //So we need to unpack to get the original exception (about three layers deep). Throwable originalThrowable = getOriginalThrowable(te); originalThrowable.printStackTrace(System.err); System.out.println("Aborted!"); System.exit(-1); } System.out.println("Success!"); } catch (Exception e) { //Some other error (shouldn't happen in this example) e.printStackTrace(System.err); System.exit(-1); } } }