]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
* Moved AFPConstants from org.apache.fop.render.afp.modca into org.apache.fop.render...
authorAdrian Cumiskey <acumiskey@apache.org>
Thu, 24 Jul 2008 18:26:43 +0000 (18:26 +0000)
committerAdrian Cumiskey <acumiskey@apache.org>
Thu, 24 Jul 2008 18:26:43 +0000 (18:26 +0000)
* Fixed sequential storage and memory hungry buffering shortcomings in DataObjectCache and also the messy getInstance().
* Renamed DataObjectCache and DataObjectFactory as ResourceStore and ResourceFactory and moved to org.apache.fop.render.afp.modca.resource package.
* Created ResourceManager to oversee and delegate to ResourceStore and ResourceFactory.
* Made data members in LineDataInfo package private.

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

35 files changed:
src/java/org/apache/fop/render/afp/AFPConstants.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/AFPRenderer.java
src/java/org/apache/fop/render/afp/AFPSVGHandler.java
src/java/org/apache/fop/render/afp/AFPState.java
src/java/org/apache/fop/render/afp/DataObjectCache.java [deleted file]
src/java/org/apache/fop/render/afp/ExternalResourceGroupManager.java [deleted file]
src/java/org/apache/fop/render/afp/LineDataInfo.java
src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java
src/java/org/apache/fop/render/afp/fonts/CharacterSet.java
src/java/org/apache/fop/render/afp/goca/GraphicsString.java
src/java/org/apache/fop/render/afp/modca/AFPConstants.java [deleted file]
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/AbstractResourceEnvironmentGroupContainer.java
src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java
src/java/org/apache/fop/render/afp/modca/DataObjectFactory.java [deleted file]
src/java/org/apache/fop/render/afp/modca/Document.java
src/java/org/apache/fop/render/afp/modca/MapCodedFont.java
src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java
src/java/org/apache/fop/render/afp/modca/NoOperation.java
src/java/org/apache/fop/render/afp/modca/Overlay.java
src/java/org/apache/fop/render/afp/modca/PageGroup.java
src/java/org/apache/fop/render/afp/modca/PageObject.java
src/java/org/apache/fop/render/afp/modca/ResourceGroup.java
src/java/org/apache/fop/render/afp/modca/ResourceObject.java
src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java
src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java
src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java
src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java

diff --git a/src/java/org/apache/fop/render/afp/AFPConstants.java b/src/java/org/apache/fop/render/afp/AFPConstants.java
new file mode 100644 (file)
index 0000000..b9ab2de
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp;
+
+/**
+ * Constants used by the AFP renderer.
+ *
+ */
+public interface AFPConstants {
+
+    /**
+     * The encoding to use to convert to EBCIDIC
+     */
+    String EBCIDIC_ENCODING = "Cp1146";
+
+    /**
+     * The encoding to use to convert to ASCII
+     */
+    String ASCII_ENCODING = "Cp1252";
+
+    /**
+     * The encoding to use to convert to US ASCII (7 bit)
+     */
+    String US_ASCII_ENCODING = "US-ASCII";
+    
+    /**
+     * The scaling of the default transform is set to
+     * approximately 72 user space coordinates per square inch
+     */
+    int DPI_72 = 72;
+    
+    /**
+     * 72dpi in millipoints
+     */
+    int DPI_72_MPTS = DPI_72 * 1000;
+}
index d61b62968c2bc5cb58f4233d62c140cc407e0f81..94918f7ec7725bcbe6dd3381a76e41c14f8a8ffb 100644 (file)
@@ -76,7 +76,6 @@ import org.apache.fop.render.afp.extensions.AFPElementMapping;
 import org.apache.fop.render.afp.extensions.AFPPageSetup;
 import org.apache.fop.render.afp.fonts.AFPFont;
 import org.apache.fop.render.afp.fonts.AFPFontCollection;
-import org.apache.fop.render.afp.modca.AFPConstants;
 import org.apache.fop.render.afp.modca.AFPDataStream;
 import org.apache.fop.render.afp.modca.PageObject;
 
@@ -213,7 +212,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
 
     /** {@inheritDoc} */
     public boolean supportsOutOfOrder() {
-        // return false;
         return true;
     }
 
@@ -326,7 +324,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
     /** {@inheritDoc} */
     public void clipRect(float x, float y, float width, float height) {
         // TODO
-        log.debug("NYI clipRect(x=" + x + ",y=" + y + ",width=" + width + ", height=" + height + ")");
+        log.debug("NYI clipRect(x=" + x + ",y=" + y
+                    + ",width=" + width + ", height=" + height + ")");
     }
 
     /** {@inheritDoc} */
@@ -372,7 +371,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
         float[] srcPts = new float[] {x * 1000, y * 1000};
         float[] dstPts = new float[srcPts.length];
         int[] coords = mpts2units(srcPts, dstPts);
-        int x2 = coords[X] + Math.round(mpt2units(width * 1000));
+        int x2 = Math.round(mpt2units(dstPts[X] + width * 1000));
         LineDataInfo lineDataInfo = new LineDataInfo();
         lineDataInfo.x1 = coords[X];
         lineDataInfo.y1 = coords[Y];
@@ -668,6 +667,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
                     imageObjectInfo.setBitsPerPixel(currentState.getBitsPerPixel());
                     imageObjectInfo.setCompression(ccitt.getCompression());
                     imageObjectInfo.setResourceInfoFromForeignAttributes(foreignAttributes);
