You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2006/01/19 10:47:12 UTC

svn commit: r370452 - in /xmlgraphics/fop/trunk: src/java/META-INF/services/ src/java/org/apache/fop/area/ src/java/org/apache/fop/render/ps/extensions/ src/java/org/apache/fop/render/xml/ src/java/org/apache/fop/util/ test/layoutengine/standard-testca...

Author: jeremias
Date: Thu Jan 19 01:46:44 2006
New Revision: 370452

URL: http://svn.apache.org/viewcvs?rev=370452&view=rev
Log:
New interface XMLizable (copied from Apache Excalibur) to mark classes that can serialize themselves to XML (SAX stream).
New interface ContentHandlerFactory (plus associated Factory with Service discovery) for sub-document parsing plug-ins. Used by the area tree but could be used independently.
ExtensionAttachments are now part of the area tree and are written by XMLRenderer and parsed by AreaTreeParser.
The PS Extensions are extended to support serialization to and deserialization from XML.
Added a test case that tests the PS Extension WRT the handling in the area tree XML.

Added:
    xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/XMLizable.java
      - copied, changed from r370132, excalibur/trunk/components/xmlutil/src/java/org/apache/excalibur/xml/sax/XMLizable.java
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml   (with props)
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSSetupCode.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java

Added: xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory (added)
+++ xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory Thu Jan 19 01:46:44 2006
@@ -0,0 +1 @@
+org.apache.fop.render.ps.extensions.PSExtensionHandlerFactory
\ No newline at end of file

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java?rev=370452&r1=370451&r2=370452&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java Thu Jan 19 01:46:44 2006
@@ -51,11 +51,14 @@
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.ElementMappingRegistry;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.ImageFactory;
 import org.apache.fop.traits.BorderProps;
+import org.apache.fop.util.ContentHandlerFactory;
+import org.apache.fop.util.ContentHandlerFactoryRegistry;
 import org.apache.fop.util.DefaultErrorListener;
 
 import org.w3c.dom.DOMImplementation;
@@ -182,6 +185,7 @@
                 delegateStack.push(qName);
                 delegate.startElement(uri, localName, qName, attributes);
             } else if (domImplementation != null) {
+                //domImplementation is set so we need to start a new DOM building sub-process
                 TransformerHandler handler;
                 try {
                     handler = tFactory.newTransformerHandler();
@@ -196,6 +200,7 @@
                 ((ForeignObject)parent).setDocument(doc);
                 
                 //activate delegate for nested foreign document
+                domImplementation = null; //Not needed anymore now
                 this.delegate = handler;
                 delegateStack.push(qName);
                 delegate.startDocument();
@@ -405,15 +410,31 @@
                         setTraits(attributes, foreign);
                         getCurrentViewport().setContent(foreign);
                         areaStack.push(foreign);
+                    } else if ("extension-attachments".equals(localName)) {
+                        //TODO implement me
                     } else {
                         handled = false;
                     }
                 } else {
-                    handled = false;
+                    ContentHandlerFactory factory 
+                            = ContentHandlerFactoryRegistry.getInstance().getFactory(uri);
+                    if (factory != null) {
+                        delegate = factory.createContentHandler();
+                        delegateStack.push(qName);
+                        delegate.startDocument();
+                        delegate.startElement(uri, localName, qName, attributes);
+                    } else {
+                        handled = false;
+                    }
                 }
                 if (!handled) {
-                    throw new SAXException("Unhandled element " + localName 
-                            + " in namespace: " + uri);
+                    if (uri == null || uri.length() == 0) {
+                        throw new SAXException("Unhandled element " + localName 
+                                + " in namespace: " + uri);
+                    } else {
+                        log.warn("Unhandled element " + localName 
+                                + " in namespace: " + uri);
+                    }
                 }
             }
         }
@@ -438,6 +459,25 @@
             }
         }
         
