* @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) {
* @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()
// 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;
* @return the URI Resolver
*/
public URIResolver getURIResolver() {
- return this.uriResolver != null ? this.uriResolver : this.foURIResolver;
+ return this.uriResolver;
}
/**
/**
- * 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;
}
/**
package org.apache.fop.image;
// Java
-import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
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;
*/
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);
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) {
package org.apache.fop;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.OutputStream;
import javax.xml.transform.Result;
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)"));
* @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();
}
//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);
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 {