+                    
                     getAFPDataStream().createObject(imageObjectInfo);
                 } else if (img instanceof ImageXMLDOM) {
                     ImageXMLDOM imgXML = (ImageXMLDOM) img;
@@ -737,9 +737,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
      *            the height of the viewport (in mpt)
      * @param foreignAttributes
      *            a mapping of foreign attributes
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
      */
     public void drawBufferedImage(ImageInfo imageInfo, RenderedImage image,
-            int imageRes, int x, int y, int width, int height, Map foreignAttributes) {
+            int imageRes, int x, int y, int width, int height, Map foreignAttributes) throws IOException {
         ByteArrayOutputStream baout = new ByteArrayOutputStream();
         try {
             // Serialize image
@@ -783,6 +784,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
         imageObjectInfo.setColor(currentState.isColorImages());
         imageObjectInfo.setBitsPerPixel(currentState.getBitsPerPixel());
         imageObjectInfo.setResourceInfoFromForeignAttributes(foreignAttributes);
+
         getAFPDataStream().createObject(imageObjectInfo);
     }
 
index dc61fdccb4bb886d312b145fca5e2caddbfb5c4f..5142c17d3dea10184fc98c0ba928370431506875 100644 (file)
@@ -37,7 +37,6 @@ import org.apache.fop.render.AbstractGenericSVGHandler;
 import org.apache.fop.render.Renderer;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.RendererContextConstants;
-import org.apache.fop.render.afp.modca.AFPConstants;
 import org.apache.fop.render.afp.modca.AFPDataStream;
 import org.apache.fop.svg.SVGEventProducer;
 import org.apache.fop.svg.SVGUserAgent;
index 5cf396362bd8d6c9cfe592d1ae10fae4cf6b6da6..8c8aaba1417ebbfb4520ce93b488610784131f3f 100644 (file)
@@ -19,6 +19,8 @@
 
 package org.apache.fop.render.afp;
 
+import java.awt.geom.AffineTransform;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -272,6 +274,27 @@ public class AFPState extends org.apache.fop.render.AbstractState {
         return ((AFPData)getData()).imageUri;
     }
 
+    /**
+     * Returns the current orientation
+     * 
+     * @return the current orientation
+     */
+    public int getOrientation() {
+        AffineTransform at = getData().getTransform();
+        int orientation = 0;
+        if (at.getScaleX() == 0 && at.getScaleY() == 0
+                && at.getShearX() == 1 && at.getShearY() == -1) {
+            orientation = 90;
+        } else if (at.getScaleX() == -1 && at.getScaleY() == -1
+                && at.getShearX() == 0 && at.getShearY() == 0) {
+            orientation = 180;
+        } else if (at.getScaleX() == 0 && at.getScaleY() == 0
+                && at.getShearX() == -1 && at.getShearY() == 1) {
+            orientation = 270;
+        }
+        return orientation;
+    }
+
     /** {@inheritDoc} */
     public String toString() {
         return "AFPState{portraitRotation=" + portraitRotation
@@ -399,14 +422,4 @@ public class AFPState extends org.apache.fop.render.AbstractState {
             + "}";
         }
     }
-
-    /**
-     * Returns the current text orientation
-     * TODO the current text orientation
-     * @return the current text orientation
-     */
-    public int getOrientation() {
-        return 0;
-    }
-
 }
\ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/DataObjectCache.java b/src/java/org/apache/fop/render/afp/DataObjectCache.java
deleted file mode 100644 (file)
index 85b96ef..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.afp;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.Map;
-
-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)
- * descendants of AbstractDataObject
- */
-public final class DataObjectCache {
-
-    /** Static logging instance */
-    private static final Log log = LogFactory.getLog(DataObjectCache.class);
-
-    private static final String CACHE_FILENAME_PREFIX = "AFP_";
-
-    /** Static mapping of data object caches id --> cache */
-    private static Map/*<Integer,DataObjectCache>*/ cacheMap
-        = new java.util.HashMap/*<Integer,DataObjectCache>*/();    
-    
-    
-    /** Mapping of data object uri --> cache record */
-    private Map/*<ResourceInfo,Record>*/ includableMap
-        = new java.util.HashMap/*<ResourceInfo,Record>*/();
-    
-    /** Used for create data objects */
-    private DataObjectFactory factory = new DataObjectFactory();
-
-    /** Used for storage of data objects */
-    private RandomAccessFile raFile;
-    
-    /** File channel used for manipulating the temporary file */
-    private FileChannel channel;
-    
-    /** The temporary cache file */
-    private File tempFile;
-    
-    /** The next file pointer position in the cache file */
-    private long nextPos;
-
-    /** Our assigned cache id */
-    private Integer id;
-    
-    /**
-     * Returns an instance of the cache
-     * 
-     * @return an instance of the cache or null if failed
-     */
-    public static DataObjectCache getInstance() {
-        synchronized (cacheMap) {
-            Integer cacheId = new Integer(System.identityHashCode(Thread.currentThread()));
-            DataObjectCache cache = (DataObjectCache)cacheMap.get(cacheId);
-            if (cache == null) {
-                try {
-                    cache = new DataObjectCache(cacheId);
-                    cacheMap.put(cacheId, cache);
-                } catch (IOException e) {
-                    log.error("Failed to create cache");
-                }
-            }
-            return cache;
-        }
-    }
-
-    /**
-     * Default constructor
-     * 
-     * @param cacheId the cache id
-     */
-    private DataObjectCache(Integer cacheId) throws IOException {
-        this.id = cacheId;
-        this.tempFile = File.createTempFile(CACHE_FILENAME_PREFIX + cacheId, null);
-        this.raFile = new RandomAccessFile(tempFile, "rw");
-        this.channel = raFile.getChannel();
-    }
-
-    /**
-     * Clears the data object cache
-     */
-    public void clear() {
-        try {
-            if (raFile != null) {
-                raFile.close();
-                raFile = null;
-            }
-            if (tempFile != null) {
-                tempFile.delete();
-                tempFile = null;
-            }
-        } catch (IOException e) {
-            log.error("Failed to close/delete temporary file: " + e.getMessage());
-        } finally {
-            synchronized (cacheMap) {
-                // remove ourselves from the cache map
-                cacheMap.remove(id); 
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void finalize() throws Throwable {
-        try {
-            clear();
-        } finally {
-            super.finalize();
-        }
-    }
-    
-    /**
-     * 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);
-            byteBuffer.put(os.toByteArray());
-            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 a cache record
-     */
-    public Record store(DataObjectInfo dataObjectInfo) {
-        Record record = null;
-        Registry.ObjectType objectType = dataObjectInfo.getObjectType();
-        if (objectType == null || !objectType.isIncludable()) {
-            AbstractNamedAFPObject dataObj = factory.createObject(dataObjectInfo);
-            if (dataObj == null) {
-                log.error("Failed to create object: " + dataObjectInfo);
-                return null;
-            }
-            record = store(dataObj);
-        } else {
-            ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
-            record = (Record)includableMap.get(resourceInfo);
-            if (record == null) {
-                AbstractNamedAFPObject dataObj = factory.createObject(dataObjectInfo);
-                if (dataObj == null) {
-                    log.error("Failed to create object: " + dataObjectInfo);
-                    return null;
-                }
-                record = store(dataObj);
-                includableMap.put(resourceInfo, record);
-            }
-        }
-        return record;
-    }
-
-    /**
-     * Returns the written binary data of the AbstractNamedDataObject from the cache file
-     * 
-     * @param record the cache record
-     * @return the binary data of the AbstractNamedDataObject or null if failed.
-     */
-    public byte[] retrieve(Record record) {
-        if (record == null) {
-            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 '" + record + "', " + e.getMessage());
-            return null;
-        }
-        if (byteBuffer.hasArray()) {
-            return byteBuffer.array();
-        } else {
-            byte[] data = new byte[record.size];
-            byteBuffer.get(data);
-            return data;
-        }
-    }
-        
-    /**
-     * Returns the data object factory
-     * 
-     * @return the data object factory
-     */
-    public DataObjectFactory getFactory() {
-        return this.factory;
-    }
-
-    
-    /**
-     * A cache record
-     */
-    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;
-        }
-    }
-}
diff --git a/src/java/org/apache/fop/render/afp/ExternalResourceGroupManager.java b/src/java/org/apache/fop/render/afp/ExternalResourceGroupManager.java
deleted file mode 100644 (file)
index 205eb62..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.apache.fop.render.afp;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.modca.ResourceGroup;
-
-/**
- * Manages the use of resource groups (external and internal)
- */
-public class ExternalResourceGroupManager {
-    
-    /** Static logging instance */
-    protected static Log log = LogFactory.getLog(ExternalResourceGroupManager.class);
-
-    /** A mapping of external resource destinations to resource groups */
-    private Map/*<String,ResourceGroup>*/externalResourceGroups
-        = new java.util.HashMap/*<String,ResourceGroup>*/();
-
-    /** Sets the default resource group file */
-    private String defaultResourceGroupFilePath;
-
-    /**
-     * Default constructor
-     */
-    public ExternalResourceGroupManager() {
-    }
-
-    /**
-     * Sets the default resource group file
-     *
-     * @param resourceGroupFilePath the default resource group file path
-     */
-    public void setDefaultResourceGroupFilePath(String resourceGroupFilePath) {
-        this.defaultResourceGroupFilePath = resourceGroupFilePath;
-    }
-
-    /**
-     * Returns the corresponding resource group for the given resource level
-     *
-     * @param level the resource level
-     * @return the corresponding resource group for the given resource level
-     * or null if not found.
-     */
-    public ResourceGroup getResourceGroup(ResourceLevel level) {
-        ResourceGroup resourceGroup = null;
-        // this resource info does not have an external resource group
-        // file definition
-        String filePath = level.getExternalFilePath();
-        if (filePath != null) {
-            filePath = level.getExternalFilePath();
-            resourceGroup = (ResourceGroup)externalResourceGroups.get(filePath);
-            if (resourceGroup == null) {
-                resourceGroup = new ResourceGroup();
-                externalResourceGroups.put(filePath, resourceGroup);
-            }
-        } else if (defaultResourceGroupFilePath != null) {
-            // fallback to default resource group file
-            level.setExternalFilePath(defaultResourceGroupFilePath);
-            resourceGroup = getResourceGroup(level);
-        }
-        return resourceGroup;
-    }
-    /**
-     * Writes out all external resource groups
-     */
-    public void write() {
-        // write any external resources
-        Iterator it = externalResourceGroups.keySet().iterator();
-        while (it.hasNext()) {
-            String filePath = (String)it.next();
-            ResourceGroup resourceGroup
-                = (ResourceGroup)externalResourceGroups.get(filePath);
-            OutputStream os = null;
-            try {
-                log.debug("Writing external AFP resource file " + filePath);
-                os = new java.io.FileOutputStream(filePath);
-                resourceGroup.write(os);
-            } catch (IOException e) {
-                log.error(
-                        "An error occurred when attempting to write external AFP resource file "
-                                + filePath);
-            } finally {
-                if (os != null) {
-                    try {
-                        os.close();
-                    } catch (IOException e) {
-                        log.error("Failed to close outputstream for external AFP resource file "
-                                        + filePath);
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
index b7a6afc908de99d01ef07d83be59cd25f18f1be7..1fd7f56267f49cad3b01c4b3df31c187865b3294 100644 (file)
@@ -25,25 +25,25 @@ import java.awt.Color;
 public class LineDataInfo {
     
     /** the x1 coordinate */
-    protected int x1;
+    int x1;
     
     /** the y1 coordinate */
-    protected int y1;
+    int y1;
     
     /** the x2 coordinate */
-    protected int x2;
+    int x2;
     
     /** the y2 coordinate */
-    protected int y2;
+    int y2;
     
     /** the thickness */
-    protected int thickness;
+    int thickness;
     
     /** the painting color */
-    protected Color color;
+    Color color;
     
     /** the orientation */
-    protected int orientation;
+    int orientation;
     
     /**
      * Default constructor
index 7951be26cbb953201927c5937588f3ee0d6e2321..731acdaeecd61bbe8c60e8f6fe3a8be49a0eb3d5 100644 (file)
@@ -31,8 +31,8 @@ import java.util.HashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.exceptions.FontRuntimeException;
-import org.apache.fop.render.afp.modca.AFPConstants;
 import org.apache.fop.render.afp.tools.StructuredFieldReader;
 
 /**
index 82300197bf4f2b2a3db7dfa5abb2a3bd854374dd..56e6f62dfe1c808de38012193cd7e6f86fb5baa7 100644 (file)
@@ -24,7 +24,7 @@ import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.tools.StringUtils;
 
 /**
index fdeeea5bb747fc899c3bfc316552085f6879fef4..1fb842ae40aea085aa827956b4af4a407e014cc7 100644 (file)
@@ -21,7 +21,7 @@ package org.apache.fop.render.afp.goca;
 
 import java.io.UnsupportedEncodingException;
 
-import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject;
 import org.apache.fop.render.afp.modca.GraphicsObject;
 import org.apache.fop.render.afp.tools.BinaryUtils;
diff --git a/src/java/org/apache/fop/render/afp/modca/AFPConstants.java b/src/java/org/apache/fop/render/afp/modca/AFPConstants.java
deleted file mode 100644 (file)
index a55f6a0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.afp.modca;
-
-/**
- * Constants used by the AFP renderer.
- *
- */
-public interface AFPConstants {
-
-    /**
-     * The encoding to use to convert to EBCIDIC
-     */
-    String EBCIDIC_ENCODING = "Cp1146";
-
-    /**
-     * The encoding to use to convert to ASCII
-     */
-    String ASCII_ENCODING = "Cp1252";
-
-    /**
-     * The encoding to use to convert to US ASCII (7 bit)
-     */
-    String US_ASCII_ENCODING = "US-ASCII";
-    
-    /**
-     * The scaling of the default transform is set to
-     * approximately 72 user space coordinates per square inch
-     */
-    int DPI_72 = 72;
-    
-    /**
-     * 72dpi in millipoints
-     */
-    int DPI_72_MPTS = DPI_72 * 1000;
-}
index 3105f88b1fe4b0ea75eebb7bdf2e0bf5523c616a..041768cd4f0f1c584791a387eeb80437d49a4a6a 100644 (file)
@@ -32,14 +32,14 @@ import org.apache.fop.render.afp.AFPFontAttributes;
 import org.apache.fop.render.afp.LineDataInfo;
 import org.apache.fop.render.afp.TextDataInfo;
 import org.apache.fop.render.afp.DataObjectInfo;
-import org.apache.fop.render.afp.ExternalResourceGroupManager;
 import org.apache.fop.render.afp.ObjectAreaInfo;
 import org.apache.fop.render.afp.ResourceInfo;
 import org.apache.fop.render.afp.ResourceLevel;
-import org.apache.fop.render.afp.DataObjectCache;
 import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.modca.resource.ResourceFactory;
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+import org.apache.fop.render.afp.modca.resource.StoreInfo;
 import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
-import org.apache.fop.render.afp.tools.StringUtils;
 
 /**
  * A data stream is a continuous ordered stream of data elements and objects
@@ -83,15 +83,6 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     /** The current page */
     private AbstractPageObject currentPage = null;
 
-    /** The page count */
-    private int pageCount = 0;
-
-    /** The page group count */
-    private int pageGroupCount = 0;
-
-    /** The overlay count */
-    private int overlayCount = 0;
-
     /** The portrait rotation */
     private int portraitRotation = 0;
 
@@ -111,18 +102,15 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     private InterchangeSet interchangeSet
         = InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);
 
-    private DataObjectCache cache = DataObjectCache.getInstance();
-
-    /**
-     * The external resource group manager
-     */
-    private ExternalResourceGroupManager externalResourceGroupManager = null;
+    private ResourceFactory factory;
 
     /**
      * Default constructor for the AFPDataStream.
      */
     public AFPDataStream() {
-        this.document = new Document();
+        this.resourceManager = new ResourceManager();
+        this.factory = resourceManager.getFactory();
+        this.document = factory.createDocument();
     }
 
     /**
@@ -188,7 +176,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
 
         if (interchangeSet.supportsLevel2()) {
             // Write out any external resource groups
-            getExternalResourceGroupManager().write();
+            resourceManager.writeExternal();
 
             // Write out any print-file level resources
             if (hasResources()) {
@@ -210,7 +198,9 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
 
         this.outputStream = null;
 
-        cache.clear();
+        this.resourceManager.clearStore();
+        
+        this.resourceManager = null;
     }
 
     /**
@@ -230,11 +220,8 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
      */
     public void startPage(int pageWidth, int pageHeight, int pageRotation,
             int pageWidthRes, int pageHeightRes) {
-        String pageName = "PGN"
-                + StringUtils.lpad(String.valueOf(++pageCount), '0', 5);
-
-        currentPageObject = new PageObject(pageName, pageWidth, pageHeight,
-                pageRotation, pageWidthRes, pageHeightRes);
+        currentPageObject = factory.createPage(pageWidth, pageHeight,
+                pageRotation, pageWidthRes, pageHeightRes);        
         currentPage = currentPageObject;
         currentOverlay = null;
     }
@@ -261,13 +248,10 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
      */
     public void startOverlay(int x, int y, int width, int height, int widthRes,
             int heightRes, int overlayRotation) {
-        String overlayName = "OVL"
-                + StringUtils.lpad(String.valueOf(++overlayCount), '0', 5);
-
-        DataObjectFactory factory = cache.getFactory();
         this.currentOverlay = factory.createOverlay(
-                overlayName, width, height, widthRes, heightRes, overlayRotation);
+                width, height, widthRes, heightRes, overlayRotation);
 
+        String overlayName = currentOverlay.getName();
         currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
         currentPage = currentOverlay;
     }
@@ -400,10 +384,11 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
      * Creates a data object in the datastream. The data object resides
      * according to its type, info and MO:DCA-L (resource) support.
      *
-     * @param dataObjectInfo
-     *            the data object info
+     * @param dataObjectInfo the data object info
+     *            
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
      */
-    public void createObject(DataObjectInfo dataObjectInfo) {
+    public void createObject(DataObjectInfo dataObjectInfo) throws IOException {
         ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
         String uri = resourceInfo.getUri();
 
@@ -432,7 +417,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
             log.info("Unknown object type for '" + dataObjectInfo + "'");
         }
         
-        DataObjectCache.Record record = cache.store(dataObjectInfo);
+        StoreInfo storeInfo = resourceManager.create(dataObjectInfo);
 
         if (objectType != null) {
             
@@ -446,14 +431,13 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
                 if (objectType.isIncludable()) {
                     
                     // Create and return include
-                    DataObjectFactory factory = cache.getFactory();
-                    String objectName = record.getObjectName();
+                    String objectName = storeInfo.getObjectName();
                     IncludeObject includeObj = factory.createInclude(objectName, dataObjectInfo);
                     getCurrentPage().addObject(includeObj);
                     
                     // Record the resource cache key (uri) in the ResourceGroup
                     ResourceGroup resourceGroup = getResourceGroup(resourceLevel);
-                    resourceGroup.addObject(record);
+                    resourceGroup.addObject(storeInfo);
                     return;   
                 } else {
                     log.warn("Data object located at '" + uri + "'"
@@ -469,7 +453,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
             }
         }
         // Unrecognised/unsupported object type so add object reference directly in current page
-        currentPageObject.addObject(record);
+        currentPageObject.addObject(storeInfo);
     }
 
 //    /**
@@ -682,10 +666,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
      */
     private PageGroup getCurrentPageGroup() {
         if (currentPageGroup == null) {
-            String pageGroupName = "PGP"
-                    + StringUtils
-                            .lpad(String.valueOf(++pageGroupCount), '0', 5);
-            this.currentPageGroup = new PageGroup(pageGroupName);
+            this.currentPageGroup = factory.createPageGroup();
         }
         return currentPageGroup;
     }
@@ -748,20 +729,20 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
      * @param filePath the default resource group file path
      */
     public void setDefaultResourceGroupFilePath(String filePath) {
-        getExternalResourceGroupManager().setDefaultResourceGroupFilePath(filePath);
+        resourceManager.getExternalManager().setDefaultFilePath(filePath);
     }
 
-    /**
-     * Returns the external resource group manager
-     * 
-     * @return the resource group manager
-     */
-    protected ExternalResourceGroupManager getExternalResourceGroupManager() {
-        if (externalResourceGroupManager == null) {
-            this.externalResourceGroupManager = new ExternalResourceGroupManager();
-        }
-        return this.externalResourceGroupManager;
-    }
+//    /**
+//     * Returns the external resource group manager
+//     * 
+//     * @return the resource group manager
+//     */
+//    protected ExternalResourceGroupManager getExternalResourceGroupManager() {
+//        if (externalResourceGroupManager == null) {
+//            this.externalResourceGroupManager = new ExternalResourceGroupManager();
+//        }
+//        return this.externalResourceGroupManager;
+//    }
 
     /**
      * Returns the resource group for a given resource info
@@ -772,7 +753,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer {
     private ResourceGroup getResourceGroup(ResourceLevel level) {
         ResourceGroup resourceGroup = null;
         if (level.isExternal()) {
-            resourceGroup = getExternalResourceGroupManager().getResourceGroup(level);
+            resourceGroup = resourceManager.getExternalManager().getResourceGroup(level);
             // use print-file level resource group in the absence
             // of an external resource group file definition
             if (resourceGroup == null) {
index 4b2d371b7908f483586b8ba62c8a5bf50b23b240..c3cd6ed43352114694cbafad3da52b24fdc1f8b5 100644 (file)
@@ -21,6 +21,8 @@ package org.apache.fop.render.afp.modca;
 
 import java.io.UnsupportedEncodingException;
 
+import org.apache.fop.render.afp.AFPConstants;
+
 /**
  * This is the base class for all named data stream objects.
  * A named data stream object has an 8 byte EBCIDIC name.
index 540e74c330f0f95c6c47f859e8d3d5695c135235..8f4742950a4619c4fe7ba045049a6813e789b847 100644 (file)
@@ -19,7 +19,6 @@
 
 package org.apache.fop.render.afp.modca;
 
-import java.awt.Color;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Iterator;
@@ -27,9 +26,10 @@ import java.util.List;
 
 import org.apache.fop.render.afp.LineDataInfo;
 import org.apache.fop.render.afp.TextDataInfo;
-import org.apache.fop.render.afp.DataObjectCache;
-import org.apache.fop.render.afp.ResourceInfo;
 import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+import org.apache.fop.render.afp.modca.resource.ResourceStore;
+import org.apache.fop.render.afp.modca.resource.StoreInfo;
 
 /**
  * Pages contain the data objects that comprise a presentation document. Each
@@ -53,79 +53,62 @@ import org.apache.fop.render.afp.fonts.AFPFont;
  */
 public abstract class AbstractPageObject extends AbstractNamedAFPObject {
 
-    /**
-     * The active environment group for the page
-     */
+    /** The resource manager */
+    protected ResourceManager resourceManager;
+
+    /** The active environment group for the page */
     protected ActiveEnvironmentGroup activeEnvironmentGroup = null;
 
-    /**
-     * The current presentation text object
-     */
+    /** The current presentation text object */
     private PresentationTextObject currentPresentationTextObject = null;
 
-    /**
-     * The list of tag logical elements
-     */
+    /** The list of tag logical elements */
     protected List/*<TagLogicalElement>*/ tagLogicalElements = null;
 
-    /**
-     * The list of the include page segments
-     */
+    /** The list of the include page segments */
     protected List/*<IncludePageSegment>*/ includePageSegments = null;
 
-    /**
-     * The list of objects within this resource container
-     */
+    /** The list of objects within this resource container */
     protected List/*<AbstractStructuredAFPObject>*/ objects = null;
 
-    /**
-     * The page width
-     */
+    /** The page width */
     private int width;
 
-    /**
-     * The page height
-     */
+    /** The page height */
     private int height;
 
-    /**
-     * The page rotation
-     */
+    /** The page rotation */
     protected int rotation = 0;
 
-    /**
-     * The page state
-     */
+    /** The page state */
     private boolean complete = false;
 
-    /**
-     * The width resolution
-     */
+    /** The width resolution */
     private int widthRes;
 
-    /**
-     * The height resolution
-     */
+    /** The height resolution */
     private int heightRes;
 
-    /**
-     * Default constructor
-     */
+    /** Default constructor */
     public AbstractPageObject() {
     }
 
     /**
-     * Named constructor
+     * Main constructor
      * 
+     * @param resourceManager the resource manager 
      * @param name the name of this page object
      */
-    public AbstractPageObject(String name) {
+    public AbstractPageObject(ResourceManager resourceManager, String name) {
         super(name);
+        this.resourceManager = resourceManager;
     }
 
     /**
      * Construct a new page object for the specified name argument, the page
      * name should be an 8 character identifier.
+     * 
+     * @param resourceManager the resource manager
      *
      * @param name
      *            the name of the page.
@@ -140,10 +123,10 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
      * @param heightRes
      *            the height resolution of the page.
      */
-    public AbstractPageObject(String name, int width, int height, int rotation,
+    public AbstractPageObject(ResourceManager resourceManager,
+            String name, int width, int height, int rotation,
             int widthRes, int heightRes) {
-        super(name);
-        
+        this(resourceManager, name);
         this.width = width;
         this.height = height;
         this.rotation = rotation;
@@ -340,20 +323,20 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
         writeObjects(this.includePageSegments, os);
         writeObjects(this.tagLogicalElements, os);
         
-        DataObjectCache cache = DataObjectCache.getInstance();
-        
         // Write objects from cache
         Iterator it = objects.iterator();
-        while (it.hasNext()) {
-            Object obj = it.next();
-            if (obj instanceof Writable) {
-                Writable writableObject = (Writable)obj;
-                writableObject.write(os);
-            } else if (obj instanceof DataObjectCache.Record) {
-                DataObjectCache.Record record = (DataObjectCache.Record)obj;
-                byte[] data = cache.retrieve(record);
-                os.write(data);
-            }
+        if (it.hasNext()) {
+            ResourceStore store = resourceManager.getStore();
+            do {
+                Object obj = it.next();
+                if (obj instanceof Writable) {
+                    Writable writableObject = (Writable)obj;
+                    writableObject.write(os);
+                } else if (obj instanceof StoreInfo) {
+                    StoreInfo storeInfo = (StoreInfo)obj;
+                    store.writeToStream(storeInfo, os);
+                }
+            } while (it.hasNext());
         }
     }
     
index d56ebef9b32f90d4569765750e1dc9543d3e0c33..6eb8268e508f45e41422b79928b9d6bbb0c7c916 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+
 /**
  * An abstract class which encapsulates the common features of 
  * Document and PageGroup resource containers 
@@ -37,10 +39,11 @@ public abstract class AbstractResourceEnvironmentGroupContainer
     /**
      * Main constructor
      * 
+     * @param resourceManager the resource manager 
      * @param name the name of this resource container
      */
-    public AbstractResourceEnvironmentGroupContainer(String name) {
-        super(name);
+    public AbstractResourceEnvironmentGroupContainer(ResourceManager resourceManager, String name) {
+        super(resourceManager, name);
     }
 
     /**
index b1d4980a8b38fd0344f52df51a5ad63b73551621..b3739c71738894fe514cf287fac2c0c5532c666f 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+
 /**
  * An abstract container of resource objects
  */
@@ -42,16 +44,19 @@ public abstract class AbstractResourceGroupContainer extends AbstractPageObject
     /**
      * Named constructor
      * 
+     * @param resourceManager the resource manager
      * @param name the name of this resource container
      */
-    public AbstractResourceGroupContainer(String name) {
-        super(name);
+    public AbstractResourceGroupContainer(ResourceManager resourceManager, String name) {
+        super(resourceManager, name);
     }
 
     /**
      * Construct a new page object for the specified name argument, the page
      * name should be an 8 character identifier.
-     *
+     * 
+     * @param resourceManager
+     *            the resource manager
      * @param name
      *            the name of the page.
      * @param width
@@ -65,9 +70,9 @@ public abstract class AbstractResourceGroupContainer extends AbstractPageObject
      * @param heightRes
      *            the height resolution of the page.
      */
-    public AbstractResourceGroupContainer(String name, int width, int height,
+    public AbstractResourceGroupContainer(ResourceManager resourceManager, String name, int width, int height,
             int rotation, int widthRes, int heightRes) {
-        super(name, width, height, rotation, widthRes, heightRes);
+        super(resourceManager, name, width, height, rotation, widthRes, heightRes);
     }
 
     /**
@@ -96,7 +101,7 @@ public abstract class AbstractResourceGroupContainer extends AbstractPageObject
      */
     protected ResourceGroup getResourceGroup() {
         if (resourceGroup == null) {
-            resourceGroup = new ResourceGroup();
+            resourceGroup = resourceManager.getFactory().createResourceGroup();
         }
         return resourceGroup;
     }
diff --git a/src/java/org/apache/fop/render/afp/modca/DataObjectFactory.java b/src/java/org/apache/fop/render/afp/modca/DataObjectFactory.java
deleted file mode 100644 (file)
index 7915dbe..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.afp.modca;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.DataObjectInfo;
-import org.apache.fop.render.afp.GraphicsObjectInfo;
-import org.apache.fop.render.afp.GraphicsObjectPainter;
-import org.apache.fop.render.afp.ImageObjectInfo;
-import org.apache.fop.render.afp.ObjectAreaInfo;
-import org.apache.fop.render.afp.ResourceInfo;
-import org.apache.fop.render.afp.ResourceLevel;
-import org.apache.fop.render.afp.modca.Registry.ObjectType;
-import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
-import org.apache.fop.render.afp.modca.triplets.MappingOptionTriplet;
-import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet;
-import org.apache.fop.render.afp.tools.StringUtils;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
-
-/**
- * Creator of MO:DCA data objects
- */
-public class DataObjectFactory {
-    private static final String IMAGE_NAME_PREFIX = "IMG";
-    private static final String GRAPHIC_NAME_PREFIX = "GRA";
-//    private static final String BARCODE_NAME_PREFIX = "BAR";
-//    private static final String OTHER_NAME_PREFIX = "OTH";
-    private static final String OBJECT_CONTAINER_NAME_PREFIX = "OC";
-    private static final String RESOURCE_NAME_PREFIX = "RES";
-
-    private int imageCount = 0;
-    private int graphicCount = 0;
-    private int objectContainerCount = 0;
-    private int resourceCount = 0;
-    
-    private Map/*<ResourceInfo,IncludeObject>*/ includeMap
-        = new java.util.HashMap/*<ResourceInfo,IncludeObject>*/();
-    
-    /** Static logging instance */
-    private static final Log log = LogFactory.getLog(DataObjectFactory.class);
-    
-    /**
-     * Converts a byte array containing 24 bit RGB image data to a grayscale
-     * image.
-     * 
-     * @param io
-     *            the target image object
-     * @param info
-     *            the image object info
-     *
-     * @return the converted image data
-     */
-    private static byte[] convertToGrayScaleImage(ImageObject io, ImageObjectInfo info) {
-        byte[] raw = info.getData();
-        int width = info.getDataWidth();
-        int height = info.getDataHeight();
-        int bitsPerPixel = info.getBitsPerPixel();
-        
-        int pixelsPerByte = 8 / bitsPerPixel;
-        int bytewidth = (width / pixelsPerByte);
-        if ((width % pixelsPerByte) != 0) {
-            bytewidth++;
-        }
-        byte[] data = new byte[height * bytewidth];
-        byte ib;
-        for (int y = 0; y < height; y++) {
-            ib = 0;
-            int i = 3 * y * width;
-            for (int x = 0; x < width; x++, i += 3) {
-
-                // see http://www.jguru.com/faq/view.jsp?EID=221919
-                double greyVal = 0.212671d * ((int) raw[i] & 0xff) + 0.715160d
-                        * ((int) raw[i + 1] & 0xff) + 0.072169d
-                        * ((int) raw[i + 2] & 0xff);
-                switch (bitsPerPixel) {
-                case 1:
-                    if (greyVal < 128) {
-                        ib |= (byte) (1 << (7 - (x % 8)));
-                    }
-                    break;
-                case 4:
-                    greyVal /= 16;
-                    ib |= (byte) ((byte) greyVal << ((1 - (x % 2)) * 4));
-                    break;
-                case 8:
-                    ib = (byte) greyVal;
-                    break;
-                default:
-                    throw new UnsupportedOperationException(
-                            "Unsupported bits per pixel: " + bitsPerPixel);
-                }
-
-                if ((x % pixelsPerByte) == (pixelsPerByte - 1)
-                        || ((x + 1) == width)) {
-                    data[(y * bytewidth) + (x / pixelsPerByte)] = ib;
-                    ib = 0;
-                }
-            }
-        }
-        return data;
-    }
-
-    /**
-     * Helper method to create an image on the current container and to return
-     * the object.
-     * 
-     * @param imageObjectInfo the image object info
-     * @return a newly created image object
-     */
-    private ImageObject createImage(ImageObjectInfo imageObjectInfo) {
-        String name = IMAGE_NAME_PREFIX
-                + StringUtils.lpad(String.valueOf(++imageCount), '0', 5);
-        ImageObject imageObj = new ImageObject(name);
-        if (imageObjectInfo.hasCompression()) {
-            int compression = imageObjectInfo.getCompression();
-            switch (compression) {
-            case TIFFImage.COMP_FAX_G3_1D:
-                imageObj.setImageEncoding(ImageContent.COMPID_G3_MH);
-                    break;
-                case TIFFImage.COMP_FAX_G3_2D:
-                    imageObj.setImageEncoding(ImageContent.COMPID_G3_MR);
-                    break;
-                case TIFFImage.COMP_FAX_G4_2D:
-                    imageObj.setImageEncoding(ImageContent.COMPID_G3_MMR);
-                    break;
-                default:
-                    throw new IllegalStateException(
-                            "Invalid compression scheme: " + compression);
-            }
-        }
-        ObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo();
-        imageObj.setImageParameters(objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes(), 
-                imageObjectInfo.getDataWidth(), imageObjectInfo.getDataHeight());
-        if (imageObjectInfo.isBuffered()) {
-            if (imageObjectInfo.isColor()) {
-                imageObj.setImageIDESize((byte)24);
-                imageObj.setImageData(imageObjectInfo.getData());
-            } else {
-                int bitsPerPixel = imageObjectInfo.getBitsPerPixel();
-                imageObj.setImageIDESize((byte)bitsPerPixel);
-                byte[] data = convertToGrayScaleImage(imageObj, imageObjectInfo);
-                imageObj.setImageData(data);
-            }    
-        }
-        return imageObj;
-    }
-    
-    /**
-     * Creates and returns a new graphics object.
-     * 
-     * @param graphicsObjectInfo the graphics object info
-     * @return a new graphics object
-     */
-    private GraphicsObject createGraphic(GraphicsObjectInfo graphicsObjectInfo) {
-        String name = GRAPHIC_NAME_PREFIX
-            + StringUtils.lpad(String.valueOf(++graphicCount), '0', 5);
-        GraphicsObject graphicsObj = new GraphicsObject(name);
-        
-        // paint the graphic using batik
-        GraphicsObjectPainter painter = graphicsObjectInfo.getPainter();
-        painter.paint(graphicsObj);
-        
-        return graphicsObj;
-    }
-
-    /**
-     * Creates and returns a new include object.
-     * 
-     * @param name the name of this include object
-     * @param dataObjectInfo a data object info
-     * 
-     * @return a new include object
-     */
-    public IncludeObject createInclude(String name, DataObjectInfo dataObjectInfo) {
-        ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
-        IncludeObject includeObj = (IncludeObject)includeMap.get(resourceInfo);
-        if (includeObj == null) {
-            includeObj = new IncludeObject(name);
-        
-            if (dataObjectInfo instanceof ImageObjectInfo) {
-                includeObj.setDataObjectType(IncludeObject.TYPE_IMAGE);
-            } else if (dataObjectInfo instanceof GraphicsObjectInfo) {
-                includeObj.setDataObjectType(IncludeObject.TYPE_GRAPHIC);
-            } else {
-                includeObj.setDataObjectType(IncludeObject.TYPE_OTHER);
-            }
-            
-            Registry.ObjectType objectType = dataObjectInfo.getObjectType();
-            if (objectType != null) {
-                includeObj.setObjectClassification(
-                   ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
-                   objectType);
-            }
-            
-            ObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
-            
-            includeObj.setObjectArea(objectAreaInfo.getX(), objectAreaInfo.getY());
-    
-            includeObj.setObjectAreaSize(
-                    objectAreaInfo.getWidth(), objectAreaInfo.getHeight());        
-    
-            includeObj.setMeasurementUnits(
-                    objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes());
-            
-            includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT);
-            
-            includeMap.put(resourceInfo, includeObj);
-        }
-        
-        return includeObj;
-    }
-
-    /**
-     * Creates and returns a new object container
-     * 
-     * @return a new object container
-     */
-    private ObjectContainer createObjectContainer() {
-        String name = OBJECT_CONTAINER_NAME_PREFIX
-        + StringUtils.lpad(String.valueOf(++objectContainerCount), '0', 6);
-        return new ObjectContainer(name);
-    }
-
-    /**
-     * Creates and returns a new resource object
-     * 
-     * @param resourceName the resource name
-     * @return a new resource object
-     */
-    private ResourceObject createResource(String resourceName) {
-        return new ResourceObject(resourceName);
-    }
-
-    /**
-     * Creates and returns a new resource object
-     * 
-     * @return a new resource object
-     */
-    private ResourceObject createResource() {
-        String name = RESOURCE_NAME_PREFIX
-        + StringUtils.lpad(String.valueOf(++resourceCount ), '0', 5);
-        return createResource(name);
-    }
-
-    /**
-     * Creates and returns a new Overlay.
-     *
-     * @param overlayName
-     *            the name of the overlay
-     * @param width
-     *            the width of the overlay
-     * @param height
-     *            the height of the overlay
-     * @param widthRes
-     *            the width resolution of the overlay
-     * @param heightRes
-     *            the height resolution of the overlay
-     * @param overlayRotation
-     *            the rotation of the overlay
-     * 
-     * @return a new overlay object
-     */
-    public Overlay createOverlay(String overlayName, int width, int height,
-            int widthRes, int heightRes, int overlayRotation) {
-        Overlay overlay = new Overlay(overlayName, width, height,
-                overlayRotation, widthRes, heightRes);
-        return overlay;        
-    }
-    
-    /**
-     * Creates and returns a new data object
-     * 
-     * @param dataObjectInfo the data object info
-     * 
-     * @return a newly created data object
-     */
-    public AbstractNamedAFPObject createObject(DataObjectInfo dataObjectInfo) {
-        AbstractNamedAFPObject dataObj;
-        
-        if (dataObjectInfo instanceof ImageObjectInfo) {
-            dataObj = createImage((ImageObjectInfo)dataObjectInfo);
-        } else if (dataObjectInfo instanceof GraphicsObjectInfo) {
-            dataObj = createGraphic((GraphicsObjectInfo)dataObjectInfo);
-        } else {
-            throw new IllegalArgumentException("Unknown data object type: " + dataObjectInfo);
-        }
-        
-        if (dataObj instanceof AbstractDataObject) {
-            ((AbstractDataObject)dataObj).setViewport(dataObjectInfo.getObjectAreaInfo());
-        }
-        
-        dataObj.setFullyQualifiedName(
-                FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_INTERNAL_RESOURCE_REF,
-                FullyQualifiedNameTriplet.FORMAT_CHARSTR, dataObj.getName());
-
-        ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
-        ResourceLevel resourceLevel = resourceInfo.getLevel();
-
-        if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
-            
-            ObjectType objectType = dataObjectInfo.getObjectType();
-            
-            if (objectType != null && objectType.isIncludable()) {
-                
-                // Wrap newly created data object in a resource object
-                // if it is to reside within a resource group at print-file or external level
-                if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
-                    ResourceObject resourceObj = null;
-                    String resourceName = resourceInfo.getName();
-                    if (resourceName != null) {
-                        resourceObj = createResource(resourceName);
-                    } else {
-                        resourceObj = createResource();
-                    }
-                    
-                    if (dataObj instanceof ObjectContainer) {
-                        resourceObj.setType(ResourceObject.OBJECT_CONTAINER);
-                    } else if (dataObj instanceof ImageObject) {
-                        resourceObj.setType(ResourceObject.IMAGE_OBJECT);
-                    } else if (dataObj instanceof GraphicsObject) {
-                        resourceObj.setType(ResourceObject.GRAPHICS_OBJECT);
-                    } else if (dataObj instanceof Document) {
-                        resourceObj.setType(ResourceObject.DOCUMENT_OBJECT);
-                    } else if (dataObj instanceof PageSegment) {
-                        resourceObj.setType(ResourceObject.PAGE_SEGMENT_OBJECT);
-                    } else if (dataObj instanceof Overlay) {
-                        resourceObj.setType(ResourceObject.OVERLAY_OBJECT);
-                    } else {
-                        throw new UnsupportedOperationException(
-                          "Unsupported resource object type " + dataObj);
-                    }
-                                
-                    resourceObj.setObjectClassification(
-                    ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
-                    objectType);
-                    
-                    resourceObj.setDataObject(dataObj);
-                    dataObj = resourceObj;
-                }
-            }
-        }
-        
-        return dataObj;
-    }    
-}
index ae4a4b9fe506a95b5d0af0bb4971165c12fb6fe0..469f3fc1e4e571618e331439f88f326b1d008eeb 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+
 /**
  * The document is the highest level of the MO:DCA data-stream document
  * component hierarchy. Documents can be made up of pages, and the pages,
@@ -61,17 +63,20 @@ public final class Document extends AbstractResourceEnvironmentGroupContainer {
 
     /**
      * Default constructor for the document object.
+     * @param resourceManager the resource manager
      */
-    public Document() {
-        this(DEFAULT_NAME);
+    public Document(ResourceManager resourceManager) {
+        this(resourceManager, DEFAULT_NAME);
     }
 
     /**
      * Constructor for the document object.
-     * @param name The name of the document
+     * 
+     * @param resourceManager the resource manager
+     * @param name the name of the document
      */
-    public Document(String name) {
-        super(name);
+    public Document(ResourceManager resourceManager, String name) {
+        super(resourceManager, name);
     }
 
     /**
index fe6f5e1c502f7d3ac35cf7663075bdb9749fe523..ad6fc3f6b98b43ee2a99ebc1d7ef227bc38399c2 100644 (file)
@@ -26,6 +26,7 @@ import java.io.UnsupportedEncodingException;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.exceptions.FontRuntimeException;
 import org.apache.fop.render.afp.fonts.AFPFont;
 import org.apache.fop.render.afp.fonts.CharacterSet;
index ce5a9233f34a944e292ee81abfe53058c67b2945..7a5889456716d00700393624160b9be828db20ef 100644 (file)
@@ -24,6 +24,7 @@ import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.List;
 
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.tools.BinaryUtils;
 
 /**
index 2c6e7abcc0905e90e35ab70d39e253642e9b0ae7..a59f3665c49ee80ef490bfed551078aaecd98c1f 100644 (file)
@@ -22,6 +22,7 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.tools.BinaryUtils;
 
 /**
index 74b42a281539d884381b6c47da5c4e905f0788d7..3013c2d09b7e52852c32f04015eeb694a93f9513 100644 (file)
@@ -22,6 +22,8 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+
 /**
  * An overlay is a MO:DCA-P resource object.
  * 
@@ -34,6 +36,8 @@ public class Overlay extends AbstractPageObject {
     /**
      * Construct a new overlay object for the specified name argument, the overlay
      * name should be an 8 character identifier.
+     * 
+     * @param resourceManager the resource manager
      *
      * @param name
      *            the name of the page.
@@ -48,9 +52,10 @@ public class Overlay extends AbstractPageObject {
      * @param heightResolution
      *            the height resolution of the page.
      */
-    public Overlay(String name, int width, int height, int rotation,
+    public Overlay(ResourceManager resourceManager,
+            String name, int width, int height, int rotation,
             int widthResolution, int heightResolution) {
-        super(name, width, height, rotation, widthResolution, heightResolution);
+        super(resourceManager, name, width, height, rotation, widthResolution, heightResolution);
     }
 
     /** {@inheritDoc} */
index b1f3aabc1e4027f55f93748b3a91efb479a11fdd..5fb42d19715860c537fcb4697e631096625ee307 100644 (file)
@@ -23,6 +23,8 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+
 /**
  * A page group is used in the data stream to define a named, logical grouping
  * of sequential pages. Page groups are delimited by begin-end structured fields
@@ -34,24 +36,20 @@ import java.util.List;
  */
 public class PageGroup extends AbstractResourceEnvironmentGroupContainer {
 
-    /**
-     * The tag logical elements contained within this group
-     */
+    /** The tag logical elements contained within this group */
     private List tagLogicalElements = null;
 
-    /**
-     * The page state
-     */
+    /** The page state */
     private boolean complete = false;
 
     /**
      * Constructor for the PageGroup.
-     *
-     * @param name
-     *            the name of the page group
+     * 
+     * @param manager the resource manager
+     * @param name the name of the page group
      */
-    public PageGroup(String name) {
-        super(name);
+    public PageGroup(ResourceManager manager, String name) {
+        super(manager, name);
     }
 
     private List getTagLogicalElements() {
index 029c0f6059c9e98b5c102939264144253191b8a5..01ee3e7e346c44d5dd9e8fe37054ad75fe96ad4c 100644 (file)
@@ -22,6 +22,7 @@ package org.apache.fop.render.afp.modca;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
 import org.apache.fop.render.afp.tools.StringUtils;
 
 /**
@@ -46,19 +47,11 @@ import org.apache.fop.render.afp.tools.StringUtils;
  */
 public class PageObject extends AbstractResourceGroupContainer {
 
-//    /**
-//     * The page segment count
-//     */
-//    private int pageSegmentCount = 0;
-//
-//    /**
-//     * The current page segment
-//     */
-//    private PageSegment currentPageSegment = null;
-
     /**
      * Construct a new page object for the specified name argument, the page
      * name should be an 8 character identifier.
+     * 
+     * @param resourceManager the resource manager 
      *
      * @param name
      *            the name of the page.
@@ -73,9 +66,10 @@ public class PageObject extends AbstractResourceGroupContainer {
      * @param heightResolution
      *            the height resolution of the page.
      */
-    public PageObject(String name, int width, int height, int rotation,
+    public PageObject(ResourceManager resourceManager,
+            String name, int width, int height, int rotation,
             int widthResolution, int heightResolution) {
-        super(name, width, height, rotation, widthResolution, heightResolution);
+        super(resourceManager, name, width, height, rotation, widthResolution, heightResolution);
     }
 
     /**
index a0e1169ef306a8704a52471b0e2e8aeab5eba2f7..1282d13aaf643b5e32c8f3fd6b6d2c511fdc900b 100644 (file)
@@ -24,8 +24,9 @@ import java.io.OutputStream;
 import java.util.Iterator;
 import java.util.Set;
 
-import org.apache.fop.render.afp.DataObjectCache;
-import org.apache.fop.render.afp.DataObjectCache.Record;
+import org.apache.fop.render.afp.modca.resource.ResourceManager;
+import org.apache.fop.render.afp.modca.resource.ResourceStore;
+import org.apache.fop.render.afp.modca.resource.StoreInfo;
 
 /**
  * A Resource Group contains a set of overlays.
@@ -38,13 +39,13 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
     /** Set of resource uri */
     private Set/*<String>*/ resourceSet = new java.util.HashSet/*<String>*/();
 
-    private DataObjectCache cache = DataObjectCache.getInstance();
-
+    private ResourceManager resourceManager;
+    
     /**
      * Default constructor
      */
-    public ResourceGroup() {
-        this(DEFAULT_NAME);
+    public ResourceGroup(ResourceManager resourceManager) {
+        this(resourceManager, DEFAULT_NAME);
     }
 
     /**
@@ -52,9 +53,11 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
      * name parameter which must be 8 characters long.
      * 
      * @param name the resource group name
+     * @param resourceManager the resource group manager
      */
-    public ResourceGroup(String name) {
+    public ResourceGroup(ResourceManager resourceManager, String name) {
         super(name);
+        this.resourceManager = resourceManager;
     }
     
 //    /**
@@ -127,7 +130,7 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
      * 
      * @param record the cache record
      */
-    public void addObject(Record record) {
+    public void addObject(StoreInfo record) {
         resourceSet.add(record);
     }
     
@@ -154,14 +157,13 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
     /** {@inheritDoc} */
     public void writeContent(OutputStream os) throws IOException {
         Iterator it = resourceSet.iterator();
-        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");
-            }
+
+        if (it.hasNext()) {            
+            ResourceStore store = resourceManager.getStore();
+            do {
+                StoreInfo saveInfo = (StoreInfo)it.next();
+                store.writeToStream(saveInfo, os);
+            } while (it.hasNext());
         }
     }
 
index 7cc5c898be9408407df316cfa6611419ed6a7167..e3f8621e09570ac86fd6e449fa7860cd89c187cb 100644 (file)
@@ -98,21 +98,33 @@ public class ResourceObject extends AbstractPreparedAFPObject {
         getTriplets().add(new ResourceObjectTypeTriplet(type));
     }
 
-    /**
-     * Resource object types
-     */
-    protected static final byte GRAPHICS_OBJECT = 0x03;
-//    private static final byte BARCODE_OBJECT = 0x05;
-    protected static final byte IMAGE_OBJECT = 0x06;
-//    private static final byte FONT_CHARACTER_SET_OBJECT = 0x40;
-//    private static final byte CODE_PAGE_OBJECT = 0x41;
-//    private static final byte CODED_FONT_OBJECT = 0x42;
-    protected static final byte OBJECT_CONTAINER = (byte) 0x92;
-    protected static final byte DOCUMENT_OBJECT = (byte) 0xA8;
-    protected static final byte PAGE_SEGMENT_OBJECT = (byte) 0xFB;
-    protected static final byte OVERLAY_OBJECT = (byte) 0xFC;
-//    private static final byte PAGEDEF_OBJECT = (byte) 0xFD;
-//    private static final byte FORMDEF_OBJECT = (byte) 0xFE;
+    /** graphics object type */
+    public static final byte TYPE_GRAPHIC = 0x03;
+    
+    /** barcode object type */
+    public static final byte BARCODE = 0x05;
+
+    /** image object type */
+    public static final byte TYPE_IMAGE = 0x06;
+    
+//    private static final byte FONT_CHARACTER_SET = 0x40;
+//    private static final byte CODE_PAGE = 0x41;
+//    private static final byte CODED_FONT = 0x42;
+    
+    /** object container type */
+    public static final byte TYPE_OBJECT_CONTAINER = (byte) 0x92;
+
+    /** document object type */
+    public static final byte TYPE_DOCUMENT = (byte) 0xA8;
+
+    /** page segment object type */
+    public static final byte TYPE_PAGE_SEGMENT = (byte) 0xFB;
+
+    /** overlay object type */
+    public static final byte TYPE_OVERLAY_OBJECT = (byte) 0xFC;
+    
+//    private static final byte PAGEDEF = (byte) 0xFD;
+//    private static final byte FORMDEF = (byte) 0xFE;
 
     private class ResourceObjectTypeTriplet extends Triplet {
 
@@ -122,7 +134,7 @@ public class ResourceObject extends AbstractPreparedAFPObject {
          * Main constructor
          * 
          * @param type
-         *            the resource type
+         *            the resource objec type
          */
         public ResourceObjectTypeTriplet(byte type) {
             super(RESOURCE_OBJECT,
index 4634e5881040d4aa17f1c085ee581fd786db65fc..5f98090a1dc4892eb31d85d9e24f7d5a0b5fa182 100644 (file)
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.tools.BinaryUtils;
 
 /**
diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java b/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java
new file mode 100644 (file)
index 0000000..2c55d76
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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: $ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca.resource;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.ResourceLevel;
+import org.apache.fop.render.afp.modca.ResourceGroup;
+
+/**
+ * Manages resource groups (external)
+ */
+public class ExternalResourceManager {
+
+    /** Static logging instance */
+    static final Log log = LogFactory.getLog(ExternalResourceManager.class);
+
+    /** the resource manager */
+    private final ResourceManager resourceManager;
+
+    /**
+     * Main constructor
+     * 
+     * @param resourceManager the resource manager
+     */
+    public ExternalResourceManager(ResourceManager resourceManager) {
+        this.resourceManager = resourceManager;
+    }
+
+    /** A mapping of external resource destinations to resource groups */
+    private Map/*<String,ResourceGroup>*/pathResourceGroupMap
+        = new java.util.HashMap/*<String,ResourceGroup>*/();
+
+    /** Sets the default resource group file */
+    private String defaultFilePath;
+
+    /**
+     * Sets the default resource group file
+     *
+     * @param filePath the default resource group file path
+     */
+    public void setDefaultFilePath(String filePath) {
+        this.defaultFilePath = filePath;
+    }
+
+    /**
+     * Returns the corresponding resource group for the given resource level
+     *
+     * @param level the resource level
+     * @return the corresponding resource group for the given resource level
+     * or null if not found.
+     */
+    public ResourceGroup getResourceGroup(ResourceLevel level) {
+        ResourceGroup resourceGroup = null;
+        // this resource info does not have an external resource group
+        // file definition
+        String filePath = level.getExternalFilePath();
+        if (filePath != null) {
+            filePath = level.getExternalFilePath();
+            resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath);
+            if (resourceGroup == null) {
+                ResourceFactory factory = resourceManager.getFactory();
+                resourceGroup = factory.createResourceGroup();
+                pathResourceGroupMap.put(filePath, resourceGroup);
+            }
+        } else if (defaultFilePath != null) {
+            // fallback to default resource group file
+            level.setExternalFilePath(defaultFilePath);
+            resourceGroup = getResourceGroup(level);
+        }
+        return resourceGroup;
+    }
+
+    /**
+     * Writes out all resource groups to external files
+     * 
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
+     */
+    public void write() throws IOException {
+        // write any external resources
+        Iterator it = pathResourceGroupMap.keySet().iterator();
+        while (it.hasNext()) {
+            String filePath = (String)it.next();
+            ResourceGroup resourceGroup
+                = (ResourceGroup)pathResourceGroupMap.get(filePath);
+            OutputStream os = null;
+            try {
+                log.debug("Writing external AFP resource file " + filePath);
+                os = new java.io.FileOutputStream(filePath);
+                resourceGroup.write(os);
+            } finally {
+                if (os != null) {
+                    try {
+                        os.close();
+                    } catch (IOException e) {
+                        log.error("Failed to close outputstream for external AFP resource file "
+                                        + filePath);
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java
new file mode 100644 (file)
index 0000000..796ffff
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca.resource;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.render.afp.DataObjectInfo;
+import org.apache.fop.render.afp.GraphicsObjectInfo;
+import org.apache.fop.render.afp.GraphicsObjectPainter;
+import org.apache.fop.render.afp.ImageObjectInfo;
+import org.apache.fop.render.afp.ObjectAreaInfo;
+import org.apache.fop.render.afp.ResourceInfo;
+import org.apache.fop.render.afp.ResourceLevel;
+import org.apache.fop.render.afp.modca.AbstractDataObject;
+import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
+import org.apache.fop.render.afp.modca.Document;
+import org.apache.fop.render.afp.modca.GraphicsObject;
+import org.apache.fop.render.afp.modca.ImageContent;
+import org.apache.fop.render.afp.modca.ImageObject;
+import org.apache.fop.render.afp.modca.IncludeObject;
+import org.apache.fop.render.afp.modca.ObjectContainer;
+import org.apache.fop.render.afp.modca.Overlay;
+import org.apache.fop.render.afp.modca.PageGroup;
+import org.apache.fop.render.afp.modca.PageObject;
+import org.apache.fop.render.afp.modca.PageSegment;
+import org.apache.fop.render.afp.modca.Registry;
+import org.apache.fop.render.afp.modca.ResourceGroup;
+import org.apache.fop.render.afp.modca.ResourceObject;
+import org.apache.fop.render.afp.modca.Registry.ObjectType;
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.render.afp.modca.triplets.MappingOptionTriplet;
+import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet;
+import org.apache.fop.render.afp.tools.StringUtils;
+
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
+
+/**
+ * Creator of MO:DCA data objects
+ */
+public class ResourceFactory {
+
+    /** Static logging instance */
+    private static final Log log = LogFactory.getLog(ResourceFactory.class);
+
+    private static final String IMAGE_NAME_PREFIX = "IMG";
+
+    private static final String GRAPHIC_NAME_PREFIX = "GRA";
+
+    private static final String BARCODE_NAME_PREFIX = "BAR";
+    
+//    private static final String OTHER_NAME_PREFIX = "OTH";
+
+    private static final String OBJECT_CONTAINER_NAME_PREFIX = "OC";
+
+    private static final String RESOURCE_NAME_PREFIX = "RES";
+
+    /** Default name for the resource group */
+    private static final String RESOURCE_GROUP_NAME_PREFIX = "RG";
+    
+    private static final String PAGE_GROUP_NAME_PREFIX = "PGP";
+
+    private static final String PAGE_NAME_PREFIX = "PGN";
+
+    private static final String OVERLAY_NAME_PREFIX = "OVL";
+
+    
+    private Map/*<ResourceInfo,IncludeObject>*/ includeMap
+        = new java.util.HashMap/*<ResourceInfo,IncludeObject>*/();
+    
+    private ResourceManager manager;
+
+    
+    /** The page group count */
+    private int pageGroupCount = 0;
+    
+    /** The page count */
+    private int pageCount = 0;
+
+    /** The image count */
+    private int imageCount = 0;
+
+    /** The graphic count */
+    private int graphicCount = 0;
+
+    /** The object container count */
+    private int objectContainerCount = 0;
+
+    /** The resource count */
+    private int resourceCount = 0;
+
+    /** The resource group count */
+    private int resourceGroupCount = 0;
+
+    /** The overlay count */
+    private int overlayCount = 0;
+        
+    /**
+     * Main constructor
+     * 
+     * @param resourceManager the resource manager
+     */
+    public ResourceFactory(ResourceManager resourceManager) {
+        this.manager = resourceManager;
+    }
+
+    /**
+     * Converts a byte array containing 24 bit RGB image data to a grayscale
+     * image.
+     * 
+     * @param io
+     *            the target image object
+     * @param info
+     *            the image object info
+     *
+     * @return the converted image data
+     */
+    private static byte[] convertToGrayScaleImage(ImageObject io, ImageObjectInfo info) {
+        byte[] raw = info.getData();
+        int width = info.getDataWidth();
+        int height = info.getDataHeight();
+        int bitsPerPixel = info.getBitsPerPixel();
+        
+        int pixelsPerByte = 8 / bitsPerPixel;
+        int bytewidth = (width / pixelsPerByte);
+        if ((width % pixelsPerByte) != 0) {
+            bytewidth++;
+        }
+        byte[] data = new byte[height * bytewidth];
+        byte ib;
+        for (int y = 0; y < height; y++) {
+            ib = 0;
+            int i = 3 * y * width;
+            for (int x = 0; x < width; x++, i += 3) {
+
+                // see http://www.jguru.com/faq/view.jsp?EID=221919
+                double greyVal = 0.212671d * ((int) raw[i] & 0xff) + 0.715160d
+                        * ((int) raw[i + 1] & 0xff) + 0.072169d
+                        * ((int) raw[i + 2] & 0xff);
+                switch (bitsPerPixel) {
+                case 1:
+                    if (greyVal < 128) {
+                        ib |= (byte) (1 << (7 - (x % 8)));
+                    }
+                    break;
+                case 4:
+                    greyVal /= 16;
+                    ib |= (byte) ((byte) greyVal << ((1 - (x % 2)) * 4));
+                    break;
+                case 8:
+                    ib = (byte) greyVal;
+                    break;
+                default:
+                    throw new UnsupportedOperationException(
+                            "Unsupported bits per pixel: " + bitsPerPixel);
+                }
+
+                if ((x % pixelsPerByte) == (pixelsPerByte - 1)
+                        || ((x + 1) == width)) {
+                    data[(y * bytewidth) + (x / pixelsPerByte)] = ib;
+                    ib = 0;
+                }
+            }
+        }
+        return data;
+    }
+
+    /**
+     * Helper method to create an image on the current container and to return
+     * the object.
+     * 
+     * @param imageObjectInfo the image object info
+     * @return a newly created image object
+     */
+    private ImageObject createImage(ImageObjectInfo imageObjectInfo) {
+        String name = IMAGE_NAME_PREFIX
+                + StringUtils.lpad(String.valueOf(++imageCount), '0', 5);
+        ImageObject imageObj = new ImageObject(name);
+        if (imageObjectInfo.hasCompression()) {
+            int compression = imageObjectInfo.getCompression();
+            switch (compression) {
+            case TIFFImage.COMP_FAX_G3_1D:
+                imageObj.setImageEncoding(ImageContent.COMPID_G3_MH);
+                    break;
+                case TIFFImage.COMP_FAX_G3_2D:
+                    imageObj.setImageEncoding(ImageContent.COMPID_G3_MR);
+                    break;
+                case TIFFImage.COMP_FAX_G4_2D:
+                    imageObj.setImageEncoding(ImageContent.COMPID_G3_MMR);
+                    break;
+                default:
+                    throw new IllegalStateException(
+                            "Invalid compression scheme: " + compression);
+            }
+        }
+        ObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo();
+        imageObj.setImageParameters(objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes(), 
+                imageObjectInfo.getDataWidth(), imageObjectInfo.getDataHeight());
+        if (imageObjectInfo.isBuffered()) {
+            if (imageObjectInfo.isColor()) {
+                imageObj.setImageIDESize((byte)24);
+                imageObj.setImageData(imageObjectInfo.getData());
+            } else {
+                int bitsPerPixel = imageObjectInfo.getBitsPerPixel();
+                imageObj.setImageIDESize((byte)bitsPerPixel);
+                byte[] data = convertToGrayScaleImage(imageObj, imageObjectInfo);
+                imageObj.setImageData(data);
+            }    
+        }
+        return imageObj;
+    }
+    
+    /**
+     * Creates and returns a new graphics object.
+     * 
+     * @param graphicsObjectInfo the graphics object info
+     * @return a new graphics object
+     */
+    private GraphicsObject createGraphic(GraphicsObjectInfo graphicsObjectInfo) {
+        String name = GRAPHIC_NAME_PREFIX
+            + StringUtils.lpad(String.valueOf(++graphicCount), '0', 5);
+        GraphicsObject graphicsObj = new GraphicsObject(name);
+        
+        // paint the graphic using batik
+        GraphicsObjectPainter painter = graphicsObjectInfo.getPainter();
+        painter.paint(graphicsObj);
+        
+        return graphicsObj;
+    }
+
+    /**
+     * Creates and returns a new object container
+     * 
+     * @return a new object container
+     */
+    private ObjectContainer createObjectContainer() {
+        String name = OBJECT_CONTAINER_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++objectContainerCount), '0', 6);
+        return new ObjectContainer(name);
+    }
+
+    /**
+     * Creates and returns a new resource object
+     * 
+     * @param resourceName the resource name
+     * @return a new resource object
+     */
+    private ResourceObject createResource(String resourceName) {
+        return new ResourceObject(resourceName);
+    }
+
+    /**
+     * Creates and returns a new resource object
+     * 
+     * @return a new resource object
+     */
+    private ResourceObject createResource() {
+        String name = RESOURCE_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++resourceCount), '0', 5);
+        return createResource(name);
+    }
+
+    /**
+     * Creates and returns a new include object.
+     * 
+     * @param name the name of this include object
+     * @param dataObjectInfo a data object info
+     * 
+     * @return a new include object
+     */
+    public IncludeObject createInclude(String name, DataObjectInfo dataObjectInfo) {
+        ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
+        IncludeObject includeObj = (IncludeObject)includeMap.get(resourceInfo);
+        if (includeObj == null) {
+            includeObj = new IncludeObject(name);
+        
+            if (dataObjectInfo instanceof ImageObjectInfo) {
+                includeObj.setDataObjectType(IncludeObject.TYPE_IMAGE);
+            } else if (dataObjectInfo instanceof GraphicsObjectInfo) {
+                includeObj.setDataObjectType(IncludeObject.TYPE_GRAPHIC);
+            } else {
+                includeObj.setDataObjectType(IncludeObject.TYPE_OTHER);
+            }
+            
+            Registry.ObjectType objectType = dataObjectInfo.getObjectType();
+            if (objectType != null) {
+                includeObj.setObjectClassification(
+                   ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
+                   objectType);
+            }
+            
+            ObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
+            
+            includeObj.setObjectArea(objectAreaInfo.getX(), objectAreaInfo.getY());
+    
+            includeObj.setObjectAreaSize(
+                    objectAreaInfo.getWidth(), objectAreaInfo.getHeight());        
+    
+            includeObj.setMeasurementUnits(
+                    objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes());
+            
+            includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT);
+            
+            includeMap.put(resourceInfo, includeObj);
+        }
+        
+        return includeObj;
+    }
+
+    /**
+     * Creates and returns a new page group
+     * 
+     * @return a new page group object
+     */
+    public PageGroup createPageGroup() {
+        String name = PAGE_GROUP_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++pageGroupCount), '0', 5);
+        return new PageGroup(manager, name);
+    }    
+
+    /**
+     * Creates and returns a new resource object
+     * 
+     * @return a new resource object
+     */
+    public ResourceGroup createResourceGroup() {
+        String name = RESOURCE_GROUP_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6);
+        return new ResourceGroup(manager, name);
+    }
+    
+    /**
+     * Creates and returns a new page object
+     * 
+     * @param pageWidth
+     *            the width of the page
+     * @param pageHeight
+     *            the height of the page
+     * @param pageRotation
+     *            the rotation of the page
+     * @param pageWidthRes
+     *            the width resolution of the page
+     * @param pageHeightRes
+     *            the height resolution of the page
+     * 
+     * @return a new page object
+     */
+    public PageObject createPage(int pageWidth, int pageHeight, int pageRotation,
+            int pageWidthRes, int pageHeightRes) {
+        String pageName = PAGE_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++pageCount), '0', 5);
+        return new PageObject(manager, pageName, pageWidth, pageHeight,
+            pageRotation, pageWidthRes, pageHeightRes);
+    }
+
+
+    /**
+     * Creates and returns a new Overlay.
+     *
+     * @param width
+     *            the width of the overlay
+     * @param height
+     *            the height of the overlay
+     * @param widthRes
+     *            the width resolution of the overlay
+     * @param heightRes
+     *            the height resolution of the overlay
+     * @param overlayRotation
+     *            the rotation of the overlay
+     * 
+     * @return a new overlay object
+     */
+    public Overlay createOverlay(int width, int height,
+            int widthRes, int heightRes, int overlayRotation) {
+        String overlayName = OVERLAY_NAME_PREFIX
+        + StringUtils.lpad(String.valueOf(++overlayCount), '0', 5);
+        Overlay overlay = new Overlay(manager, overlayName, width, height,
+                overlayRotation, widthRes, heightRes);
+        return overlay;        
+    }
+    
+    /**
+     * Creates a new MO:DCA document object
+     * 
+     * @return a new MO:DCA document object
+     */
+    public Document createDocument() {
+        return new Document(manager);
+    }
+
+    /**
+     * Creates and returns a new data object
+     * 
+     * @param dataObjectInfo the data object info
+     * 
+     * @return a newly created data object
+     */
+    public AbstractNamedAFPObject create(DataObjectInfo dataObjectInfo) {
+        AbstractNamedAFPObject dataObj;
+        
+        if (dataObjectInfo instanceof ImageObjectInfo) {
+            dataObj = createImage((ImageObjectInfo)dataObjectInfo);
+        } else if (dataObjectInfo instanceof GraphicsObjectInfo) {
+            dataObj = createGraphic((GraphicsObjectInfo)dataObjectInfo);
+        } else {
+            throw new IllegalArgumentException("Unknown data object type: " + dataObjectInfo);
+        }
+        
+        if (dataObj instanceof AbstractDataObject) {
+            ((AbstractDataObject)dataObj).setViewport(dataObjectInfo.getObjectAreaInfo());
+        }
+        
+        dataObj.setFullyQualifiedName(
+                FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_INTERNAL_RESOURCE_REF,
+                FullyQualifiedNameTriplet.FORMAT_CHARSTR, dataObj.getName());
+
+        ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
+        ResourceLevel resourceLevel = resourceInfo.getLevel();
+
+        if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
+            
+            ObjectType objectType = dataObjectInfo.getObjectType();
+            
+            if (objectType != null && objectType.isIncludable()) {
+                
+                // Wrap newly created data object in a resource object
+                // if it is to reside within a resource group at print-file or external level
+                if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
+                    ResourceObject resourceObj = null;
+                    String resourceName = resourceInfo.getName();
+                    if (resourceName != null) {
+                        resourceObj = createResource(resourceName);
+                    } else {
+                        resourceObj = createResource();
+                    }
+                    
+                    if (dataObj instanceof ObjectContainer) {
+                        resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER);
+                    } else if (dataObj instanceof ImageObject) {
+                        resourceObj.setType(ResourceObject.TYPE_IMAGE);
+                    } else if (dataObj instanceof GraphicsObject) {
+                        resourceObj.setType(ResourceObject.TYPE_GRAPHIC);
+                    } else if (dataObj instanceof Document) {
+                        resourceObj.setType(ResourceObject.TYPE_DOCUMENT);
+                    } else if (dataObj instanceof PageSegment) {
+                        resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT);
+                    } else if (dataObj instanceof Overlay) {
+                        resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT);
+                    } else {
+                        throw new UnsupportedOperationException(
+                          "Unsupported resource object type " + dataObj);
+                    }
+                                
+                    resourceObj.setObjectClassification(
+                    ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT,
+                    objectType);
+                    
+                    resourceObj.setDataObject(dataObj);
+                    dataObj = resourceObj;
+                }
+            }
+        }
+        
+        return dataObj;
+    }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java
new file mode 100644 (file)
index 0000000..60cbb72
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca.resource;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.render.afp.DataObjectInfo;
+import org.apache.fop.render.afp.ResourceInfo;
+import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
+import org.apache.fop.render.afp.modca.Registry;
+
+/**
+ * Manages the creation and storage of document resources 
+ */
+public class ResourceManager {
+    /** Static logging instance */
+    static final Log log = LogFactory.getLog(ResourceManager.class);
+
+    /** Resource storage */
+    private ResourceStore store;
+    
+    /** Resource creation factory */
+    private ResourceFactory factory;
+
+    private ExternalResourceManager external;
+    
+    /** Mapping of resource info --> store info */
+    private Map/*<ResourceInfo,StoreInfo>*/ resourceStorageMap
+            = new java.util.HashMap/*<ResourceInfo,StoreInfo>*/();
+    
+    /**
+     * Main constructor
+     */
+    public ResourceManager() {
+        this.factory = new ResourceFactory(this);
+        this.store = new ResourceStore();
+        this.external = new ExternalResourceManager(this);
+    }
+
+    /**
+     * Creates and adds a new data object and stores the save record to a temporary file.  
+     * 
+     * @param dataObjectInfo a data object info
+     * 
+     * @return a new store save information record
+     * 
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
+     */
+    public StoreInfo create(DataObjectInfo dataObjectInfo) throws IOException {
+        StoreInfo storeInfo = null;
+        Registry.ObjectType objectType = dataObjectInfo.getObjectType();
+        if (objectType == null || !objectType.isIncludable()) {
+            AbstractNamedAFPObject dataObj = factory.create(dataObjectInfo);
+            if (dataObj == null) {
+                log.error("Failed to create object: " + dataObjectInfo);
+                return null;
+            }
+            storeInfo = store.save(dataObj);
+        } else {
+            ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
+            storeInfo = (StoreInfo)resourceStorageMap.get(resourceInfo);
+            if (storeInfo == null) {
+                AbstractNamedAFPObject dataObj = factory.create(dataObjectInfo);
+                if (dataObj == null) {
+                    log.error("Failed to create object: " + dataObjectInfo);
+                    return null;
+                }
+                storeInfo = store.save(dataObj);
+                resourceStorageMap.put(resourceInfo, storeInfo);
+            }
+        }
+        return storeInfo;
+    }
+
+    /**
+     * Returns the resource factory
+     * 
+     * @return the resource factory
+     */
+    public ResourceFactory getFactory() {
+        return this.factory;
+    }
+
+    /**
+     * Returns the resource store
+     * 
+     * @return the resource store
+     */
+    public ResourceStore getStore() {
+        return this.store;
+    }
+
+    /**
+     * Returns the resource group manager
+     * 
+     * @return the resource group manager
+     */    
+    public ExternalResourceManager getExternalManager() {
+        return this.external;
+    }
+
+    /**
+     * Writes out all external resource groups that are held
+     * 
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
+     */
+    public void writeExternal() throws IOException {
+        external.write();
+    }
+
+    /**
+     * Clears the store
+     */
+    public void clearStore() {
+        store.clear();
+    }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java
new file mode 100644 (file)
index 0000000..cec528c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca.resource;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
+
+/**
+ * Caches and creates (as necessary using an instance of DataObjectFactory)
+ * descendants of AbstractDataObject
+ */
+public final class ResourceStore {
+
+    /** Static logging instance */
+    private static final Log log = LogFactory.getLog(ResourceStore.class);
+
+    private static final String TEMPFILE_PREFIX = "AFP_";
+
+    /** Internal temporary storage buffer size */
+    private static final int BUFFER_SIZE = 4096;
+        
+    /** Used for storage of data objects */
+    private RandomAccessFile raFile;
+    
+    /** The temporary cache file */
+    private File tempFile;
+
+    /** The file outputstream */
+    private FileOutputStream fos;
+    
+    /**
+     * Default constructor
+     */
+    public ResourceStore() {
+        try {
+            this.tempFile = File.createTempFile(TEMPFILE_PREFIX, null);
+            this.raFile = new RandomAccessFile(tempFile, "rw");
+            FileDescriptor fd = raFile.getFD();
+            this.fos = new FileOutputStream(fd);
+        } catch (IOException e) {
+            // TODO
+            log.error(e.getMessage());
+        }
+    }
+    
+    /**
+     * Clears the data object cache
+     */
+    public void clear() {
+        if (tempFile != null) {
+            if (!tempFile.delete()) {
+                // failed to delete to schedule so attempt to delete on exit from the VM
+                tempFile.deleteOnExit();
+            }
+            tempFile = null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void finalize() throws Throwable {
+        try {
+            clear();
+        } finally {
+            super.finalize();
+        }
+    }
+    
+    /**
+     * Stores a named data object in the cache
+     * 
+     * @param dataObj a named data object
+     * @return a new save information record
+     * 
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
+     */
+    public StoreInfo save(AbstractNamedAFPObject dataObj) throws IOException {
+        StoreInfo storeInfo = new StoreInfo();
+        storeInfo.objectName = dataObj.getName();
+        storeInfo.position = raFile.getFilePointer();
+        try {
+            dataObj.write(fos);
+        } finally {
+            fos.flush();
+        }
+        storeInfo.size = (int)(raFile.getFilePointer() - storeInfo.position);
+        return storeInfo;
+    }
+    
+    /**
+     * Writes out the resource given the save information to the given outputstream.
+     * 
+     * @param saveInfo the save information
+     * @param os the outputstream to write to
+     * 
+     * @throws java.io.IOException an I/O exception of some sort has occurred.
+     */
+    public void writeToStream(StoreInfo saveInfo, OutputStream os) throws IOException {
+        if (saveInfo == null) {
+            throw new IllegalArgumentException("save is null");
+        }
+        double chunkCount = saveInfo.size / BUFFER_SIZE;
+        byte[] buffer = new byte[BUFFER_SIZE];
+        raFile.seek(saveInfo.position);
+        for (int cnt = 0; cnt < chunkCount; cnt++) {
+            raFile.read(buffer, 0, BUFFER_SIZE);
+            os.write(buffer, 0, BUFFER_SIZE);
+        }
+        int lastChunkLength = saveInfo.size % BUFFER_SIZE;
+        raFile.read(buffer, 0, lastChunkLength);
+        os.write(buffer, 0, lastChunkLength);
+    }
+    
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java b/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java
new file mode 100644 (file)
index 0000000..775478c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca.resource;
+
+/**
+ * Store save information
+ */
+public class StoreInfo {
+    /** data position */
+    protected long position; 
+
+    /** data chunk size */
+    protected int size;
+    
+    /** name of data object */
+    protected String objectName;
+    
+    /**
+     * Returns the object name
+     * 
+     * @return the object name
+     */
+    public String getObjectName() {
+        return this.objectName;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        return "StoreInfo{name=" + objectName
+            + ", pos=" + position
+            + ", size=" + size
+            + "}";
+    }    
+}
\ No newline at end of file
index 705a8d41da6f36f44dfe52e12c3dbde1d54b28d8..68bef3e56d7090265d6d4060d3613c0f810a28e5 100644 (file)
@@ -21,7 +21,7 @@ package org.apache.fop.render.afp.modca.triplets;
 
 import java.io.UnsupportedEncodingException;
 
-import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.AFPConstants;
 
 /**
  * A Fully Qualified Name triplet enable the identification and referencing of
index 45e08eaab9186090b9d3b4deb53ac9d8897140c9..b12cc89fe63e6e421259c2be1ef1058f6d826626 100644 (file)
@@ -21,7 +21,7 @@ package org.apache.fop.render.afp.modca.triplets;
 
 import java.io.UnsupportedEncodingException;
 
-import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.modca.Registry;
 import org.apache.fop.render.afp.tools.StringUtils;
 
index 868f28a72b331d28b911db57aa6f03c02e5241da..b8c16f3686095a154091deec66f73da533c565dd 100644 (file)
@@ -23,7 +23,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 
-import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.AFPConstants;
 import org.apache.fop.render.afp.modca.AbstractAFPObject;
 
 /**