Renamed FOUserAgent.getStream() to FOUserAgent.resolveURI() which now simply returns a Source instance which the ImageFactory uses to get at an InputStream somehow. Submitted by: Manuel Mall <mm.at.arcus.com.au> git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@232949 13f79535-47bb-0310-9956-ffa450edef68pull/31/head
@@ -33,31 +33,34 @@ import org.apache.commons.logging.LogFactory; | |||
* @see javax.xml.transform.URIResolver | |||
*/ | |||
public class FOURIResolver | |||
implements javax.xml.transform.URIResolver | |||
{ | |||
implements javax.xml.transform.URIResolver { | |||
private Log log = LogFactory.getLog("FOP"); | |||
/** | |||
* Called by the processor through {@link FOUserAgent} when it encounters an uri in an external-graphic element. | |||
* Called by the processor through {@link FOUserAgent} when it encounters an | |||
* uri in an external-graphic element. | |||
* (see also {@link javax.xml.transform.URIResolver#resolve(String, String)} | |||
* This resolver will allow URLs without a scheme, i.e. it assumes 'file:' as the default | |||
* scheme. It also allows relative URLs with scheme, e.g. file:../../abc.jpg which is | |||
* not strictly RFC compliant as long as the scheme is the same as the scheme of the | |||
* base URL. If the base URL is null a 'file:' URL referencing the current directory is used as | |||
* the base URL. | |||
* This resolver will allow URLs without a scheme, i.e. it assumes 'file:' as | |||
* the default scheme. It also allows relative URLs with scheme, | |||
* e.g. file:../../abc.jpg which is not strictly RFC compliant as long as the | |||
* scheme is the same as the scheme of the base URL. If the base URL is null | |||
* a 'file:' URL referencing the current directory is used as the base URL. | |||
* If the method is successful it will return a Source of type | |||
* {@link javax.xml.transform.stream.StreamSource} with its SystemID set to the resolved | |||
* URL used to open the underlying InputStream. | |||
* {@link javax.xml.transform.stream.StreamSource} with its SystemID set to | |||
* the resolved URL used to open the underlying InputStream. | |||
* | |||
* @param href An href attribute, which may be relative or absolute. | |||
* @param base The base URI against which the first argument will be made absolute if the absolute URI is required. | |||
* @return A {@link javax.xml.transform.Source} object, or null if the href cannot be resolved. | |||
* @throws TransformerException Never thrown by this implementation. | |||
* @param base The base URI against which the first argument will be made | |||
* absolute if the absolute URI is required. | |||
* @return A {@link javax.xml.transform.Source} object, or null if the href | |||
* cannot be resolved. | |||
* @throws javax.xml.transform.TransformerException Never thrown by this implementation. | |||
* @see javax.xml.transform.URIResolver#resolve(String, String) | |||
*/ | |||
public Source resolve(String href, String base) | |||
throws javax.xml.transform.TransformerException | |||
{ | |||
throws javax.xml.transform.TransformerException { | |||
URL absoluteURL = null; | |||
URL baseURL = toBaseURL(base); | |||
if (baseURL == null) { | |||
@@ -120,8 +123,7 @@ public class FOURIResolver | |||
* @param baseURL the base URL | |||
* @returns the base URL as java.net.URL | |||
*/ | |||
private URL toBaseURL(String baseURL) | |||
{ | |||
private URL toBaseURL(String baseURL) { | |||
try { | |||
return new URL(baseURL == null | |||
? new java.io.File("").toURL().toExternalForm() |
@@ -20,14 +20,12 @@ package org.apache.fop.apps; | |||
// Java | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Map; | |||
import javax.xml.transform.Source; | |||
import javax.xml.transform.TransformerException; | |||
import javax.xml.transform.URIResolver; | |||
import javax.xml.transform.stream.StreamSource; | |||
// avalon configuration | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
@@ -409,7 +407,7 @@ public class FOUserAgent { | |||
* @return the URI Resolver | |||
*/ | |||
public URIResolver getURIResolver() { | |||
return this.uriResolver != null ? this.uriResolver : this.foURIResolver; | |||
return this.uriResolver; | |||
} | |||
/** | |||
@@ -431,29 +429,33 @@ public class FOUserAgent { | |||
/** | |||
* Get a stream source for a reference. Subclass FOUserAgent and override this method to | |||
* do custom URI to {@link javax.xml.transform.stream.StreamSource} resolution. | |||
* Alternatively set your own {@link javax.xml.transform.URIResolver} on the FOUserAgent. | |||
* Temporary solution until the API is better. | |||
* Attempts to resolve the given URI. | |||
* Will use the configured resolver and if not successful fall back | |||
* to the default resolver. | |||
* @param uri URI to access | |||
* @return StreamSource for accessing the resource. | |||
* @throws IOException in case of an I/O problem | |||
* @return A {@link javax.xml.transform.Source} object, or null if the URI | |||
* cannot be resolved. | |||
* @see org.apache.fop.apps.FOURIResolver | |||
*/ | |||
public StreamSource getStream(String uri) throws IOException { | |||
public Source resolveURI(String uri) { | |||
Source source = null; | |||
try { | |||
source = getURIResolver().resolve(uri, getBaseURL()); | |||
} catch (TransformerException te) { | |||
log.error("Attempt to resolve URI '" + uri + "' failed: ", te); | |||
URIResolver uriResolver = getURIResolver(); | |||
if (uriResolver != null) { | |||
try { | |||
source = uriResolver.resolve(uri, getBaseURL()); | |||
} catch (TransformerException te) { | |||
log.error("Attempt to resolve URI '" + uri + "' failed: ", te); | |||
} | |||
} | |||
if (source != null) { | |||
if (source instanceof StreamSource) { | |||
return (StreamSource)source; | |||
} else { | |||
log.error("Attempt to resolve URI returned unknown source"); | |||
if (source == null) { | |||
// URI Resolver not configured or returned null, use default resolver | |||
try { | |||
source = foURIResolver.resolve(uri, getBaseURL()); | |||
} catch (TransformerException te) { | |||
log.error("Attempt to resolve URI '" + uri + "' failed: ", te); | |||
} | |||
} | |||
return null; | |||
return source; | |||
} | |||
/** |
@@ -19,7 +19,6 @@ | |||
package org.apache.fop.image; | |||
// Java | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.lang.reflect.Constructor; | |||
import java.util.ArrayList; | |||
@@ -29,6 +28,7 @@ import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import javax.xml.transform.Source; | |||
import javax.xml.transform.stream.StreamSource; | |||
import org.apache.commons.logging.Log; | |||
@@ -196,12 +196,28 @@ public final class ImageFactory { | |||
*/ | |||
public FopImage loadImage(String href, FOUserAgent ua) { | |||
StreamSource source = openStream(href, ua); | |||
Source source = ua.resolveURI(href); | |||
if (source == null) { | |||
return null; | |||
} | |||
// Got a valid source, obtain an InputStream from it | |||
InputStream in = null; | |||
if (source instanceof StreamSource) { | |||
in = ((StreamSource)source).getInputStream(); | |||
} | |||
if (in == null) { | |||
try { | |||
in = new java.net.URL(source.getSystemId()).openStream(); | |||
} catch (Exception ex) { | |||
log.error("Unable to obtain stream from id '" | |||
+ source.getSystemId() + "'"); | |||
} | |||
} | |||
if (in == null) { | |||
return null; | |||
} | |||
InputStream in = source.getInputStream(); | |||
//Make sure the InputStream is decorated with a BufferedInputStream | |||
if (!(in instanceof java.io.BufferedInputStream)) { | |||
in = new java.io.BufferedInputStream(in); | |||
@@ -277,26 +293,6 @@ public final class ImageFactory { | |||
return (FopImage) imageInstance; | |||
} | |||
/** | |||
* Create a StreamSource objects. | |||
* @param href image URL as a String | |||
* @param ua user agent | |||
* @return a new StreamSource object | |||
*/ | |||
protected StreamSource openStream(String href, FOUserAgent ua) { | |||
StreamSource in = null; | |||
try { | |||
in = ua.getStream(href); | |||
} catch (IOException ioe) { | |||
log.error("Error while opening stream for (" | |||
+ href + "): " + ioe.getMessage(), ioe); | |||
return null; | |||
} | |||
return in; | |||
} | |||
private Class getImageClass(String imgMimeType) { | |||
ImageMimeType imt = (ImageMimeType)imageMimeTypes.get(imgMimeType); | |||
if (imt == null) { |
@@ -19,7 +19,6 @@ | |||
package org.apache.fop; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.OutputStream; | |||
import javax.xml.transform.Result; | |||
@@ -75,8 +74,10 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { | |||
Document doc = createAreaTree(foFile, ua); | |||
//Check how many times the resolver was consulted | |||
assertEquals(1, resolver.successCount); | |||
assertEquals(0, resolver.failureCount); | |||
assertEquals("Expected resolver to do 1 successful URI resolution", | |||
1, resolver.successCount); | |||
assertEquals("Expected resolver to do 0 failed URI resolution", | |||
0, resolver.failureCount); | |||
//Additional XPath checking on the area tree | |||
assertEquals("viewport for external-graphic is missing", | |||
"true", evalXPath(doc, "boolean(//flow/block[1]/lineArea/viewport)")); | |||
@@ -89,6 +90,7 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { | |||
* @throws Exception if anything fails | |||
*/ | |||
public void testFO2() throws Exception { | |||
//TODO This will only work when we can do URI resolution inside Batik! | |||
File foFile = new File(getBaseDir(), "test/xml/uri-resolution2.fo"); | |||
FOUserAgent ua = new FOUserAgent(); | |||
@@ -115,8 +117,10 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { | |||
} | |||
//Check how many times the resolver was consulted | |||
assertEquals(1, resolver.successCount); | |||
assertEquals(0, resolver.failureCount); | |||
assertEquals("Expected resolver to do 1 successful URI resolution", | |||
1, resolver.successCount); | |||
assertEquals("Expected resolver to do 0 failed URI resolutions", | |||
0, resolver.failureCount); | |||
//Test using PDF as the area tree doesn't invoke Batik so we could check | |||
//if the resolver is actually passed to Batik by FOP | |||
assertTrue("Generated PDF has zero length", baout.size() > 0); | |||
@@ -185,12 +189,6 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { | |||
if ("myimage123".equals(name)) { | |||
File image = new File(getBaseDir(), "test/resources/images/bgimg300dpi.jpg"); | |||
StreamSource src = new StreamSource(image); | |||
try { | |||
//TODO The next line should not be necessary!!! | |||
src.setInputStream(new java.io.FileInputStream(image)); | |||
} catch (FileNotFoundException e) { | |||
throw new TransformerException(e.getMessage(), e); | |||
} | |||
successCount++; | |||
return src; | |||
} else { |