]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Made Service a stand-alone class so it can be reused.
authorJeremias Maerki <jeremias@apache.org>
Mon, 25 Jul 2005 15:54:20 +0000 (15:54 +0000)
committerJeremias Maerki <jeremias@apache.org>
Mon, 25 Jul 2005 15:54:20 +0000 (15:54 +0000)
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

15 files changed:
src/java/org/apache/fop/apps/FOUserAgent.java
src/java/org/apache/fop/fo/FOTreeBuilder.java
src/java/org/apache/fop/render/AbstractRenderer.java
src/java/org/apache/fop/render/RendererContext.java
src/java/org/apache/fop/render/XMLHandler.java
src/java/org/apache/fop/render/XMLHandlerRegistry.java [new file with mode: 0644]
src/java/org/apache/fop/render/java2d/Java2DRenderer.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/java/org/apache/fop/render/pdf/PDFXMLHandler.java
src/java/org/apache/fop/render/ps/PSRenderer.java
src/java/org/apache/fop/render/ps/PSXMLHandler.java
src/java/org/apache/fop/render/svg/SVGRenderer.java
src/java/org/apache/fop/render/xml/XMLRenderer.java
src/java/org/apache/fop/render/xml/XMLXMLHandler.java
src/java/org/apache/fop/util/Service.java [new file with mode: 0644]

index 39f16b4f0a30b115d0686c4c69252e99082fc372..d6c0dba1fa7c604d0fc8df5a09f983fcc79b9ca8 100644 (file)
@@ -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;
+    }
+    
+    
 }
 
index 11a87bb59c788701f2c48ced928fc5d22e574516..02f94dd7123ac1e141ceb3ee868dfdd4f2e0dbeb 100644 (file)
@@ -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.
 
 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();
-    }
 
 }
 
index e3b74d8f82b5011dfd5c3bb535ca4081e8f4ea94..53b2f8c6494ee74e81dfa64096ff7490b56b6362 100644 (file)
@@ -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);
+            }
         }
     }
 
index 998a537015367b5b94dbe8ffe7bf1f51a083553a..b81e10f697a1bd8e6e5de6580037b488b3d9d74f 100644 (file)
@@ -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.
      *
index 4942a5ae3f8cff5e09236d11ebb3ca1ef35783e2..683479e93ad7ecf6039120b7d2c3565578b4d5a3 100644 (file)
@@ -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. <p>
-     *
-     * This may throw an exception if for some reason it cannot be handled. The
-     * caller is expected to deal with this exception.</p>
+     * <p>Handle an external xml document inside a Foreign Object Area.
+     * </p>
+     * <p>This may throw an exception if for some reason it cannot be handled. The
+     * caller is expected to deal with this exception.
+     * </p>
+     * <p>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).</p>
      *
      * @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 (file)
