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/06/20 16:57:45 UTC

svn commit: r415688 - in /xmlgraphics/fop/trunk: ./ lib/ src/java/META-INF/services/ src/java/org/apache/fop/fo/extensions/xmp/ src/java/org/apache/fop/pdf/ src/java/org/apache/fop/render/pdf/

Author: jeremias
Date: Tue Jun 20 07:57:44 2006
New Revision: 415688

URL: http://svn.apache.org/viewvc?rev=415688&view=rev
Log:
XML Graphics Commons 1.0 replaced with a SVN snapshot (containing the XMP framework).
Reworked the XMP support for PDF to use the XMP framework from XML Graphics Commons.
XMP metadata embedded in fo:declarations is now properly handled. Its values are copied to the Info object according to the rules from PDF/A-1.
Metadata values from the user agent (title, author etc.) are properly merged with metadata from the XSL-FO document. UserAgent metadata overrides FO metadata.
Note: This is useful and active even if you don't activate PDF/A support.

Added:
    xmlgraphics/fop/trunk/lib/xmlgraphics-commons-1.1-snapshot.jar   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java   (with props)
Removed:
    xmlgraphics/fop/trunk/lib/xmlgraphics-commons-1.0.jar
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPConstants.java
Modified:
    xmlgraphics/fop/trunk/fop.bat
    xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElement.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElementMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPElementMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetaElement.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetadata.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java

Modified: xmlgraphics/fop/trunk/fop.bat
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop.bat?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop.bat (original)
+++ xmlgraphics/fop/trunk/fop.bat Tue Jun 20 07:57:44 2006
@@ -46,7 +46,7 @@
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\xalan-2.7.0.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\serializer-2.7.0.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\batik-all-1.6.jar
-set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\xmlgraphics-commons-1.0.jar
+set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\xmlgraphics-commons-1.1-snapshot.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\avalon-framework-4.2.0.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\commons-io-1.1.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\commons-logging-1.0.4.jar

Added: xmlgraphics/fop/trunk/lib/xmlgraphics-commons-1.1-snapshot.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/lib/xmlgraphics-commons-1.1-snapshot.jar?rev=415688&view=auto
==============================================================================
Binary file - no diff available.

