]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
* Fixed bug in cache where object is not able to use IOB mechanism.
authorAdrian Cumiskey <acumiskey@apache.org>
Mon, 21 Jul 2008 11:36:49 +0000 (11:36 +0000)
committerAdrian Cumiskey <acumiskey@apache.org>
Mon, 21 Jul 2008 11:36:49 +0000 (11:36 +0000)
* Added PNG unsupported (but now recognised) mimetype to MO:DCA Registry.
* Added useful toString() to AbstractNamedDataObject.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@678394 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/render/afp/DataObjectCache.java
src/java/org/apache/fop/render/afp/modca/AFPDataStream.java
src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java
src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java
src/java/org/apache/fop/render/afp/modca/AbstractPreparedObjectContainer.java
src/java/org/apache/fop/render/afp/modca/Registry.java
src/java/org/apache/fop/render/afp/modca/ResourceGroup.java

index a247f33836bd17aee9882b52433e51999fd95b30..1c917a75b85c76d582e00bc4ba56d4d48688d2f7 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
 import org.apache.fop.render.afp.modca.DataObjectFactory;
+import org.apache.fop.render.afp.modca.Registry;
 
 /**
  * Caches and creates (as necessary using an instance of DataObjectFactory)
@@ -47,10 +48,9 @@ public final class DataObjectCache {
     private static Map/*<Integer,DataObjectCache>*/ cacheMap
         = new java.util.HashMap/*<Integer,DataObjectCache>*/();    
     
-    
     /** Mapping of data object uri --> cache record */
-    private Map/*<ResourceInfo,DataObjectCache.Record>*/ recordMap
-        = new java.util.HashMap/*<ResourceInfo,DataObjectCache.Record>*/();
+    private Map/*<ResourceInfo,Record>*/ includableMap
+        = new java.util.HashMap/*<ResourceInfo,Record>*/();
     
     /** Used for create data objects */
     private DataObjectFactory factory = new DataObjectFactory();
@@ -111,59 +111,75 @@ public final class DataObjectCache {
             log.error("Failed to close temporary file");
         }
     }
+
+    /**
+     * Stores a named data object in the cache
+     * 
+     * @param dataObj a named data object
+     * @return a new cache record
+     */
+    public Record store(AbstractNamedAFPObject dataObj) {
+        Record record = new Record();
+        record.objectName = dataObj.getName();
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        try {
+            channel.position(nextPos);
+            record.position = channel.position();
+            dataObj.write(os);
+            record.size = os.size();
+            MappedByteBuffer byteBuffer
+                = channel.map(FileChannel.MapMode.READ_WRITE, record.position, record.size);
+            byte[] data = os.toByteArray();
+            byteBuffer.put(data);
+            channel.write(byteBuffer);
+            nextPos += record.size + 1;
+        } catch (IOException e) {
+            log.error("Failed to write cache record for '"
+                    + dataObj + "', " + e.getMessage());
+        }
+        return record;
+    }
     
     /**
      * Creates and adds a new data object and record to the cache as necessary.  
      * 
      * @param dataObjectInfo a data object info
      * 
-     * @return the name of the related data object
+     * @return a cache record
      */
