diff options
Diffstat (limited to 'src/java/org/apache/fop/render')
42 files changed, 912 insertions, 309 deletions
diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java index c0c9ce88c..185aed817 100644 --- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -30,12 +30,16 @@ import org.w3c.dom.Document; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.dom.AbstractDocument; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; + import org.apache.fop.render.RendererContext.RendererContextWrapper; +import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; /** @@ -73,7 +77,7 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC //Prepare SVGUserAgent ua = new SVGUserAgent( - context.getUserAgent().getSourcePixelUnitToMillimeter(), + context.getUserAgent(), new AffineTransform()); GVTBuilder builder = new GVTBuilder(); final BridgeContext ctx = new BridgeContext(ua); @@ -83,7 +87,9 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC try { root = builder.build(ctx, doc); } catch (Exception e) { - log.error("SVG graphic could not be built: " + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); return; } @@ -115,6 +121,20 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC } /** + * Gets the document URI from a Document instance if possible. + * @param doc the Document + * @return the URI or null + */ + protected String getDocumentURI(Document doc) { + String docURI = null; + if (doc instanceof AbstractDocument) { + AbstractDocument level3Doc = (AbstractDocument)doc; + docURI = level3Doc.getDocumentURI(); + } + return docURI; + } + + /** * Override this method to update the renderer context if it needs special settings for * certain conditions. * @param context the renderer context diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index 9e13476f6..b38d973c5 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -31,6 +31,7 @@ import org.w3c.dom.Document; import org.apache.batik.parser.AWTTransformProducer; import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.util.QName; import org.apache.fop.area.Area; import org.apache.fop.area.Block; @@ -45,7 +46,6 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.FontMetrics; import org.apache.fop.traits.BorderProps; -import org.apache.fop.util.QName; /** * Abstract base class for renderers like PDF and PostScript where many painting operations diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 32c4b33c4..ca3d007d0 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -67,6 +67,7 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.WordArea; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fonts.FontInfo; @@ -113,21 +114,15 @@ public abstract class AbstractRenderer private Set warnedXMLHandlers; - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public abstract void setupFontInfo(FontInfo fontInfo); - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void setUserAgent(FOUserAgent agent) { userAgent = agent; } - /** - * @return the associated <code>FOUserAgent</code> - */ + /** {@inheritDoc} */ public FOUserAgent getUserAgent() { return userAgent; } @@ -797,10 +792,11 @@ public abstract class AbstractRenderer = new XMLHandlerConfigurator(userAgent); configurator.configure(ctx, namespace); handler.handleXML(ctx, doc, namespace); - } catch (Throwable t) { + } catch (Exception e) { // could not handle document - log.error("Some XML content will be ignored. " - + "Could not render XML", t); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + ctx.getUserAgent().getEventBroadcaster()); + eventProducer.foreignXMLProcessingError(this, doc, namespace, e); } } else { if (warnedXMLHandlers == null) { @@ -809,8 +805,9 @@ public abstract class AbstractRenderer if (!warnedXMLHandlers.contains(namespace)) { // no handler found for document warnedXMLHandlers.add(namespace); - log.warn("Some XML content will be ignored. " - + "No handler defined for XML: " + namespace); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + ctx.getUserAgent().getEventBroadcaster()); + eventProducer.foreignXMLNoHandler(this, doc, namespace); } } } diff --git a/src/java/org/apache/fop/render/Renderer.java b/src/java/org/apache/fop/render/Renderer.java index b40eec0cf..03b4582f7 100644 --- a/src/java/org/apache/fop/render/Renderer.java +++ b/src/java/org/apache/fop/render/Renderer.java @@ -89,6 +89,12 @@ public interface Renderer { void setUserAgent(FOUserAgent agent); /** + * Returns the associated user agent. + * @return the user agent + */ + FOUserAgent getUserAgent(); + + /** * Set up the given FontInfo. * * @param fontInfo The font information diff --git a/src/java/org/apache/fop/render/RendererEventProducer.java b/src/java/org/apache/fop/render/RendererEventProducer.java new file mode 100644 index 000000000..365c8f430 --- /dev/null +++ b/src/java/org/apache/fop/render/RendererEventProducer.java @@ -0,0 +1,53 @@ +/* + * 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.render; + +import java.io.IOException; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; + +/** + * Event producer interface for rendering-specific events. + */ +public interface RendererEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static RendererEventProducer get(EventBroadcaster broadcaster) { + return (RendererEventProducer)broadcaster.getEventProducerFor( + RendererEventProducer.class); + } + } + + /** + * I/O error while writing target file. + * @param source the event source + * @param ioe the original I/O error + * @event.severity ERROR + */ + void ioError(Object source, IOException ioe); +} diff --git a/src/java/org/apache/fop/render/afp/AFPEventProducer.java b/src/java/org/apache/fop/render/afp/AFPEventProducer.java new file mode 100644 index 000000000..615c54c32 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPEventProducer.java @@ -0,0 +1,63 @@ +/* + * 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.render.afp; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; + +/** + * Event producer interface for AFP-specific events. + */ +public interface AFPEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static AFPEventProducer get(EventBroadcaster broadcaster) { + return (AFPEventProducer)broadcaster.getEventProducerFor( + AFPEventProducer.class); + } + } + + /** Event model factory for AFP. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * Warn about using default font setup. + * @param source the event source + * @event.severity WARN + */ + void warnDefaultFontSetup(Object source); + +} diff --git a/src/java/org/apache/fop/render/afp/AFPEventProducer.xml b/src/java/org/apache/fop/render/afp/AFPEventProducer.xml new file mode 100644 index 000000000..8eec9b656 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPEventProducer.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="org.apache.fop.render.afp.AFPEventProducer.warnDefaultFontSetup">No AFP fonts configured. Using default setup.</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index e50e77830..629a7b62f 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -69,6 +69,7 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fonts.FontInfo; @@ -295,7 +296,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } } else { - log.warn("No AFP fonts configured - using default setup"); + AFPEventProducer eventProducer = AFPEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.warnDefaultFontSetup(this); } if (this.fontInfo.fontLookup("sans-serif", "normal", 400) == null) { CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZH200 ", @@ -908,7 +911,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { RendererContext context; context = super.createRendererContext(x, y, width, height, foreignAttributes); context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, - new Boolean(!this.colorImages)); + Boolean.valueOf(!this.colorImages)); context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO, this.fontInfo); context.setProperty(AFPRendererContextConstants.AFP_RESOLUTION, @@ -1045,13 +1048,17 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } } catch (ImageException ie) { - log.error("Error while processing image: " - + (info != null ? info.toString() : uri), ie); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); } catch (FileNotFoundException fe) { - log.error(fe.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); } catch (IOException ioe) { - log.error("I/O error while processing image: " - + (info != null ? info.toString() : uri), ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } finally { if (in != null) { IOUtils.closeQuietly(in); @@ -1217,7 +1224,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { //memory consumption (see PostScript output) ImageEncodingHelper.encodeRenderedImageAsRGB(image, baout); } catch (IOException ioe) { - log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageWritingError(this, ioe); return; } //int res = getResolution(); @@ -1363,8 +1372,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } catch (Throwable ex) { encoding = AFPConstants.EBCIDIC_ENCODING; log.warn( - "renderText():: Error getting encoding for font " - + " - using default encoding " + "renderText():: Error getting encoding for font '" + + tf.getFullName() + + "' - using default encoding " + encoding); } diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 0d3b864b0..939892648 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -113,8 +113,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { if (cfg != null) { strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText); } - final float uaResolution = context.getUserAgent().getSourceResolution(); - SVGUserAgent svgUserAgent = new SVGUserAgent(25.4f / uaResolution, new AffineTransform()); + SVGUserAgent svgUserAgent = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); BridgeContext ctx = new BridgeContext(svgUserAgent); AFPTextHandler afpTextHandler = null; diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.java b/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.java new file mode 100644 index 000000000..7b26d0771 --- /dev/null +++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.java @@ -0,0 +1,80 @@ +/* + * 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.render.bitmap; + +import java.io.IOException; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; + +/** + * Event producer interface for events generated by the bitmap renderers. + */ +public interface BitmapRendererEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static BitmapRendererEventProducer get(EventBroadcaster broadcaster) { + return (BitmapRendererEventProducer)broadcaster.getEventProducerFor( + BitmapRendererEventProducer.class); + } + } + + /** Event model factory for this event producer. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * No filename information available. Stopping early after the first page. + * @param source the event source + * @event.severity WARN + */ + void stoppingAfterFirstPageNoFilename(Object source); + + /** + * Image writer does not support multiple images. Only the first page has been produced. + * @param source the event source + * @event.severity WARN + */ + void stoppingAfterFirstPageNoMultiWriter(Object source); + + /** + * No ImageWriter found. + * @param source the event source + * @param mime the target MIME type + * @throws IOException the I/O error provoked by the method call + * @event.severity FATAL + */ + void noImageWriterFound(Object source, String mime) throws IOException; +} diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml b/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml new file mode 100644 index 000000000..a05af3e21 --- /dev/null +++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.stoppingAfterFirstPageNoFilename">No filename information available. Stopping early after the first page.</message> + <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.stoppingAfterFirstPageNoMultiWriter">Image writer does not support multiple images. Only the first page has been produced.</message> + <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.noImageWriterFound">Could not get an ImageWriter to produce "{mime}". The most likely explanation for this is a class loading problem.</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java index bedd2c499..8613ef7b8 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java @@ -23,12 +23,12 @@ import java.awt.image.RenderedImage; import java.io.IOException; import java.io.OutputStream; +import org.apache.commons.io.IOUtils; + import org.apache.xmlgraphics.image.writer.ImageWriter; import org.apache.xmlgraphics.image.writer.ImageWriterParams; import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; -import org.apache.commons.io.IOUtils; - import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.PageViewport; import org.apache.fop.render.java2d.Java2DRenderer; @@ -74,8 +74,10 @@ public class PNGRenderer extends Java2DRenderer { OutputStream os = getCurrentOutputStream(i); if (os == null) { - log.warn("No filename information available." - + " Stopping early after the first page."); + BitmapRendererEventProducer eventProducer + = BitmapRendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.stoppingAfterFirstPageNoFilename(this); break; } try { @@ -104,9 +106,10 @@ public class PNGRenderer extends Java2DRenderer { // Encode PNG image ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType()); if (writer == null) { - throw new IOException("Could not get an ImageWriter to produce " - + getMimeType() + ". The most likely explanation for this is a class" - + " loading problem."); + BitmapRendererEventProducer eventProducer + = BitmapRendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.noImageWriterFound(this, getMimeType()); } if (log.isDebugEnabled()) { log.debug("Writing image using " + writer.getClass().getName()); diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java index 4f64e45e1..9291427d2 100644 --- a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java @@ -129,7 +129,10 @@ public class TIFFRenderer extends Java2DRenderer { // Creates writer ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType()); if (writer == null) { - throw new NullPointerException("No ImageWriter for " + getMimeType() + " available!"); + BitmapRendererEventProducer eventProducer + = BitmapRendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.noImageWriterFound(this, getMimeType()); } if (writer.supportsMultiImageWriter()) { MultiImageWriter multiWriter = writer.createMultiImageWriter(outputStream); @@ -145,8 +148,10 @@ public class TIFFRenderer extends Java2DRenderer { } else { writer.writeImage((RenderedImage) pageImagesItr.next(), outputStream, writerParams); if (pageImagesItr.hasNext()) { - log.error("Image encoder does not support multiple images. Only the first page" - + " has been produced."); + BitmapRendererEventProducer eventProducer + = BitmapRendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.stoppingAfterFirstPageNoFilename(this); } } diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 583d2ad2f..0ffe3307a 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -66,6 +66,7 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -930,13 +931,17 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem pos, foreignAttributes); } } catch (ImageException ie) { - log.error("Error while processing image: " - + (info != null ? info.toString() : uri), ie); - } catch (FileNotFoundException fnfe) { - log.error(fnfe.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); + } catch (FileNotFoundException fe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); } catch (IOException ioe) { - log.error("I/O error while processing image: " - + (info != null ? info.toString() : uri), ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } } diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java index 51b458cfe..64ac823fc 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java +++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java @@ -23,26 +23,25 @@ import java.awt.geom.AffineTransform; import org.w3c.dom.Document; -import org.apache.fop.render.Renderer; -import org.apache.fop.render.XMLHandler; -import org.apache.fop.render.RendererContext; -import org.apache.fop.svg.SVGUserAgent; - -// Commons-Logging +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.gvt.GraphicsNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.batik.bridge.GVTBuilder; -import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.dom.svg.SVGDOMImplementation; -import org.apache.batik.gvt.GraphicsNode; +import org.apache.fop.render.AbstractGenericSVGHandler; +import org.apache.fop.render.Renderer; +import org.apache.fop.render.RendererContext; +import org.apache.fop.svg.SVGEventProducer; +import org.apache.fop.svg.SVGUserAgent; /** * Java2D XML handler for SVG (uses Apache Batik). * This handler handles XML for foreign objects when rendering to Java2D. * The properties from the Java2D renderer are subject to change. */ -public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConstants { +public class Java2DSVGHandler extends AbstractGenericSVGHandler + implements Java2DRendererContextConstants { /** logging instance */ private static Log log = LogFactory.getLog(Java2DSVGHandler.class); @@ -54,16 +53,6 @@ public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConsta //nop } - /** {@inheritDoc} */ - public void handleXML(RendererContext context, - Document doc, String ns) throws Exception { - Java2DInfo pdfi = getJava2DInfo(context); - - if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { - renderSVGDocument(context, doc, pdfi); - } - } - /** * Get the pdf information from the render context. * @@ -106,23 +95,18 @@ public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConsta } } - /** - * Render the svg document. - * @param context the renderer context - * @param doc the svg document - * @param info the pdf information of the current context - */ + /** {@inheritDoc} */ protected void renderSVGDocument(RendererContext context, - Document doc, - Java2DInfo info) { + Document doc) { + Java2DInfo info = getJava2DInfo(context); + if (log.isDebugEnabled()) { + log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")"); + } - log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")"); - int x = info.currentXPosition; int y = info.currentYPosition; - float ptom = context.getUserAgent().getSourcePixelUnitToMillimeter(); - SVGUserAgent ua = new SVGUserAgent(ptom, new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); GVTBuilder builder = new GVTBuilder(); BridgeContext ctx = new BridgeContext(ua); @@ -131,7 +115,9 @@ public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConsta try { root = builder.build(ctx, doc); } catch (Exception e) { - log.error("SVG graphic could not be built: " + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); return; } @@ -158,7 +144,9 @@ public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConsta try { root.paint(info.state.getGraph()); } catch (Exception e) { - log.error("Error while painting SVG", e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); } info.state.getGraph().setTransform(origTransform); @@ -169,9 +157,4 @@ public class Java2DSVGHandler implements XMLHandler, Java2DRendererContextConsta return (renderer instanceof Java2DRenderer); } - - /** {@inheritDoc} */ - public String getNamespace() { - return SVGDOMImplementation.SVG_NAMESPACE_URI; - } } diff --git a/src/java/org/apache/fop/render/pcl/PCLEventProducer.java b/src/java/org/apache/fop/render/pcl/PCLEventProducer.java new file mode 100644 index 000000000..3e72de293 --- /dev/null +++ b/src/java/org/apache/fop/render/pcl/PCLEventProducer.java @@ -0,0 +1,66 @@ +/* + * 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.render.pcl; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; + +/** + * Event producer interface for events generated by the PCL renderer. + */ +public interface PCLEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static PCLEventProducer get(EventBroadcaster broadcaster) { + return (PCLEventProducer)broadcaster.getEventProducerFor( + PCLEventProducer.class); + } + } + + /** Event model factory for this event producer. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * Paper type could not be determined. Falling back to another. + * @param source the event source + * @param pageWidth the page width (in millipoints) + * @param pageHeight the page height (in millipoints) + * @param fallbackPaper the paper type that will be used instead + * @event.severity WARN + */ + void paperTypeUnavailable(Object source, long pageWidth, long pageHeight, String fallbackPaper); + +} diff --git a/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml b/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml new file mode 100644 index 000000000..a3b36fd60 --- /dev/null +++ b/src/java/org/apache/fop/render/pcl/PCLEventProducer.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="org.apache.fop.render.pcl.PCLEventProducer.paperTypeUnavailable">Paper type ({pageWidth} x {pageHeight} mpt) could not be determined. Falling back to: {fallbackPaper}</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java index 3eb8ec425..5ca9a8bf9 100644 --- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java +++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java @@ -43,9 +43,11 @@ import java.text.DecimalFormatSymbols; import java.util.Locale; import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.fop.util.UnitConv; + import org.apache.xmlgraphics.image.GraphicsUtil; +import org.apache.fop.util.UnitConv; + /** * This class provides methods for generating PCL print files. */ @@ -355,16 +357,16 @@ public class PCLGenerator { if (usePCLShades || Color.black.equals(col) || Color.white.equals(col)) { - writeCommand("*c" + formatDouble4(w / 100) + "h" - + formatDouble4(h / 100) + "V"); + writeCommand("*c" + formatDouble4(w / 100.0) + "h" + + formatDouble4(h / 100.0) + "V"); int lineshade = convertToPCLShade(col); writeCommand("*c" + lineshade + "G"); writeCommand("*c2P"); //Shaded fill } else { defineGrayscalePattern(col, 32, DITHER_MATRIX_4X4); - writeCommand("*c" + formatDouble4(w / 100) + "h" - + formatDouble4(h / 100) + "V"); + writeCommand("*c" + formatDouble4(w / 100.0) + "h" + + formatDouble4(h / 100.0) + "V"); writeCommand("*c32G"); writeCommand("*c4P"); //User-defined pattern } diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java index 1d606e919..b89fba9c1 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java @@ -58,6 +58,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; +import org.apache.xmlgraphics.util.QName; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; @@ -77,6 +78,7 @@ import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -85,12 +87,12 @@ import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.PrintRenderer; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; +import org.apache.fop.render.RendererEventProducer; import org.apache.fop.render.java2d.FontMetricsMapper; import org.apache.fop.render.java2d.FontSetup; import org.apache.fop.render.java2d.Java2DRenderer; import org.apache.fop.render.pcl.extensions.PCLElementMapping; import org.apache.fop.traits.BorderProps; -import org.apache.fop.util.QName; import org.apache.fop.util.UnitConv; /* Note: @@ -208,7 +210,9 @@ public class PCLRenderer extends PrintRenderer { */ protected void handleIOTrouble(IOException ioe) { if (!ioTrouble) { - log.error("Error while writing to target file", ioe); + RendererEventProducer eventProducer = RendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.ioError(this, ioe); ioTrouble = true; } } @@ -417,11 +421,15 @@ public class PCLRenderer extends PrintRenderer { if (this.currentPageDefinition == null) { this.currentPageDefinition = PCLPageDefinition.getDefaultPageDefinition(); - log.warn("Paper type could not be determined. Falling back to: " - + this.currentPageDefinition.getName()); + PCLEventProducer eventProducer = PCLEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.paperTypeUnavailable(this, pagewidth, pageheight, + this.currentPageDefinition.getName()); + } + if (log.isDebugEnabled()) { + log.debug("page size: " + currentPageDefinition.getPhysicalPageSize()); + log.debug("logical page: " + currentPageDefinition.getLogicalPageRect()); } - log.debug("page size: " + currentPageDefinition.getPhysicalPageSize()); - log.debug("logical page: " + currentPageDefinition.getLogicalPageRect()); if (this.currentPageDefinition.isLandscapeFormat()) { gen.writeCommand("&l1O"); //Orientation } else { @@ -1107,12 +1115,17 @@ public class PCLRenderer extends PrintRenderer { } } catch (ImageException ie) { - log.error("Error while processing image: " - + (info != null ? info.toString() : uri), ie); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); } catch (FileNotFoundException fe) { - log.error(fe.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); } catch (IOException ioe) { - handleIOTrouble(ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } } diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererContext.java b/src/java/org/apache/fop/render/pcl/PCLRendererContext.java index 62d4bcaa4..422b9d51d 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRendererContext.java +++ b/src/java/org/apache/fop/render/pcl/PCLRendererContext.java @@ -19,9 +19,10 @@ package org.apache.fop.render.pcl; +import org.apache.xmlgraphics.util.QName; + import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.render.RendererContext; -import org.apache.fop.util.QName; /** * Wrapper on the RendererContext to access the information structure for drawing diff --git a/src/java/org/apache/fop/render/pdf/PDFEventProducer.java b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java new file mode 100644 index 000000000..f8b1bbb33 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java @@ -0,0 +1,64 @@ +/* + * 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.render.pdf; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; + +/** + * Event producer interface for events generated by the PDF renderer. + */ +public interface PDFEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static PDFEventProducer get(EventBroadcaster broadcaster) { + return (PDFEventProducer)broadcaster.getEventProducerFor( + PDFEventProducer.class); + } + } + + /** Event model factory for this event producer. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * Some link targets haven't been fully resolved. + * @param source the event source + * @param count the number of unresolved links + * @event.severity WARN + */ + void nonFullyResolvedLinkTargets(Object source, int count); + +} diff --git a/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml b/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml new file mode 100644 index 000000000..fd57d5099 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="org.apache.fop.render.pdf.PDFEventProducer.nonFullyResolvedLinkTargets">{count} link target{count,equals,1,,s} could not be fully resolved and now point{count,equals,1,,s} to the top of the page or {count,equals,1,is,are} dysfunctional.</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 55524534e..d2c8446eb 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -73,6 +73,7 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fo.extensions.xmp.XMPMetadata; @@ -490,13 +491,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { PDFGoTo gt = (PDFGoTo) unfinishedGoTos.get(0); finishIDGoTo(gt, defaultPos); } - boolean one = count == 1; - String pl = one ? "" : "s"; - String ww = one ? "was" : "were"; - String ia = one ? "is" : "are"; - log.warn("" + count + " link target" + pl + " could not be fully resolved and " - + ww + " now point to the top of the page or " - + ia + " dysfunctional."); // dysfunctional if pageref is null + PDFEventProducer eventProducer = PDFEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.nonFullyResolvedLinkTargets(this, count); + // dysfunctional if pageref is null } } @@ -555,16 +553,17 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { private void renderDestination(DestinationData dd) { String targetID = dd.getIDRef(); - if (targetID != null && targetID.length() > 0) { - PageViewport pv = dd.getPageViewport(); - if (pv == null) { - log.warn("Unresolved destination item received: " + dd.getIDRef()); - } + if (targetID == null || targetID.length() == 0) { + throw new IllegalArgumentException("DestinationData must contain a ID reference"); + } + PageViewport pv = dd.getPageViewport(); + if (pv != null) { PDFGoTo gt = getPDFGoToForID(targetID, pv.getKey()); pdfDoc.getFactory().makeDestination( dd.getIDRef(), gt.makeReference()); } else { - log.warn("DestinationData item with null or empty IDRef received."); + //Warning already issued by AreaTreeHandler (debug level is sufficient) + log.debug("Unresolved destination item received: " + dd.getIDRef()); } } @@ -584,22 +583,22 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { PDFOutline pdfOutline = null; String targetID = bookmarkItem.getIDRef(); - if (targetID != null && targetID.length() > 0) { - PageViewport pv = bookmarkItem.getPageViewport(); - if (pv != null) { - String pvKey = pv.getKey(); - PDFGoTo gt = getPDFGoToForID(targetID, pvKey); - // create outline object: - PDFOutline parent = parentBookmarkItem != null - ? parentBookmarkItem - : pdfDoc.getOutlineRoot(); - pdfOutline = pdfDoc.getFactory().makeOutline(parent, - bookmarkItem.getBookmarkTitle(), gt, bookmarkItem.showChildItems()); - } else { - log.warn("Bookmark with IDRef \"" + targetID + "\" has a null PageViewport."); - } + if (targetID == null || targetID.length() == 0) { + throw new IllegalArgumentException("DestinationData must contain a ID reference"); + } + PageViewport pv = bookmarkItem.getPageViewport(); + if (pv != null) { + String pvKey = pv.getKey(); + PDFGoTo gt = getPDFGoToForID(targetID, pvKey); + // create outline object: + PDFOutline parent = parentBookmarkItem != null + ? parentBookmarkItem + : pdfDoc.getOutlineRoot(); + pdfOutline = pdfDoc.getFactory().makeOutline(parent, + bookmarkItem.getBookmarkTitle(), gt, bookmarkItem.showChildItems()); } else { - log.warn("Bookmark item with null or empty IDRef received."); + //Warning already issued by AreaTreeHandler (debug level is sufficient) + log.debug("Bookmark with IDRef \"" + targetID + "\" has a null PageViewport."); } for (int i = 0; i < bookmarkItem.getCount(); i++) { @@ -1368,15 +1367,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { if (annotsAllowed) { action = getPDFGoToForID(idRef, pvKey); } - } else if (pvKeyOK) { - log.warn("Internal link trait with PageViewport key " + pvKey - + " contains no ID reference."); - } else if (idRefOK) { - log.warn("Internal link trait with ID reference " + idRef - + " contains no PageViewport key."); } else { - log.warn("Internal link trait received with neither PageViewport key" - + " nor ID reference."); + //Warnings already issued by AreaTreeHandler } } @@ -1671,7 +1663,9 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { x, y, posInt.width, posInt.height, foreignAttributes); handler.generateImage(context, img, origin, posInt); } catch (IOException ioe) { - log.error("I/O error while handling image: " + info, ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageWritingError(this, ioe); return; } } else { @@ -1680,13 +1674,17 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { + info + " (" + img.getClass().getName() + ")"); } } catch (ImageException ie) { - log.error("Error while processing image: " - + (info != null ? info.toString() : uri), ie); - } catch (FileNotFoundException fnfe) { - log.error(fnfe.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); + } catch (FileNotFoundException fe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); } catch (IOException ioe) { - log.error("I/O error while processing image: " - + (info != null ? info.toString() : uri), ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } // output new data @@ -1811,18 +1809,34 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { return MIME_TYPE; } + /** + * Sets the PDF/A mode for the PDF renderer. + * @param mode the PDF/A mode + */ public void setAMode(PDFAMode mode) { this.pdfAMode = mode; } + /** + * Sets the PDF/X mode for the PDF renderer. + * @param mode the PDF/X mode + */ public void setXMode(PDFXMode mode) { this.pdfXMode = mode; } + /** + * Sets the output color profile for the PDF renderer. + * @param outputProfileURI the URI to the output color profile + */ public void setOutputProfileURI(String outputProfileURI) { this.outputProfileURI = outputProfileURI; } + /** + * Sets the filter map to be used by the PDF renderer. + * @param filterMap the filter map + */ public void setFilterMap(Map filterMap) { this.filterMap = filterMap; } diff --git a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java index cbc0a8ec9..cb7c7cf89 100644 --- a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java @@ -36,6 +36,8 @@ import org.apache.batik.util.SVGConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.util.QName; + import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.FontInfo; @@ -51,8 +53,8 @@ import org.apache.fop.render.RendererContextConstants; import org.apache.fop.svg.PDFAElementBridge; import org.apache.fop.svg.PDFBridgeContext; import org.apache.fop.svg.PDFGraphics2D; +import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; -import org.apache.fop.util.QName; /** * PDF XML handler for SVG (uses Apache Batik). @@ -144,8 +146,9 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler try { super.renderSVGDocument(context, doc); } catch (IOException ioe) { - log.error("I/O error while rendering SVG graphic: " - + ioe.getMessage(), ioe); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc)); } return; } @@ -153,15 +156,13 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler int yOffset = pdfInfo.currentYPosition; FOUserAgent userAgent = context.getUserAgent(); - log.debug("Generating SVG at " - + userAgent.getTargetResolution() - + "dpi."); final float deviceResolution = userAgent.getTargetResolution(); - log.debug("Generating SVG at " + deviceResolution + "dpi."); - log.debug("Generating SVG at " + deviceResolution + "dpi."); + if (log.isDebugEnabled()) { + log.debug("Generating SVG at " + deviceResolution + "dpi."); + } final float uaResolution = userAgent.getSourceResolution(); - SVGUserAgent ua = new SVGUserAgent(25.4f / uaResolution, new AffineTransform()); + SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform()); //Scale for higher resolution on-the-fly images from Batik double s = uaResolution / deviceResolution; @@ -188,8 +189,9 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler root = builder.build(ctx, doc); builder = null; } catch (Exception e) { - log.error("svg graphic could not be built: " - + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); return; } // get the 'width' and 'height' attributes of the SVG document @@ -261,8 +263,9 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler root.paint(graphics); pdfInfo.currentStream.add(graphics.getString()); } catch (Exception e) { - log.error("svg graphic could not be rendered: " - + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); } pdfInfo.pdfState.pop(); renderer.restoreGraphicsState(); diff --git a/src/java/org/apache/fop/render/ps/PSEventProducer.java b/src/java/org/apache/fop/render/ps/PSEventProducer.java new file mode 100644 index 000000000..451ed1cea --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSEventProducer.java @@ -0,0 +1,65 @@ +/* + * 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.render.ps; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; + +/** + * Event producer interface for events generated by the PostScript renderer. + */ +public interface PSEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static PSEventProducer get(EventBroadcaster broadcaster) { + return (PSEventProducer)broadcaster.getEventProducerFor( + PSEventProducer.class); + } + } + + /** Event model factory for this event producer. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * A PostScript dictionary could not be parsed. + * @param source the event source + * @param content the PostScript content + * @param e the original exception + * @event.severity ERROR + */ + void postscriptDictionaryParseError(Object source, String content, Exception e); + +} diff --git a/src/java/org/apache/fop/render/ps/PSEventProducer.xml b/src/java/org/apache/fop/render/ps/PSEventProducer.xml new file mode 100644 index 000000000..a0078223a --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSEventProducer.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="org.apache.fop.render.ps.PSEventProducer.postscriptDictionaryParseError">Failed to parse dictionary string. Reason: {e}, content = "{content}"</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 7e32977e6..e4d582ba2 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -85,6 +85,7 @@ import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fonts.Font; @@ -95,6 +96,7 @@ import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.ImageAdapter; import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererEventProducer; import org.apache.fop.render.ps.extensions.PSCommentAfter; import org.apache.fop.render.ps.extensions.PSCommentBefore; import org.apache.fop.render.ps.extensions.PSExtensionAttachment; @@ -296,7 +298,9 @@ public class PSRenderer extends AbstractPathOrientedRenderer */ protected void handleIOTrouble(IOException ioe) { if (!ioTrouble) { - log.error("Error while writing to target file", ioe); + RendererEventProducer eventProducer = RendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.ioError(this, ioe); ioTrouble = true; } } @@ -522,12 +526,17 @@ public class PSRenderer extends AbstractPathOrientedRenderer } } catch (ImageException ie) { - log.error("Error while processing image: " - + (info != null ? info.toString() : uri), ie); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); } catch (FileNotFoundException fe) { - log.error(fe.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); } catch (IOException ioe) { - handleIOTrouble(ioe); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } } @@ -1070,8 +1079,9 @@ public class PSRenderer extends AbstractPathOrientedRenderer try { this.pageDeviceDictionary.putAll(PSDictionary.valueOf(content)); } catch (PSDictionaryFormatException e) { - log.error("Failed to parse dictionary string: " - + e.getMessage() + ", content = '" + content + "'"); + PSEventProducer eventProducer = PSEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.postscriptDictionaryParseError(this, content, e); } } } else if (attachment instanceof PSCommentBefore) { @@ -1169,8 +1179,9 @@ public class PSRenderer extends AbstractPathOrientedRenderer try { pageDeviceDictionary.putAll(PSDictionary.valueOf(content)); } catch (PSDictionaryFormatException e) { - log.error("failed to parse dictionary string: " - + e.getMessage() + ", [" + content + "]"); + PSEventProducer eventProducer = PSEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.postscriptDictionaryParseError(this, content, e); } } } diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index 5cfe617c8..ebe098282 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -23,31 +23,24 @@ package org.apache.fop.render.ps; import java.awt.geom.AffineTransform; import java.io.IOException; -// DOM import org.w3c.dom.Document; -import org.w3c.dom.svg.SVGDocument; -import org.w3c.dom.svg.SVGSVGElement; -// Batik import org.apache.avalon.framework.configuration.Configuration; -import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.bridge.ViewBox; -import org.apache.batik.dom.svg.SVGDOMImplementation; +import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.gvt.GraphicsNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.ps.PSGenerator; -// FOP import org.apache.fop.fonts.FontInfo; +import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; -import org.apache.fop.render.XMLHandler; import org.apache.fop.render.RendererContext; +import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; -import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; -import org.apache.xmlgraphics.ps.PSGenerator; - -// Commons-Logging -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * PostScript XML handler for SVG. Uses Apache Batik for SVG processing. @@ -57,7 +50,8 @@ import org.apache.commons.logging.LogFactory; * * @version $Id$ */ -public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { +public class PSSVGHandler extends AbstractGenericSVGHandler + implements PSRendererContextConstants { /** logging instance */ private static Log log = LogFactory.getLog(PSSVGHandler.class); @@ -68,16 +62,6 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { public PSSVGHandler() { } - /** {@inheritDoc} */ - public void handleXML(RendererContext context, - Document doc, String ns) throws Exception { - PSInfo psi = getPSInfo(context); - - if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { - renderSVGDocument(context, doc, psi); - } - } - /** * Get the pdf information from the render context. * @@ -234,10 +218,10 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { * Render the svg document. * @param context the renderer context * @param doc the svg document - * @param psInfo the pdf information of the current context */ protected void renderSVGDocument(RendererContext context, - Document doc, PSInfo psInfo) { + Document doc) { + PSInfo psInfo = getPSInfo(context); int xOffset = psInfo.currentXPosition; int yOffset = psInfo.currentYPosition; PSGenerator gen = psInfo.psGenerator; @@ -250,9 +234,7 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { } SVGUserAgent ua - = new SVGUserAgent( - context.getUserAgent().getSourcePixelUnitToMillimeter(), - new AffineTransform()); + = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); PSGraphics2D graphics = new PSGraphics2D(strokeText, gen); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); @@ -273,8 +255,9 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { try { root = builder.build(ctx, doc); } catch (Exception e) { - log.error("SVG graphic could not be built: " - + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); return; } // get the 'width' and 'height' attributes of the SVG document @@ -305,10 +288,10 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { // viewBox puts it. gen.concatMatrix(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f); + /* SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, - psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f); - /* + psInfo.getWidth() / 1000f, psInfo.getHeight() / 1000f, ctx); if (!at.isIdentity()) { double[] vals = new double[6]; at.getMatrix(vals); @@ -322,15 +305,17 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { try { root.paint(graphics); } catch (Exception e) { - log.error("SVG graphic could not be rendered: " - + e.getMessage(), e); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); } gen.restoreGraphicsState(); gen.commentln("%FOPEndSVG"); } catch (IOException ioe) { - log.error("SVG graphic could not be rendered: " - + ioe.getMessage(), ioe); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc)); } } @@ -339,10 +324,5 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { return (renderer instanceof PSRenderer); } - /** {@inheritDoc} */ - public String getNamespace() { - return SVGDOMImplementation.SVG_NAMESPACE_URI; - } - } diff --git a/src/java/org/apache/fop/render/ps/ResourceHandler.java b/src/java/org/apache/fop/render/ps/ResourceHandler.java index 0dfb8029f..1a363c90e 100644 --- a/src/java/org/apache/fop/render/ps/ResourceHandler.java +++ b/src/java/org/apache/fop/render/ps/ResourceHandler.java @@ -20,8 +20,8 @@ package org.apache.fop.render.ps; import java.awt.geom.Dimension2D; -import java.awt.image.RenderedImage; import java.awt.geom.Rectangle2D; +import java.awt.image.RenderedImage; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -68,6 +68,7 @@ import org.apache.xmlgraphics.ps.dsc.events.PostScriptComment; import org.apache.xmlgraphics.ps.dsc.tools.DSCTools; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fonts.FontInfo; /** @@ -321,7 +322,10 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors { throw new UnsupportedOperationException("Unsupported image type: " + img); } } catch (ImageException ie) { - throw new IOException("Error while generating form for image: " + ie.getMessage()); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + userAgent.getEventBroadcaster()); + eventProducer.imageError(resTracker, (info != null ? info.toString() : uri), + ie, null); } } } diff --git a/src/java/org/apache/fop/render/ps/extensions/AbstractPSCommentElement.java b/src/java/org/apache/fop/render/ps/extensions/AbstractPSCommentElement.java index a6e77fb13..1eb1d9d13 100644 --- a/src/java/org/apache/fop/render/ps/extensions/AbstractPSCommentElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/AbstractPSCommentElement.java @@ -22,7 +22,6 @@ package org.apache.fop.render.ps.extensions; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; -import org.apache.fop.fo.ValidationException; /** * Base postscript commment element class @@ -46,8 +45,8 @@ public abstract class AbstractPSCommentElement extends AbstractPSExtensionElemen protected void startOfNode() throws FOPException { if (parent.getNameId() != Constants.FO_DECLARATIONS && parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { - throw new ValidationException(getName() - + " must be a child of fo:declarations or fo:simple-page-master."); + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfSPMorDeclarations"); } } diff --git a/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionElement.java b/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionElement.java index a10bb7518..31e44d2d2 100644 --- a/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionElement.java @@ -20,14 +20,14 @@ package org.apache.fop.render.ps.extensions; // FOP +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.xml.sax.Locator; - /** * Base class for the PostScript-specific extension elements. */ @@ -98,7 +98,7 @@ public abstract class AbstractPSExtensionElement extends FONode { * @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */ public String getNormalNamespacePrefix() { - return "fox"; + return "ps"; } /** diff --git a/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionObject.java b/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionObject.java index 6823d75d9..78b2f91eb 100644 --- a/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionObject.java +++ b/src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionObject.java @@ -20,13 +20,14 @@ package org.apache.fop.render.ps.extensions; // FOP +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; /** * Base class for the PostScript-specific extension elements. @@ -36,15 +37,15 @@ public abstract class AbstractPSExtensionObject extends FONode { private PSSetupCode setupCode = new PSSetupCode(); /** + * Main constructor. + * @param parent the parent node * @see org.apache.fop.fo.FONode#FONode(FONode) */ public AbstractPSExtensionObject(FONode parent) { super(parent); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { @@ -71,7 +72,7 @@ public abstract class AbstractPSExtensionObject extends FONode { /**{@inheritDoc} */ public String getNormalNamespacePrefix() { - return "fox"; + return "ps"; } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java index 4bbfa0c73..d03a0220c 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java @@ -27,6 +27,9 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; */ public class PSCommentAfterElement extends AbstractPSCommentElement { + /** the element name */ + protected static final String ELEMENT = "ps-comment-after"; + /** * Main constructor * @param parent node diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java index f05e7c7fe..d74d3a194 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java @@ -27,6 +27,9 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; */ public class PSCommentBeforeElement extends AbstractPSCommentElement { + /** the element name */ + protected static final String ELEMENT = "ps-comment-before"; + /** * Main constructor * @param parent parent node diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java index 456d97430..e69500736 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java @@ -19,13 +19,15 @@ package org.apache.fop.render.ps.extensions; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.util.ContentHandlerFactory; import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; /** * ContentHandler (parser) for restoring PSExtension objects from XML. @@ -91,25 +93,19 @@ public class PSExtensionHandler extends DefaultHandler content.append(ch, start, length); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void endDocument() throws SAXException { if (listener != null) { listener.notifyObjectBuilt(getObject()); } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public Object getObject() { return returnedObject; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void setObjectBuiltListener(ObjectBuiltListener listener) { this.listener = listener; } diff --git a/src/java/org/apache/fop/render/ps/extensions/PSPageSetupCodeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSPageSetupCodeElement.java index ad46b9364..207c11e76 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSPageSetupCodeElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSPageSetupCodeElement.java @@ -22,13 +22,13 @@ package org.apache.fop.render.ps.extensions; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; -import org.apache.fop.fo.ValidationException; /** * Extension element for fox:ps-page-setup-code. */ public class PSPageSetupCodeElement extends AbstractPSExtensionObject { + /** The element name */ protected static final String ELEMENT = "ps-page-setup-code"; /** @@ -43,7 +43,8 @@ public class PSPageSetupCodeElement extends AbstractPSExtensionObject { protected void startOfNode() throws FOPException { super.startOfNode(); if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { - throw new ValidationException(getName() + " must be a child of fo:simple-page-master."); + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfSPM"); } } diff --git a/src/java/org/apache/fop/render/ps/extensions/PSSetPageDeviceElement.java b/src/java/org/apache/fop/render/ps/extensions/PSSetPageDeviceElement.java index b512c6888..21acc8001 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSSetPageDeviceElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSSetPageDeviceElement.java @@ -19,20 +19,21 @@ package org.apache.fop.render.ps.extensions; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; -import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.extensions.ExtensionAttachment; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; /** * Extension element for ps:ps-setpagedevice. */ public class PSSetPageDeviceElement extends AbstractPSExtensionElement { + /** The element name */ protected static final String ELEMENT = "ps-setpagedevice"; /** @@ -52,8 +53,8 @@ public class PSSetPageDeviceElement extends AbstractPSExtensionElement { super.startOfNode(); if ( !((parent.getNameId() == Constants.FO_DECLARATIONS) || (parent.getNameId() == Constants.FO_SIMPLE_PAGE_MASTER)) ) { - throw new ValidationException( getName() - + " must be a child of fo:declarations or fo:simple-page-master."); + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfSPMorDeclarations"); } } diff --git a/src/java/org/apache/fop/render/ps/extensions/PSSetupCodeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSSetupCodeElement.java index ec7216c44..e76dfeb64 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSSetupCodeElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSSetupCodeElement.java @@ -22,13 +22,13 @@ package org.apache.fop.render.ps.extensions; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; -import org.apache.fop.fo.ValidationException; /** * Extension element for fox:ps-setup-code. */ public class PSSetupCodeElement extends AbstractPSExtensionObject { + /** The element name */ protected static final String ELEMENT = "ps-setup-code"; /** @@ -43,7 +43,8 @@ public class PSSetupCodeElement extends AbstractPSExtensionObject { protected void startOfNode() throws FOPException { super.startOfNode(); if (parent.getNameId() != Constants.FO_DECLARATIONS) { - throw new ValidationException(getName() + " must be a child of fo:declarations."); + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfDeclarations"); } } diff --git a/src/java/org/apache/fop/render/rtf/RTFEventProducer.java b/src/java/org/apache/fop/render/rtf/RTFEventProducer.java new file mode 100644 index 000000000..a2646af46 --- /dev/null +++ b/src/java/org/apache/fop/render/rtf/RTFEventProducer.java @@ -0,0 +1,94 @@ +/* + * 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.render.rtf; + +import org.xml.sax.Locator; + +import org.apache.fop.events.EventBroadcaster; +import org.apache.fop.events.EventProducer; +import org.apache.fop.events.model.AbstractEventModelFactory; +import org.apache.fop.events.model.EventModel; +import org.apache.fop.fo.FONode; + +/** + * Event producer interface for events generated by the RTF renderer. + */ +public interface RTFEventProducer extends EventProducer { + + /** Provider class for the event producer. */ + class Provider { + + /** + * Returns an event producer. + * @param broadcaster the event broadcaster to use + * @return the event producer + */ + public static RTFEventProducer get(EventBroadcaster broadcaster) { + return (RTFEventProducer)broadcaster.getEventProducerFor( + RTFEventProducer.class); + } + } + + /** Event model factory for this event producer. */ + public static class EventModelFactory extends AbstractEventModelFactory { + + /** {@inheritDoc} */ + public EventModel createEventModel() { + return loadModel(getClass(), "event-model.xml"); + } + + } + + /** + * The RTF handler only supports simple-page-masters. + * @param source the event source + * @param masterReference the reference page-master-set + * @param loc the location of the error or null + * @event.severity WARN + */ + void onlySPMSupported(Object source, String masterReference, Locator loc); + + /** + * No simple-page-master could be determined- + * @param source the event source + * @param loc the location of the error or null + * @event.severity WARN + */ + void noSPMFound(Object source, Locator loc); + + /** + * The RTF handler requires explicit table-columns for now. + * @param source the event source + * @param loc the location of the error or null + * @event.severity WARN + */ + void explicitTableColumnsRequired(Object source, Locator loc); + + /** + * The RTF handler ignored some deferred event (i.e. an unsupported element). + * @param source the event source + * @param node the FO tree node being ignored + * @param start true for start, false for end + * @param loc the location of the error or null + * @event.severity WARN + */ + void ignoredDeferredEvent(Object source, FONode node, boolean start, Locator loc); + +} diff --git a/src/java/org/apache/fop/render/rtf/RTFEventProducer.xml b/src/java/org/apache/fop/render/rtf/RTFEventProducer.xml new file mode 100644 index 000000000..8f1f21a81 --- /dev/null +++ b/src/java/org/apache/fop/render/rtf/RTFEventProducer.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<catalogue xml:lang="en"> + <message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message> + <message key="org.apache.fop.render.rtf.RTFEventProducer.onlySPMSupported">Only simple-page-masters are supported on page-sequences. Using default simple-page-master from page-sequence-master "{masterReference}".{{locator}}</message> + <message key="org.apache.fop.render.rtf.RTFEventProducer.noSPMFound">No simple-page-master could be determined.</message> + <message key="org.apache.fop.render.rtf.RTFEventProducer.explicitTableColumnsRequired">No table-columns found on table. RTF output requires that all table-columns for a table are defined. Output will be incorrect.{{locator}}</message> + <message key="org.apache.fop.render.rtf.RTFEventProducer.ignoredDeferredEvent">Ignored deferred event for {node} ({start,if,start,end}).{{locator}}</message> +</catalogue> diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java index d2f2c4192..88e34e17a 100644 --- a/src/java/org/apache/fop/render/rtf/RTFHandler.java +++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java @@ -21,6 +21,7 @@ package org.apache.fop.render.rtf; // Java import java.awt.geom.Point2D; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -51,6 +52,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.datatypes.LengthBase; import org.apache.fop.datatypes.SimplePercentBaseContext; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FONode; @@ -88,6 +90,7 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.FixedLength; import org.apache.fop.fonts.FontSetup; import org.apache.fop.render.DefaultFontResolver; +import org.apache.fop.render.RendererEventProducer; import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer; import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfBeforeContainer; import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfListContainer; @@ -159,6 +162,16 @@ public class RTFHandler extends FOEventHandler { } /** + * Central exception handler for I/O exceptions. + * @param ioe IOException to handle + */ + protected void handleIOTrouble(IOException ioe) { + RendererEventProducer eventProducer = RendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.ioError(this, ioe); + } + + /** * {@inheritDoc} */ public void startDocument() throws SAXException { @@ -195,9 +208,9 @@ public class RTFHandler extends FOEventHandler { this.pagemaster = pageSeq.getRoot().getLayoutMasterSet().getSimplePageMaster(reference); if (this.pagemaster == null) { - log.warn("Only simple-page-masters are supported on page-sequences: " - + reference); - log.warn("Using default simple-page-master from page-sequence-master..."); + RTFEventProducer eventProducer = RTFEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.onlySPMSupported(this, reference, pageSeq.getLocator()); PageSequenceMaster master = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference); this.pagemaster = master.getNextSimplePageMaster( @@ -218,7 +231,9 @@ public class RTFHandler extends FOEventHandler { PageAttributesConverter.convertPageAttributes( pagemaster)); } else { - log.warn("No simple-page-master could be determined!"); + RTFEventProducer eventProducer = RTFEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.noSPMFound(this, pageSeq.getLocator()); } builderContext.pushContainer(sect); @@ -226,9 +241,7 @@ public class RTFHandler extends FOEventHandler { bHeaderSpecified = false; bFooterSpecified = false; } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("startPageSequence: " + ioe.getMessage(), ioe); - //TODO throw new FOPException(ioe); + handleIOTrouble(ioe); } catch (FOPException fope) { // TODO could we throw Exception in all FOEventHandler events? log.error("startPageSequence: " + fope.getMessage(), fope); @@ -338,8 +351,7 @@ public class RTFHandler extends FOEventHandler { log.warn("A " + fl.getLocalName() + " has been skipped: " + fl.getFlowName()); } } catch (IOException ioe) { - log.error("startFlow: " + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startFlow: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -396,9 +408,7 @@ public class RTFHandler extends FOEventHandler { textrun.pushBlockAttributes(rtfAttr); textrun.addBookmark(bl.getId()); } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("startBlock: " + ioe.getMessage()); - throw new RuntimeException("IOException: " + ioe); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startBlock: " + e.getMessage()); throw new RuntimeException("Exception: " + e); @@ -427,8 +437,7 @@ public class RTFHandler extends FOEventHandler { textrun.popBlockAttributes(); } catch (IOException ioe) { - log.error("startBlock:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startBlock:" + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -457,9 +466,7 @@ public class RTFHandler extends FOEventHandler { textrun.addParagraphBreak(); textrun.pushBlockAttributes(rtfAttr); } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("startBlock: " + ioe.getMessage()); - throw new RuntimeException("IOException: " + ioe); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startBlock: " + e.getMessage()); throw new RuntimeException("Exception: " + e); @@ -486,8 +493,7 @@ public class RTFHandler extends FOEventHandler { textrun.popBlockAttributes(); } catch (IOException ioe) { - log.error("startBlock:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startBlock:" + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -530,6 +536,8 @@ public class RTFHandler extends FOEventHandler { table.setBorderAttributes(borderAttributes); builderContext.pushContainer(table); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("startTable:" + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -590,7 +598,6 @@ public class RTFHandler extends FOEventHandler { log.error("startColumn: " + e.getMessage()); throw new RuntimeException(e.getMessage()); } - } /** @@ -649,8 +656,7 @@ public class RTFHandler extends FOEventHandler { textrun.pushInlineAttributes(rtfAttr); textrun.addBookmark(inl.getId()); } catch (IOException ioe) { - log.error("startInline:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (FOPException fe) { log.error("startInline:" + fe.getMessage()); throw new RuntimeException(fe.getMessage()); @@ -677,8 +683,7 @@ public class RTFHandler extends FOEventHandler { RtfTextrun textrun = container.getTextrun(); textrun.popInlineAttributes(); } catch (IOException ioe) { - log.error("startInline:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startInline:" + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -698,6 +703,8 @@ public class RTFHandler extends FOEventHandler { RtfTable tbl = (RtfTable)builderContext.getContainer(RtfTable.class, true, this); tbl.setHeaderAttribs(atts); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("startBody: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -715,6 +722,8 @@ public class RTFHandler extends FOEventHandler { try { RtfTable tbl = (RtfTable)builderContext.getContainer(RtfTable.class, true, this); tbl.setHeaderAttribs(null); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("endBody: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -745,6 +754,8 @@ public class RTFHandler extends FOEventHandler { // reset column iteration index to correctly access column widths builderContext.getTableContext().selectFirstColumn(); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("startRow: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -778,6 +789,8 @@ public class RTFHandler extends FOEventHandler { tctx.selectNextColumn(); } + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("endRow: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -870,6 +883,8 @@ public class RTFHandler extends FOEventHandler { } builderContext.pushContainer(cell); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("startCell: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -906,8 +921,7 @@ public class RTFHandler extends FOEventHandler { ListAttributesConverter.convertAttributes(lb)); builderContext.pushContainer(newList); } catch (IOException ioe) { - log.error("startList: " + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (FOPException fe) { log.error("startList: " + fe.getMessage()); throw new RuntimeException(fe.getMessage()); @@ -961,8 +975,7 @@ public class RTFHandler extends FOEventHandler { builderContext.pushContainer(list.newListItem()); } catch (IOException ioe) { - log.error("startList: " + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startList: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -995,8 +1008,7 @@ public class RTFHandler extends FOEventHandler { RtfListItemLabel label = item.new RtfListItemLabel(item); builderContext.pushContainer(label); } catch (IOException ioe) { - log.error("startPageNumber:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startPageNumber: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -1077,8 +1089,7 @@ public class RTFHandler extends FOEventHandler { builderContext.pushContainer(link); } catch (IOException ioe) { - log.error("startLink:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startLink: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -1104,21 +1115,28 @@ public class RTFHandler extends FOEventHandler { return; } + String uri = eg.getURL(); + ImageInfo info = null; try { - String uri = eg.getURL(); //set image data FOUserAgent userAgent = eg.getUserAgent(); ImageManager manager = userAgent.getFactory().getImageManager(); - ImageInfo info = manager.getImageInfo(uri, userAgent.getImageSessionContext()); - if (info == null) { - log.error("Image could not be found: " + uri); - return; - } + info = manager.getImageInfo(uri, userAgent.getImageSessionContext()); putGraphic(eg, info); - } catch (Exception e) { - log.error("Error while handling an external-graphic: " + e.getMessage(), e); + } catch (ImageException ie) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); + } catch (FileNotFoundException fe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); + } catch (IOException ioe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } } @@ -1144,6 +1162,12 @@ public class RTFHandler extends FOEventHandler { // Set the image size to the size of the svg. Point2D csize = new Point2D.Float(-1, -1); Point2D intrinsicDimensions = child.getDimension(csize); + if (intrinsicDimensions == null) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.ifoNoIntrinsicSize(this, child.getLocator()); + return; + } size.setSizeInMillipoints( (int)Math.round(intrinsicDimensions.getX() * 1000), (int)Math.round(intrinsicDimensions.getY() * 1000)); @@ -1157,8 +1181,14 @@ public class RTFHandler extends FOEventHandler { Image converted = manager.convertImage(image, FLAVORS); putGraphic(ifo, converted); - } catch (Exception e) { - log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e); + } catch (ImageException ie) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, null, ie, null); + } catch (IOException ioe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, null, ioe, null); } } @@ -1183,7 +1213,9 @@ public class RTFHandler extends FOEventHandler { putGraphic(abstractGraphic, image); } catch (ImageException ie) { - log.error("Error while loading/processing image: " + info.getOriginalURI(), ie); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, null, ie, null); } } @@ -1210,8 +1242,9 @@ public class RTFHandler extends FOEventHandler { } if (rawData == null) { - log.warn(FONode.decorateWithContextInfo("Image could not be embedded: " - + image, abstractGraphic)); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageWritingError(this, null); return; } @@ -1322,9 +1355,7 @@ public class RTFHandler extends FOEventHandler { builderContext.pushContainer(rtfFootnote); } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("startFootnote: " + ioe.getMessage()); - throw new RuntimeException("IOException: " + ioe); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startFootnote: " + e.getMessage()); throw new RuntimeException("Exception: " + e); @@ -1358,9 +1389,7 @@ public class RTFHandler extends FOEventHandler { rtfFootnote.startBody(); } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("startFootnoteBody: " + ioe.getMessage()); - throw new RuntimeException("IOException: " + ioe); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startFootnoteBody: " + e.getMessage()); throw new RuntimeException("Exception: " + e); @@ -1383,9 +1412,7 @@ public class RTFHandler extends FOEventHandler { rtfFootnote.endBody(); } catch (IOException ioe) { - // TODO could we throw Exception in all FOEventHandler events? - log.error("endFootnoteBody: " + ioe.getMessage()); - throw new RuntimeException("IOException: " + ioe); + handleIOTrouble(ioe); } catch (Exception e) { log.error("endFootnoteBody: " + e.getMessage()); throw new RuntimeException("Exception: " + e); @@ -1421,10 +1448,8 @@ public class RTFHandler extends FOEventHandler { textrun.pushInlineAttributes(rtfAttr); textrun.addString(new String(data, start, length - start)); textrun.popInlineAttributes(); - } catch (IOException ioe) { - // FIXME could we throw Exception in all FOEventHandler events? - log.error("characters: " + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + } catch (IOException ioe) { + handleIOTrouble(ioe); } catch (Exception e) { log.error("characters:" + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -1452,8 +1477,7 @@ public class RTFHandler extends FOEventHandler { RtfTextrun textrun = container.getTextrun(); textrun.addPageNumber(rtfAttr); } catch (IOException ioe) { - log.error("startPageNumber:" + ioe.getMessage()); - throw new RuntimeException(ioe.getMessage()); + handleIOTrouble(ioe); } catch (Exception e) { log.error("startPageNumber: " + e.getMessage()); throw new RuntimeException(e.getMessage()); @@ -1611,7 +1635,9 @@ public class RTFHandler extends FOEventHandler { endCell( (TableCell) foNode); } } else { - log.warn("Ignored deferred event for " + foNode); + RTFEventProducer eventProducer = RTFEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.ignoredDeferredEvent(this, foNode, bStart, foNode.getLocator()); } } @@ -1655,8 +1681,9 @@ public class RTFHandler extends FOEventHandler { } } else { //TODO Implement implicit column setup handling! - log.warn("No table-columns found on table. RTF output requires that all" - + " table-columns for a table are defined. Output will be incorrect."); + RTFEventProducer eventProducer = RTFEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.explicitTableColumnsRequired(this, table.getLocator()); } //recurse table-header diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index 66cce0ae1..eb3c92e1b 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -41,6 +41,7 @@ import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.AttributesImpl; +import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.util.XMLizable; import org.apache.fop.apps.FOPException; @@ -90,7 +91,6 @@ import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; import org.apache.fop.render.XMLHandler; import org.apache.fop.util.ColorUtil; -import org.apache.fop.util.QName; /** * Renderer that renders areas to XML for debugging purposes. |