index 0000000..11a9470
--- /dev/null
@@ -0,0 +1,166 @@
+/*\r
+ * Copyright 2005 The Apache Software Foundation.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.render;\r
+\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.apache.fop.util.Service;\r
+\r
+/**\r
+ * This class holds references to various XML handlers used by FOP. It also\r
+ * supports automatic discovery of additional XML handlers available through\r
+ * the class path.\r
+ */\r
+public class XMLHandlerRegistry {\r
+\r
+    /** the logger */\r
+    private static Log log = LogFactory.getLog(XMLHandlerRegistry.class);\r
+    \r
+    /** Map containing XML handlers for various document types */\r
+    private Map handlers = new java.util.HashMap();\r
+    \r
+    \r
+    /**\r
+     * Default constructor.\r
+     */\r
+    public XMLHandlerRegistry() {\r
+        discoverXMLHandlers();\r
+    }\r
+    \r
+    /**\r
+     * Set the default XML handler for the given MIME type.\r
+     * @param mime MIME type\r
+     * @param handler XMLHandler to use\r
+     */\r
+    private void setDefaultXMLHandler(String mime,\r
+                                     XMLHandler handler) {\r
+        addXMLHandler(mime, XMLHandler.HANDLE_ALL, handler);\r
+    }\r
+    \r
+    /**\r
+     * Add an XML handler. The handler itself is inspected to find out what it supports.\r
+     * @param classname the fully qualified class name\r
+     */\r
+    public void addXMLHandler(String classname) {\r
+        try {\r
+            XMLHandler handlerInstance =\r
+                (XMLHandler)Class.forName(classname).newInstance();\r
+            addXMLHandler(handlerInstance);\r
+        } catch (ClassNotFoundException e) {\r
+            throw new IllegalArgumentException("Could not find "\r
+                                               + classname);\r
+        } catch (InstantiationException e) {\r
+            throw new IllegalArgumentException("Could not instantiate "\r
+                                               + classname);\r
+        } catch (IllegalAccessException e) {\r
+            throw new IllegalArgumentException("Could not access "\r
+                                               + classname);\r
+        } catch (ClassCastException e) {\r
+            throw new IllegalArgumentException(classname\r
+                                               + " is not an ElementMapping");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Add an XML handler. The handler itself is inspected to find out what it supports.\r
+     * @param handler the XMLHandler instance\r
+     */\r
+    public void addXMLHandler(XMLHandler handler) {\r
+        String mime = handler.getMimeType();\r
+        String ns = handler.getNamespace();\r
+        if (ns == null) {\r
+            setDefaultXMLHandler(mime, handler);\r
+        } else {\r
+            addXMLHandler(mime, ns, handler);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Add an XML handler for the given MIME type and XML namespace.\r
+     * @param mime MIME type\r
+     * @param ns Namespace URI\r
+     * @param handler XMLHandler to use\r
+     */\r
+    private void addXMLHandler(String mime, String ns,\r
+                              XMLHandler handler) {\r
+        Map mh = (Map)handlers.get(mime);\r
+        if (mh == null) {\r
+            mh = new java.util.HashMap();\r
+            handlers.put(mime, mh);\r
+        }\r
+        mh.put(ns, handler);\r
+    }\r
+    \r
+    /**\r
+     * Returns an XMLHandler which handles an XML dialect of the given namespace and for\r
+     * a specified output format defined by its MIME type.\r
+     * @param mime the MIME type of the output format\r
+     * @param ns the XML namespace associated with the XML to be rendered\r
+     * @return the XMLHandler responsible for handling the XML or null if none is available\r
+     */\r
+    public XMLHandler getXMLHandler(String mime, String ns) {\r
+        XMLHandler handler = null;\r
+\r
+        Map mh = (Map)handlers.get(mime);\r
+        if (mh != null) {\r
+            handler = (XMLHandler)mh.get(ns);\r
+            if (handler == null) {\r
+                handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL);\r
+            }\r
+        }\r
+        if (handler == null) {\r
+            mh = (Map)handlers.get(XMLHandler.HANDLE_ALL);\r
+            if (mh != null) {\r
+                handler = (XMLHandler)mh.get(ns);\r
+                if (handler == null) {\r
+                    handler = (XMLHandler)mh.get(XMLHandler.HANDLE_ALL);\r
+                }\r
+            }\r
+        }\r
+        return handler;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Discovers XMLHandler implementations through the classpath and dynamically\r
+     * registers them.\r
+     */\r
+    private void discoverXMLHandlers() {\r
+        // add mappings from available services\r
+        Iterator providers =\r
+            Service.providers(XMLHandler.class);\r
+        if (providers != null) {\r
+            while (providers.hasNext()) {\r
+                String str = (String)providers.next();\r
+                try {\r
+                    if (log.isDebugEnabled()) {\r
+                        log.debug("Dynamically adding XMLHandler: " + str);\r
+                    }\r
+                    addXMLHandler(str);\r
+                } catch (IllegalArgumentException e) {\r
+                    log.error("Error while adding XMLHandler", e);\r
+                }\r
+\r
+            }\r
+        }\r
+    }\r
+}\r
index cda0db5dbfad8bbe0e29747500e9c5e381e9ae4b..b991cb1e48188de7a98eebdd85c5a5a1f0f31de4 100644 (file)
@@ -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()
index 5af6df8d8f2b08e3b55b87910e5ad81949f486d1..4c079669aeee9803dd211f10c0e672af6c72e730 100644 (file)
@@ -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);
 
     }
 
index a1debb513701a973703ead389843839479a6a5f3..62f7d24918b6b61c323aeb98b71a7f9965022121 100644 (file)
@@ -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
index fbe7a998430969f27f8895b6fdfa165e02c8939c..5ac3a110173595fb95afc3051443fec3cb07295d 100644 (file)
@@ -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 */
index 3f5020bf91c60f62bc8939b6e4da21e888484cd2..d73267d74d43cd126a1eef878d56c1b3659cbe5b 100644 (file)
@@ -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;
+    }
+    
 }
 