-    public String put(DataObjectInfo dataObjectInfo) {
-        ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
-        Record record = (Record)recordMap.get(resourceInfo);
-        if (record == null) {
-            record = new Record();
+    public Record store(DataObjectInfo dataObjectInfo) {
+        Registry.ObjectType objectType = dataObjectInfo.getObjectType();
+        Record record = null;
+        if (!objectType.canBeIncluded()) {
             AbstractNamedAFPObject dataObj = factory.createObject(dataObjectInfo);
-            record.objectName = dataObj.getName();
-
-            ByteArrayOutputStream os = new ByteArrayOutputStream();
-            try {
-                channel.position(nextPos);
-                record.position = channel.position();
-                dataObj.write(os);
-                record.size = os.size();
-                MappedByteBuffer byteBuffer
-                    = channel.map(FileChannel.MapMode.READ_WRITE, record.position, record.size);
-                byte[] data = os.toByteArray();
-                byteBuffer.put(data);
-                channel.write(byteBuffer);
-                nextPos += record.size + 1;
-            } catch (IOException e) {
-                log.error("Failed to write cache record for '"
-                        + resourceInfo + "', " + e.getMessage());
+            record = store(dataObj);
+        } else {
+            ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
+            record = (Record)includableMap.get(resourceInfo);
+            if (record == null) {
+                AbstractNamedAFPObject dataObj = factory.createObject(dataObjectInfo);
+                record = store(dataObj);
+                includableMap.put(resourceInfo, record);
             }
-            recordMap.put(resourceInfo, record);
         }
-        return record.objectName;
+        return record;
     }
-    
+
     /**
      * Returns the written binary data of the AbstractDataObject from the cache file
      * 
-     * @param resourceInfo the data resource info
+     * @param record the cache record
      * @return the binary data of the AbstractDataObject or null if failed.
      */
-    public byte[] get(ResourceInfo resourceInfo) {
-        Record record = (Record)recordMap.get(resourceInfo);
+    public byte[] retrieve(Record record) {
         if (record == null) {
-            throw new IllegalArgumentException("Unknown data object " + resourceInfo);
+            throw new IllegalArgumentException("Cache record is null");
         }
         MappedByteBuffer byteBuffer = null;
         try {
             byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, record.position, record.size);
         } catch (IOException e) {
-            log.error("Failed to read cache record for '" + resourceInfo + "', " + e.getMessage());
+            log.error("Failed to read cache record for '" + record + "', " + e.getMessage());
             return null;
         }
         if (byteBuffer.hasArray()) {
@@ -174,7 +190,7 @@ public final class DataObjectCache {
             return data;
         }
     }
-    
+        
     /**
      * Returns the data object factory
      * 
@@ -184,19 +200,30 @@ public final class DataObjectCache {
         return this.factory;
     }
 
+    
     /**
      * A cache record
      */
-    private class Record {
-        protected long position; 
-        protected int size;
-        protected String objectName;
+    public class Record {
+        private long position; 
+        private int size;
+        private String objectName;
         
+        /** {@inheritDoc} */
         public String toString() {
             return "Record{name=" + objectName
                 + ", pos=" + position
                 + ", size=" + size
                 + "}";
         }
+        
+        /**
+         * Returns the object name
+         * 
+         * @return the object name
+         */
+        public String getObjectName() {
+            return this.objectName;
+        }
     }
 }
index 8d640b998fc0eccbc3c9106152deb6d73e25c753..1d85f60be36168c05e9e6c0c73485b573ace0c6c 100644 (file)
@@ -60,85 +60,58 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     /** Static logging instance */
     protected static Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
 
-    /**
-     * Boolean completion indicator
-     */
+    /** Boolean completion indicator */
     private boolean complete = false;
 
-    /**
-     * The application producing the AFP document
-     */
+    /** The application producing the AFP document */
     // not used
     // private String producer = null;
-    /**
-     * The AFP document object
-     */
+    
+    /** The AFP document object */
     private Document document = null;
 
-    /**
-     * The current page group object
-     */
+    /** The current page group object */
     private PageGroup currentPageGroup = null;
 
-    /**
-     * The current page object
-     */
+    /** The current page object */
     private PageObject currentPageObject = null;
 
-    /**
-     * The current overlay object
-     */
+    /** The current overlay object */
     private Overlay currentOverlay = null;
 
-    /**
-     * The current page
-     */
+    /** The current page */
     private AbstractPageObject currentPage = null;
 
-    /**
-     * The page count
-     */
+    /** The page count */
     private int pageCount = 0;
 
-    /**
-     * The page group count
-     */
+    /** The page group count */
     private int pageGroupCount = 0;
 
-    /**
-     * The overlay count
-     */
+    /** The overlay count */
     private int overlayCount = 0;
 
-    /**
-     * The portrait rotation
-     */
+    /** The portrait rotation */
     private int portraitRotation = 0;
 
-    /**
-     * The landscape rotation
-     */
+    /** The landscape rotation */
     private int landscapeRotation = 270;
 
-    /**
-     * The rotation
-     */
+    /** The rotation */
     private int orientation;
 
-    /**
-     * The outputstream for the data stream
-     */
+    /** The outputstream for the data stream */
     private OutputStream outputStream = null;
 
     /** Maintain a reference count of instream objects for referencing purposes */
     private int instreamObjectCount = 0;
 
-    /**
-     * The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set)
-     */
+    /** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */
     private InterchangeSet interchangeSet
         = InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);
 
+    private DataObjectCache cache = DataObjectCache.getInstance();
+
     /**
      * The external resource group manager
      */
@@ -152,6 +125,8 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     }
 
     /**
+     * Returns the document object
+     * 
      * @return the document object
      */
     private Document getDocument() {
@@ -159,6 +134,8 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     }
 
     /**
+     * Returns the current page
+     * 
      * @return the current page
      */
     protected AbstractPageObject getCurrentPage() {
@@ -259,7 +236,6 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
                 pageRotation, pageWidthRes, pageHeightRes);
         currentPage = currentPageObject;
         currentOverlay = null;
-//        setOffsets(0, 0, 0);
     }
 
     /**
@@ -454,8 +430,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
             dataObjectInfo.setObjectType(objectType);
         }
         
-        DataObjectCache cache = DataObjectCache.getInstance();
-        String includeName = cache.put(dataObjectInfo);
+        DataObjectCache.Record record = cache.store(dataObjectInfo);
 
         if (objectType != null) {
             
@@ -470,17 +445,19 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
                     
                     // Create and return include
                     DataObjectFactory factory = cache.getFactory();                         
-                    IncludeObject includeObj = factory.createInclude(includeName, dataObjectInfo);
+                    IncludeObject includeObj = factory.createInclude(
+                            record.getObjectName(), dataObjectInfo);
                     getCurrentPage().addObject(includeObj);
                     
                     // Record the resource cache key (uri) in the ResourceGroup
                     ResourceGroup resourceGroup = getResourceGroup(resourceLevel);
-                    resourceGroup.addObject(resourceInfo);
+                    resourceGroup.addObject(record);
                     return;   
                 } else {
                     log.warn("Data object located at '" + uri + "'"
                             + " of type '" + objectType.getMimeType() + "'"
-                            + " cannot be included with an IOB so it will be embedded directly");
+                            + " cannot be referenced with an include"
+                            + " so it will be embedded directly");
                 }                
             } else {
                 if (resourceLevel.isExternal()) {
@@ -490,7 +467,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
             }
         }
         // Unrecognised/unsupported object type so add object reference directly in current page
-        currentPageObject.addObject(resourceInfo);
+        currentPageObject.addObject(record);
     }
 
 //    /**
index 6ed3411bc4c7736e6175d5a3dac779675911d28e..4b2d371b7908f483586b8ba62c8a5bf50b23b240 100644 (file)
@@ -89,4 +89,9 @@ public abstract class AbstractNamedAFPObject extends AbstractStructuredAFPObject
     public String getName() {
         return name;
     }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        return getName();
+    }
 }
index d3b4d10a99086977590331507b63cc9e97b02cef..8e6314adb70b7685a0cfa064177df98203bc6457 100644 (file)
@@ -362,9 +362,9 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
             if (obj instanceof Writable) {
                 Writable writableObject = (Writable)obj;
                 writableObject.write(os);
-            } else if (obj instanceof ResourceInfo) {
-                ResourceInfo resourceInfo = (ResourceInfo)obj;
-                byte[] data = cache.get(resourceInfo);
+            } else if (obj instanceof DataObjectCache.Record) {
+                DataObjectCache.Record record = (DataObjectCache.Record)obj;
+                byte[] data = cache.retrieve(record);
                 os.write(data);
             }
         }
index 03e64691399383530955367d127f41586a0c1fcb..7fcd0095d0fc8656a4b308bf359d7a423f7a04f7 100644 (file)
@@ -69,7 +69,6 @@ implements PreparedAFPObject {
      * @return the drawingOrder if it was added, null otherwise
      */
     public PreparedAFPObject addObject(PreparedAFPObject preparedObject) {
-//        log.debug(this + " adding " + preparedObject);
         getObjects().add(preparedObject);
         return preparedObject;
     }
index dc2941ca81bdf14570e29270e4833a204562f503..201696bd09acfc708657aafceecab6e7d49d9e4a 100644 (file)
@@ -128,16 +128,22 @@ public final class Registry {
                         MimeConstants.MIME_PCL
                 )
         );