+        /**
+         * Handles objects created by "sub-parsers" that implement the ObjectSource interface.
+         * An example of object handled here are ExtensionAttachments.
+         * @param obj the Object to be handled.
+         */
+        protected void handleExternallyGeneratedObject(Object obj) {
+            if (areaStack.size() == 0 && obj instanceof ExtensionAttachment) {
+                ExtensionAttachment attachment = (ExtensionAttachment)obj;
+                if (this.currentPageViewport == null) {
+                    this.treeModel.handleOffDocumentItem(
+                            new OffDocumentExtensionAttachment(attachment));
+                } else {
+                    this.currentPageViewport.addExtensionAttachment(attachment);
+                }
+            } else {
+                log.warn("Don't know how to handle externally generated object: " + obj);
+            }
+        }
+
         /** @see org.xml.sax.helpers.DefaultHandler */
         public void endElement(String uri, String localName, String qName) throws SAXException {
             if (delegate != null) {
@@ -445,8 +485,11 @@
                 delegateStack.pop();
                 if (delegateStack.size() == 0) {
                     delegate.endDocument();
-                    delegate = null;
-                    domImplementation = null;
+                    if (delegate instanceof ContentHandlerFactory.ObjectSource) {
+                        Object obj = ((ContentHandlerFactory.ObjectSource)delegate).getObject();
+                        handleExternallyGeneratedObject(obj);
+                    }
+                    delegate = null; //Sub-document is processed, return to normal processing
                 }
             } else {
                 if ("".equals(uri)) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java?rev=370452&r1=370451&r2=370452&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/PageViewport.java Thu Jan 19 01:46:44 2006
@@ -32,6 +32,7 @@
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 
 /**
@@ -490,6 +491,17 @@
     /** @return the name of the simple-page-master that created this page */
     public String getSimplePageMasterName() {
         return this.simplePageMasterName;
+    }
+    
+    /**
+     * Adds a new ExtensionAttachment instance to this page.
+     * @param attachment the ExtensionAttachment
+     */
+    public void addExtensionAttachment(ExtensionAttachment attachment) {
+        if (this.extensionAttachments == null) {
+            this.extensionAttachments = new java.util.ArrayList();
+        }
+        extensionAttachments.add(attachment);
     }
     
     /** @return the list of extension attachments for this page */

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java Thu Jan 19 01:46:44 2006
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2006 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.ps.extensions;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.area.AreaTreeParser;
+import org.apache.fop.util.ContentHandlerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * ContentHandler (parser) for restoring PSExtension objects from XML.
+ */
+public class PSExtensionHandler extends DefaultHandler 
+            implements ContentHandlerFactory.ObjectSource {
+
+    /** Logger instance */
+    protected static Log log = LogFactory.getLog(PSExtensionHandler.class);
+
+    private StringBuffer content = new StringBuffer();
+    private Attributes lastAttributes;
+    
+    private PSSetupCode returnedObject;
+    
+    /** @see org.xml.sax.helpers.DefaultHandler */
+    public void startElement(String uri, String localName, String qName, Attributes attributes) 
+                throws SAXException {
+        boolean handled = false;
+        if (PSSetupCode.CATEGORY.equals(uri)) {
+            lastAttributes = attributes;
+            handled = true; 
+            if ("ps-setup-code".equals(localName)) {
+                //handled in endElement
+            } else {
+                handled = false;
+            }
+        }
+        if (!handled) {
+            if (PSSetupCode.CATEGORY.equals(uri)) {
+                throw new SAXException("Unhandled element " + localName 
+                        + " in namespace: " + uri);
+            } else {
+                log.warn("Unhandled element " + localName 
+                        + " in namespace: " + uri);
+            }
+        }
+    }
+
+    /** @see org.xml.sax.helpers.DefaultHandler */
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (PSSetupCode.CATEGORY.equals(uri)) {
+            if ("ps-setup-code".equals(localName)) {
+                String name = lastAttributes.getValue("name");
+                this.returnedObject = new PSSetupCode(name, content.toString());
+            }
+        }    
+        content.setLength(0); //Reset text buffer (see characters())
+    }
+
+    /** @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        content.append(ch, start, length);
+    }
+
+    /** @see org.apache.fop.area.AreaTreeParser.ObjectSource#getObject() */
+    public Object getObject() {
+        return returnedObject;
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java Thu Jan 19 01:46:44 2006
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 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.ps.extensions;
+
+import org.apache.fop.util.ContentHandlerFactory;
+import org.xml.sax.ContentHandler;
+
+/**
+ * Factory for the ContentHandler that handles serialized PSSetupCode instances.
+ */
+public class PSExtensionHandlerFactory implements ContentHandlerFactory {
+
+    private static final String[] NAMESPACES = new String[] {PSSetupCode.CATEGORY};
+    
+    /** @see org.apache.fop.util.ContentHandlerFactory#getSupportedNamespaces() */
+    public String[] getSupportedNamespaces() {
+        return NAMESPACES;
+    }
+
+    /** @see org.apache.fop.util.ContentHandlerFactory#createContentHandler() */
+    public ContentHandler createContentHandler() {
+        return new PSExtensionHandler();
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandlerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSSetupCode.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSSetupCode.java?rev=370452&r1=370451&r2=370452&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSSetupCode.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/extensions/PSSetupCode.java Thu Jan 19 01:46:44 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Copyright 2005-2006 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.
@@ -21,11 +21,15 @@
 import java.io.Serializable;
 
 import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.util.XMLizable;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * This is the pass-through value object for the PostScript extension.
  */
-public class PSSetupCode implements ExtensionAttachment, Serializable {
+public class PSSetupCode implements ExtensionAttachment, Serializable, XMLizable {
 
     /** The category URI for this extension attachment. */
     public static final String CATEGORY = "apache:fop:extensions:postscript";
@@ -81,9 +85,26 @@
         return CATEGORY;
     }
     
-    
     /** @see java.lang.Object#toString() */
     public String toString() {
         return "PSSetupCode(name=" + getName() + ")";
     }
+
+    private static final String ATT_NAME = "name";
+    private static final String ELEMENT = "ps-setup-code";
+    
+    /** @see org.apache.fop.util.XMLizable#toSAX(org.xml.sax.ContentHandler) */
+    public void toSAX(ContentHandler handler) throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+        if (name != null && name.length() > 0) {
+            atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name);
+        }
+        handler.startElement(CATEGORY, ELEMENT, ELEMENT, atts);
+        if (content != null && content.length() > 0) {
+            char[] chars = content.toCharArray();
+            handler.characters(chars, 0, chars.length);
+        }
+        handler.endElement(CATEGORY, ELEMENT, ELEMENT);
+    }
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java?rev=370452&r1=370451&r2=370452&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java Thu Jan 19 01:46:44 2006
@@ -43,6 +43,7 @@
 import org.apache.fop.render.Renderer;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.XMLHandler;
+import org.apache.fop.util.XMLizable;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.MimeConstants;
@@ -56,6 +57,8 @@
 import org.apache.fop.area.Footnote;
 import org.apache.fop.area.LineArea;
 import org.apache.fop.area.MainReference;
+import org.apache.fop.area.OffDocumentExtensionAttachment;
+import org.apache.fop.area.OffDocumentItem;
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.RegionReference;
 import org.apache.fop.area.RegionViewport;
@@ -75,6 +78,7 @@
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontTriplet;
@@ -114,6 +118,9 @@
     
     /** The OutputStream to write the generated XML to. */
     protected OutputStream out;
+
+    /** A list of ExtensionAttachements received through processOffDocumentItem() */
+    protected List extensionAttachments;
     
     /**
      * Creates a new XML renderer.
@@ -357,6 +364,28 @@
                   + (int) rect.getWidth() + " " + (int) rect.getHeight();
     }
 
+    private void handleDocumentExtensionAttachments() {
+        if (extensionAttachments != null && extensionAttachments.size() > 0) {
+            handleExtensionAttachments(extensionAttachments);
+            extensionAttachments.clear();
+        }
+    }
+    
+    /** @see org.apache.fop.render.AbstractRenderer#processOffDocumentItem() */
+    public void processOffDocumentItem(OffDocumentItem oDI) {
+        if (oDI instanceof OffDocumentExtensionAttachment) {
+            ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment();
+            if (extensionAttachments == null) {
+                extensionAttachments = new java.util.ArrayList();
+            }
+            extensionAttachments.add(attachment);
+        } else {
+            String warn = "Ignoring OffDocumentItem: " + oDI;
+            comment("WARNING: " + warn);
+            log.warn(warn);
+        }
+    }
+
     /**
      * @see org.apache.fop.render.Renderer#startRenderer(OutputStream)
      */
@@ -416,15 +445,45 @@
         addAttribute("nr", page.getPageNumberString());
         startElement("pageViewport", atts);
         startElement("page");
+        
+        handlePageExtensionAttachments(page);
         super.renderPage(page);
+        
         endElement("page");
         endElement("pageViewport");
     }
 
+    private void handleExtensionAttachments(List attachments) {
+        if (attachments != null && attachments.size() > 0) {
+            startElement("extension-attachments");
+            Iterator i = attachments.iterator();
+            while (i.hasNext()) {
+                ExtensionAttachment attachment = (ExtensionAttachment)i.next();
+                if (attachment instanceof XMLizable) {
+                    try {
+                        ((XMLizable)attachment).toSAX(this.handler);
+                    } catch (SAXException e) {
+                        log.error("Error while serializing Extension Attachment", e);
+                    }
+                } else {
+                    String warn = "Ignoring non-XMLizable ExtensionAttachment: " + attachment;
+                    comment("WARNING: " + warn);
+                    log.warn(warn);
+                }
+            }
+            endElement("extension-attachments");
+        }
+    }
+    
+    private void handlePageExtensionAttachments(PageViewport page) {
+        handleExtensionAttachments(page.getExtensionAttachments());
+    }
+    
     /**
      * @see org.apache.fop.render.Renderer#startPageSequence(LineArea)
      */
     public void startPageSequence(LineArea seqTitle) {
+        handleDocumentExtensionAttachments();
         if (startedSequence) {
             endElement("pageSequence");
         }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java Thu Jan 19 01:46:44 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 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 org.xml.sax.ContentHandler;
+
+/**
+ * Factory interface implemented by classes that can instantiate ContentHandler subclasses which
+ * parse a SAX stream into Java objects.
+ */
+public interface ContentHandlerFactory {
+
+    /**
+     * @return an array of supported namespaces.
+     */
+    String[] getSupportedNamespaces();
+    
+    /**
+     * @return a new ContentHandler to handle a SAX stream
+     */
+    ContentHandler createContentHandler();
+    
+    /**
+     * Interface that ContentHandler implementations that parse Java objects from XML can implement
+     * to return these objects.
+     */
+    public interface ObjectSource {
+        
+        /**
+         * @return the object parsed from the SAX stream (call valid after parsing)
+         */
+        Object getObject();
+        
+    }
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java Thu Jan 19 01:46:44 2006
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2006 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.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 ContentHandlerFactoryRegistry {
+
+    /** the logger */
+    private static Log log = LogFactory.getLog(ContentHandlerFactoryRegistry.class);
+    
+    private static ContentHandlerFactoryRegistry instance;
+    
+    /** Map from namespace URIs to ContentHandlerFactories */
+    private Map factories = new java.util.HashMap();
+    
+    /**
+     * @return a singleton instance of the ContentHandlerFactoryRegistry.
+     */
+    public static ContentHandlerFactoryRegistry getInstance() {
+        if (instance == null) {
+            instance = new ContentHandlerFactoryRegistry();
+        }
+        return instance;
+    }
+    
+    /**
+     * Default constructor.
+     */
+    public ContentHandlerFactoryRegistry() {
+        discover();
+    }
+    
+    /**
+     * Add an XML handler. The handler itself is inspected to find out what it supports.
+     * @param classname the fully qualified class name
+     */
+    public void addContentHandlerFactory(String classname) {
+        try {
+            ContentHandlerFactory factory 
+                = (ContentHandlerFactory)Class.forName(classname).newInstance();
+            addContentHandlerFactory(factory);
+        } 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 " 
+                                               + ContentHandlerFactory.class.getName());
+        }
+    }
+    
+    /**
+     * Add an ContentHandlerFactory. The instance is inspected to find out what it supports.
+     * @param factory the ContentHandlerFactory instance
+     */
+    public void addContentHandlerFactory(ContentHandlerFactory factory) {
+        String[] ns = factory.getSupportedNamespaces();
+        for (int i = 0; i < ns.length; i++) {
+            factories.put(ns[i], factory);
+        }
+    }
+    
+    /**
+     * Retrieves a ContentHandlerFactory instance of a given namespace URI.
+     * @param namespaceURI the namespace to be handled.
+     * @return the ContentHandlerFactory or null, if no suitable instance is available.
+     */
+    public ContentHandlerFactory getFactory(String namespaceURI) {
+        ContentHandlerFactory factory = (ContentHandlerFactory)factories.get(namespaceURI);
+        return factory;
+    }
+    
+    /**
+     * Discovers ContentHandlerFactory implementations through the classpath and dynamically
+     * registers them.
+     */
+    private void discover() {
+        // add mappings from available services
+        Iterator providers = Service.providers(ContentHandlerFactory.class);
+        if (providers != null) {
+            while (providers.hasNext()) {
+                String str = (String)providers.next();
+                try {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Dynamically adding ContentHandlerFactory: " + str);
+                    }
+                    addContentHandlerFactory(str);
+                } catch (IllegalArgumentException e) {
+                    log.error("Error while adding ContentHandlerFactory", e);
+                }
+
+            }
+        }
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/XMLizable.java (from r370132, excalibur/trunk/components/xmlutil/src/java/org/apache/excalibur/xml/sax/XMLizable.java)
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/XMLizable.java?p2=xmlgraphics/fop/trunk/src/java/org/apache/fop/util/XMLizable.java&p1=excalibur/trunk/components/xmlutil/src/java/org/apache/excalibur/xml/sax/XMLizable.java&r1=370132&r2=370452&rev=370452&view=diff
==============================================================================
--- excalibur/trunk/components/xmlutil/src/java/org/apache/excalibur/xml/sax/XMLizable.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/XMLizable.java Thu Jan 19 01:46:44 2006
@@ -1,20 +1,28 @@
 /* 
- * Copyright 2002-2004 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
+ * Copyright 2002-2004 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.
- * 
+ * 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.
  */
-package org.apache.excalibur.xml.sax;
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+/* 
+ * Copied from Apache Excalibur:
+ * https://svn.apache.org/repos/asf/excalibur/trunk/components/xmlutil/
+ *                                           src/java/org/apache/excalibur/xml/sax/XMLizable.java
+ */
 
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -22,17 +30,14 @@
 /**
  * This interface can be implemented by classes willing to provide an XML representation
  * of their current state as SAX events.
- *
- * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
- * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:20 $
  */
-public interface XMLizable
-{
+public interface XMLizable {
+    
     /**
      * Generates SAX events representing the object's state.
-     * <b>NOTE</b> : if the implementation can produce lexical events, care should be taken
-     * that <code>handler</code> can actually be a {@link XMLConsumer} that accepts such
-     * events or directly implements the LexicalHandler interface!
+     * @param handler ContentHandler instance to send the SAX events to
+     * @throws SAXException if there's a problem generating the SAX events
      */
-    void toSAX( ContentHandler handler ) throws SAXException;
+    void toSAX(ContentHandler handler) throws SAXException;
+    
 }

Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml?rev=370452&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml (added)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml Thu Jan 19 01:46:44 2006
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2006 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$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks the PostScript extension for custom setup code. The extension attachments need to show
+      up in the area tree XML so the AreaTreeParser can fully restore the area tree.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:ps="http://xmlgraphics.apache.org/fop/postscript">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+          <fo:region-body/>
+          <ps:ps-page-setup-code name="media-dict">%FOPTestPSPageSetupCode: MediaDict!</ps:ps-page-setup-code>
+          <ps:ps-page-setup-code name="bla">%FOPTestPSPageSetupCode: Blah blah!</ps:ps-page-setup-code>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:declarations>
+        <ps:ps-setup-code>%FOPTestPSSetupCode: General setup code here!</ps:ps-setup-code>
+        <ps:ps-setup-code name="multi-line">
+%FOPTestPSSetupCode: Line 1
+%FOPTestPSSetupCode: Line 2
+        </ps:ps-setup-code>
+      </fo:declarations>
+      <fo:page-sequence master-reference="normal">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>Text on page <fo:page-number/>.</fo:block>
+          <fo:block break-before="page">Text on page <fo:page-number/>.</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="2" xpath="count(/areaTree/extension-attachments/child::*)"/>
+    <eval expected="%FOPTestPSSetupCode: General setup code here!" xpath="/areaTree/extension-attachments/child::*[1]"/>
+    <true xpath="contains(/areaTree/extension-attachments/child::*[2], '%FOPTestPSSetupCode: Line 1')"/>
+    <eval expected="multi-line" xpath="/areaTree/extension-attachments/child::*[2]/@name"/>
+
+    <eval expected="2" xpath="count(/areaTree/pageSequence/pageViewport[@nr=1]/page/extension-attachments/child::*)"/>
+    <eval expected="media-dict" xpath="/areaTree/pageSequence/pageViewport[@nr=1]/page/extension-attachments/child::*[1]/@name"/>
+    <eval expected="%FOPTestPSPageSetupCode: MediaDict!" xpath="/areaTree/pageSequence/pageViewport[@nr=1]/page/extension-attachments/child::*[1]"/>
+    <eval expected="bla" xpath="/areaTree/pageSequence/pageViewport[@nr=1]/page/extension-attachments/child::*[2]/@name"/>
+    <eval expected="%FOPTestPSPageSetupCode: Blah blah!" xpath="/areaTree/pageSequence/pageViewport[@nr=1]/page/extension-attachments/child::*[2]"/>
+
+    <eval expected="2" xpath="count(/areaTree/pageSequence/pageViewport[@nr=2]/page/extension-attachments/child::*)"/>
+    <eval expected="media-dict" xpath="/areaTree/pageSequence/pageViewport[@nr=2]/page/extension-attachments/child::*[1]/@name"/>
+    <eval expected="%FOPTestPSPageSetupCode: MediaDict!" xpath="/areaTree/pageSequence/pageViewport[@nr=2]/page/extension-attachments/child::*[1]"/>
+    <eval expected="bla" xpath="/areaTree/pageSequence/pageViewport[@nr=2]/page/extension-attachments/child::*[2]/@name"/>
+    <eval expected="%FOPTestPSPageSetupCode: Blah blah!" xpath="/areaTree/pageSequence/pageViewport[@nr=2]/page/extension-attachments/child::*[2]"/>
+  </checks>
+</testcase>

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/ps-extension_1.xml
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org