diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-08-15 10:34:31 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-08-15 10:34:31 +0000 |
commit | a349b7be0b545f1e17dda314d6622d2f60458821 (patch) | |
tree | fb57b8092d8fdbb05a56f854e3cdca34247e531c /src/java/org/apache/fop/apps | |
parent | d432b9cdfb206b1dbaeb51167c40a141af71c4ae (diff) | |
download | xmlgraphics-fop-a349b7be0b545f1e17dda314d6622d2f60458821.tar.gz xmlgraphics-fop-a349b7be0b545f1e17dda314d6622d2f60458821.zip |
Bugzilla #36082
1. Addresses the URI resolving issue as discussed in this bug by providing a
FOP implementation of the URIResolver interface as well as the capabilities to
set a URIResolver on the FOUserAgent object.
2. Modifies the BMPReader to extract the resolution information.
3. Fixes a possible array bounds exception in BMPImage which can happen for BMP
images with extra bytes at the end.
4. Provides some infrastructure in ImageFactory in preparation of external
configuration of multiple prioritised image providers per mime type.
5. Sets a proper base URL in SVGElement.
6. Provides test cases and test images for the different formats and
resolutions.
Submitted by: Manuel Mall <mm.at.arcus.com.au>
Patch slightly modified:
- EPS sample graphic exchanged with a very simple and more importantly much smaller one generated by Barcode4J.
- Enabled resolution checking for some of the format-specific testcases (especially after working around resolution detection for PNG)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@232786 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/apps')
-rw-r--r-- | src/java/org/apache/fop/apps/FOURIResolver.java | 135 | ||||
-rw-r--r-- | src/java/org/apache/fop/apps/FOUserAgent.java | 58 |
2 files changed, 181 insertions, 12 deletions
diff --git a/src/java/org/apache/fop/apps/FOURIResolver.java b/src/java/org/apache/fop/apps/FOURIResolver.java new file mode 100644 index 000000000..57a473752 --- /dev/null +++ b/src/java/org/apache/fop/apps/FOURIResolver.java @@ -0,0 +1,135 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id: $ */ + +package org.apache.fop.apps; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +// commons logging +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Provides FOP specific URI resolution. + * This is the default URIResolver {@link FOUserAgent} will use unless overidden. + * @see javax.xml.transform.URIResolver + */ +public class FOURIResolver + 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. + * (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. + * 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. + * + * @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. + * @see javax.xml.transform.URIResolver#resolve(String, String) + */ + public Source resolve(String href, String base) + throws javax.xml.transform.TransformerException + { + URL absoluteURL = null; + URL baseURL = toBaseURL(base); + if (baseURL == null) { + // We don't have a valid baseURL just use the URL as given + try { + absoluteURL = new URL(href); + } catch (MalformedURLException mue) { + try { + // the above failed, we give it another go in case + // the href contains only a path then file: is assumed + absoluteURL = new URL("file:" + href); + } catch (MalformedURLException mfue) { + log.error("Error with URL '" + href + "': " + mue.getMessage(), mue); + return null; + } + } + } else { + try { + /* + This piece of code is based on the following statement in RFC2396 section 5.2: + + 3) If the scheme component is defined, indicating that the reference + starts with a scheme name, then the reference is interpreted as an + absolute URI and we are done. Otherwise, the reference URI's + scheme is inherited from the base URI's scheme component. + + Due to a loophole in prior specifications [RFC1630], some parsers + allow the scheme name to be present in a relative URI if it is the + same as the base URI scheme. Unfortunately, this can conflict + with the correct parsing of non-hierarchical URI. For backwards + compatibility, an implementation may work around such references + by removing the scheme if it matches that of the base URI and the + scheme is known to always use the <hier_part> syntax. + + The URL class does not implement this work around, so we do. + */ + + String scheme = baseURL.getProtocol() + ":"; + if (href.startsWith(scheme)) { + href = href.substring(scheme.length()); + } + absoluteURL = new URL(baseURL, href); + } catch (MalformedURLException mfue) { + log.error("Error with URL '" + href + "': " + mfue.getMessage(), mfue); + return null; + } + } + try { + return new StreamSource(absoluteURL.openStream(), absoluteURL.toExternalForm()); + } catch (java.io.IOException ioe) { + log.error("Error with opening URL '" + href + "': " + ioe.getMessage(), ioe); + } + return null; + } + + /** + * Returns the base URL as a java.net.URL. + * If the base URL is not set a default URL pointing to the + * current directory is returned. + * @param baseURL the base URL + * @returns the base URL as java.net.URL + */ + private URL toBaseURL(String baseURL) + { + try { + return new URL(baseURL == null + ? new java.io.File("").toURL().toExternalForm() + : baseURL); + } catch (MalformedURLException mfue) { + log.error("Error with base URL: " + mfue.getMessage(), mfue); + } + return null; + } + +} diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index a308e6a86..708c39a92 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -21,10 +21,13 @@ package org.apache.fop.apps; // Java import java.io.File; import java.io.IOException; -import java.io.InputStream; 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; @@ -71,6 +74,12 @@ public class FOUserAgent { private XMLHandlerRegistry xmlHandlers = new XMLHandlerRegistry(); private String baseURL; + + /** A user settable URI Resolver */ + private URIResolver uriResolver = null; + /** Our default resolver if none is set */ + private URIResolver foURIResolver = new FOURIResolver(); + private PDFEncryptionParams pdfEncryptionParams; private float px2mm = DEFAULT_PX2MM; private Map rendererOptions = new java.util.HashMap(); @@ -384,11 +393,23 @@ public class FOUserAgent { * @return the base URL */ public String getBaseURL() { - if ((this.baseURL == null) || (this.baseURL.trim().equals(""))) { - return "file:."; - } else { - return this.baseURL; - } + return this.baseURL; + } + + /** + * Sets the URI Resolver. + * @param uriResolver the new URI resolver + */ + public void setURIResolver(URIResolver uriResolver) { + this.uriResolver = uriResolver; + } + + /** + * Returns the URI Resolver. + * @return the URI Resolver + */ + public URIResolver getURIResolver() { + return this.uriResolver != null ? this.uriResolver : this.foURIResolver; } /** @@ -410,15 +431,28 @@ public class FOUserAgent { /** - * Get an input stream for a reference. Subclass FOUserAgent and override this method to - * do custom URI to InputStream resolution. + * 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. * @param uri URI to access - * @return InputStream for accessing the resource. + * @return StreamSource for accessing the resource. * @throws IOException in case of an I/O problem */ - public InputStream getStream(String uri) throws IOException { - //The default implementation does noting. Subclass FOUserAgent to add custom behaviour. + public StreamSource getStream(String uri) throws IOException { + Source source = null; + try { + source = getURIResolver().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"); + } + } return null; } @@ -434,7 +468,7 @@ public class FOUserAgent { * Gets the output File. * @return the output File */ - public File getOutputFile(){ + public File getOutputFile() { return outputFile; } |