From 24664f14599a17792b0704ae352702407cb5c0e0 Mon Sep 17 00:00:00 2001 From: Mehdi Houshmand Date: Mon, 11 Jun 2012 14:35:57 +0000 Subject: [PATCH] Removed AFP resource handling mechanism in favour of a unified resource resolver git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_URI_Unification@1348871 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/afp/AFPDitheredRectanglePainter.java | 3 +- .../org/apache/fop/afp/AFPResourceInfo.java | 3 +- .../org/apache/fop/afp/AFPResourceLevel.java | 133 +++++----- .../fop/afp/AFPResourceLevelDefaults.java | 3 +- .../apache/fop/afp/AFPResourceManager.java | 24 +- src/java/org/apache/fop/afp/AFPStreamer.java | 126 +++++----- .../apache/fop/afp/fonts/CharacterSet.java | 8 +- .../fop/afp/fonts/CharacterSetBuilder.java | 51 ++-- .../apache/fop/afp/fonts/FopCharacterSet.java | 4 +- .../fop/afp/modca/IncludedResourceObject.java | 6 +- ...Accessor.java => AFPResourceAccessor.java} | 13 +- .../fop/afp/util/SimpleResourceAccessor.java | 76 ------ .../org/apache/fop/apps/FopConfParser.java | 6 +- .../apache/fop/apps/FopFactoryBuilder.java | 4 +- .../fop/apps/io/DefaultResourceResolver.java | 49 ---- .../fop/apps/io/ResourceResolverFactory.java | 238 ++++++++++++++++++ .../io/TempResourceResolver.java} | 20 +- src/java/org/apache/fop/pdf/PDFResources.java | 2 - .../fop/render/afp/AFPCustomizable.java | 8 +- .../fop/render/afp/AFPDocumentHandler.java | 13 +- .../apache/fop/render/afp/AFPFontConfig.java | 13 +- .../render/afp/AFPForeignAttributeReader.java | 43 +--- .../fop/render/afp/AFPImageHandlerSVG.java | 3 +- .../org/apache/fop/render/afp/AFPPainter.java | 13 +- .../fop/render/afp/AFPRendererConfig.java | 35 +-- .../render/afp/AFPRendererConfigurator.java | 7 +- .../apache/fop/render/afp/AFPShadingMode.java | 14 +- .../bitmap/BitmapRendererConfigurator.java | 17 +- .../fop/render/bitmap/PNGDocumentHandler.java | 4 +- .../fop/render/bitmap/PNGRendererConfig.java | 47 ++++ .../render/java2d/Java2DGraphicsState.java | 2 +- .../PDFDocumentGraphics2DConfigurator.java | 5 +- .../org/apache/fop/URIResolutionTestCase.java | 4 +- .../fop/afp/AFPResourceManagerTestCase.java | 10 +- .../fop/apps/AFPRendererConfBuilder.java | 56 ++++- .../fop/apps/FopFactoryBuilderTestCase.java | 4 +- .../io/ResourceResolverFactoryTestCase.java | 212 ++++++++++++++++ .../fop/fonts/DejaVuLGCSerifTestCase.java | 4 +- .../fonts/truetype/TTFFontLoaderTestCase.java | 4 +- .../apache/fop/pdf/PDFFactoryTestCase.java | 8 +- .../afp/AFPRendererConfigParserTestCase.java | 69 +++-- .../afp/AFPRendererConfiguratorTestCase.java | 227 +++++++++++++---- 42 files changed, 1042 insertions(+), 549 deletions(-) rename src/java/org/apache/fop/afp/util/{DefaultFOPResourceAccessor.java => AFPResourceAccessor.java} (83%) delete mode 100644 src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java delete mode 100644 src/java/org/apache/fop/apps/io/DefaultResourceResolver.java create mode 100644 src/java/org/apache/fop/apps/io/ResourceResolverFactory.java rename src/java/org/apache/fop/{afp/util/ResourceAccessor.java => apps/io/TempResourceResolver.java} (60%) create mode 100644 src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java create mode 100644 test/java/org/apache/fop/apps/io/ResourceResolverFactoryTestCase.java diff --git a/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java b/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java index d1c693afb..a953718bd 100644 --- a/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java +++ b/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java @@ -28,6 +28,7 @@ import java.io.IOException; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.util.MimeConstants; +import org.apache.fop.afp.AFPResourceLevel.ResourceType; import org.apache.fop.afp.modca.triplets.MappingOptionTriplet; import org.apache.fop.util.bitmap.DitherUtil; @@ -66,7 +67,7 @@ public class AFPDitheredRectanglePainter extends AbstractAFPPainter { AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo(); imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10); //imageObjectInfo.setCreatePageSegment(true); - imageObjectInfo.getResourceInfo().setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); + imageObjectInfo.getResourceInfo().setLevel(new AFPResourceLevel(ResourceType.INLINE)); imageObjectInfo.getResourceInfo().setImageDimension(ditherSize); imageObjectInfo.setBitsPerPixel(1); imageObjectInfo.setColor(false); diff --git a/src/java/org/apache/fop/afp/AFPResourceInfo.java b/src/java/org/apache/fop/afp/AFPResourceInfo.java index 1bf26f2bb..bbd552c67 100644 --- a/src/java/org/apache/fop/afp/AFPResourceInfo.java +++ b/src/java/org/apache/fop/afp/AFPResourceInfo.java @@ -21,6 +21,7 @@ package org.apache.fop.afp; import java.awt.Dimension; +import org.apache.fop.afp.AFPResourceLevel.ResourceType; /** * The level at which a resource is to reside in the AFP output @@ -29,7 +30,7 @@ public class AFPResourceInfo { /** the general default resource level */ public static final AFPResourceLevel DEFAULT_LEVEL - = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE); + = new AFPResourceLevel(ResourceType.PRINT_FILE); /** the URI of this resource */ private String uri = null; diff --git a/src/java/org/apache/fop/afp/AFPResourceLevel.java b/src/java/org/apache/fop/afp/AFPResourceLevel.java index d884b56a6..7dcff1183 100644 --- a/src/java/org/apache/fop/afp/AFPResourceLevel.java +++ b/src/java/org/apache/fop/afp/AFPResourceLevel.java @@ -19,46 +19,56 @@ package org.apache.fop.afp; +import java.net.URI; + +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.DOCUMENT; +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.EXTERNAL; +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.INLINE; +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PAGE; +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PAGE_GROUP; +import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PRINT_FILE; + /** * A resource level */ public class AFPResourceLevel { + public enum ResourceType { + /** directly in page **/ + INLINE("inline"), + /** page level **/ + PAGE("page"), + /** page group level **/ + PAGE_GROUP("page-group"), + /** document level **/ + DOCUMENT("document"), + /** print file level **/ + PRINT_FILE("print-file"), + /** external level **/ + EXTERNAL("external"); + + private final String name; + + private ResourceType(String name) { + this.name = name; + } - /** directly in page **/ - public static final int INLINE = 0; - - /** page level **/ - public static final int PAGE = 1; - - /** page group level **/ - public static final int PAGE_GROUP = 2; - - /** document level **/ - public static final int DOCUMENT = 3; - - /** print file level **/ - public static final int PRINT_FILE = 4; - - /** external level **/ - public static final int EXTERNAL = 5; - - private static final String NAME_INLINE = "inline"; - private static final String NAME_PAGE = "page"; - private static final String NAME_PAGE_GROUP = "page-group"; - private static final String NAME_DOCUMENT = "document"; - private static final String NAME_PRINT_FILE = "print-file"; - private static final String NAME_EXTERNAL = "external"; - - private static final String[] NAMES = new String[] { - NAME_INLINE, NAME_PAGE, NAME_PAGE_GROUP, NAME_DOCUMENT, NAME_PRINT_FILE, NAME_EXTERNAL - }; - + public static ResourceType getValueOf(String levelString) { + for (ResourceType resType : ResourceType.values()) { + if (resType.name.equalsIgnoreCase(levelString)) { + return resType; + } + } + return null; + } - /** where the resource will reside in the AFP output */ - private int level = PRINT_FILE; // default is print-file level (images) + public String getName() { + return name; + } + } /** the external resource group file path */ - private String extFilePath = null; + private URI extUri = null; + private ResourceType resourceType; /** * Sets the resource placement level within the AFP output @@ -67,18 +77,8 @@ public class AFPResourceLevel { * @return true if the resource level was successfully set */ public static AFPResourceLevel valueOf(String levelString) { - if (levelString != null) { - levelString = levelString.toLowerCase(); - AFPResourceLevel resourceLevel = null; - for (int i = 0; i < NAMES.length; i++) { - if (NAMES[i].equals(levelString)) { - resourceLevel = new AFPResourceLevel(i); - break; - } - } - return resourceLevel; - } - return null; + ResourceType resType = ResourceType.getValueOf(levelString); + return resType != null ? new AFPResourceLevel(resType) : null; } /** @@ -86,17 +86,8 @@ public class AFPResourceLevel { * * @param level the resource level */ - public AFPResourceLevel(int level) { - setLevel(level); - } - - /** - * Sets the resource level - * - * @param level the resource level - */ - public void setLevel(int level) { - this.level = level; + public AFPResourceLevel(ResourceType resourceType) { + this.resourceType = resourceType; } /** @@ -105,7 +96,7 @@ public class AFPResourceLevel { * @return true if this is at page level */ public boolean isPage() { - return level == PAGE; + return resourceType == PAGE; } /** @@ -114,7 +105,7 @@ public class AFPResourceLevel { * @return true if this is at page group level */ public boolean isPageGroup() { - return level == PAGE_GROUP; + return resourceType == PAGE_GROUP; } /** @@ -123,7 +114,7 @@ public class AFPResourceLevel { * @return true if this is at document level */ public boolean isDocument() { - return level == DOCUMENT; + return resourceType == DOCUMENT; } /** @@ -132,7 +123,7 @@ public class AFPResourceLevel { * @return true if this is at external level */ public boolean isExternal() { - return level == EXTERNAL; + return resourceType == EXTERNAL; } /** @@ -141,7 +132,7 @@ public class AFPResourceLevel { * @return true if this is at print-file level */ public boolean isPrintFile() { - return level == PRINT_FILE; + return resourceType == PRINT_FILE; } /** @@ -150,7 +141,7 @@ public class AFPResourceLevel { * @return true if this resource level is inline */ public boolean isInline() { - return level == INLINE; + return resourceType == INLINE; } /** @@ -158,8 +149,8 @@ public class AFPResourceLevel { * * @return the destination file path of the external resource group file */ - public String getExternalFilePath() { - return this.extFilePath; + public URI getExternalUri() { + return this.extUri; } /** @@ -167,13 +158,13 @@ public class AFPResourceLevel { * * @param filePath the external resource group file */ - public void setExternalFilePath(String filePath) { - this.extFilePath = filePath; + public void setExternalUri(URI uri) { + this.extUri = uri; } /** {@inheritDoc} */ public String toString() { - return NAMES[level] + (isExternal() ? ", file=" + extFilePath : ""); + return resourceType + (isExternal() ? ", uri=" + extUri : ""); } /** {@inheritDoc} */ @@ -186,16 +177,16 @@ public class AFPResourceLevel { } AFPResourceLevel rl = (AFPResourceLevel)obj; - return (level == rl.level) - && (extFilePath == rl.extFilePath - || extFilePath != null && extFilePath.equals(rl.extFilePath)); + return (resourceType == rl.resourceType) + && (extUri == rl.extUri + || extUri != null && extUri.equals(rl.extUri)); } /** {@inheritDoc} */ public int hashCode() { int hash = 7; - hash = 31 * hash + level; - hash = 31 * hash + (null == extFilePath ? 0 : extFilePath.hashCode()); + hash = 31 * hash + resourceType.hashCode(); + hash = 31 * hash + (null == extUri ? 0 : extUri.hashCode()); return hash; } } diff --git a/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java b/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java index 8cb0ebaaf..aea97cb7d 100644 --- a/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java +++ b/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java @@ -22,6 +22,7 @@ package org.apache.fop.afp; import java.util.Iterator; import java.util.Map; +import org.apache.fop.afp.AFPResourceLevel.ResourceType; import org.apache.fop.afp.modca.ResourceObject; /** @@ -58,7 +59,7 @@ public class AFPResourceLevelDefaults { // level not explicitly set/changed so default to inline for GOCA graphic objects // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine) setDefaultResourceLevel(ResourceObject.TYPE_GRAPHIC, - new AFPResourceLevel(AFPResourceLevel.INLINE)); + new AFPResourceLevel(ResourceType.INLINE)); } /** diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java index 89341588c..d6f7202b1 100644 --- a/src/java/org/apache/fop/afp/AFPResourceManager.java +++ b/src/java/org/apache/fop/afp/AFPResourceManager.java @@ -31,6 +31,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.afp.AFPResourceLevel.ResourceType; import org.apache.fop.afp.fonts.AFPFont; import org.apache.fop.afp.fonts.CharacterSet; import org.apache.fop.afp.modca.AbstractNamedAFPObject; @@ -41,8 +42,9 @@ import org.apache.fop.afp.modca.PageSegment; import org.apache.fop.afp.modca.Registry; import org.apache.fop.afp.modca.ResourceGroup; import org.apache.fop.afp.modca.ResourceObject; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.afp.util.AFPResourceUtil; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.apps.io.URIResolverWrapper; /** * Manages the creation and storage of document resources @@ -78,9 +80,9 @@ public class AFPResourceManager { /** * Main constructor */ - public AFPResourceManager() { + public AFPResourceManager(URIResolverWrapper uriResolverWrapper) { this.factory = new Factory(); - this.streamer = new AFPStreamer(factory); + this.streamer = new AFPStreamer(factory, uriResolverWrapper); this.dataObjectFactory = new AFPDataObjectFactory(factory); } @@ -123,8 +125,8 @@ public class AFPResourceManager { * @param filePath the default resource group file path */ - public void setDefaultResourceGroupFilePath(String filePath) { - streamer.setDefaultResourceGroupFilePath(filePath); + public void setDefaultResourceGroupUri(URI uri) { + streamer.setDefaultResourceGroupUri(uri); } /** @@ -257,7 +259,7 @@ public class AFPResourceManager { if (afpFont.isEmbeddable()) { //Embed fonts (char sets and code pages) if (charSet.getResourceAccessor() != null) { - ResourceAccessor accessor = charSet.getResourceAccessor(); + AFPResourceAccessor accessor = charSet.getResourceAccessor(); createIncludedResource( charSet.getName(), accessor, ResourceObject.TYPE_FONT_CHARACTER_SET); @@ -284,7 +286,7 @@ public class AFPResourceManager { * @param resourceObjectType the resource object type ({@link ResourceObject}.*) * @throws IOException if an I/O error occurs while loading the resource */ - public void createIncludedResource(String resourceName, ResourceAccessor accessor, + public void createIncludedResource(String resourceName, AFPResourceAccessor accessor, byte resourceObjectType) throws IOException { URI uri; try { @@ -305,9 +307,9 @@ public class AFPResourceManager { * @param resourceObjectType the resource object type ({@link ResourceObject}.*) * @throws IOException if an I/O error occurs while loading the resource */ - public void createIncludedResource(String resourceName, URI uri, ResourceAccessor accessor, + public void createIncludedResource(String resourceName, URI uri, AFPResourceAccessor accessor, byte resourceObjectType) throws IOException { - AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE); + AFPResourceLevel resourceLevel = new AFPResourceLevel(ResourceType.PRINT_FILE); AFPResourceInfo resourceInfo = new AFPResourceInfo(); resourceInfo.setLevel(resourceLevel); @@ -343,9 +345,9 @@ public class AFPResourceManager { * @throws IOException if an I/O error occurs while loading the resource */ public void createIncludedResourceFromExternal(final String resourceName, - final URI uri, final ResourceAccessor accessor) throws IOException { + final URI uri, final AFPResourceAccessor accessor) throws IOException { - AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE); + AFPResourceLevel resourceLevel = new AFPResourceLevel(ResourceType.PRINT_FILE); AFPResourceInfo resourceInfo = new AFPResourceInfo(); resourceInfo.setLevel(resourceLevel); diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java index 65686b92a..3edcd1265 100644 --- a/src/java/org/apache/fop/afp/AFPStreamer.java +++ b/src/java/org/apache/fop/afp/AFPStreamer.java @@ -20,20 +20,23 @@ package org.apache.fop.afp; import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; -import java.io.RandomAccessFile; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.afp.modca.ResourceGroup; import org.apache.fop.afp.modca.StreamedResourceGroup; +import org.apache.fop.apps.io.URIResolverWrapper; /** * Manages the streaming of the AFP output @@ -42,34 +45,28 @@ public class AFPStreamer implements Streamable { /** Static logging instance */ private static final Log LOG = LogFactory.getLog(AFPStreamer.class); - private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_"; - - private static final int BUFFER_SIZE = 4096; // 4k writing buffer - private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp"; - private final Factory factory; + private final URIResolverWrapper uriResolverWrapper; + /** A mapping of external resource destinations to resource groups */ - private final Map/**/pathResourceGroupMap - = new java.util.HashMap/**/(); + private final Map pathResourceGroupMap = new HashMap(); private StreamedResourceGroup printFileResourceGroup; /** Sets the default resource group file path */ - private String defaultResourceGroupFilePath = DEFAULT_EXTERNAL_RESOURCE_FILENAME; + private URI defaultResourceGroupUri; - private File tempFile; + private final URI tempUri; /** temporary document outputstream */ - private OutputStream documentOutputStream; + private OutputStream tempOutputStream; /** the final outputstream */ private OutputStream outputStream; - private RandomAccessFile documentFile; - private DataStream dataStream; /** @@ -77,8 +74,12 @@ public class AFPStreamer implements Streamable { * * @param factory a factory */ - public AFPStreamer(Factory factory) { + public AFPStreamer(Factory factory, URIResolverWrapper uriResolverWrapper) { this.factory = factory; + this.uriResolverWrapper = uriResolverWrapper; + this.tempUri = TempUriGenerator.INSTANCE.generate(); + defaultResourceGroupUri = URI.create(DEFAULT_EXTERNAL_RESOURCE_FILENAME); + } /** @@ -89,11 +90,8 @@ public class AFPStreamer implements Streamable { * @throws IOException thrown if an I/O exception of some sort has occurred */ public DataStream createDataStream(AFPPaintingState paintingState) throws IOException { - this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null); - this.documentFile = new RandomAccessFile(tempFile, "rw"); - this.documentOutputStream = new BufferedOutputStream( - new FileOutputStream(documentFile.getFD())); - this.dataStream = factory.createDataStream(paintingState, documentOutputStream); + this.tempOutputStream = new BufferedOutputStream(uriResolverWrapper.resolveOut(tempUri)); + this.dataStream = factory.createDataStream(paintingState, tempOutputStream); return dataStream; } @@ -102,8 +100,8 @@ public class AFPStreamer implements Streamable { * * @param filePath the default resource group file path */ - public void setDefaultResourceGroupFilePath(String filePath) { - this.defaultResourceGroupFilePath = filePath; + public void setDefaultResourceGroupUri(URI uri) { + this.defaultResourceGroupUri = uri; } /** @@ -118,23 +116,23 @@ public class AFPStreamer implements Streamable { return null; } if (level.isExternal()) { - String filePath = level.getExternalFilePath(); - if (filePath == null) { + URI uri = level.getExternalUri(); + if (uri == null) { LOG.warn("No file path provided for external resource, using default."); - filePath = defaultResourceGroupFilePath; + uri = defaultResourceGroupUri; } - resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath); + resourceGroup = pathResourceGroupMap.get(uri); if (resourceGroup == null) { OutputStream os = null; try { - os = new BufferedOutputStream(new FileOutputStream(filePath)); - } catch (FileNotFoundException fnfe) { - LOG.error("Failed to create/open external resource group file '" - + filePath + "'"); + os = new BufferedOutputStream(uriResolverWrapper.resolveOut(uri)); + } catch (IOException ioe) { + LOG.error("Failed to create/open external resource group for uri '" + + uri + "'"); } finally { if (os != null) { resourceGroup = factory.createStreamedResourceGroup(os); - pathResourceGroupMap.put(filePath, resourceGroup); + pathResourceGroupMap.put(uri, resourceGroup); } } } @@ -156,34 +154,20 @@ public class AFPStreamer implements Streamable { * * @throws IOException if an an I/O exception of some sort has occurred */ - // write out any external resource groups + // write out any external resource groups public void close() throws IOException { Iterator it = pathResourceGroupMap.values().iterator(); while (it.hasNext()) { StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next(); resourceGroup.close(); } - // close any open print-file resource group if (printFileResourceGroup != null) { printFileResourceGroup.close(); } - // write out document writeToStream(outputStream); - outputStream.close(); - - - if (documentOutputStream != null) { - documentOutputStream.close(); - } - - if (documentFile != null) { - documentFile.close(); - } - // delete temporary file - tempFile.delete(); } /** @@ -197,28 +181,32 @@ public class AFPStreamer implements Streamable { /** {@inheritDoc} */ public void writeToStream(OutputStream os) throws IOException { -// long start = System.currentTimeMillis(); - int len = (int)documentFile.length(); - int numChunks = len / BUFFER_SIZE; - int remainingChunkSize = len % BUFFER_SIZE; - byte[] buffer; - - documentFile.seek(0); - if (numChunks > 0) { - buffer = new byte[BUFFER_SIZE]; - for (int i = 0; i < numChunks; i++) { - documentFile.read(buffer, 0, BUFFER_SIZE); - os.write(buffer, 0, BUFFER_SIZE); - } - } else { - buffer = new byte[remainingChunkSize]; + tempOutputStream.close(); + InputStream tempInputStream = uriResolverWrapper.resolveIn(tempUri); + IOUtils.copy(tempInputStream, os); + //TODO this should notify the stream provider that it is safe to delete the temp data + tempInputStream.close(); + os.flush(); + } + + private static final class TempUriGenerator { + + private static final TempUriGenerator INSTANCE = new TempUriGenerator(); + + private static final String AFPDATASTREAM_TEMP_URL_PREFIX = "tmp:///AFPDataStream_"; + + private final AtomicLong counter; + + private TempUriGenerator() { + counter = new AtomicLong(); } - if (remainingChunkSize > 0) { - documentFile.read(buffer, 0, remainingChunkSize); - os.write(buffer, 0, remainingChunkSize); + + public URI generate() { + try { + return new URI(AFPDATASTREAM_TEMP_URL_PREFIX + counter.getAndIncrement()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } - os.flush(); -// long end = System.currentTimeMillis(); -// log.debug("writing time " + (end - start) + "ms"); } } diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java index fad5e95e6..8881a2649 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java @@ -30,7 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.AFPEventProducer; import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.afp.util.StringUtils; /** @@ -77,7 +77,7 @@ public class CharacterSet { protected final String name; /** The path to the installed fonts */ - private final ResourceAccessor accessor; + private final AFPResourceAccessor accessor; /** The current orientation (currently only 0 is supported by FOP) */ private final String currentOrientation = "0"; @@ -100,7 +100,7 @@ public class CharacterSet { * @param eventProducer for handling AFP related events */ CharacterSet(String codePage, String encoding, CharacterSetType charsetType, String name, - ResourceAccessor accessor, AFPEventProducer eventProducer) { + AFPResourceAccessor accessor, AFPEventProducer eventProducer) { if (name.length() > MAX_NAME_LEN) { String msg = "Character set name '" + name + "' must be a maximum of " + MAX_NAME_LEN + " characters"; @@ -211,7 +211,7 @@ public class CharacterSet { * Returns the resource accessor to load the font resources with. * @return the resource accessor to load the font resources with */ - public ResourceAccessor getResourceAccessor() { + public AFPResourceAccessor getResourceAccessor() { return this.accessor; } diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java index 18eaf41ee..3cada1ed3 100644 --- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java +++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java @@ -19,9 +19,9 @@ package org.apache.fop.afp.fonts; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -38,7 +38,7 @@ import org.apache.xmlgraphics.image.loader.util.SoftMapCache; import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.AFPEventProducer; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.afp.util.StructuredFieldReader; import org.apache.fop.fonts.Typeface; @@ -138,28 +138,24 @@ public abstract class CharacterSetBuilder { * Returns an InputStream to a given file path and filename * * * @param accessor the resource accessor - * @param filename the file name + * @param uriStr the URI * @param eventProducer for handling AFP related events * @return an inputStream - * * @throws IOException in the event that an I/O exception of some sort has occurred */ - protected InputStream openInputStream(ResourceAccessor accessor, String filename, + protected InputStream openInputStream(AFPResourceAccessor accessor, String uriStr, AFPEventProducer eventProducer) throws IOException { URI uri; try { - uri = new URI(filename.trim()); + uri = new URI(uriStr.trim()); } catch (URISyntaxException e) { - throw new FileNotFoundException("Invalid filename: " - + filename + " (" + e.getMessage() + ")"); + throw new MalformedURLException("Invalid uri: " + uriStr + " (" + e.getMessage() + ")"); } - if (LOG.isDebugEnabled()) { LOG.debug("Opening " + uri); } - InputStream inputStream = accessor.createInputStream(uri); - return inputStream; + return accessor.createInputStream(uri); } /** @@ -191,7 +187,7 @@ public abstract class CharacterSetBuilder { * @throws IOException if an I/O error occurs */ public CharacterSet buildSBCS(String characterSetName, String codePageName, String encoding, - ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { + AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { return processFont(characterSetName, codePageName, encoding, CharacterSetType.SINGLE_BYTE, accessor, eventProducer); } @@ -211,7 +207,7 @@ public abstract class CharacterSetBuilder { * @throws IOException if an I/O error occurs */ public CharacterSet buildDBCS(String characterSetName, String codePageName, String encoding, - CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer) + CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { return processFont(characterSetName, codePageName, encoding, charsetType, accessor, eventProducer); @@ -236,7 +232,7 @@ public abstract class CharacterSetBuilder { } private CharacterSet processFont(String characterSetName, String codePageName, String encoding, - CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer) + CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { // check for cached version of the characterset String descriptor = characterSetName + "_" + encoding + "_" + codePageName; @@ -329,7 +325,7 @@ public abstract class CharacterSetBuilder { * @throws IOException if an I/O exception of some sort has occurred. */ protected Map loadCodePage(String codePage, String encoding, - ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { + AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { // Create the HashMap to store code page information Map codePages = new HashMap(); @@ -337,7 +333,11 @@ public abstract class CharacterSetBuilder { InputStream inputStream = null; try { inputStream = openInputStream(accessor, codePage.trim(), eventProducer); - + } catch (IOException e) { + eventProducer.codePageNotFound(this, e); + throw e; + } + try { StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); byte[] data = structuredFieldReader.getNext(CHARACTER_TABLE_SF); @@ -367,8 +367,6 @@ public abstract class CharacterSetBuilder { position++; } } - } catch (FileNotFoundException e) { - eventProducer.codePageNotFound(this, e); } finally { closeInputStream(inputStream); } @@ -709,21 +707,21 @@ public abstract class CharacterSetBuilder { } protected Map loadCodePage(String codePage, String encoding, - ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { - + AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { // Create the HashMap to store code page information Map codePages = new HashMap(); - InputStream inputStream = null; try { inputStream = openInputStream(accessor, codePage.trim(), eventProducer); - - StructuredFieldReader structuredFieldReader - = new StructuredFieldReader(inputStream); + } catch (IOException e) { + eventProducer.codePageNotFound(this, e); + throw e; + } + try { + StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); byte[] data; while ((data = structuredFieldReader.getNext(CHARACTER_TABLE_SF)) != null) { int position = 0; - byte[] gcgiBytes = new byte[8]; byte[] charBytes = new byte[2]; // Read data, ignoring bytes 0 - 2 @@ -751,12 +749,9 @@ public abstract class CharacterSetBuilder { } } } - } catch (FileNotFoundException e) { - eventProducer.codePageNotFound(this, e); } finally { closeInputStream(inputStream); } - return codePages; } diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java index f83c38621..7c2b68506 100644 --- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java +++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java @@ -20,7 +20,7 @@ package org.apache.fop.afp.fonts; import org.apache.fop.afp.AFPEventProducer; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.fonts.Typeface; /** @@ -42,7 +42,7 @@ public class FopCharacterSet extends CharacterSet { */ public FopCharacterSet(String codePage, String encoding, String name, Typeface charSet, AFPEventProducer eventProducer) { - super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, (ResourceAccessor) null, + super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, (AFPResourceAccessor) null, eventProducer); this.charSet = charSet; } diff --git a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java index dc841bd40..0d6e0bc09 100644 --- a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java +++ b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java @@ -27,7 +27,7 @@ import java.net.URI; import org.apache.commons.io.IOUtils; import org.apache.fop.afp.util.AFPResourceUtil; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; /** @@ -35,7 +35,7 @@ import org.apache.fop.afp.util.ResourceAccessor; */ public class IncludedResourceObject extends AbstractNamedAFPObject { - private ResourceAccessor resourceAccessor; + private AFPResourceAccessor resourceAccessor; private URI uri; /** @@ -45,7 +45,7 @@ public class IncludedResourceObject extends AbstractNamedAFPObject { * @param uri the URI of the external file */ public IncludedResourceObject(String name, - ResourceAccessor resourceAccessor, URI uri) { + AFPResourceAccessor resourceAccessor, URI uri) { super(name); this.resourceAccessor = resourceAccessor; this.uri = uri; diff --git a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java similarity index 83% rename from src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java rename to src/java/org/apache/fop/afp/util/AFPResourceAccessor.java index a9dc533e6..4200e8d36 100644 --- a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java +++ b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java @@ -24,14 +24,12 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.io.URIResolverWrapper; /** - * Default implementation of the {@link ResourceAccessor} interface for use inside FOP. + * Defines an interface through which external resource objects can be accessed. */ -public class DefaultFOPResourceAccessor extends SimpleResourceAccessor { +public final class AFPResourceAccessor { private final URIResolverWrapper resolver; private final String baseURI; @@ -46,14 +44,12 @@ public class DefaultFOPResourceAccessor extends SimpleResourceAccessor { * @param categoryBaseURI the category base URI (may be null) * @param baseURI the custom base URI to resolve relative URIs against (may be null) */ - public DefaultFOPResourceAccessor(URIResolverWrapper resolver, String baseURI) { - super(resolver.getBaseURI()); + public AFPResourceAccessor(URIResolverWrapper resolver, String baseURI) { this.resolver = resolver; this.baseURI = baseURI; } - public DefaultFOPResourceAccessor(URIResolverWrapper resolver) { - super(resolver.getBaseURI()); + public AFPResourceAccessor(URIResolverWrapper resolver) { this.resolver = resolver; this.baseURI = null; } @@ -74,4 +70,5 @@ public class DefaultFOPResourceAccessor extends SimpleResourceAccessor { public InputStream createInputStream(URI uri) throws IOException { return resolver.resolveIn(getResourceURI(uri)); } + } diff --git a/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java b/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java deleted file mode 100644 index 7a963928b..000000000 --- a/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java +++ /dev/null @@ -1,76 +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.afp.util; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URL; - -/** - * Simple implementation of the {@link ResourceAccessor} interface for access relative to a - * base URI. - */ -public class SimpleResourceAccessor implements ResourceAccessor { - - private URI baseURI; - - /** - * Creates a new simple resource accessor. - * @param baseURI the base URI to resolve relative URIs against (may be null) - */ - public SimpleResourceAccessor(URI baseURI) { - this.baseURI = baseURI; - } - - /** - * Creates a new simple resource accessor. - * @param baseDir the base directory to resolve relative filenames against (may be null) - */ - public SimpleResourceAccessor(File baseDir) { - this(baseDir != null ? baseDir.toURI() : null); - } - - /** - * Returns the base URI. - * @return the base URI (or null if no base URI was set) - */ - public URI getBaseURI() { - return this.baseURI; - } - - /** - * Resolve the given URI against the baseURI. - * @param uri the URI to resolve - * @return the resolved URI - */ - protected URI resolveAgainstBase(URI uri) { - return (getBaseURI() != null ? getBaseURI().resolve(uri) : uri); - } - - /** {@inheritDoc} */ - public InputStream createInputStream(URI uri) throws IOException { - URI resolved = resolveAgainstBase(uri); - URL url = resolved.toURL(); - return url.openStream(); - } - -} diff --git a/src/java/org/apache/fop/apps/FopConfParser.java b/src/java/org/apache/fop/apps/FopConfParser.java index 4ab788701..b095d8f74 100644 --- a/src/java/org/apache/fop/apps/FopConfParser.java +++ b/src/java/org/apache/fop/apps/FopConfParser.java @@ -39,8 +39,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.util.Penalty; -import org.apache.fop.apps.io.DefaultResourceResolver; import org.apache.fop.apps.io.ResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.URIResolverWrapper; import org.apache.fop.fonts.FontManagerConfigurator; import org.apache.fop.hyphenation.HyphenationTreeCache; @@ -107,7 +107,7 @@ public class FopConfParser { */ public FopConfParser(InputStream fopConfStream, URI defaultBaseURI) throws SAXException, IOException { - this(fopConfStream, defaultBaseURI, new DefaultResourceResolver()); + this(fopConfStream, defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver()); } /** @@ -118,7 +118,7 @@ public class FopConfParser { * @throws IOException if an I/O error is thrown while parsing the FOP conf */ public FopConfParser(File fopConfFile) throws SAXException, IOException { - this(fopConfFile, new DefaultResourceResolver()); + this(fopConfFile, ResourceResolverFactory.createDefaultResourceResolver()); } /** diff --git a/src/java/org/apache/fop/apps/FopFactoryBuilder.java b/src/java/org/apache/fop/apps/FopFactoryBuilder.java index b2d134db0..013b15efe 100644 --- a/src/java/org/apache/fop/apps/FopFactoryBuilder.java +++ b/src/java/org/apache/fop/apps/FopFactoryBuilder.java @@ -33,9 +33,9 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.fop.apps.io.DefaultResourceResolver; import org.apache.fop.apps.io.FOURIResolver; import org.apache.fop.apps.io.ResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.fonts.FontManager; import org.apache.fop.hyphenation.HyphenationTreeResolver; import org.apache.fop.layoutmgr.LayoutManagerMaker; @@ -70,7 +70,7 @@ public final class FopFactoryBuilder { * @param defaultBaseURI the default base URI for resolving URIs against */ public FopFactoryBuilder(URI defaultBaseURI) { - this(defaultBaseURI, new DefaultResourceResolver()); + this(defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver()); } /** diff --git a/src/java/org/apache/fop/apps/io/DefaultResourceResolver.java b/src/java/org/apache/fop/apps/io/DefaultResourceResolver.java deleted file mode 100644 index af04f218a..000000000 --- a/src/java/org/apache/fop/apps/io/DefaultResourceResolver.java +++ /dev/null @@ -1,49 +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.apps.io; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URI; - - -public class DefaultResourceResolver implements ResourceResolver { - - public Resource getResource(URI uri) throws IOException { - try { - return new Resource(uri.toURL().openStream()); - } catch (MalformedURLException mue) { - throw new RuntimeException(mue); - } - } - - public OutputStream getOutputStream(URI uri) throws IOException { - throw new UnsupportedOperationException(); - } - - public static URIResolverWrapper createDefaultWrapper() { - // Not sure if this is the right place for this, but I don't have any better ideas as of yet - URI thisUri = new File(".").getAbsoluteFile().toURI(); - return new URIResolverWrapper(thisUri, new DefaultResourceResolver()); - } - -} diff --git a/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java new file mode 100644 index 000000000..6e9484c82 --- /dev/null +++ b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java @@ -0,0 +1,238 @@ +/* + * 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.apps.io; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class ResourceResolverFactory { + + private ResourceResolverFactory() { + } + + public static ResourceResolver createDefaultResourceResolver() { + return DefaultResourceResolver.INSTANCE; + } + + public static ResourceResolver createTempAwareResourceResolver(TempResourceResolver tempResourceResolver, + ResourceResolver defaultResourceResolver) { + return new TempAwareResourceResolver(tempResourceResolver, defaultResourceResolver); + } + + public static URIResolverWrapper createDefaultWrapper() { + // Not sure if this is the right place for this, but I don't have any better ideas as of yet + URI thisUri = new File(".").getAbsoluteFile().toURI(); + return new URIResolverWrapper(thisUri, new DefaultResourceResolver()); + } + + public static SchemaAwareResourceResolverBuilder createSchemaAwareResourceResolverBuilder( + ResourceResolver defaultResolver) { + return new SchemaAwareResourceResolverBuilderImpl(defaultResolver); + } + + + + private static final class DefaultResourceResolver implements ResourceResolver { + + private static final ResourceResolver INSTANCE = new DefaultResourceResolver(); + + private final TempAwareResourceResolver delegate; + + private DefaultResourceResolver() { + delegate = new TempAwareResourceResolver(new DefaultTempResourceResolver(), + new NormalResourceResolver()); + } + + public Resource getResource(URI uri) throws IOException { + return delegate.getResource(uri); + } + + public OutputStream getOutputStream(URI uri) throws IOException { + return delegate.getOutputStream(uri); + } + + } + + private static final class TempAwareResourceResolver implements ResourceResolver { + + private final TempResourceResolver tempResourceResolver; + + private final ResourceResolver defaultResourceResolver; + + public TempAwareResourceResolver(TempResourceResolver tempResourceHandler, + ResourceResolver defaultResourceResolver) { + this.tempResourceResolver = tempResourceHandler; + this.defaultResourceResolver = defaultResourceResolver; + } + + private static boolean isTempUri(URI uri) { + return "tmp".equals(uri.getScheme()); + } + + public Resource getResource(URI uri) throws IOException { + if (isTempUri(uri)) { + return tempResourceResolver.getResource(uri.getPath()); + } else { + return defaultResourceResolver.getResource(uri); + } + } + + public OutputStream getOutputStream(URI uri) throws IOException { + if (isTempUri(uri)) { + return tempResourceResolver.getOutputStream(uri.getPath()); + } else { + return defaultResourceResolver.getOutputStream(uri); + } + } + + } + + private static class DefaultTempResourceResolver implements TempResourceResolver { + private static File getTempFile(String path) throws IOException { + File file = new File(System.getProperty("java.io.tmpdir"), path); + file.deleteOnExit(); + return file; + } + + public Resource getResource(String id) throws IOException { + return new Resource(getTempFile(id).toURI().toURL().openStream()); + } + + public OutputStream getOutputStream(String id) throws IOException { + File file = getTempFile(id); + // TODO handle error + file.createNewFile(); + return new FileOutputStream(file); + } + } + + private static class NormalResourceResolver implements ResourceResolver { + public Resource getResource(URI uri) throws IOException { + return new Resource(uri.toURL().openStream()); + } + + public OutputStream getOutputStream(URI uri) throws IOException { + return new FileOutputStream(new File(uri)); + } + } + + private static final class SchemaAwareResourceResolver implements ResourceResolver { + + private final Map schemaHandlingResourceResolvers; + + private final ResourceResolver defaultResolver; + + private SchemaAwareResourceResolver(Map schemaHandlingResourceResolvers, + ResourceResolver defaultResolver) { + this.schemaHandlingResourceResolvers = schemaHandlingResourceResolvers; + this.defaultResolver = defaultResolver; + } + + private ResourceResolver getResourceResolverForSchema(URI uri) { + String schema = uri.getScheme(); + if (schemaHandlingResourceResolvers.containsKey(schema)) { + return schemaHandlingResourceResolvers.get(schema); + } else { + return defaultResolver; + } + } + + public Resource getResource(URI uri) throws IOException { + return getResourceResolverForSchema(uri).getResource(uri); + } + + public OutputStream getOutputStream(URI uri) throws IOException { + return getResourceResolverForSchema(uri).getOutputStream(uri); + } + } + + public interface SchemaAwareResourceResolverBuilder { + + void registerResourceResolverForSchema(String schema, ResourceResolver resourceResolver); + + ResourceResolver build(); + } + + private static final class CompletedSchemaAwareResourceResolverBuilder + implements SchemaAwareResourceResolverBuilder { + + private static final SchemaAwareResourceResolverBuilder INSTANCE + = new CompletedSchemaAwareResourceResolverBuilder(); + + public ResourceResolver build() { + throw new IllegalStateException("Resource resolver already built"); + } + + public void registerResourceResolverForSchema(String schema, + ResourceResolver resourceResolver) { + throw new IllegalStateException("Resource resolver already built"); + } + } + + private static final class ActiveSchemaAwareResourceResolverBuilder + implements SchemaAwareResourceResolverBuilder { + + private final Map schemaHandlingResourceResolvers + = new HashMap(); + + private final ResourceResolver defaultResolver; + + private ActiveSchemaAwareResourceResolverBuilder(ResourceResolver defaultResolver) { + this.defaultResolver = defaultResolver; + } + + public void registerResourceResolverForSchema(String schema, ResourceResolver resourceResolver) { + schemaHandlingResourceResolvers.put(schema, resourceResolver); + } + + public ResourceResolver build() { + return new SchemaAwareResourceResolver( + Collections.unmodifiableMap(schemaHandlingResourceResolvers), defaultResolver); + } + + } + + private static final class SchemaAwareResourceResolverBuilderImpl + implements SchemaAwareResourceResolverBuilder { + + private SchemaAwareResourceResolverBuilder delegate; + + private SchemaAwareResourceResolverBuilderImpl(ResourceResolver defaultResolver) { + this.delegate = new ActiveSchemaAwareResourceResolverBuilder(defaultResolver); + } + + public void registerResourceResolverForSchema(String schema, ResourceResolver resourceResolver) { + delegate.registerResourceResolverForSchema(schema, resourceResolver); + } + + public ResourceResolver build() { + ResourceResolver resourceResolver = delegate.build(); + delegate = CompletedSchemaAwareResourceResolverBuilder.INSTANCE; + return resourceResolver; + } + } + +} diff --git a/src/java/org/apache/fop/afp/util/ResourceAccessor.java b/src/java/org/apache/fop/apps/io/TempResourceResolver.java similarity index 60% rename from src/java/org/apache/fop/afp/util/ResourceAccessor.java rename to src/java/org/apache/fop/apps/io/TempResourceResolver.java index 6b9995c44..ab9b4d75f 100644 --- a/src/java/org/apache/fop/afp/util/ResourceAccessor.java +++ b/src/java/org/apache/fop/apps/io/TempResourceResolver.java @@ -17,24 +17,14 @@ /* $Id$ */ -package org.apache.fop.afp.util; +package org.apache.fop.apps.io; import java.io.IOException; -import java.io.InputStream; -import java.net.URI; +import java.io.OutputStream; -/** - * Defines an interface through which external resource objects can be accessed. - */ -public interface ResourceAccessor { +public interface TempResourceResolver { - /** - * Creates a new {@link InputStream} for the given URI that allows read access to an external - * resource. - * @param uri the URI of an external resource. - * @return the new input stream - * @throws IOException if an I/O error occurs while opening the resource - */ - InputStream createInputStream(URI uri) throws IOException; + Resource getResource(String id) throws IOException; + OutputStream getOutputStream(String id) throws IOException; } diff --git a/src/java/org/apache/fop/pdf/PDFResources.java b/src/java/org/apache/fop/pdf/PDFResources.java index e7dcccabe..cded7c00a 100644 --- a/src/java/org/apache/fop/pdf/PDFResources.java +++ b/src/java/org/apache/fop/pdf/PDFResources.java @@ -23,8 +23,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java index e0924c0d0..1bdb18cf2 100644 --- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java +++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java @@ -19,6 +19,8 @@ package org.apache.fop.render.afp; +import java.net.URI; + import org.apache.fop.afp.AFPResourceLevelDefaults; /** @@ -152,10 +154,10 @@ public interface AFPCustomizable { boolean isStrokeGOCAText(); /** - * Sets the default resource group file path - * @param filePath the default resource group file path + * Sets the default resource group URI + * @param uri the default resource group URI */ - void setDefaultResourceGroupFilePath(String filePath); + void setDefaultResourceGroupUri(URI uri); /** * Sets the resource level defaults. The object passed in provides information which resource diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index 6f7899c86..c1432041a 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -23,6 +23,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.geom.AffineTransform; import java.io.IOException; +import java.net.URI; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -38,8 +39,7 @@ import org.apache.fop.afp.DataStream; import org.apache.fop.afp.fonts.AFPFontCollection; import org.apache.fop.afp.fonts.AFPPageFonts; import org.apache.fop.afp.modca.ResourceObject; -import org.apache.fop.afp.util.DefaultFOPResourceAccessor; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.FontCollection; import org.apache.fop.fonts.FontEventAdapter; @@ -104,7 +104,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler */ public AFPDocumentHandler(IFContext context) { super(context); - this.resourceManager = new AFPResourceManager(); + this.resourceManager = new AFPResourceManager(context.getUserAgent().getNewURIResolver()); this.paintingState = new AFPPaintingState(); this.unitConv = paintingState.getUnitConverter(); } @@ -385,7 +385,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } } else if (extension instanceof AFPIncludeFormMap) { AFPIncludeFormMap formMap = (AFPIncludeFormMap)extension; - ResourceAccessor accessor = new DefaultFOPResourceAccessor( + AFPResourceAccessor accessor = new AFPResourceAccessor( getUserAgent().getNewURIResolver()); try { getResourceManager().createIncludedResource(formMap.getName(), @@ -497,9 +497,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler return paintingState.getFS45(); } - /** {@inheritDoc} */ - public void setDefaultResourceGroupFilePath(String filePath) { - resourceManager.setDefaultResourceGroupFilePath(filePath); + public void setDefaultResourceGroupUri(URI uri) { + resourceManager.setDefaultResourceGroupUri(uri); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/afp/AFPFontConfig.java b/src/java/org/apache/fop/render/afp/AFPFontConfig.java index 42c3be54a..0eae4e262 100644 --- a/src/java/org/apache/fop/render/afp/AFPFontConfig.java +++ b/src/java/org/apache/fop/render/afp/AFPFontConfig.java @@ -38,8 +38,7 @@ import org.apache.fop.afp.fonts.CharacterSetType; import org.apache.fop.afp.fonts.DoubleByteFont; import org.apache.fop.afp.fonts.OutlineFont; import org.apache.fop.afp.fonts.RasterFont; -import org.apache.fop.afp.util.DefaultFOPResourceAccessor; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.io.URIResolverWrapper; import org.apache.fop.events.EventProducer; @@ -306,8 +305,8 @@ public final class AFPFontConfig implements FontConfig { abstract AFPFontInfo getFontInfo(URIResolverWrapper resolver, AFPEventProducer eventProducer) throws IOException; - ResourceAccessor getAccessor(URIResolverWrapper resolver) { - return new DefaultFOPResourceAccessor(resolver, uri); + AFPResourceAccessor getAccessor(URIResolverWrapper resolver) { + return new AFPResourceAccessor(resolver, uri); } } @@ -327,7 +326,7 @@ public final class AFPFontConfig implements FontConfig { @Override AFPFontInfo getFontInfo(URIResolverWrapper resolver, AFPEventProducer eventProducer) throws IOException { - ResourceAccessor accessor = getAccessor(resolver); + AFPResourceAccessor accessor = getAccessor(resolver); CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS( characterset, super.codePage, super.encoding, charsetType, accessor, eventProducer); return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet), @@ -371,7 +370,7 @@ public final class AFPFontConfig implements FontConfig { LOG.error(msg); } } else { - ResourceAccessor accessor = getAccessor(resolver); + AFPResourceAccessor accessor = getAccessor(resolver); characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS( characterset, super.codePage, super.encoding, accessor, eventProducer); } @@ -416,7 +415,7 @@ public final class AFPFontConfig implements FontConfig { LOG.error(msg); } } else { - ResourceAccessor accessor = getAccessor(resolver); + AFPResourceAccessor accessor = getAccessor(resolver); rasterFont.addCharacterSet(charset.size, CharacterSetBuilder.getSingleByteInstance().buildSBCS(charset.characterset, super.codePage, super.encoding, accessor, eventProducer)); diff --git a/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java index a03aaf816..5f155e277 100644 --- a/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java +++ b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java @@ -19,7 +19,7 @@ package org.apache.fop.render.afp; -import java.io.File; +import java.net.URI; import java.util.Map; import org.apache.commons.logging.Log; @@ -46,7 +46,7 @@ public class AFPForeignAttributeReader { AFPElementMapping.NAMESPACE, "afp:resource-level"); /** the resource-group-file attribute */ - public static final QName RESOURCE_GROUP_FILE = new QName( + public static final QName RESOURCE_GROUP_URI = new QName( AFPElementMapping.NAMESPACE, "afp:resource-group-file"); /** @@ -64,7 +64,7 @@ public class AFPForeignAttributeReader { public AFPResourceInfo getResourceInfo(Map/**/ foreignAttributes) { AFPResourceInfo resourceInfo = new AFPResourceInfo(); if (foreignAttributes != null && !foreignAttributes.isEmpty()) { - String resourceName = (String)foreignAttributes.get(RESOURCE_NAME); + String resourceName = (String) foreignAttributes.get(RESOURCE_NAME); if (resourceName != null) { resourceInfo.setName(resourceName); } @@ -82,45 +82,20 @@ public class AFPForeignAttributeReader { * @param foreignAttributes the foreign attributes * @return the resource level */ - public AFPResourceLevel getResourceLevel(Map/**/ foreignAttributes) { + public AFPResourceLevel getResourceLevel(Map foreignAttributes) { AFPResourceLevel resourceLevel = null; if (foreignAttributes != null && !foreignAttributes.isEmpty()) { if (foreignAttributes.containsKey(RESOURCE_LEVEL)) { - String levelString = (String)foreignAttributes.get(RESOURCE_LEVEL); + String levelString = foreignAttributes.get(RESOURCE_LEVEL); resourceLevel = AFPResourceLevel.valueOf(levelString); // if external get resource group file attributes if (resourceLevel != null && resourceLevel.isExternal()) { - String resourceGroupFile - = (String)foreignAttributes.get(RESOURCE_GROUP_FILE); - if (resourceGroupFile == null) { - String msg = RESOURCE_GROUP_FILE + " not specified"; - LOG.error(msg); + String resourceGroupUri = foreignAttributes.get(RESOURCE_GROUP_URI); + if (resourceGroupUri == null) { + String msg = RESOURCE_GROUP_URI + " not specified"; throw new UnsupportedOperationException(msg); } - File resourceExternalGroupFile = new File(resourceGroupFile); - SecurityManager security = System.getSecurityManager(); - try { - if (security != null) { - security.checkWrite(resourceExternalGroupFile.getPath()); - } - } catch (SecurityException ex) { - String msg = "unable to gain write access to external resource file: " - + resourceGroupFile; - LOG.error(msg); - } - - try { - boolean exists = resourceExternalGroupFile.exists(); - if (exists) { - LOG.warn("overwriting external resource file: " - + resourceGroupFile); - } - resourceLevel.setExternalFilePath(resourceGroupFile); - } catch (SecurityException ex) { - String msg = "unable to gain read access to external resource file: " - + resourceGroupFile; - LOG.error(msg); - } + resourceLevel.setExternalUri(URI.create(resourceGroupUri)); } } } diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java index 834304f6b..68d806a1c 100644 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java @@ -42,6 +42,7 @@ import org.apache.fop.afp.AFPObjectAreaInfo; import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; import org.apache.fop.afp.AFPResourceLevel; +import org.apache.fop.afp.AFPResourceLevel.ResourceType; import org.apache.fop.afp.AFPResourceManager; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.image.loader.batik.BatikImageFlavors; @@ -142,7 +143,7 @@ public class AFPImageHandlerSVG implements ImageHandler { //level not explicitly set/changed so default to inline for GOCA graphic objects // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine) if (!resourceInfo.levelChanged()) { - resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); + resourceInfo.setLevel(new AFPResourceLevel(ResourceType.INLINE)); } } diff --git a/src/java/org/apache/fop/render/afp/AFPPainter.java b/src/java/org/apache/fop/render/afp/AFPPainter.java index 1f60ce440..1c4611d2b 100644 --- a/src/java/org/apache/fop/render/afp/AFPPainter.java +++ b/src/java/org/apache/fop/render/afp/AFPPainter.java @@ -30,11 +30,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Map; -import org.w3c.dom.Document; - -import org.apache.xmlgraphics.image.loader.ImageProcessingHints; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; - import org.apache.fop.afp.AFPBorderPainter; import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPUnitConverter; @@ -50,8 +45,7 @@ import org.apache.fop.afp.modca.AbstractPageObject; import org.apache.fop.afp.modca.PresentationTextObject; import org.apache.fop.afp.ptoca.PtocaBuilder; import org.apache.fop.afp.ptoca.PtocaProducer; -import org.apache.fop.afp.util.DefaultFOPResourceAccessor; -import org.apache.fop.afp.util.ResourceAccessor; +import org.apache.fop.afp.util.AFPResourceAccessor; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; @@ -66,6 +60,9 @@ import org.apache.fop.render.intermediate.IFUtil; import org.apache.fop.traits.BorderProps; import org.apache.fop.traits.RuleStyle; import org.apache.fop.util.CharUtilities; +import org.apache.xmlgraphics.image.loader.ImageProcessingHints; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; +import org.w3c.dom.Document; /** * IFPainter implementation that produces AFP (MO:DCA). @@ -205,7 +202,7 @@ public class AFPPainter extends AbstractIFPainter { //Do we need to embed an external page segment? if (pageSegment.getURI() != null) { - ResourceAccessor accessor = new DefaultFOPResourceAccessor ( + AFPResourceAccessor accessor = new AFPResourceAccessor( documentHandler.getUserAgent().getNewURIResolver()); try { URI resourceUri = new URI(pageSegment.getURI()); diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfig.java b/src/java/org/apache/fop/render/afp/AFPRendererConfig.java index b7331c5c5..f85357238 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfig.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfig.java @@ -19,8 +19,7 @@ package org.apache.fop.render.afp; -import java.io.File; -import java.io.IOException; +import java.net.URI; import java.util.EnumMap; import org.apache.avalon.framework.configuration.Configuration; @@ -59,7 +58,7 @@ import static org.apache.fop.render.afp.AFPRendererConfig.Options.JPEG_ALLOW_JPE import static org.apache.fop.render.afp.AFPRendererConfig.Options.JPEG_BITMAP_ENCODING_QUALITY; import static org.apache.fop.render.afp.AFPRendererConfig.Options.LINE_WIDTH_CORRECTION; import static org.apache.fop.render.afp.AFPRendererConfig.Options.RENDERER_RESOLUTION; -import static org.apache.fop.render.afp.AFPRendererConfig.Options.RESOURCE_GROUP_FILE; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.RESOURCE_GROUP_URI; import static org.apache.fop.render.afp.AFPRendererConfig.Options.SHADING; public final class AFPRendererConfig implements RendererConfig { @@ -110,7 +109,7 @@ public final class AFPRendererConfig implements RendererConfig { JPEG_ALLOW_JPEG_EMBEDDING("allow-embedding", Boolean.class), JPEG_BITMAP_ENCODING_QUALITY("bitmap-encoding-quality", Float.class), RENDERER_RESOLUTION("renderer-resolution", Integer.class), - RESOURCE_GROUP_FILE("resource-group-file", String.class), + RESOURCE_GROUP_URI("resource-group-file", URI.class), SHADING("shading", AFPShadingMode.class), LINE_WIDTH_CORRECTION("line-width-correction", Float.class), GOCA("goca", Boolean.class), @@ -179,8 +178,9 @@ public final class AFPRendererConfig implements RendererConfig { return getParam(RENDERER_RESOLUTION, Integer.class); } - public String getDefaultResourceGroupFilePath() { - return getParam(RESOURCE_GROUP_FILE, String.class); + + public URI getDefaultResourceGroupUri() { + return getParam(RESOURCE_GROUP_URI, URI.class); } public AFPResourceLevelDefaults getResourceLevelDefaults() { @@ -273,7 +273,7 @@ public final class AFPRendererConfig implements RendererConfig { private void configure() throws ConfigurationException, FOPException { configureImages(); - setParam(SHADING, AFPShadingMode.valueOf( + setParam(SHADING, AFPShadingMode.getValueOf( cfg.getChild(SHADING.getName()).getValue(AFPShadingMode.COLOR.getName()))); Configuration rendererResolutionCfg = cfg.getChild(RENDERER_RESOLUTION.getName(), false); setParam(RENDERER_RESOLUTION, rendererResolutionCfg == null ? 240 @@ -362,25 +362,14 @@ public final class AFPRendererConfig implements RendererConfig { private void createResourceGroupFile() throws FOPException { try { - Configuration resourceGroupFileCfg = cfg.getChild(RESOURCE_GROUP_FILE.getName(), false); - if (resourceGroupFileCfg != null) { - String resourceGroupDest = null; - resourceGroupDest = resourceGroupFileCfg.getValue(); - if (resourceGroupDest != null) { - File resourceGroupFile = new File(resourceGroupDest); - boolean created = resourceGroupFile.createNewFile(); - if (created && resourceGroupFile.canWrite()) { - setParam(RESOURCE_GROUP_FILE, resourceGroupDest); - } else { - LOG.warn("Unable to write to default external resource group file '" - + resourceGroupDest + "'"); - } - } + Configuration resourceGroupUriCfg = cfg.getChild(RESOURCE_GROUP_URI.getName(), false); + if (resourceGroupUriCfg != null) { + URI resourceGroupUri = URI.create(resourceGroupUriCfg.getValue()); + // TODO validate? + setParam(RESOURCE_GROUP_URI, resourceGroupUri); } } catch (ConfigurationException e) { LogUtil.handleException(LOG, e, strict); - } catch (IOException ioe) { - throw new FOPException("Could not create default external resource group file", ioe); } } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 243087d96..bd7d89095 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -92,16 +92,12 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator implement if (config.getResolution() != null) { documentHandler.setResolution(config.getResolution()); } - if (config.getDefaultResourceGroupFilePath() != null) { - documentHandler.setDefaultResourceGroupFilePath(config.getDefaultResourceGroupFilePath()); - } if (config.isWrapPseg() != null) { documentHandler.setWrapPSeg(config.isWrapPseg()); } if (config.isFs45() != null) { documentHandler.setFS45(config.isFs45()); } - if (config.allowJpegEmbedding() != null) { documentHandler.canEmbedJpeg(config.allowJpegEmbedding()); } @@ -117,6 +113,9 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator implement if (config.isStrokeGocaText() != null) { documentHandler.setStrokeGOCAText(config.isStrokeGocaText()); } + if (config.getDefaultResourceGroupUri() != null) { + documentHandler.setDefaultResourceGroupUri(config.getDefaultResourceGroupUri()); + } AFPResourceLevelDefaults resourceLevelDefaults = config.getResourceLevelDefaults(); if (resourceLevelDefaults != null) { documentHandler.setResourceLevelDefaults(resourceLevelDefaults); diff --git a/src/java/org/apache/fop/render/afp/AFPShadingMode.java b/src/java/org/apache/fop/render/afp/AFPShadingMode.java index b45c33a8e..c2ae21f74 100644 --- a/src/java/org/apache/fop/render/afp/AFPShadingMode.java +++ b/src/java/org/apache/fop/render/afp/AFPShadingMode.java @@ -22,15 +22,12 @@ package org.apache.fop.render.afp; import java.io.ObjectStreamException; import java.io.Serializable; -/** Enumeration class for the AFP shading mode. */ -public final class AFPShadingMode implements Serializable { - - private static final long serialVersionUID = 8579867898716480779L; - +/** Enumeration of the AFP shading modes. */ +public enum AFPShadingMode implements Serializable { /** the color mode (the default) */ - public static final AFPShadingMode COLOR = new AFPShadingMode("COLOR"); + COLOR("COLOR"), /** the dithered mode */ - public static final AFPShadingMode DITHERED = new AFPShadingMode("DITHERED"); + DITHERED("DITHERED"); private String name; @@ -52,7 +49,7 @@ public final class AFPShadingMode implements Serializable { * @param name the name of the enumeration value * @return the enumeration object */ - public static AFPShadingMode valueOf(String name) { + public static AFPShadingMode getValueOf(String name) { if (COLOR.getName().equalsIgnoreCase(name)) { return COLOR; } else if (DITHERED.getName().equalsIgnoreCase(name)) { @@ -70,5 +67,4 @@ public final class AFPShadingMode implements Serializable { public String toString() { return getClass().getName() + ":" + name; } - } diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java index efdd88081..9235431a6 100644 --- a/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java +++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java @@ -24,11 +24,14 @@ import java.util.List; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.io.URIResolverWrapper; +import org.apache.fop.fonts.EmbedFontInfo; import org.apache.fop.fonts.FontCollection; import org.apache.fop.render.RendererConfig.RendererConfigParser; import org.apache.fop.render.bitmap.BitmapRendererConfig.BitmapRendererConfigParser; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.java2d.Base14FontCollection; +import org.apache.fop.render.java2d.ConfiguredFontCollection; import org.apache.fop.render.java2d.InstalledFontCollection; import org.apache.fop.render.java2d.Java2DFontMetrics; import org.apache.fop.render.java2d.Java2DRendererConfigurator; @@ -46,14 +49,6 @@ public class BitmapRendererConfigurator extends Java2DRendererConfigurator { super(userAgent, rendererConfigParser); } - /** - * Default constructor - * @param userAgent user agent - */ - public BitmapRendererConfigurator(FOUserAgent userAgent) { - super(userAgent, null); - } - // ---=== IFDocumentHandler configuration ===--- /** {@inheritDoc} */ @@ -89,6 +84,12 @@ public class BitmapRendererConfigurator extends Java2DRendererConfigurator { } } + @Override + protected FontCollection createCollectionFromFontList(URIResolverWrapper uriResolverWrapper, + List fontList) { + return new ConfiguredFontCollection(uriResolverWrapper, fontList, userAgent.isComplexScriptFeaturesEnabled()); + } + @Override protected List getDefaultFontCollection() { final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics(); diff --git a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java index 524ab9746..68f6bac05 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java +++ b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java @@ -20,6 +20,7 @@ package org.apache.fop.render.bitmap; import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.bitmap.PNGRendererConfig.PNGRendererConfigParser; import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; @@ -47,8 +48,7 @@ public class PNGDocumentHandler extends AbstractBitmapDocumentHandler { /** {@inheritDoc} */ public IFDocumentHandlerConfigurator getConfigurator() { - // TODO what constructir params? - return new BitmapRendererConfigurator(getUserAgent()); + return new BitmapRendererConfigurator(getUserAgent(), new PNGRendererConfigParser()); } } diff --git a/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java b/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java new file mode 100644 index 000000000..14984963c --- /dev/null +++ b/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package org.apache.fop.render.bitmap; + +import org.apache.avalon.framework.configuration.Configuration; + +import org.apache.xmlgraphics.util.MimeConstants; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fonts.DefaultFontConfig; +import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; + +public final class PNGRendererConfig extends BitmapRendererConfig { + + private PNGRendererConfig(DefaultFontConfig fontConfig) { + super(fontConfig); + } + + public static class PNGRendererConfigParser implements RendererConfigParser { + + public PNGRendererConfig build(FOUserAgent userAgent, Configuration cfg) + throws FOPException { + return new PNGRendererConfig(new DefaultFontConfigParser().parse(cfg, + userAgent.validateStrictly())); + } + + public String getMimeType() { + return MimeConstants.MIME_PNG; + } + } +} diff --git a/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java b/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java index b0c003b91..70fe0b449 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java +++ b/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java @@ -130,7 +130,7 @@ public class Java2DGraphicsState { */ public boolean updateFont(String name, int size) { - FontMetricsMapper mapper = (FontMetricsMapper)fontInfo.getMetricsFor(name); + FontMetricsMapper mapper = (FontMetricsMapper) fontInfo.getMetricsFor(name); boolean updateName = (!mapper.getFontName().equals( getGraph().getFont().getFontName())); boolean updateSize = (size != (getGraph().getFont().getSize() * 1000)); diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java index 844751db7..0cbe6e992 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java @@ -25,7 +25,7 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.io.DefaultResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.URIResolverWrapper; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfigurator; @@ -85,8 +85,7 @@ public class PDFDocumentGraphics2DConfigurator { FontInfo fontInfo = new FontInfo(); final boolean strict = false; if (cfg != null) { - //TODO Wire in the FontEventListener - URIResolverWrapper resolver = DefaultResourceResolver.createDefaultWrapper(); + URIResolverWrapper resolver = ResourceResolverFactory.createDefaultWrapper(); //TODO The following could be optimized by retaining the FontManager somewhere FontManager fontManager = new FontManager(resolver, FontDetectorFactory.createDefault(), FontCacheManagerFactory.createDefault()); diff --git a/test/java/org/apache/fop/URIResolutionTestCase.java b/test/java/org/apache/fop/URIResolutionTestCase.java index a63c1c5b6..f1dd89725 100644 --- a/test/java/org/apache/fop/URIResolutionTestCase.java +++ b/test/java/org/apache/fop/URIResolutionTestCase.java @@ -52,9 +52,9 @@ import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.FopFactoryBuilder; import org.apache.fop.apps.MimeConstants; -import org.apache.fop.apps.io.DefaultResourceResolver; import org.apache.fop.apps.io.Resource; import org.apache.fop.apps.io.ResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.render.xml.XMLRenderer; import static org.apache.fop.FOPTestUtils.getBaseDir; @@ -177,7 +177,7 @@ public class URIResolutionTestCase { } private static final class CustomURIResolver implements ResourceResolver { - private final DefaultResourceResolver defaultImpl = new DefaultResourceResolver(); + private final ResourceResolver defaultImpl = ResourceResolverFactory.createDefaultResourceResolver(); public Resource getResource(URI uri) throws IOException { if (uri.getScheme().equals("funky") && uri.getSchemeSpecificPart().equals("myimage123")) { diff --git a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java index c9ea9a5f4..27a3a41d0 100644 --- a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java +++ b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java @@ -19,9 +19,6 @@ package org.apache.fop.afp; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -30,6 +27,11 @@ import org.junit.Test; import org.apache.xmlgraphics.util.MimeConstants; +import org.apache.fop.apps.io.ResourceResolverFactory; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + /** * Test case for {@link AFPResourceManager}. */ @@ -39,7 +41,7 @@ public class AFPResourceManagerTestCase { @Before public void setUp() throws IOException { - sut = new AFPResourceManager(); + sut = new AFPResourceManager(ResourceResolverFactory.createDefaultWrapper()); AFPPaintingState paintingState = new AFPPaintingState(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DataStream stream = sut.createDataStream(paintingState, outStream); diff --git a/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java b/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java index 40932f7fd..4ce9cb2a0 100644 --- a/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java +++ b/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java @@ -20,6 +20,7 @@ package org.apache.fop.apps; +import java.net.URI; import java.util.Map; import org.w3c.dom.Element; @@ -33,11 +34,17 @@ import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE import static org.apache.fop.render.afp.AFPRendererConfig.Options.DEFAULT_RESOURCE_LEVELS; import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES; import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_DITHERING_QUALITY; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_FS45; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_JPEG; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_MAPPING_OPTION; import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_MODE; import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_NATIVE; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.IMAGES_WRAP_PSEG; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.JPEG_ALLOW_JPEG_EMBEDDING; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.JPEG_BITMAP_ENCODING_QUALITY; import static org.apache.fop.render.afp.AFPRendererConfig.Options.RENDERER_RESOLUTION; import static org.apache.fop.render.afp.AFPRendererConfig.Options.LINE_WIDTH_CORRECTION; -import static org.apache.fop.render.afp.AFPRendererConfig.Options.RESOURCE_GROUP_FILE; +import static org.apache.fop.render.afp.AFPRendererConfig.Options.RESOURCE_GROUP_URI; import static org.apache.fop.render.afp.AFPRendererConfig.Options.SHADING; /** @@ -82,12 +89,12 @@ public final class AFPRendererConfBuilder extends RendererConfBuilder { return this; } - public AFPRendererConfBuilder setResourceGroupFile(String value) { - createTextElement(RESOURCE_GROUP_FILE, value); + public AFPRendererConfBuilder setResourceGroupUri(String uri) { + createTextElement(RESOURCE_GROUP_URI, uri); return this; } - public AFPRendererConfBuilder setResourceResourceLevels(Map levels) { + public AFPRendererConfBuilder setDefaultResourceLevels(Map levels) { Element e = createElement(DEFAULT_RESOURCE_LEVELS.getName()); for (String key : levels.keySet()) { e.setAttribute(key, levels.get(key)); @@ -99,6 +106,8 @@ public final class AFPRendererConfBuilder extends RendererConfBuilder { private final Element el; + private Element jpeg; + private ImagesBuilder(AFPRendererConfig.ImagesModeOptions mode) { el = createElement(IMAGES.getName()); setAttribute(IMAGES_MODE, mode.getName()); @@ -108,29 +117,58 @@ public final class AFPRendererConfBuilder extends RendererConfBuilder { return setAttribute(name, value); } + public ImagesBuilder setAllowJpegEmbedding(boolean value) { + getJpeg().setAttribute(JPEG_ALLOW_JPEG_EMBEDDING.getName(), String.valueOf(value)); + return this; + } + + public ImagesBuilder setBitmapEncodingQuality(float value) { + getJpeg().setAttribute(JPEG_BITMAP_ENCODING_QUALITY.getName(), String.valueOf(value)); + return this; + } + public ImagesBuilder setDitheringQuality(String value) { return setAttribute(IMAGES_DITHERING_QUALITY, value); } public ImagesBuilder setDitheringQuality(float value) { - return setAttribute(IMAGES_DITHERING_QUALITY, String.valueOf(value)); + return setAttribute(IMAGES_DITHERING_QUALITY, value); + } + + public ImagesBuilder setFs45(boolean value) { + return setAttribute(IMAGES_FS45, value); + } + + public ImagesBuilder setMappingOption(String value) { + return setAttribute(IMAGES_MAPPING_OPTION, value); + } + + public ImagesBuilder setWrapPseg(boolean value) { + return setAttribute(IMAGES_WRAP_PSEG, value); } public ImagesBuilder setNativeImageSupport(boolean value) { - return setAttribute(IMAGES_NATIVE, String.valueOf(value)); + return setAttribute(IMAGES_NATIVE, value); } public AFPRendererConfBuilder endImages() { return AFPRendererConfBuilder.this.endImages(); } - private ImagesBuilder setAttribute(Options options, String value) { + private ImagesBuilder setAttribute(Options options, Object value) { return setAttribute(options.getName(), value); } - private ImagesBuilder setAttribute(String name, String value) { - el.setAttribute(name, value); + private ImagesBuilder setAttribute(String name, Object value) { + el.setAttribute(name, String.valueOf(value)); return this; } + + private Element getJpeg() { + if (jpeg == null) { + jpeg = createElement(IMAGES_JPEG.getName(), el); + } + return jpeg; + } } } diff --git a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java index edb20fad6..f56373218 100644 --- a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java +++ b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java @@ -27,7 +27,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; -import org.apache.fop.apps.io.DefaultResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.area.AreaTreeHandler; import org.apache.fop.area.Block; import org.apache.fop.fo.FONode; @@ -67,7 +67,7 @@ public class FopFactoryBuilderTestCase { @Test(expected = IllegalArgumentException.class) public void testNullParamsInConstructor() throws URISyntaxException { - new FopFactoryBuilder(null, new DefaultResourceResolver()); + new FopFactoryBuilder(null, ResourceResolverFactory.createDefaultResourceResolver()); } @Test diff --git a/test/java/org/apache/fop/apps/io/ResourceResolverFactoryTestCase.java b/test/java/org/apache/fop/apps/io/ResourceResolverFactoryTestCase.java new file mode 100644 index 000000000..223f74045 --- /dev/null +++ b/test/java/org/apache/fop/apps/io/ResourceResolverFactoryTestCase.java @@ -0,0 +1,212 @@ +/* + * 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.apps.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; + +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +public class ResourceResolverFactoryTestCase { + + private static final byte[] DATA = new byte[]{(byte) 0, (byte) 1, (byte) 2}; + + private void writeDataTo(File f) throws IOException { + writeDataTo(new FileOutputStream(f)); + } + + private void writeDataTo(OutputStream os) throws IOException { + os.write(DATA); + os.close(); + } + + private void checkStream(InputStream inputStream) throws IOException { + byte[] actual = new byte[DATA.length]; + for (int i = 0; i < DATA.length; i++) { + actual[i] = (byte) inputStream.read(); + } + assertEquals(-1, inputStream.read()); + assertArrayEquals(DATA, actual); + } + + @Test + public void testDefaultResourceResolverGetResource() throws Exception { + ResourceResolver sut = ResourceResolverFactory.createDefaultResourceResolver(); + File inputFile = File.createTempFile("prefix", "suffix"); + InputStream is = null; + try { + writeDataTo(inputFile); + is = sut.getResource(inputFile.toURI()); + checkStream(is); + } finally { + if (is != null) { + is.close(); + } + inputFile.delete(); + } + } + + @Test + public void testDefaultResourceResolverGetOutput() throws Exception { + ResourceResolver sut = ResourceResolverFactory.createDefaultResourceResolver(); + File outputFile = File.createTempFile("prefix", "suffix"); + writeDataTo(sut.getOutputStream(outputFile.toURI())); + InputStream is = new FileInputStream(outputFile); + try { + checkStream(is); + } finally { + is.close(); + } + } + + private static class TestCreateTempAwareResourceResolverHelper implements ResourceResolver { + + final TempResourceResolver tempResourceResolver = mock(TempResourceResolver.class); + + final ResourceResolver defaultResourceResolver = mock(ResourceResolver.class); + + final ResourceResolver sut = ResourceResolverFactory.createTempAwareResourceResolver( + tempResourceResolver, defaultResourceResolver); + + public Resource getResource(URI uri) throws IOException { + return sut.getResource(uri); + } + public OutputStream getOutputStream(URI uri) throws IOException { + return sut.getOutputStream(uri); + } + } + + @Test + public void testCreateTempAwareResourceResolverForTmpResource() throws Exception { + URI uri = URI.create("tmp:///id"); + TestCreateTempAwareResourceResolverHelper helper = new TestCreateTempAwareResourceResolverHelper(); + helper.getResource(uri); + verify(helper.tempResourceResolver, times(1)).getResource(uri.getPath()); + verify(helper.defaultResourceResolver, never()).getResource(uri); + } + + @Test + public void testCreateTempAwareResourceResolverForRegularResource() throws Exception { + URI uri = URI.create("file:///path/to/file"); + TestCreateTempAwareResourceResolverHelper helper = new TestCreateTempAwareResourceResolverHelper(); + helper.getResource(uri); + verify(helper.tempResourceResolver, never()).getResource(uri.getPath()); + verify(helper.defaultResourceResolver, times(1)).getResource(uri); + } + + @Test + public void testCreateTempAwareResourceResolverForTmpOuput() throws Exception { + URI uri = URI.create("tmp:///id"); + TestCreateTempAwareResourceResolverHelper helper = new TestCreateTempAwareResourceResolverHelper(); + helper.getOutputStream(uri); + verify(helper.tempResourceResolver, times(1)).getOutputStream(uri.getPath()); + verify(helper.defaultResourceResolver, never()).getOutputStream(uri); + } + + @Test + public void testCreateTempAwareResourceResolverForRegularOutput() throws Exception { + URI uri = URI.create("file:///path/to/file"); + TestCreateTempAwareResourceResolverHelper helper = new TestCreateTempAwareResourceResolverHelper(); + helper.getOutputStream(uri); + verify(helper.tempResourceResolver, never()).getOutputStream(uri.getPath()); + verify(helper.defaultResourceResolver, times(1)).getOutputStream(uri); + } + + @Test + public void testCreateSchemaAwareResourceResolverForDefaultResource() throws Exception { + URI uri = URI.create("file:///path/to/file"); + TestCreateSchemaAwareResourceResolverBuilderHelper helper + = new TestCreateSchemaAwareResourceResolverBuilderHelper(); + helper.getResource(uri); + verify(helper.registedResourceResolver, never()).getResource(uri); + verify(helper.defaultResourceResolver, times(1)).getResource(uri); + } + + @Test + public void testCreateSchemaAwareResourceResolverForRegisteredResource() throws Exception { + URI uri = URI.create(TestCreateSchemaAwareResourceResolverBuilderHelper.SCHEMA + ":///path"); + TestCreateSchemaAwareResourceResolverBuilderHelper helper + = new TestCreateSchemaAwareResourceResolverBuilderHelper(); + helper.getResource(uri); + verify(helper.registedResourceResolver, times(1)).getResource(uri); + verify(helper.defaultResourceResolver, never()).getResource(uri); + } + + @Test + public void testCreateSchemaAwareResourceResolverForDefaultOutput() throws Exception { + URI uri = URI.create("file:///path/to/file"); + TestCreateSchemaAwareResourceResolverBuilderHelper helper + = new TestCreateSchemaAwareResourceResolverBuilderHelper(); + helper.getOutputStream(uri); + verify(helper.registedResourceResolver, never()).getOutputStream(uri); + verify(helper.defaultResourceResolver, times(1)).getOutputStream(uri); + } + + @Test + public void testCreateSchemaAwareResourceResolverForRegisteredOutput() throws Exception { + URI uri = URI.create(TestCreateSchemaAwareResourceResolverBuilderHelper.SCHEMA + ":///path"); + TestCreateSchemaAwareResourceResolverBuilderHelper helper + = new TestCreateSchemaAwareResourceResolverBuilderHelper(); + helper.getOutputStream(uri); + verify(helper.registedResourceResolver, times(1)).getOutputStream(uri); + verify(helper.defaultResourceResolver, never()).getOutputStream(uri); + } + + private static class TestCreateSchemaAwareResourceResolverBuilderHelper implements ResourceResolver { + + private static final String SCHEMA = "protocol"; + + final ResourceResolver registedResourceResolver = mock(ResourceResolver.class); + + final ResourceResolver defaultResourceResolver = mock(ResourceResolver.class); + + final ResourceResolver sut; + + TestCreateSchemaAwareResourceResolverBuilderHelper() { + ResourceResolverFactory.SchemaAwareResourceResolverBuilder builder + = ResourceResolverFactory.createSchemaAwareResourceResolverBuilder( + defaultResourceResolver); + builder.registerResourceResolverForSchema(SCHEMA, registedResourceResolver); + sut = builder.build(); + + } + + public Resource getResource(URI uri) throws IOException { + return sut.getResource(uri); + } + public OutputStream getOutputStream(URI uri) throws IOException { + return sut.getOutputStream(uri); + } + } + +} + diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java index 4a261c87e..761333183 100644 --- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java +++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java @@ -24,7 +24,7 @@ import java.io.File; import org.junit.Before; import org.junit.Test; -import org.apache.fop.apps.io.DefaultResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.URIResolverWrapper; import static org.junit.Assert.assertEquals; @@ -35,7 +35,7 @@ import static org.junit.Assert.assertEquals; public class DejaVuLGCSerifTestCase { private URIResolverWrapper resolver = new URIResolverWrapper(new File(".").toURI(), - new DefaultResourceResolver()); + ResourceResolverFactory.createDefaultResourceResolver()); private CustomFont font; /** diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java index 1c4e92aec..edd65f108 100644 --- a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java @@ -25,7 +25,7 @@ import java.net.URI; import org.junit.Test; -import org.apache.fop.apps.io.DefaultResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.URIResolverWrapper; import org.apache.fop.fonts.EncodingMode; @@ -42,7 +42,7 @@ public class TTFFontLoaderTestCase { boolean useComplexScriptFeatures = false; File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); URI absoluteFilePath = file.toURI(); - URIResolverWrapper resolver = DefaultResourceResolver.createDefaultWrapper(); + URIResolverWrapper resolver = ResourceResolverFactory.createDefaultWrapper(); String fontName = "Deja Vu"; boolean embedded = false; boolean useKerning = true; diff --git a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java index e108266b5..80cbddd2d 100644 --- a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java @@ -19,15 +19,15 @@ package org.apache.fop.pdf; -import static org.junit.Assert.assertEquals; - import org.junit.Test; -import org.apache.fop.apps.io.DefaultResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.URIResolverWrapper; import org.apache.fop.fonts.CIDSubset; import org.apache.fop.fonts.MultiByteFont; +import static org.junit.Assert.assertEquals; + /** * Test case for {@link PDFFactory}. */ @@ -56,7 +56,7 @@ public class PDFFactoryTestCase { } PDFDocument doc = new PDFDocument("Test"); PDFFactory pdfFactory = new PDFFactory(doc); - MockedFont font = new MockedFont(DefaultResourceResolver.createDefaultWrapper()); + MockedFont font = new MockedFont(ResourceResolverFactory.createDefaultWrapper()); PDFFont pdfDejaVu = pdfFactory.makeFont("DejaVu", "DejaVu", "TTF", font, font); assertEquals("/EAAAAA+DejaVu", pdfDejaVu.getBaseFont().toString()); diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java index 233e636ca..799045872 100644 --- a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java +++ b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java @@ -38,7 +38,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; public class AFPRendererConfigParserTestCase -extends AbstractRendererConfigParserTester { + extends AbstractRendererConfigParserTester { public AFPRendererConfigParserTestCase() { super(new AFPRendererConfigParser(), AFPRendererConfBuilder.class); @@ -63,21 +63,22 @@ extends AbstractRendererConfigParserTester levels = new HashMap(); levels.put("goca", "page"); - parseConfig(createRenderer().setResourceResourceLevels(levels)); + parseConfig(createRenderer().setDefaultResourceLevels(levels)); assertNotNull(conf.getResourceLevelDefaults()); } @@ -99,23 +100,22 @@ extends AbstractRendererConfigParserTesteruri - * - * @param uri the URI of the config file - */ - private void setConfigFile(String uri) { - String confTestsDir = "test/resources/conf/afp/"; - try { - userAgent = FopFactory.newInstance(new File(confTestsDir + uri)).newFOUserAgent(); - sut = new AFPRendererConfigurator(userAgent, new AFPRendererConfigParser()); - } catch (IOException ioe) { - fail("IOException: " + ioe); - } catch (SAXException se) { - fail("SAXException: " + se); +public class AFPRendererConfiguratorTestCase extends + AbstractRendererConfiguratorTest { + + public AFPRendererConfiguratorTestCase() { + super(MimeConstants.MIME_AFP, AFPRendererConfBuilder.class, AFPDocumentHandler.class); + } + + @Override + public void setUpDocumentHandler() { + } + + @Override + protected AFPRendererConfigurator createConfigurator() { + return new AFPRendererConfigurator(userAgent, new AFPRendererConfigParser()); + } + + private AFPDocumentHandler getDocHandler() { + return (AFPDocumentHandler) docHandler; + } + + @Test + public void testColorImages() throws Exception { + parseConfig(createBuilder().startImages(ImagesModeOptions.MODE_COLOR) + .endImages()); + verify(getDocHandler()).setColorImages(true); + + parseConfig(createBuilder().startImages(ImagesModeOptions.MODE_GRAYSCALE) + .endImages()); + verify(getDocHandler()).setColorImages(false); + } + + @Test + public void testCMYKImagesSupport() throws Exception { + parseConfig(createBuilder().startImages(ImagesModeOptions.MODE_COLOR) + .setModeAttribute("cmyk", "true") + .endImages()); + verify(getDocHandler()).setCMYKImagesSupported(true); + + parseConfig(createBuilder().startImages(ImagesModeOptions.MODE_COLOR) + .setModeAttribute("cmyk", "false") + .endImages()); + verify(getDocHandler()).setCMYKImagesSupported(false); + } + + @Test + public void testBitsPerPixel() throws Exception { + for (int bpp = 0; bpp < 40; bpp += 8) { + parseConfig(createBuilder().startImages() + .setModeAttribute("bits-per-pixel", String.valueOf(bpp)) + .endImages()); + verify(getDocHandler()).setBitsPerPixel(bpp); + } + } + + @Test + public void testDitheringQuality() throws Exception { + float ditheringQuality = 100f; + parseConfig(createBuilder().startImages() + .setDitheringQuality(ditheringQuality) + .endImages()); + verify(getDocHandler()).setDitheringQuality(ditheringQuality); + + ditheringQuality = 1000f; + parseConfig(createBuilder().startImages() + .setDitheringQuality(ditheringQuality) + .endImages()); + verify(getDocHandler()).setDitheringQuality(ditheringQuality); + } + + @Test + public void testNativeImagesSupported() throws Exception { + parseConfig(createBuilder().startImages() + .setNativeImageSupport(true) + .endImages()); + verify(getDocHandler()).setNativeImagesSupported(true); + + parseConfig(createBuilder().startImages() + .setNativeImageSupport(false) + .endImages()); + verify(getDocHandler()).setNativeImagesSupported(false); + } + + @Test + public void testShadingMode() throws Exception { + for (AFPShadingMode mode : AFPShadingMode.values()) { + parseConfig(createBuilder().setShading(mode)); + verify(getDocHandler()).setShadingMode(mode); } } - /** - * Test several config files relating to JPEG images in AFP. - * - * @throws FOPException if an error is thrown - */ @Test - public void testJpegImageConfig() throws FOPException { - testJpegSettings("no_image_config.xconf", 1.0f, false); - testJpegSettings("can_embed_jpeg.xconf", 1.0f, true); - testJpegSettings("bitmap_encode_quality.xconf", 0.5f, false); + public void testRendererResolution() throws Exception { + for (int resolution = 0; resolution < 1000; resolution += 100) { + parseConfig(createBuilder().setRenderingResolution(resolution)); + verify(getDocHandler()).setResolution(resolution); + } + } + + @Test + public void testLineWidthCorrection() throws Exception { + for (float resolution = 0; resolution < 50; resolution += 5) { + parseConfig(createBuilder().setLineWidthCorrection(resolution)); + verify(getDocHandler()).setLineWidthCorrection(resolution); + } + } + + @Test + public void testResourceGroupURI() throws Exception { + URI uri = URI.create("test://URI/just/used/for/testing"); + parseConfig(createBuilder().setResourceGroupUri(uri.toASCIIString())); + verify(getDocHandler()).setDefaultResourceGroupUri(uri); + } + + @Test + public void testResourceLevelDefaults() throws Exception { + testResourceLevelDefault(ResourceType.DOCUMENT); + } + + private void testResourceLevelDefault(ResourceType resType) throws Exception { + Map resourceLevels = new HashMap(); + resourceLevels.put("goca", resType.getName()); + parseConfig(createBuilder().setDefaultResourceLevels(resourceLevels)); + ArgumentCaptor argument = ArgumentCaptor.forClass(AFPResourceLevelDefaults.class); + verify(getDocHandler()).setResourceLevelDefaults(argument.capture()); + AFPResourceLevel expectedLevel = new AFPResourceLevel(resType); + assertEquals(expectedLevel, argument.getValue().getDefaultResourceLevel((byte) 3)); + } + + @Test + public void testExternalResourceDefault() throws Exception { + testResourceLevelDefault(ResourceType.EXTERNAL); } - private void testJpegSettings(String uri, float bitmapEncodingQual, boolean canEmbed) - throws FOPException { - AFPDocumentHandler docHandler = new AFPDocumentHandler(new IFContext(userAgent)); + @Test + public void testInlineResourceDefault() throws Exception { + testResourceLevelDefault(ResourceType.INLINE); + } + + @Test + public void testPageResourceDefault() throws Exception { + testResourceLevelDefault(ResourceType.PAGE); + } + + @Test + public void testPageGroupResourceDefault() throws Exception { + testResourceLevelDefault(ResourceType.PAGE_GROUP); + } - setConfigFile(uri); - sut.configure(docHandler); + @Test + public void testPrintFileResourceDefault() throws Exception { + testResourceLevelDefault(ResourceType.PRINT_FILE); + } + + @Test + public void testBitmapEncodeQuality() throws Exception { + parseConfig(createBuilder().startImages() + .setBitmapEncodingQuality(0.5f) + .endImages()); + verify(getDocHandler()).setBitmapEncodingQuality(0.5f); + } + + @Test + public void testCanEmbedJpeg() throws Exception { + parseConfig(createBuilder().startImages() + .setAllowJpegEmbedding(true) + .endImages()); + verify(getDocHandler()).canEmbedJpeg(true); - AFPPaintingState paintingState = docHandler.getPaintingState(); - assertEquals(bitmapEncodingQual, paintingState.getBitmapEncodingQuality(), 0.01f); - assertEquals(canEmbed, paintingState.canEmbedJpeg()); + parseConfig(createBuilder().startImages() + .setAllowJpegEmbedding(false) + .endImages()); + verify(getDocHandler()).canEmbedJpeg(false); } + } -- 2.39.5