From: Adrian Cumiskey Date: Thu, 24 Jul 2008 18:26:43 +0000 (+0000) Subject: * Moved AFPConstants from org.apache.fop.render.afp.modca into org.apache.fop.render... X-Git-Tag: fop-1_0~376^2~104 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cc5d6604bde87fca098633ceccd66fc92808bddc;p=xmlgraphics-fop.git * Moved AFPConstants from org.apache.fop.render.afp.modca into org.apache.fop.render.afp as it is used in other subpackages. * 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 --- 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 index 000000000..b9ab2de78 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPConstants.java @@ -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; +} diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index d61b62968..94918f7ec 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -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); } diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index dc61fdccb..5142c17d3 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -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; diff --git a/src/java/org/apache/fop/render/afp/AFPState.java b/src/java/org/apache/fop/render/afp/AFPState.java index 5cf396362..8c8aaba14 100644 --- a/src/java/org/apache/fop/render/afp/AFPState.java +++ b/src/java/org/apache/fop/render/afp/AFPState.java @@ -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 index 85b96eff8..000000000 --- a/src/java/org/apache/fop/render/afp/DataObjectCache.java +++ /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/**/ cacheMap - = new java.util.HashMap/**/(); - - - /** Mapping of data object uri --> cache record */ - private Map/**/ includableMap - = new java.util.HashMap/**/(); - - /** 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 index 205eb62fa..000000000 --- a/src/java/org/apache/fop/render/afp/ExternalResourceGroupManager.java +++ /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/**/externalResourceGroups - = new java.util.HashMap/**/(); - - /** 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 diff --git a/src/java/org/apache/fop/render/afp/LineDataInfo.java b/src/java/org/apache/fop/render/afp/LineDataInfo.java index b7a6afc90..1fd7f5626 100644 --- a/src/java/org/apache/fop/render/afp/LineDataInfo.java +++ b/src/java/org/apache/fop/render/afp/LineDataInfo.java @@ -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 diff --git a/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java b/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java index 7951be26c..731acdaee 100644 --- a/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java +++ b/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java @@ -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; /** diff --git a/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java index 82300197b..56e6f62df 100644 --- a/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java +++ b/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java @@ -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; /** diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsString.java b/src/java/org/apache/fop/render/afp/goca/GraphicsString.java index fdeeea5bb..1fb842ae4 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsString.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsString.java @@ -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 index a55f6a076..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AFPConstants.java +++ /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; -} 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 3105f88b1..041768cd4 100644 --- a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java +++ b/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java @@ -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) { 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 4b2d371b7..c3cd6ed43 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java @@ -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. 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 540e74c33..8f4742950 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java @@ -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/**/ tagLogicalElements = null; - /** - * The list of the include page segments - */ + /** The list of the include page segments */ protected List/**/ includePageSegments = null; - /** - * The list of objects within this resource container - */ + /** The list of objects within this resource container */ protected List/**/ 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()); } } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java index d56ebef9b..6eb8268e5 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java @@ -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); } /** diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java index b1d4980a8..b3739c717 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java @@ -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 index 7915dbeb8..000000000 --- a/src/java/org/apache/fop/render/afp/modca/DataObjectFactory.java +++ /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/**/ includeMap - = new java.util.HashMap/**/(); - - /** 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; - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/Document.java b/src/java/org/apache/fop/render/afp/modca/Document.java index ae4a4b9fe..469f3fc1e 100644 --- a/src/java/org/apache/fop/render/afp/modca/Document.java +++ b/src/java/org/apache/fop/render/afp/modca/Document.java @@ -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); } /** diff --git a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java index fe6f5e1c5..ad6fc3f6b 100644 --- a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java +++ b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java @@ -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; diff --git a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java index ce5a9233f..7a5889456 100644 --- a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java +++ b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java @@ -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; /** diff --git a/src/java/org/apache/fop/render/afp/modca/NoOperation.java b/src/java/org/apache/fop/render/afp/modca/NoOperation.java index 2c6e7abcc..a59f3665c 100644 --- a/src/java/org/apache/fop/render/afp/modca/NoOperation.java +++ b/src/java/org/apache/fop/render/afp/modca/NoOperation.java @@ -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; /** diff --git a/src/java/org/apache/fop/render/afp/modca/Overlay.java b/src/java/org/apache/fop/render/afp/modca/Overlay.java index 74b42a281..3013c2d09 100644 --- a/src/java/org/apache/fop/render/afp/modca/Overlay.java +++ b/src/java/org/apache/fop/render/afp/modca/Overlay.java @@ -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} */ diff --git a/src/java/org/apache/fop/render/afp/modca/PageGroup.java b/src/java/org/apache/fop/render/afp/modca/PageGroup.java index b1f3aabc1..5fb42d197 100644 --- a/src/java/org/apache/fop/render/afp/modca/PageGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/PageGroup.java @@ -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() { diff --git a/src/java/org/apache/fop/render/afp/modca/PageObject.java b/src/java/org/apache/fop/render/afp/modca/PageObject.java index 029c0f605..01ee3e7e3 100644 --- a/src/java/org/apache/fop/render/afp/modca/PageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/PageObject.java @@ -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); } /** 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 a0e1169ef..1282d13aa 100644 --- a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java @@ -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/**/ resourceSet = new java.util.HashSet/**/(); - 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()); } } diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceObject.java b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java index 7cc5c898b..e3f8621e0 100644 --- a/src/java/org/apache/fop/render/afp/modca/ResourceObject.java +++ b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java @@ -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, diff --git a/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java b/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java index 4634e5881..5f98090a1 100644 --- a/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java +++ b/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java @@ -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 index 000000000..2c55d7618 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java @@ -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/**/pathResourceGroupMap + = new java.util.HashMap/**/(); + + /** 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 index 000000000..796ffff1a --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java @@ -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/**/ includeMap + = new java.util.HashMap/**/(); + + 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 index 000000000..60cbb7257 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java @@ -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/**/ resourceStorageMap + = new java.util.HashMap/**/(); + + /** + * 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 index 000000000..cec528c54 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java @@ -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 index 000000000..775478cd4 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java @@ -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 diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java index 705a8d41d..68bef3e56 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java @@ -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 diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java index 45e08eaab..b12cc89fe 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java @@ -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; diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java index 868f28a72..b8c16f368 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java @@ -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; /**