From d57530eed04016c68143a1c01ea5320610e4a169 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 25 Jul 2005 15:54:20 +0000 Subject: Made Service a stand-alone class so it can be reused. Made XMLHandler discoverable through the Service class. Moved XMLHandler collection into new XMLHandlerRegistry class. Adjusted the Renderers and XMLHandler to the above changes. This should make it easier to write certain FOP extensions. The changes were triggered by my work on the FOP extension for Barcode4J for the FOP Trunk. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@225143 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/FOUserAgent.java | 34 +++-- src/java/org/apache/fop/fo/FOTreeBuilder.java | 95 +----------- .../org/apache/fop/render/AbstractRenderer.java | 54 ++----- .../org/apache/fop/render/RendererContext.java | 16 +- src/java/org/apache/fop/render/XMLHandler.java | 31 +++- .../org/apache/fop/render/XMLHandlerRegistry.java | 166 +++++++++++++++++++++ .../apache/fop/render/java2d/Java2DRenderer.java | 7 +- .../org/apache/fop/render/pdf/PDFRenderer.java | 10 +- .../org/apache/fop/render/pdf/PDFXMLHandler.java | 41 +++-- src/java/org/apache/fop/render/ps/PSRenderer.java | 8 +- .../org/apache/fop/render/ps/PSXMLHandler.java | 31 ++-- .../org/apache/fop/render/svg/SVGRenderer.java | 24 +-- .../org/apache/fop/render/xml/XMLRenderer.java | 8 +- .../org/apache/fop/render/xml/XMLXMLHandler.java | 19 ++- src/java/org/apache/fop/util/Service.java | 113 ++++++++++++++ 15 files changed, 436 insertions(+), 221 deletions(-) create mode 100644 src/java/org/apache/fop/render/XMLHandlerRegistry.java create mode 100644 src/java/org/apache/fop/util/Service.java (limited to 'src') diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index 39f16b4f0..d6c0dba1f 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -22,9 +22,8 @@ package org.apache.fop.apps; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; +import java.util.List; import java.util.Map; // avalon configuration @@ -41,6 +40,7 @@ import org.apache.fop.fo.FOEventHandler; import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.render.Renderer; +import org.apache.fop.render.XMLHandlerRegistry; /** * The User Agent for fo. @@ -67,15 +67,13 @@ public class FOUserAgent { /** Defines the default resolution (72dpi) for FOP */ public static final float DEFAULT_PX2MM = (25.4f / 72); //dpi (=25.4/dpi) - /** Map containing various default values */ - public Map defaults = new java.util.HashMap(); - /** Map containing XML handlers for various document types */ - public Map handlers = new java.util.HashMap(); + /** Registry for XML handlers */ + private XMLHandlerRegistry xmlHandlers = new XMLHandlerRegistry(); private String baseURL; private PDFEncryptionParams pdfEncryptionParams; private float px2mm = DEFAULT_PX2MM; - private HashMap rendererOptions = new java.util.HashMap(); + private Map rendererOptions = new java.util.HashMap(); private InputHandler inputHandler = null; private File outputFile = null; private Renderer rendererOverride = null; @@ -93,7 +91,7 @@ public class FOUserAgent { private boolean strictValidation = true; /* Additional fo.ElementMapping subclasses set by user */ - private ArrayList additionalElementMappings = null; + private List additionalElementMappings = null; /** Producer: Metadata element for the system/software that produces * the document. (Some renderers can store this in the document.) @@ -140,16 +138,16 @@ public class FOUserAgent { */ public void addElementMapping(ElementMapping elementMapping) { if (additionalElementMappings == null) { - additionalElementMappings = new ArrayList(); + additionalElementMappings = new java.util.ArrayList(); } additionalElementMappings.add(elementMapping); } /** - * Returns the ArrayList of user-added ElementMapping class names - * @return ArrayList of Strings holding ElementMapping names. + * Returns the List of user-added ElementMapping class names + * @return List of Strings holding ElementMapping names. */ - public ArrayList getAdditionalElementMappings() { + public List getAdditionalElementMappings() { return additionalElementMappings; } @@ -322,7 +320,7 @@ public class FOUserAgent { * Returns the renderer options * @return renderer options */ - public HashMap getRendererOptions() { + public Map getRendererOptions() { return rendererOptions; } @@ -457,11 +455,19 @@ public class FOUserAgent { /** * If to create hot links to footnotes and before floats. - * @return True if hot links dhould be created + * @return True if hot links should be created */ public boolean linkToFootnotes() { return true; } + /** + * @return the XML handler registry + */ + public XMLHandlerRegistry getXMLHandlerRegistry() { + return this.xmlHandlers; + } + + } diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java index 11a87bb59..02f94dd71 100644 --- a/src/java/org/apache/fop/fo/FOTreeBuilder.java +++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,7 @@ package org.apache.fop.fo; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -36,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.render.RendererFactory; +import org.apache.fop.util.Service; import org.apache.fop.fo.ElementMapping.Maker; import org.apache.fop.fo.pagination.Root; import org.xml.sax.Attributes; @@ -115,7 +109,7 @@ public class FOTreeBuilder extends DefaultHandler { setupDefaultMappings(); // add additional ElementMappings defined within FOUserAgent - ArrayList addlEMs = foUserAgent.getAdditionalElementMappings(); + List addlEMs = foUserAgent.getAdditionalElementMappings(); if (addlEMs != null) { for (int i = 0; i < addlEMs.size(); i++) { @@ -356,89 +350,6 @@ public class FOTreeBuilder extends DefaultHandler { rootFObj = null; foEventHandler = null; } -} - -// code stolen from org.apache.batik.util and modified slightly -// does what sun.misc.Service probably does, but it cannot be relied on. -// hopefully will be part of standard jdk sometime. - -/** - * This class loads services present in the class path. - */ -class Service { - - private static Map providerMap = new java.util.Hashtable(); - - public static synchronized Iterator providers(Class cls) { - ClassLoader cl = cls.getClassLoader(); - // null if loaded by bootstrap class loader - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } - String serviceFile = "META-INF/services/" + cls.getName(); - - // log.debug("File: " + serviceFile); - - List lst = (List)providerMap.get(serviceFile); - if (lst != null) { - return lst.iterator(); - } - - lst = new java.util.Vector(); - providerMap.put(serviceFile, lst); - - Enumeration e; - try { - e = cl.getResources(serviceFile); - } catch (IOException ioe) { - return lst.iterator(); - } - - while (e.hasMoreElements()) { - try { - java.net.URL u = (java.net.URL)e.nextElement(); - //log.debug("URL: " + u); - - InputStream is = u.openStream(); - Reader r = new InputStreamReader(is, "UTF-8"); - BufferedReader br = new BufferedReader(r); - - String line = br.readLine(); - while (line != null) { - try { - // First strip any comment... - int idx = line.indexOf('#'); - if (idx != -1) { - line = line.substring(0, idx); - } - - // Trim whitespace. - line = line.trim(); - - // If nothing left then loop around... - if (line.length() == 0) { - line = br.readLine(); - continue; - } - // log.debug("Line: " + line); - - // Try and load the class - // Object obj = cl.loadClass(line).newInstance(); - // stick it into our vector... - lst.add(line); - } catch (Exception ex) { - // Just try the next line - } - - line = br.readLine(); - } - } catch (Exception ex) { - // Just try the next file... - } - - } - return lst.iterator(); - } } diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index e3b74d8f8..53b2f8c64 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -22,9 +22,9 @@ package org.apache.fop.render; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.OutputStream; -import java.util.Map; import java.util.List; import java.util.Iterator; +import java.util.Set; // XML import org.w3c.dom.Document; @@ -109,6 +109,8 @@ public abstract class AbstractRenderer */ protected int containingIPPosition = 0; + private Set warnedXMLHandlers; + /** * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) */ @@ -693,32 +695,6 @@ public abstract class AbstractRenderer // Some renderers (ex. Text) don't support foreign objects. } - /** - * Set the default xml handler for the given mime type. - * @param mime MIME type - * @param handler XMLHandler to use - */ - public void setDefaultXMLHandler(FOUserAgent foua, String mime, - XMLHandler handler) { - foua.defaults.put(mime, handler); - } - - /** - * Add an xml handler for the given mime type and xml namespace. - * @param mime MIME type - * @param ns Namespace URI - * @param handler XMLHandler to use - */ - public void addXMLHandler(FOUserAgent foua, String mime, String ns, - XMLHandler handler) { - Map mh = (Map) foua.handlers.get(mime); - if (mh == null) { - mh = new java.util.HashMap(); - foua.handlers.put(mime, mh); - } - mh.put(ns, handler); - } - /** * Render the xml document with the given xml namespace. * The Render Context is by the handle to render into the current @@ -727,17 +703,11 @@ public abstract class AbstractRenderer * @param doc DOM Document containing the source document * @param namespace Namespace URI of the document */ - public void renderXML(FOUserAgent foua, RendererContext ctx, Document doc, + public void renderXML(RendererContext ctx, Document doc, String namespace) { String mime = ctx.getMimeType(); - Map mh = (Map) foua.handlers.get(mime); - XMLHandler handler = null; - if (mh != null) { - handler = (XMLHandler) mh.get(namespace); - } - if (handler == null) { - handler = (XMLHandler) foua.defaults.get(mime); - } + XMLHandler handler = userAgent.getXMLHandlerRegistry().getXMLHandler( + mime, namespace); if (handler != null) { try { handler.handleXML(ctx, doc, namespace); @@ -747,9 +717,15 @@ public abstract class AbstractRenderer + "Could not render XML", t); } } else { - // no handler found for document - getLogger().warn("Some XML content will be ignored. " - + "No handler defined for XML: " + namespace); + if (warnedXMLHandlers == null) { + warnedXMLHandlers = new java.util.HashSet(); + } + if (!warnedXMLHandlers.contains(namespace)) { + // no handler found for document + warnedXMLHandlers.add(namespace); + getLogger().warn("Some XML content will be ignored. " + + "No handler defined for XML: " + namespace); + } } } diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java index 998a53701..b81e10f69 100644 --- a/src/java/org/apache/fop/render/RendererContext.java +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,18 +32,28 @@ import org.apache.fop.apps.FOUserAgent; public class RendererContext { private String mime; + private AbstractRenderer renderer; private FOUserAgent userAgent; private Map props = new java.util.HashMap(); /** * Contructor for this class. It takes a MIME type as parameter. * + * @param renderer The current renderer * @param m The MIME type of the output that's generated. */ - public RendererContext(String m) { - mime = m; + public RendererContext(AbstractRenderer renderer, String m) { + this.renderer = renderer; + this.mime = m; } + /** + * @return Returns the renderer. + */ + public AbstractRenderer getRenderer() { + return renderer; + } + /** * Returns the MIME type associated with this RendererContext. * diff --git a/src/java/org/apache/fop/render/XMLHandler.java b/src/java/org/apache/fop/render/XMLHandler.java index 4942a5ae3..683479e93 100644 --- a/src/java/org/apache/fop/render/XMLHandler.java +++ b/src/java/org/apache/fop/render/XMLHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,11 +26,18 @@ import org.w3c.dom.Document; */ public interface XMLHandler { + /** Used to indicate that all MIME types or XML namespaces are handled. */ + String HANDLE_ALL = "*"; + /** - * Handle an external xml document inside a Foreign Object Area.