+        
+        // Entries without component and object ids
         mimeEntryMap.put(
                 MimeConstants.MIME_SVG,
                 new ObjectType(
-                        COMPID_EPS,
-                        null, // no component id
                         "Scaleable Vector Graphics",
-                        false,
                         MimeConstants.MIME_SVG
                 )
         );
+        mimeEntryMap.put(
+                MimeConstants.MIME_PNG,
+                new ObjectType(
+                        "Portable Network Graphics",
+                        MimeConstants.MIME_PNG
+                )
+        );
     }
 
     /**
@@ -181,9 +187,33 @@ public final class Registry {
         private String name;
         private boolean canBeIncluded;
         private String mimeType;
-        
+
+        /**
+         * Constructor
+         * 
+         * @param name the object type name
+         * @param canBeIncluded true if this object can be included with an IOB structured field
+         * @param mimeType the mime type associated with this object type
+         */
+        private ObjectType(String name, boolean canBeIncluded, String mimeType) {
+            this.name = name;
+            this.canBeIncluded = canBeIncluded;
+            this.mimeType = mimeType;
+        }
+
+        /**
+         * Constructor
+         * 
+         * @param name the object type name
+         * @param mimeType the mime type associated with this object type
+         */
+        private ObjectType(String name, String mimeType) {
+            this(name, false, mimeType);
+        }
+
         /**
          * Main constructor
+         * 
          * @param componentId the component id of this object type
          * @param oid the object id of this object type
          * @param name the object type name
@@ -192,15 +222,14 @@ public final class Registry {
          */
         public ObjectType(byte componentId, byte[] oid, String name,
                 boolean canBeIncluded, String mimeType) {
+            this(name, canBeIncluded, mimeType);
             this.componentId = componentId;
             this.oid = oid;
-            this.name = name;
-            this.canBeIncluded = canBeIncluded;
-            this.mimeType = mimeType;
         }
