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