]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Removed URI resolving class that are no longer needed and handled data URIs
authorMehdi Houshmand <mehdi@apache.org>
Thu, 14 Jun 2012 14:05:16 +0000 (14:05 +0000)
committerMehdi Houshmand <mehdi@apache.org>
Thu, 14 Jun 2012 14:05:16 +0000 (14:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_URI_Unification@1350248 13f79535-47bb-0310-9956-ffa450edef68

29 files changed:
src/java/org/apache/fop/afp/AFPStreamer.java
src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
src/java/org/apache/fop/apps/FOUserAgent.java
src/java/org/apache/fop/apps/FopConfParser.java
src/java/org/apache/fop/apps/FopFactory.java
src/java/org/apache/fop/apps/FopFactoryBuilder.java
src/java/org/apache/fop/apps/FopFactoryConfig.java
src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java [new file with mode: 0644]
src/java/org/apache/fop/apps/io/URIResolverWrapper.java
src/java/org/apache/fop/area/CachedRenderPagesModel.java
src/java/org/apache/fop/fo/extensions/svg/SVGElement.java
src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java [deleted file]
src/java/org/apache/fop/hyphenation/Hyphenator.java
src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
src/java/org/apache/fop/pdf/PDFDocument.java
src/java/org/apache/fop/pdf/StreamCacheFactory.java
src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java
src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
src/java/org/apache/fop/render/pcl/PCLGenerator.java
src/java/org/apache/fop/render/ps/PSDocumentHandler.java
src/java/org/apache/fop/util/ColorSpaceCache.java
src/java/org/apache/fop/util/ColorUtil.java
test/java/org/apache/fop/apps/FopConfParserTestCase.java
test/java/org/apache/fop/config/FOURIResolverTestCase.java [deleted file]
test/java/org/apache/fop/config/UserConfigTestSuite.java
test/java/org/apache/fop/fotreetest/FOTreeTestCase.java
test/java/org/apache/fop/util/ColorUtilTestCase.java
test/layoutengine/standard-testcases/external-graphic_rfc2397.xml

index 3edcd1265c4af3c28580edfe7269435e3aae2b8a..93a0075c9d63735ab424b50f23c0f2ba507bd04a 100644 (file)
@@ -24,11 +24,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 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;
@@ -36,6 +34,7 @@ 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.TempResourceURIGenerator;
 import org.apache.fop.apps.io.URIResolverWrapper;
 
 /**
@@ -47,6 +46,9 @@ public class AFPStreamer implements Streamable {
 
     private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";
 
+    private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+            = new TempResourceURIGenerator("AFPDataStream_");
+
     private final Factory factory;
 
     private final URIResolverWrapper uriResolverWrapper;
@@ -77,7 +79,7 @@ public class AFPStreamer implements Streamable {
     public AFPStreamer(Factory factory, URIResolverWrapper uriResolverWrapper) {
         this.factory = factory;
         this.uriResolverWrapper = uriResolverWrapper;
-        this.tempUri = TempUriGenerator.INSTANCE.generate();
+        this.tempUri = TEMP_URI_GENERATOR.generate();
         defaultResourceGroupUri = URI.create(DEFAULT_EXTERNAL_RESOURCE_FILENAME);
 
     }
@@ -188,25 +190,4 @@ public class AFPStreamer implements Streamable {
         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();
-        }
-
-        public URI generate() {
-            try {
-                return new URI(AFPDATASTREAM_TEMP_URL_PREFIX + counter.getAndIncrement());
-            } catch (URISyntaxException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
 }
index 3cada1ed312f2f2f1003959feedc24a4777c119f..e145de74538971fa42acd2876303562bcb9c968f 100644 (file)
@@ -143,7 +143,7 @@ public abstract class CharacterSetBuilder {
      * @return an inputStream
      * @throws IOException in the event that an I/O exception of some sort has occurred
      */
-    protected InputStream openInputStream(AFPResourceAccessor accessor, String uriStr,
+    private InputStream openInputStream(AFPResourceAccessor accessor, String uriStr,
             AFPEventProducer eventProducer)
             throws IOException {
         URI uri;
@@ -163,7 +163,7 @@ public abstract class CharacterSetBuilder {
      *
      * @param inputStream the inputstream to close
      */
-    protected void closeInputStream(InputStream inputStream) {
+    private void closeInputStream(InputStream inputStream) {
         try {
             if (inputStream != null) {
                 inputStream.close();
@@ -381,9 +381,8 @@ public abstract class CharacterSetBuilder {
      * @return a class representing the font descriptor
      * @throws IOException if an I/O exception of some sort has occurred.
      */
-    protected static FontDescriptor processFontDescriptor(
-                StructuredFieldReader structuredFieldReader)
-    throws IOException {
+    private static FontDescriptor processFontDescriptor(
+            StructuredFieldReader structuredFieldReader) throws IOException {
 
         byte[] fndData = structuredFieldReader.getNext(FONT_DESCRIPTOR_SF);
         return new FontDescriptor(fndData);
@@ -397,8 +396,8 @@ public abstract class CharacterSetBuilder {
      * @return the FontControl
      * @throws IOException if an I/O exception of some sort has occurred.
      */
-    protected FontControl processFontControl(StructuredFieldReader structuredFieldReader)
-    throws IOException {
+    private FontControl processFontControl(StructuredFieldReader structuredFieldReader)
+            throws IOException {
 
         byte[] fncData = structuredFieldReader.getNext(FONT_CONTROL_SF);
 
@@ -429,7 +428,7 @@ public abstract class CharacterSetBuilder {
      * @return CharacterSetOrientation array
      * @throws IOException if an I/O exception of some sort has occurred.
      */
-    protected CharacterSetOrientation[] processFontOrientation(
+    private CharacterSetOrientation[] processFontOrientation(
         StructuredFieldReader structuredFieldReader) throws IOException {
 
         byte[] data = structuredFieldReader.getNext(FONT_ORIENTATION_SF);
@@ -477,7 +476,7 @@ public abstract class CharacterSetBuilder {
      *                  font metric values
      * @throws IOException if an I/O exception of some sort has occurred.
      */
-    protected void processFontPosition(StructuredFieldReader structuredFieldReader,
+    private void processFontPosition(StructuredFieldReader structuredFieldReader,
         CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
             throws IOException {
 
@@ -534,7 +533,7 @@ public abstract class CharacterSetBuilder {
      *                  font metric values
      * @throws IOException if an I/O exception of some sort has occurred.
      */
-    protected void processFontIndex(StructuredFieldReader structuredFieldReader,
+    private void processFontIndex(StructuredFieldReader structuredFieldReader,
             CharacterSetOrientation cso, Map<String, String> codepage,
             double metricNormalizationFactor)
         throws IOException {
@@ -706,13 +705,14 @@ public abstract class CharacterSetBuilder {
             return INSTANCE;
         }
 
+        @Override
         protected Map<String, String> loadCodePage(String codePage, String encoding,
                 AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
             // Create the HashMap to store code page information
             Map<String, String> codePages = new HashMap<String, String>();
             InputStream inputStream = null;
             try {
-                inputStream = openInputStream(accessor, codePage.trim(), eventProducer);
+                inputStream = super.openInputStream(accessor, codePage.trim(), eventProducer);
             } catch (IOException e) {
                 eventProducer.codePageNotFound(this, e);
                 throw e;
@@ -750,7 +750,7 @@ public abstract class CharacterSetBuilder {
                     }
                 }
             } finally {
-                closeInputStream(inputStream);
+                super.closeInputStream(inputStream);
             }
             return codePages;
         }
index c395d01d8d47d8ec7fe556e51e70a585e4bd66af..b8459e4599da4877f4aae8996237cc9743390352 100644 (file)
@@ -23,7 +23,6 @@ package org.apache.fop.apps;
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Date;
 import java.util.Map;
@@ -41,7 +40,6 @@ import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
 import org.apache.xmlgraphics.util.UnitConv;
-import org.apache.xmlgraphics.util.uri.CommonURIResolver;
 
 import org.apache.fop.Version;
 import org.apache.fop.accessibility.Accessibility;
@@ -57,7 +55,6 @@ import org.apache.fop.events.LoggingEventListener;
 import org.apache.fop.fo.ElementMappingRegistry;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fonts.FontManager;
-import org.apache.fop.hyphenation.HyphenationTreeResolver;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
 import org.apache.fop.render.ImageHandlerRegistry;
 import org.apache.fop.render.Renderer;
@@ -220,7 +217,6 @@ public class FOUserAgent {
             setStructureTreeEventHandler(documentHandler.getStructureTreeEventHandler());
         }
         this.documentHandlerOverride = documentHandler;
-
     }
 
     /**
@@ -409,16 +405,9 @@ public class FOUserAgent {
     public Source resolveURI(String uri) {
         // TODO: What do we want to do when resources aren't found???
         try {
-            Source src;
             // Have to do this so we can resolve data URIs
-            if (uri.startsWith("data:")) {
-                CommonURIResolver uriResolver = new CommonURIResolver();
-                src = uriResolver.resolve(uri, "");
-            } else {
-                URI actualUri = URIResolverWrapper.cleanURI(uri);
-                src = new StreamSource(newUriResolver.resolveIn(actualUri));
-                src.setSystemId(uri);
-            }
+            Source src = new StreamSource(newUriResolver.resolveIn(uri));
+            src.setSystemId(uri);
             return src;
         } catch (URISyntaxException use) {
             return null;
@@ -801,11 +790,6 @@ public class FOUserAgent {
         return factory.getColorSpaceCache();
     }
 
-    /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
-    public HyphenationTreeResolver getHyphenationTreeResolver() {
-        return factory.getHyphenationTreeResolver();
-    }
-
     public Map<String, String> getHyphPatNames() {
         return factory.getHyphPatNames();
     }
index b095d8f74356cc43c7a415076c38ef0ec5a38748..3ecba717b44e9ad83d9667a2a2709289ccea4b24 100644 (file)
@@ -171,18 +171,6 @@ public class FopConfParser {
             }
         }
 
-        if (cfg.getChild("hyphenation-base", false) != null) {
-            String path = cfg.getChild("hyphenation-base").getValue(null);
-            if (defaultBaseURI != null) {
-                try {
-                    URI hyphBaseUri = URIResolverWrapper.getBaseURI(path);
-                    fopFactoryBuilder.setHyphenationBaseURI(defaultBaseURI.resolve(hyphBaseUri));
-                } catch (URISyntaxException use) {
-                    LogUtil.handleException(log, use, strict);
-                }
-            }
-        }
-
         // renderer options
         if (cfg.getChild("source-resolution", false) != null) {
             float srcRes = cfg.getChild("source-resolution").getValueAsFloat(
index 9cb4edc270bae0189e5bdc36f90ba80b61a697fb..f60e6675bc8caee949d0a6c8d555013d032cf2be 100644 (file)
@@ -28,9 +28,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
-import javax.xml.transform.Source;
-import javax.xml.transform.TransformerException;
-
 import org.xml.sax.SAXException;
 
 import org.apache.avalon.framework.configuration.Configuration;
@@ -45,7 +42,6 @@ import org.apache.fop.apps.io.URIResolverWrapper;
 import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.ElementMappingRegistry;
 import org.apache.fop.fonts.FontManager;
-import org.apache.fop.hyphenation.HyphenationTreeResolver;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
 import org.apache.fop.render.ImageHandlerRegistry;
 import org.apache.fop.render.RendererConfig;
@@ -94,7 +90,7 @@ public final class FopFactory implements ImageContext {
         this.config = config;
         this.uriResolverWrapper = new URIResolverWrapper(config.getBaseURI(), config.getNewURIResolver());
         this.elementMappingRegistry = new ElementMappingRegistry(this);
-        this.colorSpaceCache = new ColorSpaceCache(config.getURIResolver());
+        this.colorSpaceCache = new ColorSpaceCache(uriResolverWrapper);
         this.rendererFactory = new RendererFactory(config.preferRenderer());
         this.xmlHandlers = new XMLHandlerRegistry();
         this.imageHandlers = new ImageHandlerRegistry();
@@ -343,15 +339,6 @@ public final class FopFactory implements ImageContext {
         return config.getLayoutManagerMakerOverride();
     }
 
-    /** @return the hyphen base URI */
-    public String getHyphenBaseURI() {
-        return config.getHyphenationBaseURI().toASCIIString();
-    }
-
-    /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
-    public HyphenationTreeResolver getHyphenationTreeResolver() {
-        return config.getHyphenationTreeResolver();
-    }
 
     public Map<String, String> getHyphPatNames() {
         return config.getHyphPatNames();
@@ -465,26 +452,6 @@ public final class FopFactory implements ImageContext {
         return config.getFontManager();
     }
 
-    /**
-     * Attempts to resolve the given URI.
-     * Will use the configured resolver and if not successful fall back
-     * to the default resolver.
-     * @param href URI to access
-     * @param baseUri the base URI to resolve against
-     * @return A {@link javax.xml.transform.Source} object, or null if the URI
-     * cannot be resolved.
-     * @see org.apache.fop.apps.io.FOURIResolver
-     */
-    public Source resolveURI(String href, String baseUri) {
-        Source source = null;
-        try {
-            source = config.getURIResolver().resolve(href, baseUri);
-        } catch (TransformerException e) {
-            log.error("Attempt to resolve URI '" + href + "' failed: ", e);
-        }
-        return source;
-    }
-
     /**
      * Returns the color space cache for this instance.
      * <p>
index 013b15efeca476228062cb72ca7f9c08a722e077..5d49712ba4ed76ca107ecc384892e8076044f0a9 100644 (file)
@@ -33,11 +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.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;
 
 /**
@@ -189,32 +187,6 @@ public final class FopFactoryBuilder {
         return this;
     }
 
-    /**
-     * Sets the base URI for hyphenation data.
-     *
-     * @param hyphenationBase the hyphenation-base-URI
-     * @return <code>this</code>
-     * @deprecated this will be phased out in favour of a unified URI resolution mechanism
-     */
-    public FopFactoryBuilder setHyphenationBaseURI(URI hyphenationBase) {
-        fopFactoryConfigBuilder.setHyphenationBaseURI(hyphenationBase);
-        return this;
-    }
-
-    /**
-     * Sets the URI resolver specific to Hyphenation data.
-     *
-     * @param hyphResolver the hyphenation-URI-resolver
-     * @return <code>this</code>
-     * @deprecated this will be phased out in favour of a unified URI resolution mechanism
-     */
-    public FopFactoryBuilder setHyphenationTreeResolver(
-            HyphenationTreeResolver hyphResolver) {
-        fopFactoryConfigBuilder.setHyphenationTreeResolver(hyphResolver);
-        return this;
-
-    }
-
     /**
      * Sets whether to perform strict validation on the FO used.
      *
@@ -362,10 +334,6 @@ public final class FopFactoryBuilder {
 
         private URI baseURI;
 
-        private URI hyphenationBaseURI;
-
-        private HyphenationTreeResolver hyphenationTreeResolver;
-
         private boolean hasStrictFOValidation = true;
 
         private boolean hasStrictUserValidation = FopFactoryConfig.DEFAULT_STRICT_USERCONFIG_VALIDATION;
@@ -410,7 +378,6 @@ public final class FopFactoryBuilder {
             this.enviro = enviro;
             this.baseURI = enviro.getDefaultBaseURI();
             this.imageManager = new ImageManager(new ImageContextImpl(this));
-            this.resolver = new FOURIResolver();
         }
 
         /** {@inheritDoc} */
@@ -438,16 +405,6 @@ public final class FopFactoryBuilder {
             return baseURI;
         }
 
-        /** {@inheritDoc} */
-        public URI getHyphenationBaseURI() {
-            return hyphenationBaseURI;
-        }
-
-        /** {@inheritDoc} */
-        public HyphenationTreeResolver getHyphenationTreeResolver() {
-            return hyphenationTreeResolver;
-        }
-
         /** {@inheritDoc} */
         public boolean validateStrictly() {
             return hasStrictFOValidation;
@@ -532,10 +489,6 @@ public final class FopFactoryBuilder {
 
         void setBaseURI(URI baseURI);
 
-        void setHyphenationBaseURI(URI hyphenationBase);
-
-        void setHyphenationTreeResolver(HyphenationTreeResolver hyphResolver);
-
         void setStrictFOValidation(boolean validateStrictly);
 
         void setStrictUserConfigValidation(boolean validateStrictly);
@@ -593,11 +546,6 @@ public final class FopFactoryBuilder {
             throwIllegalStateException();
         }
 
-        public void setHyphenationTreeResolver(
-                HyphenationTreeResolver hyphResolver) {
-            throwIllegalStateException();
-        }
-
         public void setStrictFOValidation(boolean validateStrictly) {
             throwIllegalStateException();
         }
@@ -677,14 +625,6 @@ public final class FopFactoryBuilder {
             config.baseURI = baseURI;
         }
 
-        public void setHyphenationBaseURI(URI hyphenationBase) {
-            config.hyphenationBaseURI = hyphenationBase;
-        }
-
-        public void setHyphenationTreeResolver(HyphenationTreeResolver hyphResolver) {
-            config.hyphenationTreeResolver = hyphResolver;
-        }
-
         public void setStrictFOValidation(boolean validateStrictly) {
             config.hasStrictFOValidation = validateStrictly;
         }
index 792f2fa043eab3d802fcecb99ff7b7c2c5fe8bc5..525d32204644ee30e45a93fef3e899704f3e0a53 100644 (file)
@@ -23,15 +23,12 @@ import java.net.URI;
 import java.util.Map;
 import java.util.Set;
 
-import javax.xml.transform.URIResolver;
-
 import org.apache.avalon.framework.configuration.Configuration;
 
 import org.apache.xmlgraphics.image.loader.ImageManager;
 
 import org.apache.fop.apps.io.ResourceResolver;
 import org.apache.fop.fonts.FontManager;
-import org.apache.fop.hyphenation.HyphenationTreeResolver;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
 
 /**
@@ -77,14 +74,6 @@ public interface FopFactoryConfig {
      */
     ResourceResolver getNewURIResolver();
 
-    /**
-     * The URI resolver for controlling file access.
-     *
-     * @return the URI resolver
-     * @deprecated please use the {@link #getNewURIResolver()} method.
-     */
-    URIResolver getURIResolver();
-
     /**
      * The base URI from which URIs are resolved against.
      *
@@ -92,24 +81,6 @@ public interface FopFactoryConfig {
      */
     URI getBaseURI();
 
-    /**
-     * The base URI of hyphenation data.
-     *
-     * @return the hyphenation-base-URI
-     * @deprecated this intelligence can be configured in the URI resolver set in
-     * {@link #getNewURIResolver()}
-     */
-    URI getHyphenationBaseURI();
-
-    /**
-     * The URI resolver for resolving hyphenation data.
-     *
-     * @return the hyphenation-URI-resolver
-     * @deprecated this intelligence can be configured in the URI resolver set in
-     * {@link #getNewURIResolver()}
-     */
-    HyphenationTreeResolver getHyphenationTreeResolver();
-
     /** @see {@link FopFactory#validateStrictly()} */
     boolean validateStrictly();
 
index 6e9484c823c02fa435a3310ccb26f5224d7a2d75..89ba34e1410a69a5176b2ec41f8f0180b5b867d3 100644 (file)
@@ -89,7 +89,7 @@ public final class ResourceResolverFactory {
         }
 
         private static boolean isTempUri(URI uri) {
-            return "tmp".equals(uri.getScheme());
+            return TempResourceURIGenerator.isTempUri(uri);
         }
 
         public Resource getResource(URI uri) throws IOException {
diff --git a/src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java b/src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java
new file mode 100644 (file)
index 0000000..039f4ca
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.apps.io;
+
+import java.net.URI;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Creates a URI for any temporary resource used within FOP.
+ */
+public final class TempResourceURIGenerator {
+
+    private static final String TMP_SCHEMA = "tmp";
+
+    private final String tempURIPrefix;
+
+    private final AtomicLong counter;
+
+    /**
+     * @param uriPrefix a prefix used to name the unique URI
+     */
+    public TempResourceURIGenerator(String uriPrefix) {
+        counter = new AtomicLong();
+        tempURIPrefix = URI.create(TMP_SCHEMA + ":///" + uriPrefix).toASCIIString();
+    }
+
+    /**
+     * Generate a unique URI for a temporary resource
+     * @return the URI
+     */
+    public URI generate() {
+        return URI.create(tempURIPrefix + getUniqueId());
+    }
+
+    private String getUniqueId() {
+        return Long.toHexString(counter.getAndIncrement());
+    }
+
+    public static boolean isTempUri(URI uri) {
+        return TMP_SCHEMA.equals(uri.getScheme());
+    }
+}
index 7ff9120899093d4fe6268e7f3250f33d5413f57f..2d2420d499808be2785f380636c59d7e0e0b6708 100644 (file)
@@ -25,10 +25,16 @@ import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xmlgraphics.util.uri.DataURIResolver;
 
 public class URIResolverWrapper {
     private final URI baseUri;
     private final ResourceResolver uriResolver;
+    private final DataURIResolver dataSchemeResolver = new DataURIResolver();
 
     public URIResolverWrapper(URI baseUri, ResourceResolver uriResolver) {
         this.baseUri = baseUri;
@@ -40,10 +46,16 @@ public class URIResolverWrapper {
     }
 
     public InputStream resolveIn(String stringUri) throws IOException, URISyntaxException {
+        if (stringUri.startsWith("data:")) {
+            return resolveDataURI(stringUri);
+        }
         return resolveIn(cleanURI(stringUri));
     }
 
     public InputStream resolveIn(URI uri) throws IOException {
+        if (uri.getScheme() != null && uri.getScheme().startsWith("data")) {
+            return resolveDataURI(uri.toASCIIString());
+        }
         return uriResolver.getResource(resolveFromBase(uri));
     }
 
@@ -55,12 +67,12 @@ public class URIResolverWrapper {
         return baseUri.resolve(uri);
     }
 
-    public static URI cleanURI(String base) throws URISyntaxException {
+    public static URI cleanURI(String uriStr) throws URISyntaxException {
         // replace back slash with forward slash to ensure windows file:/// URLS are supported
-        if (base == null) {
+        if (uriStr == null) {
             return null;
         }
-        String fixedUri = base.replace('\\', '/');
+        String fixedUri = uriStr.replace('\\', '/');
         fixedUri = fixedUri.replace(" ", "%20");
         URI baseURI = new URI(fixedUri);
         return baseURI;
@@ -71,4 +83,12 @@ public class URIResolverWrapper {
         return cleanURI(path);
     }
 
+    private InputStream resolveDataURI(String dataURI) {
+        try {
+            Source src = dataSchemeResolver.resolve(dataURI, "");
+            return src == null ? null : ((StreamSource) src).getInputStream();
+        } catch (TransformerException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
index 288884a55927ee32b4e20da72042deb6725e5546..4844ddcbd4e5d1562a15fb913f2b15eebca43d0d 100644 (file)
@@ -21,13 +21,12 @@ package org.apache.fop.area;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.net.URI;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -36,9 +35,9 @@ import org.xml.sax.SAXException;
 
 import org.apache.commons.io.IOUtils;
 
-import org.apache.fop.ResourceEventProducer;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.io.TempResourceURIGenerator;
 import org.apache.fop.fonts.FontInfo;
 
 /**
@@ -49,10 +48,12 @@ import org.apache.fop.fonts.FontInfo;
  */
 public class CachedRenderPagesModel extends RenderPagesModel {
 
-    private Map<PageViewport, String> pageMap = new HashMap<PageViewport, String>();
+    private Map<PageViewport, URI> pageMap = new HashMap<PageViewport, URI>();
 
     /** Base directory to save temporary file in, typically points to the user's temp dir. */
-    protected File baseDir;
+    private final URI tempBaseURI;
+    private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+            = new TempResourceURIGenerator("cached-pages");
 
     /**
      * Main Constructor
@@ -65,8 +66,7 @@ public class CachedRenderPagesModel extends RenderPagesModel {
     public CachedRenderPagesModel (FOUserAgent userAgent, String outputFormat,
             FontInfo fontInfo, OutputStream stream) throws FOPException {
         super(userAgent, outputFormat, fontInfo, stream);
-        //TODO: Avoid System.getProperty()?
-        this.baseDir = new File(System.getProperty("java.io.tmpdir"));
+        tempBaseURI = TEMP_URI_GENERATOR.generate();
     }
 
     /** {@inheritDoc} */
@@ -78,27 +78,19 @@ public class CachedRenderPagesModel extends RenderPagesModel {
                 if (pageViewport != newpage) {
                     try {
                         // load page from cache
-                        String name = pageMap.get(pageViewport);
-                        File tempFile = new File(baseDir, name);
-                        log.debug("Loading page from: " + tempFile);
-                        ObjectInputStream in = new ObjectInputStream(
-                                             new BufferedInputStream(
-                                               new FileInputStream(tempFile)));
+                        URI tempURI = pageMap.get(pageViewport);
+                        log.debug("Loading page from: " + tempURI);
+                        InputStream inStream = renderer.getUserAgent().getNewURIResolver().resolveIn(tempURI);
+                        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(inStream));
                         try {
                             pageViewport.loadPage(in);
                         } finally {
+                            IOUtils.closeQuietly(inStream);
                             IOUtils.closeQuietly(in);
                         }
-                        if (!tempFile.delete()) {
-                            ResourceEventProducer eventProducer
-                                = ResourceEventProducer.Provider.get(
-                                        renderer.getUserAgent().getEventBroadcaster());
-                            eventProducer.cannotDeleteTempFile(this, tempFile);
-                        }
                         pageMap.remove(pageViewport);
                     } catch (Exception e) {
-                        AreaEventProducer eventProducer
-                            = AreaEventProducer.Provider.get(
+                        AreaEventProducer eventProducer = AreaEventProducer.Provider.get(
                                 renderer.getUserAgent().getEventBroadcaster());
                         eventProducer.pageLoadError(this, pageViewport.getPageNumberString(), e);
                     }
@@ -131,18 +123,17 @@ public class CachedRenderPagesModel extends RenderPagesModel {
             // save page to cache
             ObjectOutputStream tempstream;
             String fname = "fop-page-" + page.getPageIndex() + ".ser";
-            File tempFile = new File(baseDir, fname);
-            tempFile.deleteOnExit();
-            tempstream = new ObjectOutputStream(new BufferedOutputStream(
-                                                new FileOutputStream(tempFile)));
+            URI tempURI = tempBaseURI.resolve(fname);
+            OutputStream outStream = renderer.getUserAgent().getNewURIResolver().resolveOut(tempURI);
+            tempstream = new ObjectOutputStream(new BufferedOutputStream(outStream));
             try {
                 page.savePage(tempstream);
             } finally {
                 IOUtils.closeQuietly(tempstream);
             }
-            pageMap.put(page, fname);
+            pageMap.put(page, tempURI);
             if (log.isDebugEnabled()) {
-                log.debug("Page saved to temporary file: " + tempFile);
+                log.debug("Page saved to temporary file: " + tempURI);
             }
         } catch (IOException ioe) {
             AreaEventProducer eventProducer
index 7b771776d816404c741e61394ba8e670cf5983c5..eb1e2bd83fb15f3e74b85156c57b3dfe05a6d2e9 100644 (file)
@@ -23,7 +23,6 @@ package org.apache.fop.fo.extensions.svg;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
-import java.io.File;
 import java.net.URI;
 
 import org.w3c.dom.Element;
@@ -73,7 +72,6 @@ public class SVGElement extends SVGObj {
 
         try {
             URI baseUri = getUserAgent().getNewURIResolver().getBaseURI();
-            baseUri = baseUri == null ? new File("").toURI() : baseUri;
             if (baseUri != null) {
                 SVGOMDocument svgdoc = (SVGOMDocument)doc;
                 svgdoc.setURLObject(baseUri.toURL());
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java b/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java
deleted file mode 100644 (file)
index c9d9ed1..0000000
+++ /dev/null
@@ -1,38 +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.hyphenation;
-
-import javax.xml.transform.Source;
-
-/**
- * <p>This interface is used to resolve relative URIs pointing to hyphenation tree files.</p>
- */
-public interface HyphenationTreeResolver {
-
-    /**
-     * Called to resolve an URI to a Source instance. The base URI needed by the URIResolver's
-     * resolve() method is defined to be implicitely available in this case. If the URI cannot
-     * be resolved, null is returned.
-     * @param href An href attribute, which may be relative or absolute.
-     * @return A Source object, or null if the href could not resolved.
-     */
-    Source resolve(String href);
-
-}
index 062b0e922ddd5091a5453c48d9a2eb7f9b278d9d..6959e07a1fb516983b2353087c76d463e142f56a 100644 (file)
 package org.apache.fop.hyphenation;
 
 import java.io.BufferedInputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
+import java.net.URISyntaxException;
 import java.util.Map;
 
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
 import org.xml.sax.InputSource;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.fop.apps.io.URIResolverWrapper;
+
 /**
  * <p>This class is the main entry point to the hyphenation package.
  * You can use only the static methods or create an instance.</p>
@@ -75,7 +74,7 @@ public final class Hyphenator {
      * @return the hyphenation tree
      */
     public static HyphenationTree getHyphenationTree(String lang,
-            String country, HyphenationTreeResolver resolver, Map hyphPatNames) {
+            String country, URIResolverWrapper resolver, Map hyphPatNames) {
         String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
         HyphenationTreeCache cache = getHyphenationTreeCache();
 
@@ -130,8 +129,8 @@ public final class Hyphenator {
      * @param hyphPatNames the map with user-configured hyphenation pattern file names
      * @return the hyphenation tree
      */
-    private static HyphenationTree getHyphenationTree2(String lang,
-            String country, HyphenationTreeResolver resolver, Map hyphPatNames) {
+    public static HyphenationTree getHyphenationTree2(String lang,
+            String country, URIResolverWrapper resolver, Map hyphPatNames) {
         String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
         HyphenationTreeCache cache = getHyphenationTreeCache();
 
@@ -226,25 +225,6 @@ public final class Hyphenator {
         return hTree;
     }
 
-    /**
-     * Load tree from serialized file or xml file
-     * using configuration settings
-     * @param key language key for the requested hyphenation file
-     * @param hyphenDir base directory to find hyphenation files in
-     * @return the requested HypenationTree or null if it is not available
-     */
-    public static HyphenationTree getUserHyphenationTree(String key,
-            String hyphenDir) {
-        final File baseDir = new File(hyphenDir);
-        HyphenationTreeResolver resolver = new HyphenationTreeResolver() {
-            public Source resolve(String href) {
-                File f = new File(baseDir, href);
-                return new StreamSource(f);
-            }
-        };
-        return getUserHyphenationTree(key, resolver);
-    }
-
     /**
      * Load tree from serialized file or xml file
      * using configuration settings
@@ -253,7 +233,7 @@ public final class Hyphenator {
      * @return the requested HypenationTree or null if it is not available
      */
     public static HyphenationTree getUserHyphenationTree(String key,
-            HyphenationTreeResolver resolver) {
+            URIResolverWrapper resolver) {
         HyphenationTree hTree = null;
         // I use here the following convention. The file name specified in
         // the configuration is taken as the base name. First we try
@@ -262,88 +242,58 @@ public final class Hyphenator {
 
         // first try serialized object
         String name = key + ".hyp";
-        Source source = resolver.resolve(name);
-        if (source != null) {
+        try {
+            InputStream in = getHyphenationTreeStream(name, resolver);
             try {
-                InputStream in = null;
-                if (source instanceof StreamSource) {
-                    in = ((StreamSource) source).getInputStream();
-                }
-                if (in == null) {
-                    if (source.getSystemId() != null) {
-                        in = new java.net.URL(source.getSystemId()).openStream();
-                    } else {
-                        throw new UnsupportedOperationException
-                            ("Cannot load hyphenation pattern file"
-                            + " with the supplied Source object: " + source);
-                    }
-                }
-                in = new BufferedInputStream(in);
-                try {
-                    hTree = readHyphenationTree(in);
-                } finally {
-                    IOUtils.closeQuietly(in);
-                }
-                return hTree;
-            } catch (IOException ioe) {
-                if (log.isDebugEnabled()) {
-                    log.debug("I/O problem while trying to load " + name, ioe);
-                }
+                hTree = readHyphenationTree(in);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+            return hTree;
+        } catch (IOException ioe) {
+            if (log.isDebugEnabled()) {
+                log.debug("I/O problem while trying to load " + name, ioe);
             }
         }
 
         // try the raw XML file
         name = key + ".xml";
-        source = resolver.resolve(name);
-        if (source != null) {
-            hTree = new HyphenationTree();
+        hTree = new HyphenationTree();
+        try {
+            InputStream in = getHyphenationTreeStream(name, resolver);
             try {
-                InputStream in = null;
-                if (source instanceof StreamSource) {
-                    in = ((StreamSource) source).getInputStream();
-                }
-                if (in == null) {
-                    if (source.getSystemId() != null) {
-                        in = new java.net.URL(source.getSystemId()).openStream();
-                    } else {
-                        throw new UnsupportedOperationException(
-                                "Cannot load hyphenation pattern file"
-                                    + " with the supplied Source object: " + source);
-                    }
-                }
-                if (!(in instanceof BufferedInputStream)) {
-                    in = new BufferedInputStream(in);
-                }
-                try {
-                    InputSource src = new InputSource(in);
-                    src.setSystemId(source.getSystemId());
-                    hTree.loadPatterns(src);
-                } finally {
-                    IOUtils.closeQuietly(in);
-                }
-                if (statisticsDump) {
-                    System.out.println("Stats: ");
-                    hTree.printStats();
-                }
-                return hTree;
-            } catch (HyphenationException ex) {
-                log.error("Can't load user patterns from XML file " + source.getSystemId()
-                        + ": " + ex.getMessage());
-                return null;
-            } catch (IOException ioe) {
-                if (log.isDebugEnabled()) {
-                    log.debug("I/O problem while trying to load " + name, ioe);
-                }
-                return null;
+                InputSource src = new InputSource(in);
+                src.setSystemId(name);
+                hTree.loadPatterns(src);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+            if (statisticsDump) {
+                System.out.println("Stats: ");
+                hTree.printStats();
             }
-        } else {
+            return hTree;
+        } catch (HyphenationException ex) {
+            log.error("Can't load user patterns from XML file " + name + ": " + ex.getMessage());
+            return null;
+        } catch (IOException ioe) {
             if (log.isDebugEnabled()) {
-                log.debug("Could not load user hyphenation file for '" + key + "'.");
+                log.debug("I/O problem while trying to load " + name, ioe);
             }
             return null;
         }
     }
 
+    private static InputStream getHyphenationTreeStream(String name, URIResolverWrapper resolver)
+            throws IOException {
+        try {
+            return new BufferedInputStream(resolver.resolveIn(name));
+        } catch (URISyntaxException use) {
+            log.debug("An exception was thrown while attempting to load " + name, use);
+        }
+        return null;
+    }
+
     /**
      * Hyphenates a word.
      * @param lang the language
@@ -356,15 +306,11 @@ public final class Hyphenator {
      * @return the hyphenation result
      */
     public static Hyphenation hyphenate(String lang, String country,
-                                        HyphenationTreeResolver resolver,
-                                        Map hyphPatNames,
-                                        String word,
-                                        int leftMin, int rightMin) {
+            URIResolverWrapper resolver, Map hyphPatNames, String word, int leftMin, int rightMin) {
         HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames);
         if (hTree == null) {
             return null;
         }
         return hTree.hyphenate(word, leftMin, rightMin);
     }
-
 }
index 0f959022ca25cef31e59bd0c39990c061bc434c5..2ad0eb82349352668625096b1e637f52efb9fac4 100644 (file)
@@ -1396,10 +1396,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager
         // TextLM which generate the hyphenation buffer,
         // since these properties inherit and could be specified
         // on an inline or wrapper below the block level.
-        Hyphenation hyph
-            = Hyphenator.hyphenate(hyphenationProperties.language.getString(),
+        Hyphenation hyph = Hyphenator.hyphenate(hyphenationProperties.language.getString(),
                                hyphenationProperties.country.getString(),
-                               getFObj().getUserAgent().getHyphenationTreeResolver(),
+                               getFObj().getUserAgent().getNewURIResolver(),
                                getFObj().getUserAgent().getHyphPatNames(),
                                sbChars.toString(),
                                hyphenationProperties.hyphenationRemainCharacterCount.getValue(),
index 9850c605e3c2056fc57d4c95b97eb7e732fbbc85..dad404d1148fd6ece0ae5540cd4f5442c1c39b2a 100644 (file)
@@ -21,7 +21,6 @@ package org.apache.fop.pdf;
 
 // Java
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.security.NoSuchAlgorithmException;
@@ -718,24 +717,6 @@ public class PDFDocument {
         return this.fontMap;
     }
 
-    /**
-     * Resolve a URI.
-     *
-     * @param uri the uri to resolve
-     * @throws java.io.FileNotFoundException if the URI could not be resolved
-     * @return the InputStream from the URI.
-     */
-    protected InputStream resolveURI(String uri)
-        throws java.io.FileNotFoundException {
-        try {
-            /* TODO: Temporary hack to compile, improve later */
-            return new java.net.URL(uri).openStream();
-        } catch (Exception e) {
-            throw new java.io.FileNotFoundException(
-                "URI could not be resolved (" + e.getMessage() + "): " + uri);
-        }
-    }
-
     /**
      * Get an image from the image map.
      *
index 4e2d12eb2bf6dd959d29987f78058cec41960ff1..aa4d665daa4e71fd4a388a3a66135d59f7f1ba22 100644 (file)
@@ -24,56 +24,24 @@ import java.io.IOException;
 /**
  * This class is serves as a factory from
  */
-public class StreamCacheFactory {
+public final class StreamCacheFactory {
 
-    private static boolean defaultCacheToFile = false;
-    private static StreamCacheFactory fileInstance = null;
-    private static StreamCacheFactory memoryInstance = null;
-
-    private boolean cacheToFile = false;
+    private static StreamCacheFactory memoryInstance = new StreamCacheFactory();
 
     /**
      * Returns an instance of a StreamCacheFactory with the requested features.
      * @param cacheToFile True if file shall be cached using a temporary file
      * @return StreamCacheFactory the requested factory
      */
-    public static StreamCacheFactory getInstance(boolean cacheToFile) {
-        if (cacheToFile) {
-            if (fileInstance == null) {
-                fileInstance = new StreamCacheFactory(true);
-            }
-            return fileInstance;
-        } else {
-            if (memoryInstance == null) {
-                memoryInstance = new StreamCacheFactory(false);
-            }
-            return memoryInstance;
-        }
-    }
-
-    /**
-     * Returns an instance of a StreamCacheFactory depending on the default
-     * setting for cacheToFile.
-     * @return StreamCacheFactory the requested factory
-     */
     public static StreamCacheFactory getInstance() {
-        return getInstance(defaultCacheToFile);
-    }
-
-    /**
-     * Sets the global default for cacheToFile
-     * @param cacheToFile True if stream caches should be held in files.
-     */
-    public static void setDefaultCacheToFile(boolean cacheToFile) {
-        defaultCacheToFile = cacheToFile;
+        return memoryInstance;
     }
 
     /**
      * Creates a new StreamCacheFactory.
      * @param cacheToFile True if file shall be cached using a temporary file
      */
-    public StreamCacheFactory(boolean cacheToFile) {
-        this.cacheToFile = cacheToFile;
+    private StreamCacheFactory() {
     }
 
     /**
@@ -83,11 +51,7 @@ public class StreamCacheFactory {
      * @return a new StreamCache for caching streams
      */
     public StreamCache createStreamCache() throws IOException {
-        if (this.cacheToFile) {
-            return new TempFileStreamCache();
-        } else {
-            return new InMemoryStreamCache();
-        }
+        return new InMemoryStreamCache();
     }
 
     /**
@@ -98,20 +62,6 @@ public class StreamCacheFactory {
      * @return a new StreamCache for caching streams
      */
     public StreamCache createStreamCache(int hintSize) throws IOException {
-        if (this.cacheToFile) {
-            return new TempFileStreamCache();
-        } else {
-            return new InMemoryStreamCache(hintSize);
-        }
-    }
-
-    /**
-     * Get the value of the global cacheToFile flag.
-     * @return the current cache to file flag
-     */
-    public boolean getCacheToFile() {
-        return this.cacheToFile;
+        return new InMemoryStreamCache(hintSize);
     }
-
-
 }
index 0a5324384af67ee222e8858ab075e56678e70da2..24a91d9e3e11f9aa6f4f20e81b226306d6b15b72 100644 (file)
 
 package org.apache.fop.render.intermediate;
 
-import java.io.File;
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.net.URL;
+import java.net.URI;
 
 import javax.xml.transform.Result;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 
 import org.apache.fop.fonts.FontCollection;
@@ -56,7 +55,7 @@ public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFD
     /** {@inheritDoc} */
     public void setResult(Result result) throws IFException {
         if (result instanceof StreamResult) {
-            StreamResult streamResult = (StreamResult)result;
+            StreamResult streamResult = (StreamResult) result;
             OutputStream out = streamResult.getOutputStream();
             if (out == null) {
                 if (streamResult.getWriter() != null) {
@@ -64,22 +63,13 @@ public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFD
                             "FOP cannot use a Writer. Please supply an OutputStream!");
                 }
                 try {
-                    URL url = new URL(streamResult.getSystemId());
-                    File f = FileUtils.toFile(url);
-                    if (f != null) {
-                        out = new java.io.FileOutputStream(f);
-                    } else {
-                        out = url.openConnection().getOutputStream();
-                    }
+                    URI resultURI = URI.create(streamResult.getSystemId());
+                    out = new BufferedOutputStream(getUserAgent().getNewURIResolver().resolveOut(resultURI));
                 } catch (IOException ioe) {
                     throw new IFException("I/O error while opening output stream" , ioe);
                 }
-                out = new java.io.BufferedOutputStream(out);
                 this.ownOutputStream = true;
             }
-            if (out == null) {
-                throw new IllegalArgumentException("Need a StreamResult with an OutputStream");
-            }
             this.outputStream = out;
         } else {
             throw new UnsupportedOperationException(
index 0ba85146cdfe27a2ce74102d710dc67149a2098a..d2e06d76fbf8dce9266ddd67c8d11db3ffa46219 100644 (file)
@@ -274,7 +274,6 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
     public void endPageContent() throws IFException {
         if (this.currentImage != null) {
             try {
-                //ImageWriterUtil.saveAsPNG(this.currentImage, new java.io.File("D:/page.png"));
                 Rectangle printArea = this.currentPageDefinition.getLogicalPageRect();
                 gen.setCursorPos(0, 0);
                 gen.paintBitmap(this.currentImage, printArea.getSize(), true);
index 29fe77323bc1319fcd4e18e7a279ddc6c8c9f25f..0db295a5a36ec4e4c8a1d94345e14655b13b382d 100644 (file)
@@ -677,13 +677,6 @@ public class PCLGenerator {
             } finally {
                 g2d.dispose();
             }
-            /*
-            try {
-                BatchDiffer.saveAsPNG(alpha, new java.io.File("D:/out-alpha.png"));
-                BatchDiffer.saveAsPNG(mask, new java.io.File("D:/out-mask.png"));
-            } catch (IOException e) {
-                e.printStackTrace();
-            }*/
             return mask;
         } else {
             return null;
@@ -715,7 +708,6 @@ public class PCLGenerator {
                     (int)Math.ceil(UnitConv.mpt2px(targetDim.height, effResolution)));
         }
         boolean scaled = !orgDim.equals(effDim);
-        //ImageWriterUtil.saveAsPNG(img, new java.io.File("D:/text-0-org.png"));
 
         boolean monochrome = isMonochromeImage(img);
         if (!monochrome) {
index 76e9b66e509199f15ab79cbd1c12b8738b2f996c..a126fc1767b1deb65dc808947e3b0b8f4719c0d8 100644 (file)
@@ -22,10 +22,12 @@ package org.apache.fop.render.ps;
 import java.awt.Dimension;
 import java.awt.geom.Dimension2D;
 import java.awt.geom.Rectangle2D;
-import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -51,6 +53,7 @@ import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox;
 import org.apache.xmlgraphics.ps.dsc.events.DSCCommentHiResBoundingBox;
 
 import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.io.TempResourceURIGenerator;
 import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
 import org.apache.fop.render.intermediate.IFContext;
 import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
@@ -83,7 +86,9 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
     protected PSGenerator gen;
 
     /** the temporary file in case of two-pass processing */
-    private File tempFile;
+    private URI tempURI;
+    private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+            = new TempResourceURIGenerator("ps-optimize");
 
     private int currentPageNumber = 0;
     private PageDefinition currentPageDefinition;
@@ -141,11 +146,10 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
         super.startDocument();
         this.fontResources = new FontResourceCache(getFontInfo());
         try {
-            OutputStream out;
+            final OutputStream out;
             if (psUtil.isOptimizeResources()) {
-                this.tempFile = File.createTempFile("fop", null);
-                out = new java.io.FileOutputStream(this.tempFile);
-                out = new java.io.BufferedOutputStream(out);
+                tempURI = TEMP_URI_GENERATOR.generate();
+                out = new BufferedOutputStream(getUserAgent().getNewURIResolver().resolveOut(tempURI));
             } else {
                 out = this.outputStream;
             }
@@ -252,8 +256,7 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
         log.debug("Processing PostScript resources...");
         long startTime = System.currentTimeMillis();
         ResourceTracker resTracker = gen.getResourceTracker();
-        InputStream in = new java.io.FileInputStream(this.tempFile);
-        in = new java.io.BufferedInputStream(in);
+        InputStream in = new BufferedInputStream(getUserAgent().getNewURIResolver().resolveIn(tempURI));
         try {
             try {
                 ResourceHandler handler = new ResourceHandler(getUserAgent(), this.fontInfo,
@@ -266,10 +269,6 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
             }
         } finally {
             IOUtils.closeQuietly(in);
-            if (!this.tempFile.delete()) {
-                this.tempFile.deleteOnExit();
-                log.warn("Could not delete temporary file: " + this.tempFile);
-            }
         }
         if (log.isDebugEnabled()) {
             long duration = System.currentTimeMillis() - startTime;
index e7c8f04b557dd895f6aff34e42c80e5b97b71a48..15db719e9af6e135bb7cd47cb7c3e762d4e2b275 100644 (file)
@@ -21,21 +21,16 @@ package org.apache.fop.util;
 
 import java.awt.color.ColorSpace;
 import java.awt.color.ICC_Profile;
-import java.net.URI;
-import java.net.URISyntaxException;
+import java.io.InputStream;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
-import javax.xml.transform.Source;
-import javax.xml.transform.URIResolver;
-import javax.xml.transform.stream.StreamSource;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent;
 import org.apache.xmlgraphics.java2d.color.RenderingIntent;
-import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
 
 import org.apache.fop.apps.io.URIResolverWrapper;
 
@@ -46,15 +41,14 @@ public class ColorSpaceCache {
     /** logger instance */
     private static Log log = LogFactory.getLog(ColorSpaceCache.class);
 
-    private URIResolver resolver;
-    private Map<String, ColorSpace> colorSpaceMap
-            = Collections.synchronizedMap(new java.util.HashMap<String, ColorSpace>());
+    private URIResolverWrapper resolver;
+    private Map<String, ColorSpace> colorSpaceMap = Collections.synchronizedMap(new HashMap<String, ColorSpace>());
 
     /**
      * Default constructor
      * @param resolver uri resolver
      */
-    public ColorSpaceCache(URIResolver resolver) {
+    public ColorSpaceCache(URIResolverWrapper resolver) {
         this.resolver = resolver;
     }
 
@@ -73,28 +67,21 @@ public class ColorSpaceCache {
      * @param renderingIntent overriding rendering intent
      * @return ICC ColorSpace object or null if ColorSpace could not be created
      */
-    public ColorSpace get(String profileName, String base, String iccProfileSrc,
+    public ColorSpace get(String profileName, String iccProfileSrc,
             RenderingIntent renderingIntent) {
-        String key = profileName + ":" + base + iccProfileSrc;
+        String key = profileName + ":" + iccProfileSrc;
         // TODO: This stuff needs some TLC, fix it!!
-        try {
-            URI uri = URIResolverWrapper.getBaseURI(base);
-            key = uri.resolve(URIResolverWrapper.cleanURI(iccProfileSrc)).toASCIIString();
-        } catch (URISyntaxException e) {
-            // TODO: handle this
-        }
         ColorSpace colorSpace = null;
         if (!colorSpaceMap.containsKey(key)) {
             try {
                 ICC_Profile iccProfile = null;
                 // First attempt to use the FOP URI resolver to locate the ICC
                 // profile
-                Source src = resolver.resolve(iccProfileSrc, base);
-                if (src != null && src instanceof StreamSource) {
+                InputStream stream = resolver.resolveIn(iccProfileSrc);
+                if (stream != null) {
                     // FOP URI resolver found ICC profile - create ICC profile
                     // from the Source
-                    iccProfile = ColorProfileUtil.getICC_Profile(((StreamSource) src)
-                            .getInputStream());
+                    iccProfile = ICC_Profile.getInstance(stream);
                 } else {
                     // TODO - Would it make sense to fall back on VM ICC
                     // resolution
index c03130f2d63b7058bc6b7db11e8964bcfe8ff93b..b1819265726c14e5dfb68bb4a462f7f6470fb12f 100644 (file)
@@ -405,9 +405,7 @@ public final class ColorUtil {
                     RenderingIntent renderingIntent = RenderingIntent.AUTO;
                     //TODO connect to fo:color-profile/@rendering-intent
                     colorSpace = foUserAgent.getColorSpaceCache().get(
-                            iccProfileName,
-                            foUserAgent.getNewURIResolver().getBaseURI().toASCIIString(),
-                            iccProfileSrc, renderingIntent);
+                            iccProfileName, iccProfileSrc, renderingIntent);
                 }
                 if (colorSpace != null) {
                     // ColorSpace is available
@@ -489,9 +487,7 @@ public final class ColorUtil {
                     RenderingIntent renderingIntent = RenderingIntent.AUTO;
                     //TODO connect to fo:color-profile/@rendering-intent
                     colorSpace = (ICC_ColorSpace)foUserAgent.getColorSpaceCache().get(
-                            iccProfileName,
-                            foUserAgent.getNewURIResolver().getBaseURI().toASCIIString(),
-                            iccProfileSrc, renderingIntent);
+                            iccProfileName, iccProfileSrc, renderingIntent);
                 }
                 if (colorSpace != null) {
                     ICC_Profile profile = colorSpace.getProfile();
index ca9dd1440dea2a2ea4e6e00e3f6c6afd0e3e570a..2fe939f767f51bf32eac49d6066307bed41775fe 100644 (file)
@@ -86,14 +86,6 @@ public class FopConfParserTestCase {
         assertFalse(buildFactory().isAccessibilityEnabled());
     }
 
-    @Test
-    public void testHyphenationBaseURI() {
-        String hyphBaseURI = "./test/base/uri/";
-        builder.setHyphenationBaseURI(hyphBaseURI);
-        assertEquals(baseURI.resolve(hyphBaseURI),
-                URI.create(buildFactory().getHyphenBaseURI()));
-    }
-
     @Test
     public void testSourceResolution() {
         float srcRes = 123.456f;
diff --git a/test/java/org/apache/fop/config/FOURIResolverTestCase.java b/test/java/org/apache/fop/config/FOURIResolverTestCase.java
deleted file mode 100644 (file)
index 0358638..0000000
+++ /dev/null
@@ -1,59 +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.config;
-
-import static org.junit.Assert.fail;
-
-import java.net.MalformedURLException;
-
-import org.apache.fop.apps.io.FOURIResolver;
-import org.junit.Test;
-
-/**
- * This tests some aspects of the {@link FOURIResolver} class.
- */
-public class FOURIResolverTestCase {
-
-    /**
-     * Checks the {@link FOURIResolver#checkBaseURL(String)} method.
-     * @throws Exception if an error occurs
-     */
-    @Test
-    public void testCheckBaseURI() throws Exception {
-        FOURIResolver resolver = new FOURIResolver(true);
-        System.out.println(resolver.checkBaseURL("./test/config"));
-        System.out.println(resolver.checkBaseURL("file:test/config"));
-        System.out.println(resolver.checkBaseURL("fantasy:myconfig"));
-        System.out.println(resolver.checkBaseURL("file:test\\config\\"));
-        try {
-            resolver.checkBaseURL("./doesnotexist");
-            fail("Expected an exception for a inexistent base directory");
-        } catch (MalformedURLException mfue) {
-            //expected
-        }
-        try {
-            resolver.checkBaseURL("file:doesnotexist");
-            fail("Expected an exception for a inexistent base URI");
-        } catch (MalformedURLException mfue) {
-            //expected
-        }
-    }
-
-}
index 91329f6ec05c0742ea9fb73461964c7d0e9a0a2d..9cb5c4270bfc4d93abea6b566560a4f9184bb390 100644 (file)
@@ -34,8 +34,7 @@ import org.junit.runners.Suite.SuiteClasses;
         FontMetricsUrlMalformedTestCase.class,
         FontsDirectoryRecursiveTestCase.class,
         FontsAutoDetectTestCase.class,
-        FontsSubstitutionTestCase.class,
-        FOURIResolverTestCase.class
+        FontsSubstitutionTestCase.class
 })
 public class UserConfigTestSuite {
 }
index c45b4d1f4d72e8be4be82a4b4b877e5d85f22feb..7e03b2e8b80959b3e779b49133dcfb12657b8c18 100644 (file)
@@ -28,7 +28,6 @@ import java.util.Set;
 
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-import javax.xml.transform.URIResolver;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -52,7 +51,6 @@ import org.apache.fop.apps.FopFactoryConfig;
 import org.apache.fop.apps.io.ResourceResolver;
 import org.apache.fop.fonts.FontManager;
 import org.apache.fop.fotreetest.ext.TestElementMapping;
-import org.apache.fop.hyphenation.HyphenationTreeResolver;
 import org.apache.fop.layoutengine.LayoutEngineTestUtils;
 import org.apache.fop.layoutengine.TestFilesConfiguration;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
@@ -209,22 +207,10 @@ public class FOTreeTestCase {
             return delegate.getNewURIResolver();
         }
 
-        public URIResolver getURIResolver() {
-            return delegate.getURIResolver();
-        }
-
         public URI getBaseURI() {
             return delegate.getBaseURI();
         }
 
-        public URI getHyphenationBaseURI() {
-            return delegate.getHyphenationBaseURI();
-        }
-
-        public HyphenationTreeResolver getHyphenationTreeResolver() {
-            return delegate.getHyphenationTreeResolver();
-        }
-
         public boolean validateStrictly() {
             return delegate.validateStrictly();
         }
index 6271b18de825a7c427940b1e98d58b75a473ba15..6e65004a377bfed72dfb5ee794f7fec634279817 100644 (file)
@@ -44,7 +44,6 @@ import static org.junit.Assert.assertTrue;
  */
 public class ColorUtilTestCase {
     private FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
-    private final String thisDirectory = "file:" + new File("./").getAbsolutePath();
 
     /**
      * Test serialization to String.
@@ -131,7 +130,7 @@ public class ColorUtilTestCase {
         FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
         URI sRGBLoc = new URI("src/java/org/apache/fop/pdf/sRGB%20Color%20Space%20Profile.icm");
         ColorSpace cs = fopFactory.getColorSpaceCache().get(
-                "sRGBAlt", thisDirectory, sRGBLoc.toASCIIString(), RenderingIntent.AUTO);
+                "sRGBAlt", sRGBLoc.toASCIIString(), RenderingIntent.AUTO);
         assertNotNull("Color profile not found", cs);
 
         FOUserAgent ua = fopFactory.newFOUserAgent();
@@ -300,7 +299,7 @@ public class ColorUtilTestCase {
         FopFactory fopFactory = FopFactory.newInstance(new File("./").toURI());
         URI ncpLoc = new URI("test/resources/color/ncp-example.icc");
         ColorSpace cs = fopFactory.getColorSpaceCache().get(
-                "NCP", thisDirectory, ncpLoc.toASCIIString(), RenderingIntent.AUTO);
+                "NCP", ncpLoc.toASCIIString(), RenderingIntent.AUTO);
         assertNotNull("Color profile not found", cs);
 
         FOUserAgent ua = fopFactory.newFOUserAgent();
index 8508cad8b643bce123c92f5a732d9b39da5cd890..0e8b333d8fc4d8f9eb9833bd315d5d7e1edef77f 100644 (file)
@@ -33,7 +33,7 @@
         <fo:flow flow-name="xsl-region-body">
           <fo:block>Image referenced by RFC 2397 "data" URL:</fo:block>
           <fo:block>
-            <fo:external-graphic src="url(&quot;data:image/gif;base64, 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&#xA;&quot;)"/>EOG
+            <fo:external-graphic src="url(&quot;data:image/gif;base64,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&#xA;&quot;)"/>EOG
           </fo:block>
           <fo:block>EOF</fo:block>
         </fo:flow>