Browse Source

Bugzilla #36082

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-ffa450edef68
pull/31/head
Jeremias Maerki 19 years ago
parent
commit
a62babfa7e

+ 19
- 17
src/java/org/apache/fop/apps/FOURIResolver.java View File

@@ -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()

+ 22
- 20
src/java/org/apache/fop/apps/FOUserAgent.java View File

@@ -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
- 23
src/java/org/apache/fop/image/ImageFactory.java View File

@@ -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) {

+ 9
- 11
test/java/org/apache/fop/URIResolutionTestCase.java View File

@@ -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 {

Loading…
Cancel
Save