-                
+     
         /**
          * Returns a MOD:CA object type OID from a given a componentId
+         * 
          * @return the corresponding object type id for a given component id
          * or null if the component id is unknown and the object type OID was not found.
          */
@@ -209,6 +238,8 @@ public final class Registry {
         }
 
         /**
+         * Returns the object type name for the given componentId
+         * 
          * @return the object type name for the given componentId 
          */
         public String getName() {
@@ -216,6 +247,8 @@ public final class Registry {
         }
 
         /**
+         * Returns the compontentId for this entry
+         * 
          * @return the compontentId for this entry
          */
         public byte getComponentId() {
@@ -223,6 +256,8 @@ public final class Registry {
         }
 
         /**
+         * Returns true if this component can be included with an IOB structured field
+         * 
          * @return true if this component can be included with an IOB structured field
          */
         public boolean canBeIncluded() {
@@ -230,6 +265,8 @@ public final class Registry {
         }
 
         /**
+         * Returns the mime type associated with this object type
+         * 
          * @return the mime type associated with this object type
          */
         public String getMimeType() {
@@ -237,24 +274,27 @@ public final class Registry {
         }
 
         /**
+         * Returns true if this is an image type
+         * 
          * @return true if this is an image type
          */
         public boolean isImage() {
             return mimeType == MimeConstants.MIME_TIFF
             || mimeType == MimeConstants.MIME_GIF
+            || mimeType == MimeConstants.MIME_PNG
             || mimeType == MimeConstants.MIME_JPEG;
         }
 
         /**
+         * Returns true if this is a graphic type
+         * 
          * @return true if this is a graphic type
          */
         public boolean isGraphic() {
             return mimeType == MimeConstants.MIME_SVG;
         }
 
-        /**
-         * {@inheritDoc}
-         */
+        /** {@inheritDoc} */
         public String toString() {
             return this.getName();
         }
index 8b7648ad7e9f0d434a0c201ef873e1e27e8ab8fa..a0e1169ef306a8704a52471b0e2e8aeab5eba2f7 100644 (file)
@@ -25,7 +25,7 @@ import java.util.Iterator;
 import java.util.Set;
 
 import org.apache.fop.render.afp.DataObjectCache;
-import org.apache.fop.render.afp.ResourceInfo;
+import org.apache.fop.render.afp.DataObjectCache.Record;
 
 /**
  * A Resource Group contains a set of overlays.
@@ -38,6 +38,8 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
     /** Set of resource uri */
     private Set/*<String>*/ resourceSet = new java.util.HashSet/*<String>*/();
 
+    private DataObjectCache cache = DataObjectCache.getInstance();
+
     /**
      * Default constructor
      */
@@ -121,12 +123,12 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
 //    }
 
     /**
-     * Add this object cache resource info to this resource group
+     * Add this object cache record to this resource group
      * 
-     * @param resourceInfo the resource info
+     * @param record the cache record
      */
-    public void addObject(ResourceInfo resourceInfo) {
-        resourceSet.add(resourceInfo);
+    public void addObject(Record record) {
+        resourceSet.add(record);
     }
     
     /**
@@ -152,16 +154,13 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
     /** {@inheritDoc} */
     public void writeContent(OutputStream os) throws IOException {
         Iterator it = resourceSet.iterator();
-        if (it.hasNext()) {
-            DataObjectCache cache = DataObjectCache.getInstance();
-            while (it.hasNext()) {
-                ResourceInfo resourceInfo = (ResourceInfo)it.next();
-                byte[] data = cache.get(resourceInfo);
-                if (data != null) {
-                    os.write(data);
-                } else {
-                    log.error("data was null");
-                }
+        while (it.hasNext()) {
+            Record record = (Record)it.next();
+            byte[] data = cache.retrieve(record);
+            if (data != null) {
+                os.write(data);
+            } else {
+                log.error("data was null");
             }
         }
     }