- * - * This may throw an exception if for some reason it cannot be handled. The - * caller is expected to deal with this exception.

+ *

Handle an external xml document inside a Foreign Object Area. + *

+ *

This may throw an exception if for some reason it cannot be handled. The + * caller is expected to deal with this exception. + *

+ *

The implementation may convert the XML document internally to another + * XML dialect (SVG, for example) and call renderXML() on the AbstractRenderer + * again (which can be retrieved through the RendererContext).

* * @param context The RendererContext (contains the user agent) * @param doc A DOM containing the foreign object to be @@ -38,8 +45,18 @@ public interface XMLHandler { * @param ns The Namespace of the foreign object * @exception Exception If an error occurs during processing. */ - void handleXML(RendererContext context, Document doc, String ns) - throws Exception; + void handleXML(RendererContext context, + Document doc, String ns) throws Exception; + + /** + * @return the MIME type for which this XMLHandler was written + */ + String getMimeType(); + /** + * @return the XML namespace for the XML dialect this XMLHandler supports, + * null if all XML content is handled by this instance. + */ + String getNamespace(); } diff --git a/src/java/org/apache/fop/render/XMLHandlerRegistry.java b/src/java/org/apache/fop/render/XMLHandlerRegistry.java new file mode 100644 index 000000000..11a9470a1 --- /dev/null +++ b/src/java/org/apache/fop/render/XMLHandlerRegistry.java @@ -0,0 +1,166 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.util.Iterator; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.util.Service; + +/** + * This class holds references to various XML handlers used by FOP. It also + * supports automatic discovery of additional XML handlers available through + * the class path. + */ +public class XMLHandlerRegistry { + + /** the logger */ + private static Log log = LogFactory.getLog(XMLHandlerRegistry.class); + + /** Map containing XML handlers for various document types */ + private Map handlers = new java.util.HashMap(); + + + /** + * Default constructor. + */ + public XMLHandlerRegistry() { + discoverXMLHandlers(); + } + + /** + * Set the default XML handler for the given MIME type. + * @param mime MIME type + * @param handler XMLHandler to use + */ + private void setDefaultXMLHandler(String mime, + XMLHandler handler) { + addXMLHandler(mime, XMLHandler.HANDLE_ALL, handler); + } + + /** + * Add an XML handler. The handler itself is inspected to find out what it supports. + * @param classname the fully qualified class name + */ + public void addXMLHandler(String classname) { + try { + XMLHandler handlerInstance = + (XMLHandler)Class.forName(classname).newInstance(); + addXMLHandler(handlerInstance); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Could not find " + + classname); + } catch (InstantiationException e) { + throw new IllegalArgumentException("Could not instantiate " + + classname); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Could not access " + + classname); + } catch (ClassCastException e) { + throw new IllegalArgumentException(classname + + " is not an ElementMapping"); + } + } + + /** + * Add an XML handler. The handler itself is inspected to find out what it supports. + * @param handler the XMLHandler instance + */ + public void addXMLHandler(XMLHandler handler) { + String mime = handler.getMimeType(); + String ns = handler.getNamespace(); + if (ns == null) { + setDefaultXMLHandler(mime, handler); + } else { + addXMLHandler(mime, ns, handler); + } + } + + /** + * Add an XML handler for the given MIME type and XML namespace. + * @param mime MIME type + * @param ns Namespace URI + * @param handler XMLHandler to use + */ + private void addXMLHandler(String mime, String ns, + XMLHandler handler) { + Map mh = (Map)handlers.get(mime); + if (mh == null) { + mh = new java.util.HashMap(); + handlers.put(mime, mh); + } + mh.put(ns, handler); + } + + /** + * Returns an XMLHandler which handles an XML dialect of the given namespace and for + * a specified output format defined by its MIME type. + * @param mime the MIME type of the output format + * @param ns the XML namespace associated with the XML to be rendered + * @return the XMLHandler responsible for handling the XML or null if none is available + */ + public XMLHandler getXMLHandler(String mime, String ns) { + XMLHandler handler = null; + + Map mh = (Map)handlers.get(mime); + if (mh != null) { + handler = (XMLHandler)mh.get(ns); + if (handler == null) { + handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL); + } + } + if (handler == null) { + mh = (Map)handlers.get(XMLHandler.HANDLE_ALL); + if (mh != null) { + handler = (XMLHandler)mh.get(ns); + if (handler == null) { + handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL); + } + } + } + return handler; + } + + + /** + * Discovers XMLHandler implementations through the classpath and dynamically + * registers them. + */ + private void discoverXMLHandlers() { + // add mappings from available services + Iterator providers = + Service.providers(XMLHandler.class); + if (providers != null) { + while (providers.hasNext()) { + String str = (String)providers.next(); + try { + if (log.isDebugEnabled()) { + log.debug("Dynamically adding XMLHandler: " + str); + } + addXMLHandler(str); + } catch (IllegalArgumentException e) { + log.error("Error while adding XMLHandler", e); + } + + } + } + } +} diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index cda0db5db..b991cb1e4 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -49,6 +49,7 @@ import java.util.Map; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.bridge.ViewBox; +import org.apache.batik.dom.svg.SVGDOMImplementation; import org.apache.batik.gvt.GraphicsNode; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; @@ -1024,7 +1025,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { Document doc = fo.getDocument(); String ns = fo.getNameSpace(); - if (ns.equals("http://www.w3.org/2000/svg")) { + if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { renderSVGDocument(doc, pos); } else { renderDocument(doc, ns, pos); @@ -1041,7 +1042,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab */ public void renderDocument(Document doc, String ns, Rectangle2D pos) { RendererContext context; - context = new RendererContext(MIME_TYPE); + context = new RendererContext(this, MIME_TYPE); context.setUserAgent(userAgent); // TODO implement /* @@ -1074,7 +1075,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab int y = currentBPPosition; RendererContext context; - context = new RendererContext(MIME_TYPE); + context = new RendererContext(this, MIME_TYPE); context.setUserAgent(userAgent); SVGUserAgent ua = new SVGUserAgent(context.getUserAgent() diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 5af6df8d8..4c079669a 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -237,9 +237,7 @@ public class PDFRenderer extends PrintRenderer { public void setUserAgent(FOUserAgent agent) { super.setUserAgent(agent); PDFXMLHandler xmlHandler = new PDFXMLHandler(); - //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler); - String svg = "http://www.w3.org/2000/svg"; - addXMLHandler(userAgent, MIME_TYPE, svg, xmlHandler); + userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler); } /** @@ -1570,7 +1568,7 @@ public class PDFRenderer extends PrintRenderer { * @param pdf StringBuffer to write the PDF code to, if null, the code is * written to the current stream. */ - private void setColor(Color col, boolean fill, StringBuffer pdf) { + protected void setColor(Color col, boolean fill, StringBuffer pdf) { PDFColor color = new PDFColor(col); closeText(); @@ -1754,7 +1752,7 @@ public class PDFRenderer extends PrintRenderer { */ public void renderDocument(Document doc, String ns, Rectangle2D pos) { RendererContext context; - context = new RendererContext(MIME_TYPE); + context = new RendererContext(this, MIME_TYPE); context.setUserAgent(userAgent); context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); @@ -1777,7 +1775,7 @@ public class PDFRenderer extends PrintRenderer { new Integer((int) pos.getWidth())); context.setProperty(PDFXMLHandler.PDF_HEIGHT, new Integer((int) pos.getHeight())); - renderXML(userAgent, context, doc, ns); + renderXML(context, doc, ns); } diff --git a/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java b/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java index a1debb513..62f7d2491 100644 --- a/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,12 +45,14 @@ import java.io.OutputStream; 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.gvt.GraphicsNode; import org.w3c.dom.svg.SVGDocument; import org.w3c.dom.svg.SVGSVGElement; +import java.awt.Color; import java.awt.geom.AffineTransform; /** @@ -137,17 +139,9 @@ public class PDFXMLHandler implements XMLHandler { public PDFXMLHandler() { } - /** - * Handle the XML. - * This checks the type of XML and handles appropraitely. - * - * @param context the renderer context - * @param doc the XML document to render - * @param ns the namespace of the XML document - * @throws Exception any sort of exception could be thrown and shuld be handled - */ - public void handleXML(RendererContext context, org.w3c.dom.Document doc, - String ns) throws Exception { + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + org.w3c.dom.Document doc, String ns) throws Exception { PDFInfo pdfi = getPDFInfo(context); String svg = "http://www.w3.org/2000/svg"; @@ -269,7 +263,11 @@ public class PDFXMLHandler implements XMLHandler { * Note: To have the svg overlay (under) a text area then use * an fo:block-container */ - pdfInfo.currentStream.add("q\n"); + PDFRenderer renderer = (PDFRenderer)context.getRenderer(); + renderer.saveGraphicsState(); + //pdfInfo.currentStream.add("q\n"); + renderer.setColor(Color.BLACK, false, null); + renderer.setColor(Color.BLACK, true, null); // transform so that the coordinates (0,0) is from the top left // and positive is down and to the right. (0,0) is where the // viewBox puts it. @@ -278,7 +276,7 @@ public class PDFXMLHandler implements XMLHandler { SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, w / 1000f, h / 1000f); - if (!at.isIdentity()) { + if (false && !at.isIdentity()) { double[] vals = new double[6]; at.getMatrix(vals); pdfInfo.currentStream.add(PDFNumber.doubleOut(vals[0], 5) + " " @@ -312,9 +310,20 @@ public class PDFXMLHandler implements XMLHandler { + e.getMessage(), e); } - pdfInfo.currentStream.add("Q\n"); + //pdfInfo.currentStream.add("Q\n"); + renderer.restoreGraphicsState(); pdfInfo.pdfState.pop(); } } -} + + /** @see org.apache.fop.render.XMLHandler#getMimeType() */ + public String getMimeType() { + return PDFRenderer.MIME_TYPE; + } + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return SVGDOMImplementation.SVG_NAMESPACE_URI; + } + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index fbe7a9984..5ac3a1101 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -112,9 +112,7 @@ public class PSRenderer extends PrintRenderer { public void setUserAgent(FOUserAgent agent) { super.setUserAgent(agent); PSXMLHandler xmlHandler = new PSXMLHandler(); - //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler); - String svg = "http://www.w3.org/2000/svg"; - addXMLHandler(userAgent, MIME_TYPE, svg, xmlHandler); + userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler); } /** @@ -815,7 +813,7 @@ public class PSRenderer extends PrintRenderer { */ public void renderDocument(Document doc, String ns, Rectangle2D pos) { RendererContext context; - context = new RendererContext(MIME_TYPE); + context = new RendererContext(this, MIME_TYPE); context.setUserAgent(userAgent); context.setProperty(PSXMLHandler.PS_GENERATOR, this.gen); @@ -830,7 +828,7 @@ public class PSRenderer extends PrintRenderer { new Integer(currentBPPosition + (int) pos.getY())); //context.setProperty("strokeSVGText", options.get("strokeSVGText")); - renderXML(userAgent, context, doc, ns); + renderXML(context, doc, ns); } /** @see org.apache.fop.render.AbstractRenderer */ diff --git a/src/java/org/apache/fop/render/ps/PSXMLHandler.java b/src/java/org/apache/fop/render/ps/PSXMLHandler.java index 3f5020bf9..d73267d74 100644 --- a/src/java/org/apache/fop/render/ps/PSXMLHandler.java +++ b/src/java/org/apache/fop/render/ps/PSXMLHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.w3c.dom.svg.SVGSVGElement; 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.gvt.GraphicsNode; // FOP @@ -96,21 +97,12 @@ public class PSXMLHandler implements XMLHandler { public PSXMLHandler() { } - /** - * Handle the XML. - * This checks the type of XML and handles appropraitely. - * - * @param context the renderer context - * @param doc the XML document to render - * @param ns the namespace of the XML document - * @throws Exception any sort of exception could be thrown and shuld be handled - */ - public void handleXML(RendererContext context, org.w3c.dom.Document doc, - String ns) throws Exception { + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + org.w3c.dom.Document doc, String ns) throws Exception { PSInfo psi = getPSInfo(context); - String svg = "http://www.w3.org/2000/svg"; - if (svg.equals(ns)) { + if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { SVGHandler svghandler = new SVGHandler(); svghandler.renderSVGDocument(context, doc, psi); } else { @@ -360,5 +352,16 @@ public class PSXMLHandler implements XMLHandler { } } } + + /** @see org.apache.fop.render.XMLHandler#getMimeType() */ + public String getMimeType() { + return PSRenderer.MIME_TYPE; + } + + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return SVGDOMImplementation.SVG_NAMESPACE_URI; + } + } diff --git a/src/java/org/apache/fop/render/svg/SVGRenderer.java b/src/java/org/apache/fop/render/svg/SVGRenderer.java index ccf1e82f4..294f269a3 100644 --- a/src/java/org/apache/fop/render/svg/SVGRenderer.java +++ b/src/java/org/apache/fop/render/svg/SVGRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,7 +118,7 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { * Creates a new SVG renderer. */ public SVGRenderer() { - context = new RendererContext(SVG_MIME_TYPE); + context = new RendererContext(this, SVG_MIME_TYPE); } /** @@ -126,8 +126,7 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { */ public void setUserAgent(FOUserAgent agent) { super.setUserAgent(agent); - setDefaultXMLHandler(userAgent, SVG_MIME_TYPE, this); - addXMLHandler(userAgent, SVG_MIME_TYPE, SVG_NAMESPACE, this); + userAgent.getXMLHandlerRegistry().addXMLHandler(this); } /** @@ -316,17 +315,15 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { * Method renderForeignObject. * @param fo the foreign object */ - public void renderForeignObject(ForeignObject fo) { + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { org.w3c.dom.Document doc = fo.getDocument(); String ns = fo.getNameSpace(); - renderXML(userAgent, context, doc, ns); + renderXML(context, doc, ns); } - /** - * @see org.apache.fop.render.XMLHandler#handleXML(RendererContext, Document, String) - */ - public void handleXML(RendererContext context, org.w3c.dom.Document doc, - String ns) throws Exception { + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + org.w3c.dom.Document doc, String ns) throws Exception { if (SVG_NAMESPACE.equals(ns)) { if (!(doc instanceof SVGDocument)) { DOMImplementation impl = @@ -419,5 +416,10 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { return SVG_MIME_TYPE; } + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return SVG_NAMESPACE; + } + } diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index 95ff72564..60b4ee4a8 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -105,7 +105,7 @@ public class XMLRenderer extends AbstractRenderer { * Creates a new XML renderer. */ public XMLRenderer() { - context = new RendererContext(XML_MIME_TYPE); + context = new RendererContext(this, XML_MIME_TYPE); } /** @@ -117,9 +117,7 @@ public class XMLRenderer extends AbstractRenderer { // //userAgent.addExtensionHandler(); XMLHandler handler = new XMLXMLHandler(); - setDefaultXMLHandler(userAgent, XML_MIME_TYPE, handler); - String svg = "http://www.w3.org/2000/svg"; - addXMLHandler(userAgent, XML_MIME_TYPE, svg, handler); + userAgent.getXMLHandlerRegistry().addXMLHandler(handler); } /** @@ -563,7 +561,7 @@ public class XMLRenderer extends AbstractRenderer { Document doc = fo.getDocument(); String ns = fo.getNameSpace(); context.setProperty(XMLXMLHandler.HANDLER, handler); - renderXML(userAgent, context, doc, ns); + renderXML(context, doc, ns); endElement("foreignObject"); } diff --git a/src/java/org/apache/fop/render/xml/XMLXMLHandler.java b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java index 74c54629d..269f1dd45 100644 --- a/src/java/org/apache/fop/render/xml/XMLXMLHandler.java +++ b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java @@ -40,14 +40,11 @@ public class XMLXMLHandler implements XMLHandler { private AttributesImpl atts = new AttributesImpl(); - /** - * @see org.apache.fop.render.XMLHandler#handleXML(RendererContext, Document, String) - */ - public void handleXML(RendererContext context, Document doc, - String ns) throws Exception { + /** @see org.apache.fop.render.XMLHandler */ + public void handleXML(RendererContext context, + org.w3c.dom.Document doc, String ns) throws Exception { TransformerHandler handler = (TransformerHandler) context.getProperty(HANDLER); - //String svg = "http://www.w3.org/2000/svg"; writeDocument(doc, handler); } @@ -166,5 +163,15 @@ public class XMLXMLHandler implements XMLHandler { return result.toString(); } + /** @see org.apache.fop.render.XMLHandler#getMimeType() */ + public String getMimeType() { + return XMLRenderer.XML_MIME_TYPE; + } + + /** @see org.apache.fop.render.XMLHandler#getNamespace() */ + public String getNamespace() { + return null; //Handle all XML content + } + } diff --git a/src/java/org/apache/fop/util/Service.java b/src/java/org/apache/fop/util/Service.java new file mode 100644 index 000000000..717b0f47f --- /dev/null +++ b/src/java/org/apache/fop/util/Service.java @@ -0,0 +1,113 @@ +/* + * Copyright 1999-2005 The Apache Software Foundation. + * + * Licensed 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.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +//code stolen from org.apache.batik.util and modified slightly +//does what sun.misc.Service probably does, but it cannot be relied on. +//hopefully will be part of standard jdk sometime. + +/** + * This class loads services present in the class path. + */ +public class Service { + + private static Map providerMap = new java.util.Hashtable(); + + public static synchronized Iterator providers(Class cls) { + ClassLoader cl = cls.getClassLoader(); + // null if loaded by bootstrap class loader + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + String serviceFile = "META-INF/services/" + cls.getName(); + + // log.debug("File: " + serviceFile); + + List lst = (List)providerMap.get(serviceFile); + if (lst != null) { + return lst.iterator(); + } + + lst = new java.util.Vector(); + providerMap.put(serviceFile, lst); + + Enumeration e; + try { + e = cl.getResources(serviceFile); + } catch (IOException ioe) { + return lst.iterator(); + } + + while (e.hasMoreElements()) { + try { + java.net.URL u = (java.net.URL)e.nextElement(); + //log.debug("URL: " + u); + + InputStream is = u.openStream(); + Reader r = new InputStreamReader(is, "UTF-8"); + BufferedReader br = new BufferedReader(r); + + String line = br.readLine(); + while (line != null) { + try { + // First strip any comment... + int idx = line.indexOf('#'); + if (idx != -1) { + line = line.substring(0, idx); + } + + // Trim whitespace. + line = line.trim(); + + // If nothing left then loop around... + if (line.length() == 0) { + line = br.readLine(); + continue; + } + // log.debug("Line: " + line); + + // Try and load the class + // Object obj = cl.loadClass(line).newInstance(); + // stick it into our vector... + lst.add(line); + } catch (Exception ex) { + // Just try the next line + } + + line = br.readLine(); + } + } catch (Exception ex) { + // Just try the next file... + } + + } + return lst.iterator(); + } + + } \ No newline at end of file -- cgit v1.2.3