index ccf1e82f4d553351eaee90d69491825015497eda..294f269a30e20bc7ac0d548842b77cae1b9eb42c 100644 (file)
@@ -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;
+    }
+
 }
 
index 95ff725644b61cebe590cb64f6159f2e2801eb9b..60b4ee4a88d91a3901751195d2eed4cb15837cdc 100644 (file)
@@ -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");
     }
 
index 74c54629da16e2c553179391d92949a3fbb9fa33..269f1dd450b85ade12c476a778b7d2a62e61c979 100644 (file)
@@ -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 (file)
index 0000000..717b0f4
--- /dev/null
@@ -0,0 +1,113 @@
+/*\r
+ * Copyright 1999-2005 The Apache Software Foundation.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.util;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.Reader;\r
+import java.util.Enumeration;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+//code stolen from org.apache.batik.util and modified slightly\r
+//does what sun.misc.Service probably does, but it cannot be relied on.\r
+//hopefully will be part of standard jdk sometime.\r
+\r
+/**\r
+ * This class loads services present in the class path.\r
+ */\r
+public class Service {\r
+\r
+     private static Map providerMap = new java.util.Hashtable();\r
+\r
+     public static synchronized Iterator providers(Class cls) {\r
+         ClassLoader cl = cls.getClassLoader();\r
+         // null if loaded by bootstrap class loader\r
+         if (cl == null) {\r
+             cl = ClassLoader.getSystemClassLoader();\r
+         }\r
+         String serviceFile = "META-INF/services/" + cls.getName();\r
+\r
+         // log.debug("File: " + serviceFile);\r
+\r
+         List lst = (List)providerMap.get(serviceFile);\r
+         if (lst != null) {\r
+             return lst.iterator();\r
+         }\r
+\r
+         lst = new java.util.Vector();\r
+         providerMap.put(serviceFile, lst);\r
+\r
+         Enumeration e;\r
+         try {\r
+             e = cl.getResources(serviceFile);\r
+         } catch (IOException ioe) {\r
+             return lst.iterator();\r
+         }\r
+\r
+         while (e.hasMoreElements()) {\r
+             try {\r
+                 java.net.URL u = (java.net.URL)e.nextElement();\r
+                 //log.debug("URL: " + u);\r
+\r
+                 InputStream is = u.openStream();\r
+                 Reader r = new InputStreamReader(is, "UTF-8");\r
+                 BufferedReader br = new BufferedReader(r);\r
+\r
+                 String line = br.readLine();\r
+                 while (line != null) {\r
+                     try {\r
+                         // First strip any comment...\r
+                         int idx = line.indexOf('#');\r
+                         if (idx != -1) {\r
+                             line = line.substring(0, idx);\r
+                         }\r
+\r
+                         // Trim whitespace.\r
+                         line = line.trim();\r
+\r
+                         // If nothing left then loop around...\r
+                         if (line.length() == 0) {\r
+                             line = br.readLine();\r
+                             continue;\r
+                         }\r
+                         // log.debug("Line: " + line);\r
+\r
+                         // Try and load the class\r
+                         // Object obj = cl.loadClass(line).newInstance();\r
+                         // stick it into our vector...\r
+                         lst.add(line);\r
+                     } catch (Exception ex) {\r
+                         // Just try the next line\r
+                     }\r
+\r
+                     line = br.readLine();\r
+                 }\r
+             } catch (Exception ex) {\r
+                 // Just try the next file...\r
+             }\r
+\r
+         }\r
+         return lst.iterator();\r
+     }\r
+\r
+ }
\ No newline at end of file