Propchange: xmlgraphics/fop/trunk/lib/xmlgraphics-commons-1.1-snapshot.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory (original)
+++ xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.util.ContentHandlerFactory Tue Jun 20 07:57:44 2006
@@ -1 +1,2 @@
-org.apache.fop.render.ps.extensions.PSExtensionHandlerFactory
\ No newline at end of file
+org.apache.fop.render.ps.extensions.PSExtensionHandlerFactory
+org.apache.fop.fo.extensions.xmp.XMPContentHandlerFactory
\ No newline at end of file

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java?rev=415688&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java Tue Jun 20 07:57:44 2006
@@ -0,0 +1,68 @@
+/*
+ * 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.fo.extensions.xmp;
+
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.util.ContentHandlerFactory;
+import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener;
+import org.apache.xmlgraphics.xmp.Metadata;
+
+/**
+ * Abstract base class for the XMP and RDF root nodes.
+ */
+public abstract class AbstractMetadataElement extends FONode implements ObjectBuiltListener {
+
+    private XMPMetadata attachment;
+    
+    /**
+     * Main constructor.
+     * @param parent the parent formatting object
+     */
+    public AbstractMetadataElement(FONode parent) {
+        super(parent);
+    }
+    
+    /**
+     * @see org.apache.fop.fo.FONode#getContentHandlerFactory()
+     */
+    public ContentHandlerFactory getContentHandlerFactory() {
+        return new XMPContentHandlerFactory();
+    }
+    
+    /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
+    public ExtensionAttachment getExtensionAttachment() {
+        if (parent instanceof FObj) {
+            if (attachment == null) {
+                attachment = new XMPMetadata();
+            }
+            return attachment;
+        } else {
+            return super.getExtensionAttachment();
+        }
+    }
+
+    /** @see org.apache.fop.fo.XMLObj#notifyObjectBuilt(java.lang.Object) */
+    public void notifyObjectBuilt(Object obj) {
+        attachment.setMetadata((Metadata)obj);
+    }
+
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/AbstractMetadataElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElement.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElement.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElement.java Tue Jun 20 07:57:44 2006
@@ -18,21 +18,14 @@
 
 package org.apache.fop.fo.extensions.xmp;
 
-import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.XMLObj;
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-import org.apache.fop.util.ContentHandlerFactory;
-import org.apache.fop.util.DOMBuilderContentHandlerFactory;
+import org.apache.xmlgraphics.xmp.XMPConstants;
 
 /**
  * Represents the top-level "RDF" element used by XMP metadata.
  */
-public class RDFElement extends XMLObj {
+public class RDFElement extends AbstractMetadataElement {
 
-    private XMPMetadata attachment;
-    
     /**
      * Main constructor.
      * @param parent the parent formatting object
@@ -41,6 +34,11 @@
         super(parent);
     }
     
+    /** @see org.apache.fop.fo.FONode#getLocalName() */
+    public String getLocalName() {
+        return "RDF";
+    }
+
     /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
     public String getNormalNamespacePrefix() {
         return "rdf";
@@ -49,34 +47,6 @@
     /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
     public String getNamespaceURI() {
         return XMPConstants.RDF_NAMESPACE;
-    }
-
-    /**
-     * @see org.apache.fop.fo.FONode#getContentHandlerFactory()
-     */
-    public ContentHandlerFactory getContentHandlerFactory() {
-        return new DOMBuilderContentHandlerFactory(getNamespaceURI(), 
-                ElementMapping.getDefaultDOMImplementation());
-    }
-    
-    /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
-    public ExtensionAttachment getExtensionAttachment() {
-        if (parent instanceof FObj) {
-            if (attachment == null) {
-                attachment = new XMPMetadata(doc);
-            }
-            return attachment;
-        } else {
-            return super.getExtensionAttachment();
-        }
-    }
-
-    /**
-     * @see org.apache.fop.fo.XMLObj#notifyObjectBuilt(java.lang.Object)
-     */
-    public void notifyObjectBuilt(Object obj) {
-        super.notifyObjectBuilt(obj);
-        attachment.setDocument(doc);
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElementMapping.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/RDFElementMapping.java Tue Jun 20 07:57:44 2006
@@ -22,6 +22,7 @@
 
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.ElementMapping;
+import org.apache.xmlgraphics.xmp.XMPConstants;
 
 import org.w3c.dom.DOMImplementation;
 

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java?rev=415688&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java Tue Jun 20 07:57:44 2006
@@ -0,0 +1,70 @@
+/*
+ * 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.fo.extensions.xmp;
+
+import org.apache.fop.util.ContentHandlerFactory;
+import org.apache.xmlgraphics.xmp.XMPConstants;
+import org.apache.xmlgraphics.xmp.XMPHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * ContentHandlerFactory for the XMP root element.
+ */
+public class XMPContentHandlerFactory implements ContentHandlerFactory {
+
+    private static final String[] NAMESPACES = new String[] 
+                                         {XMPConstants.XMP_NAMESPACE, XMPConstants.RDF_NAMESPACE};
+
+    /** @see org.apache.fop.util.ContentHandlerFactory#getSupportedNamespaces() */
+    public String[] getSupportedNamespaces() {
+        return NAMESPACES;
+    }
+
+    /** @see org.apache.fop.util.ContentHandlerFactory#createContentHandler() */
+    public ContentHandler createContentHandler() throws SAXException {
+        return new FOPXMPHandler();
+    }
+
+    /**
+     * Local subclass of XMPHandler that implements ObjectSource for FOP integration.
+     */
+    private class FOPXMPHandler extends XMPHandler implements ObjectSource {
+
+        private ObjectBuiltListener obListener;
+        
+        public Object getObject() {
+            return getMetadata();
+        }
+
+        /** @see org.apache.fop.util.ContentHandlerFactory.ObjectSource */
+        public void setObjectBuiltListener(ObjectBuiltListener listener) {
+            this.obListener = listener;
+        }
+        
+        /** @see org.xml.sax.helpers.DefaultHandler#endDocument() */
+        public void endDocument() throws SAXException {
+            if (obListener != null) {
+                obListener.notifyObjectBuilt(getObject());
+            }
+        }
+        
+    }
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPContentHandlerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPElementMapping.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPElementMapping.java Tue Jun 20 07:57:44 2006
@@ -22,6 +22,7 @@
 
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.ElementMapping;
+import org.apache.xmlgraphics.xmp.XMPConstants;
 
 import org.w3c.dom.DOMImplementation;
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetaElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetaElement.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetaElement.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetaElement.java Tue Jun 20 07:57:44 2006
@@ -18,21 +18,14 @@
 
 package org.apache.fop.fo.extensions.xmp;
 
-import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.XMLObj;
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-import org.apache.fop.util.ContentHandlerFactory;
-import org.apache.fop.util.DOMBuilderContentHandlerFactory;
+import org.apache.xmlgraphics.xmp.XMPConstants;
 
 /**
  * Represents the top-level "xmpmeta" element used by XMP metadata.
  */
-public class XMPMetaElement extends XMLObj {
+public class XMPMetaElement extends AbstractMetadataElement {
 
-    private XMPMetadata attachment;
-    
     /**
      * Main constructor.
      * @param parent the parent formatting object
@@ -41,6 +34,11 @@
         super(parent);
     }
     
+    /** @see org.apache.fop.fo.FONode#getLocalName() */
+    public String getLocalName() {
+        return "xmpmeta";
+    }
+
     /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
     public String getNormalNamespacePrefix() {
         return "x";
@@ -49,34 +47,6 @@
     /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
     public String getNamespaceURI() {
         return XMPConstants.XMP_NAMESPACE;
-    }
-
-    /**
-     * @see org.apache.fop.fo.FONode#getContentHandlerFactory()
-     */
-    public ContentHandlerFactory getContentHandlerFactory() {
-        return new DOMBuilderContentHandlerFactory(getNamespaceURI(), 
-                ElementMapping.getDefaultDOMImplementation());
-    }
-    
-    /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
-    public ExtensionAttachment getExtensionAttachment() {
-        if (parent instanceof FObj) {
-            if (attachment == null) {
-                attachment = new XMPMetadata(doc);
-            }
-            return attachment;
-        } else {
-            return super.getExtensionAttachment();
-        }
-    }
-
-    /**
-     * @see org.apache.fop.fo.XMLObj#notifyObjectBuilt(java.lang.Object)
-     */
-    public void notifyObjectBuilt(Object obj) {
-        super.notifyObjectBuilt(obj);
-        attachment.setDocument(doc);
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetadata.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetadata.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetadata.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/xmp/XMPMetadata.java Tue Jun 20 07:57:44 2006
@@ -21,9 +21,9 @@
 import java.io.Serializable;
 
 import org.apache.fop.fo.extensions.ExtensionAttachment;
-import org.apache.fop.util.DOM2SAX;
 import org.apache.fop.util.XMLizable;
-import org.w3c.dom.Document;
+import org.apache.xmlgraphics.xmp.Metadata;
+import org.apache.xmlgraphics.xmp.XMPConstants;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
@@ -35,7 +35,7 @@
     /** The category URI for this extension attachment. */
     public static final String CATEGORY = XMPConstants.XMP_NAMESPACE;
     
-    private Document doc;
+    private Metadata meta;
     private boolean readOnly = true;
 
     /**
@@ -47,23 +47,23 @@
     
     /**
      * Default constructor.
-     * @param doc the DOM document containing the XMP metadata
+     * @param metadata the XMP metadata
      */
-    public XMPMetadata(Document doc) {
-        this.doc = doc;
+    public XMPMetadata(Metadata metadata) {
+        this.meta = metadata;
     }
     
-    /** @return the DOM document containing the XMP metadata */
-    public Document getDocument() {
-        return this.doc;
+    /** @return the XMP metadata */
+    public Metadata getMetadata() {
+        return this.meta;
     }
     
     /**
-     * Sets the DOM document containing the XMP metadata.
-     * @param document the DOM document
+     * Sets the XMP metadata.
+     * @param metadata the XMP metadata
      */
-    public void setDocument(Document document) {
-        this.doc = document;
+    public void setMetadata(Metadata metadata) {
+        this.meta = metadata;
     }
     
     /** @return true if the XMP metadata is marked read-only. */
@@ -86,7 +86,7 @@
     
     /** @see org.apache.fop.util.XMLizable#toSAX(org.xml.sax.ContentHandler) */
     public void toSAX(ContentHandler handler) throws SAXException {
-        new DOM2SAX(handler).writeDocument(getDocument(), true);
+        getMetadata().toSAX(handler);
     }
     
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java Tue Jun 20 07:57:44 2006
@@ -53,6 +53,7 @@
 import org.apache.fop.fonts.truetype.TTFSubSetFile;
 import org.apache.fop.fonts.type1.PFBData;
 import org.apache.fop.fonts.type1.PFBParser;
+import org.apache.xmlgraphics.xmp.Metadata;
 
 /**
  * This class provides method to create and register PDF objects.
@@ -146,8 +147,8 @@
      * @param readOnly true if the metadata packet should be marked read-only
      * @return the newly created Metadata object
      */
-    public PDFMetadata makeMetadata(Document doc, boolean readOnly) {
-        PDFMetadata pdfMetadata = new PDFMetadata(doc, readOnly);
+    public PDFMetadata makeMetadata(Metadata meta, boolean readOnly) {
+        PDFMetadata pdfMetadata = new PDFMetadata(meta, readOnly);
         getDocument().registerObject(pdfMetadata);
         return pdfMetadata;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java Tue Jun 20 07:57:44 2006
@@ -37,6 +37,7 @@
     private String subject = null;
     private String keywords = null;
     private Date creationDate = null;
+    private Date modDate = null;
 
     /**
      * the name of the application that created the
@@ -142,6 +143,20 @@
         creationDate = date;
     }
 
+    /** @return last modification date
+     */
+    public Date getModDate() {
+        return this.modDate;
+    }
+
+    /**
+     * Sets the date of the last modification.
+     * @param date the last modification date or null if there are no modifications
+     */
+    public void setModDate(Date date) {
+        this.modDate = date;
+    }
+
     /**
      * @see org.apache.fop.pdf.PDFObject#toPDF()
      */
@@ -192,9 +207,12 @@
             bout.write(encodeString(formatDateTime(creationDate)));
             bout.write(encode("\n"));
             
-            if (profile.isModDateRequired()) {
+            if (profile.isModDateRequired() && this.modDate == null) {
+                this.modDate = this.creationDate;
+            }
+            if (this.modDate != null) {
                 bout.write(encode("/ModDate "));
-                bout.write(encodeString(formatDateTime(creationDate)));
+                bout.write(encodeString(formatDateTime(modDate)));
                 bout.write(encode("\n"));
             }
             if (profile.isPDFXActive()) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java Tue Jun 20 07:57:44 2006
@@ -20,25 +20,23 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
 import java.util.Date;
 
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.fop.fo.ElementMapping;
-import org.apache.fop.fo.extensions.xmp.XMPConstants;
-
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+
+import org.apache.xmlgraphics.xmp.Metadata;
+import org.apache.xmlgraphics.xmp.XMPSerializer;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAOldXMPSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema;
+
+import org.xml.sax.SAXException;
 
 /**
  * Special PDFStream for Metadata.
@@ -46,20 +44,15 @@
  */
 public class PDFMetadata extends PDFStream {
     
-    private static final String XMLNS = "http://www.w3.org/2000/xmlns/";
-
-    private static DateFormat pseudoISO8601DateFormat = new SimpleDateFormat(
-        "yyyy'-'MM'-'dd'T'HH':'mm':'ss");
-
-    private Document xmpMetadata;
+    private Metadata xmpMetadata;
     private boolean readOnly = true;
 
     /** @see org.apache.fop.pdf.PDFObject#PDFObject() */
-    public PDFMetadata(Document xmp, boolean readOnly) {
+    public PDFMetadata(Metadata xmp, boolean readOnly) {
         super();
         if (xmp == null) {
             throw new NullPointerException(
-                    "DOM Document representing the metadata must no be null");
+                    "The parameter for the XMP Document must not be null");
         }
         this.xmpMetadata = xmp;
         this.readOnly = readOnly;
@@ -80,6 +73,11 @@
         return false; //XMP metadata packet must be scannable by non PDF-compatible readers
     }
 
+    /** @return the XMP metadata */
+    public Metadata getMetadata() {
+        return this.xmpMetadata;
+    }
+    
     /**
      * overload the base object method so we don't have to copy
      * byte arrays around so much
@@ -94,39 +92,14 @@
     
     /** @see org.apache.fop.pdf.AbstractPDFStream#outputRawStreamData(java.io.OutputStream) */
     protected void outputRawStreamData(OutputStream out) throws IOException {
-        final String encoding = "UTF-8";
-        out.write("<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"
-                .getBytes(encoding));
         try {
-            TransformerFactory tFactory = TransformerFactory.newInstance();
-            Transformer transformer = tFactory.newTransformer();
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
-            transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
-            transformer.setOutputProperty(OutputKeys.INDENT, "no");
-            DOMSource src = new DOMSource(this.xmpMetadata);
-            StreamResult res = new StreamResult(out);
-            transformer.transform(src, res);
-        } catch (TransformerConfigurationException e) {
+            XMPSerializer.writeXMPPacket(xmpMetadata, out, this.readOnly);
+        } catch (TransformerConfigurationException tce) {
             throw new IOException("Error setting up Transformer for XMP stream serialization: " 
-                    + e.getMessage());
-        } catch (TransformerException e) {
+                    + tce.getMessage());
+        } catch (SAXException saxe) {
             throw new IOException("Error while serializing XMP stream: " 
-                    + e.getMessage());
-        }
-        if (readOnly) {
-            out.write("\n<?xpacket end=\"r\"?>".getBytes(encoding));
-        } else {
-            //Create padding string (40 * 101 characters is more or less the recommended 4KB)
-            StringBuffer sb = new StringBuffer(101);
-            sb.append('\n');
-            for (int i = 0; i < 100; i++) {
-                sb.append(" ");
-            }
-            byte[] padding = sb.toString().getBytes(encoding);
-            for (int i = 0; i < 40; i++) {
-                out.write(padding);
-            }
-            out.write("\n<?xpacket end=\"w\"?>".getBytes(encoding));
+                    + saxe.getMessage());
         }
     }
     
@@ -150,58 +123,15 @@
     }
 
     /**
-     * Formats a Date using ISO 8601 format in the default time zone.
-     * @param dt the date
-     * @return the formatted date
-     */
-    public static String formatISO8601Date(Date dt) {
-        //ISO 8601 cannot be expressed directly using SimpleDateFormat
-        StringBuffer sb = new StringBuffer(pseudoISO8601DateFormat.format(dt));
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(dt);
-        int offset = cal.get(Calendar.ZONE_OFFSET);
-        offset += cal.get(Calendar.DST_OFFSET);
-        offset /= (1000 * 60); //Convert to minutes
-        
-        if (offset == 0) {
-            sb.append('Z');
-        } else {
-            int zoh = offset / 60;
-            int zom = Math.abs(offset % 60);
-            if (zoh > 0) {
-                sb.append('+');
-            } else {
-                sb.append('-');
-            }
-            if (zoh < 10) {
-                sb.append('0');
-            }
-            sb.append(zoh);
-            sb.append(':');
-            if (zom < 10) {
-                sb.append('0');
-            }
-            sb.append(zom);
-        }
-        
-        return sb.toString();
-    }
-    
-    /**
      * Creates an XMP document based on the settings on the PDF Document.
      * @param pdfDoc the PDF Document
-     * @return a DOM document representing the requested XMP metadata
+     * @return the requested XMP metadata
      */
-    public static Document createXMPFromUserAgent(PDFDocument pdfDoc) {
-        DOMImplementation domImplementation = ElementMapping.getDefaultDOMImplementation();
-        Document doc = domImplementation.createDocument(
-                XMPConstants.XMP_NAMESPACE, "x:xmpmeta", null);
-        Element rdf = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:RDF");
-        doc.getDocumentElement().appendChild(rdf);
+    public static Metadata createXMPFromUserAgent(PDFDocument pdfDoc) {
+        Metadata meta = new Metadata();
         
-        Element desc, el;
         PDFInfo info = pdfDoc.getInfo();
-        
+
         //Set creation date if not available, yet
         if (info.getCreationDate() == null) {
             Date d = new Date();
@@ -213,105 +143,98 @@
         //error even if the times are essentially equal.
 
         //Dublin Core
-        desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description");
-        desc.setAttributeNS(XMPConstants.RDF_NAMESPACE, "rdf:about", "");
-        desc.setAttributeNS(XMLNS, "xmlns:dc", XMPConstants.DUBLIN_CORE_NAMESPACE);
-        rdf.appendChild(desc);
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta);
         if (info.getAuthor() != null) {
-            el = doc.createElementNS(XMPConstants.DUBLIN_CORE_NAMESPACE, "dc:creator");
-            desc.appendChild(el);
-            Element seq = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Seq");
-            el.appendChild(seq);
-            Element li = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:li");
-            seq.appendChild(li);
-            li.appendChild(doc.createTextNode(info.getAuthor()));
+            dc.addCreator(info.getAuthor());
         }
         if (info.getTitle() != null) {
-            el = doc.createElementNS(XMPConstants.DUBLIN_CORE_NAMESPACE, "dc:title");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(info.getTitle()));
+            dc.setTitle(info.getTitle());
         }
         if (info.getSubject() != null) {
-            el = doc.createElementNS(XMPConstants.DUBLIN_CORE_NAMESPACE, "dc:subject");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(info.getSubject()));
-        }
-        el = doc.createElementNS(XMPConstants.DUBLIN_CORE_NAMESPACE, "dc:date");
-        desc.appendChild(el);
-        el.appendChild(doc.createTextNode(formatISO8601Date(info.getCreationDate())));
+            dc.addSubject(info.getSubject());
+        }
+        dc.addDate(info.getCreationDate());
+
+        //PDF/A identification
+        PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode(); 
+        if (pdfaMode.isPDFA1LevelB()) {
+            PDFAAdapter pdfa = PDFAXMPSchema.getAdapter(meta);
+            //Create the identification a second time with the old namespace to keep 
+            //Adobe Acrobat happy
+            PDFAAdapter pdfaOld = PDFAOldXMPSchema.getAdapter(meta);
+            pdfa.setPart(1);
+            pdfaOld.setPart(1);
+            if (pdfaMode == PDFAMode.PDFA_1A) {
+                pdfa.setConformance("A"); //PDF/A-1a
+                pdfaOld.setConformance("A"); //PDF/A-1a
+            } else {
+                pdfa.setConformance("B"); //PDF/A-1b
+                pdfaOld.setConformance("B"); //PDF/A-1b
+            }
+        }
         
         //XMP Basic Schema
-        desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description");
-        desc.setAttributeNS(XMPConstants.RDF_NAMESPACE, "rdf:about", "");
-        desc.setAttributeNS(XMLNS, "xmlns:xmp", XMPConstants.XMP_BASIC_NAMESPACE);
-        rdf.appendChild(desc);
-        el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreateDate");
-        desc.appendChild(el);
-        el.appendChild(doc.createTextNode(formatISO8601Date(info.getCreationDate())));
+        XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(meta);
+        xmpBasic.setCreateDate(info.getCreationDate());
         PDFProfile profile = pdfDoc.getProfile(); 
         if (profile.isModDateRequired()) {
-            el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:ModifyDate");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(formatISO8601Date(info.getCreationDate())));
+            xmpBasic.setModifyDate(info.getCreationDate());
         }
         if (info.getCreator() != null) {
-            el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreatorTool");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(info.getCreator()));
+            xmpBasic.setCreatorTool(info.getCreator());
         }
-        
-        //Adobe PDF Schema
-        desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description");
-        desc.setAttributeNS(XMPConstants.RDF_NAMESPACE, "rdf:about", "");
-        desc.setAttributeNS(XMLNS, "xmlns:pdf", XMPConstants.ADOBE_PDF_NAMESPACE);
-        rdf.appendChild(desc);
+
+        AdobePDFAdapter adobePDF = AdobePDFSchema.getAdapter(meta);
         if (info.getKeywords() != null) {
-            el = doc.createElementNS(XMPConstants.ADOBE_PDF_NAMESPACE, "pdf:Keywords");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(info.getKeywords()));
+            adobePDF.setKeywords(info.getKeywords());
         }
         if (info.getProducer() != null) {
-            el = doc.createElementNS(XMPConstants.ADOBE_PDF_NAMESPACE, "pdf:Producer");
-            desc.appendChild(el);
-            el.appendChild(doc.createTextNode(info.getProducer()));
-        }
-        el = doc.createElementNS(XMPConstants.ADOBE_PDF_NAMESPACE, "pdf:PDFVersion");
-        desc.appendChild(el);
-        el.appendChild(doc.createTextNode(pdfDoc.getPDFVersionString()));
-        
-        //PDF/A identification
-        PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode(); 
-        if (pdfaMode.isPDFA1LevelB()) {
-            createPDFAIndentification(doc, rdf, 
-                    XMPConstants.PDF_A_IDENTIFICATION, "pdfaid", pdfaMode);
-            //Create the identification a second time with the old namespace to keep 
-            //Adobe Acrobat happy
-            createPDFAIndentification(doc, rdf, 
-                    XMPConstants.PDF_A_IDENTIFICATION_OLD, "pdfaid_1", pdfaMode);
+            adobePDF.setProducer(info.getProducer());
         }
+        adobePDF.setPDFVersion(pdfDoc.getPDFVersionString());
+        
         
-        return doc;
+        return meta;
     }
 
-    private static void createPDFAIndentification(Document doc, Element rdf, 
-            String pdfaNamespace, String prefix, PDFAMode pdfaMode) {
-        Element desc;
-        Element el;
-        desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description");
-        desc.setAttributeNS(XMPConstants.RDF_NAMESPACE, "rdf:about", "");
-        desc.setAttributeNS(XMLNS, "xmlns:" + prefix, pdfaNamespace);
-        rdf.appendChild(desc);
-        el = doc.createElementNS(pdfaNamespace, prefix + ":part");
-        desc.appendChild(el);
-        el.appendChild(doc.createTextNode("1")); //PDF/A-1
-        el = doc.createElementNS(pdfaNamespace, prefix + ":conformance");
-        desc.appendChild(el);
-        if (pdfaMode == PDFAMode.PDFA_1A) {
-            el.appendChild(doc.createTextNode("A")); //PDF/A-1a
+    /**
+     * Updates the values in the Info object from the XMP metadata according to the rules defined
+     * in PDF/A-1 (ISO 19005-1:2005)
+     * @param meta the metadata
+     * @param info the Info object
+     */
+    public static void updateInfoFromMetadata(Metadata meta, PDFInfo info) {
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta);
+        info.setTitle(dc.getTitle());
+        String[] creators = dc.getCreators();
+        if (creators != null && creators.length > 0) {
+            info.setAuthor(creators[0]);
+        } else {
+            info.setAuthor(null);
+        }
+        String[] subjects = dc.getSubjects();
+        //PDF/A-1 defines dc:subject as "Text" but XMP defines it as "bag Text".
+        //We're simply doing the inverse from createXMPFromUserAgent() above.
+        if (subjects != null && subjects.length > 0) {
+            info.setSubject(subjects[0]);
         } else {
-            el.appendChild(doc.createTextNode("B")); //PDF/A-1b
+            info.setSubject(null);
         }
+        
+        AdobePDFAdapter pdf = AdobePDFSchema.getAdapter(meta);
+        info.setKeywords(pdf.getKeywords());
+        info.setProducer(pdf.getProducer());
+        
+        XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(meta);
+        info.setCreator(xmpBasic.getCreatorTool());
+        Date d;
+        d = xmpBasic.getCreateDate();
+        xmpBasic.setCreateDate(d); //To make Adobe Acrobat happy (bug filed with Adobe)
+        //Adobe Acrobat doesn't like it when the xmp:CreateDate has a different timezone
+        //than Info/CreationDate
+        info.setCreationDate(d);
+        d = xmpBasic.getModifyDate();
+        xmpBasic.setModifyDate(d);
+        info.setModDate(d);
     }
-    
-    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=415688&r1=415687&r2=415688&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java Tue Jun 20 07:57:44 2006
@@ -100,22 +100,12 @@
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
-
-/*
-todo:
-
-word rendering and optimistion
-pdf state optimisation
-line and border
-background pattern
-writing mode
-text decoration
-
-*/
+import org.apache.xmlgraphics.xmp.Metadata;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
 
 /**
- * Renderer that renders areas to PDF
- *
+ * Renderer that renders areas to PDF.
  */
 public class PDFRenderer extends AbstractPathOrientedRenderer {
     
@@ -234,38 +224,11 @@
     protected Map filterMap;
 
     /**
-     * true if a TJ command is left to be written
-     */
-    //protected boolean textOpen = false;
-
-    /**
      * true if a BT command has been written. 
      */
     protected boolean inTextMode = false;
 
     /**
-     * the previous Y coordinate of the last word written.
-     * Used to decide if we can draw the next word on the same line.
-     */
-    //protected int prevWordY = 0;
-
-    /**
-     * the previous X coordinate of the last word written.
-     * used to calculate how much space between two words
-     */
-    //protected int prevWordX = 0;
-
-    /**
-     * The width of the previous word. Used to calculate space between
-     */
-    //protected int prevWordWidth = 0;
-
-    /**
-     * reusable word area string buffer to reduce memory usage
-     */
-    //private StringBuffer wordAreaPDF = new StringBuffer();
-
-    /**
      * create the PDF renderer
      */
     public PDFRenderer() {
@@ -393,8 +356,8 @@
                 userAgent.getProducer() != null ? userAgent.getProducer() : "");
         this.pdfDoc.getProfile().setPDFAMode(this.pdfAMode);
         this.pdfDoc.getProfile().setPDFXMode(this.pdfXMode);
-        this.pdfDoc.setCreator(userAgent.getCreator());
-        this.pdfDoc.setCreationDate(userAgent.getCreationDate());
+        this.pdfDoc.getInfo().setCreator(userAgent.getCreator());
+        this.pdfDoc.getInfo().setCreationDate(userAgent.getCreationDate());
         this.pdfDoc.getInfo().setAuthor(userAgent.getAuthor());
         this.pdfDoc.getInfo().setTitle(userAgent.getTitle());
         this.pdfDoc.getInfo().setKeywords(userAgent.getKeywords());
@@ -601,8 +564,17 @@
     }
     
     private void renderXMPMetadata(XMPMetadata metadata) {
+        Metadata docXMP = metadata.getMetadata();
+        Metadata fopXMP = PDFMetadata.createXMPFromUserAgent(pdfDoc);
+        //Merge FOP's own metadata into the one from the XSL-FO document
+        fopXMP.mergeInto(docXMP);
+        XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(docXMP);
+        //Metadata was changed so update metadata date
+        xmpBasic.setMetadataDate(new java.util.Date());
+        PDFMetadata.updateInfoFromMetadata(docXMP, pdfDoc.getInfo());
+
         PDFMetadata pdfMetadata = pdfDoc.getFactory().makeMetadata(
-                metadata.getDocument(), metadata.isReadOnly());
+                docXMP, metadata.isReadOnly());
         pdfDoc.getRoot().setMetadata(pdfMetadata);
     }
 
@@ -670,7 +642,7 @@
         if (pdfDoc.getRoot().getMetadata() == null) {
             //If at this time no XMP metadata for the overall document has been set, create it
             //from the PDFInfo object.
-            Document xmp = PDFMetadata.createXMPFromUserAgent(pdfDoc);
+            Metadata xmp = PDFMetadata.createXMPFromUserAgent(pdfDoc);
             PDFMetadata pdfMetadata = pdfDoc.getFactory().makeMetadata(
                     xmp, true);
             pdfDoc.getRoot().setMetadata(pdfMetadata);



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