Index: src/java/org/apache/fop/apps/FOUserAgent.java =================================================================== --- src/java/org/apache/fop/apps/FOUserAgent.java (revision 542841) +++ src/java/org/apache/fop/apps/FOUserAgent.java (working copy) @@ -41,37 +41,32 @@ import org.apache.fop.render.pdf.PDFRenderer; /** - * This is the user agent for FOP. - * It is the entity through which you can interact with the XSL-FO processing and is - * used by the processing to obtain user configurable options. + * This is the user agent for FOP. It is the entity through which you can + * interact with the XSL-FO processing and is used by the processing to obtain + * user configurable options. *
- * Renderer specific extensions (that do not produce normal areas on
- * the output) will be done like so:
- *
- * The extension will create an area, custom if necessary
- *
- * this area will be added to the user agent with a key
- *
- * the renderer will know keys for particular extensions
- *
- * eg. bookmarks will be held in a special hierarchical area representing
- * the title and bookmark structure
- *
- * These areas may contain resolvable areas that will be processed
- * with other resolvable areas
+ * Renderer specific extensions (that do not produce normal areas on the output)
+ * will be done like so:
+ * The extension will create an area, custom if necessary
+ * this area will be added to the user agent with a key
+ * the renderer will know keys for particular extensions
+ * eg. bookmarks will be held in a special hierarchical area representing the
+ * title and bookmark structure
+ * These areas may contain resolvable areas that will be processed with other
+ * resolvable areas
*/
public class FOUserAgent {
/** Defines the default target resolution (72dpi) for FOP */
- public static final float DEFAULT_TARGET_RESOLUTION = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+ public static final float DEFAULT_TARGET_RESOLUTION
+ = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
private static Log log = LogFactory.getLog("FOP");
private FopFactory factory;
-
+
/**
- * The base URL for all URL resolutions, especially for
- * external-graphics.
+ * The base URL for all URL resolutions, especially for external-graphics.
*/
private String base = null;
@@ -80,72 +75,89 @@
/** A user settable URI Resolver */
private URIResolver uriResolver = null;
-
+
private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+
private Map rendererOptions = new java.util.HashMap();
+
private File outputFile = null;
+
private Renderer rendererOverride = null;
+
private FOEventHandler foEventHandlerOverride = null;
-
- /** Producer: Metadata element for the system/software that produces
- * the document. (Some renderers can store this in the document.)
+
+ /**
+ * Producer: Metadata element for the system/software that produces the
+ * document. (Some renderers can store this in the document.)
*/
protected String producer = "Apache FOP Version " + Version.getVersion();
- /** Creator: Metadata element for the user that created the
- * document. (Some renderers can store this in the document.)
+ /**
+ * Creator: Metadata element for the user that created the document. (Some
+ * renderers can store this in the document.)
*/
protected String creator = null;
- /** Creation Date: Override of the date the document was created.
- * (Some renderers can store this in the document.)
+ /**
+ * Creation Date: Override of the date the document was created. (Some
+ * renderers can store this in the document.)
*/
protected Date creationDate = null;
-
+
/** Author of the content of the document. */
protected String author = null;
+
/** Title of the document. */
protected String title = null;
+
/** Set of keywords applicable to this document. */
protected String keywords = null;
-
+
/**
* Default constructor
+ *
* @see org.apache.fop.apps.FopFactory
- * @deprecated Provided for compatibility only. Please use the methods from
+ * @deprecated Provided for compatibility only. Please use the methods from
* FopFactory to construct FOUserAgent instances!
*/
public FOUserAgent() throws FOPException {
this(FopFactory.newInstance());
}
-
+
/**
- * Main constructor. This constructor should not be called directly. Please use the
- * methods from FopFactory to construct FOUserAgent instances!
- * @param factory the factory that provides environment-level information
+ * Main constructor. This constructor should not be called directly.
+ * Please use the methods from FopFactory to construct FOUserAgent
+ * instances!
+ *
+ * @param factory
+ * the factory that provides environment-level information
* @see org.apache.fop.apps.FopFactory
*/
public FOUserAgent(FopFactory factory) {
if (factory == null) {
- throw new NullPointerException("The factory parameter must not be null");
+ throw new NullPointerException(
+ "The factory parameter must not be null");
}
this.factory = factory;
setBaseURL(factory.getBaseURL());
setFontBaseURL(factory.getFontBaseURL());
setTargetResolution(factory.getTargetResolution());
}
-
+
/** @return the associated FopFactory instance */
public FopFactory getFactory() {
return this.factory;
}
-
- // ---------------------------------------------- rendering-run dependent stuff
-
+
+ // ---------------------------------------------- rendering-run dependent
+ // stuff
+
/**
- * Sets an explicit renderer to use which overrides the one defined by the
- * render type setting.
- * @param renderer the Renderer instance to use
+ * Sets an explicit renderer to use which overrides the one defined by the
+ * render type setting.
+ *
+ * @param renderer
+ * the Renderer instance to use
*/
public void setRendererOverride(Renderer renderer) {
this.rendererOverride = renderer;
@@ -153,6 +165,7 @@
/**
* Returns the overriding Renderer instance, if any.
+ *
* @return the overriding Renderer or null
*/
public Renderer getRendererOverride() {
@@ -160,9 +173,11 @@
}
/**
- * Sets an explicit FOEventHandler instance which overrides the one
- * defined by the render type setting.
- * @param handler the FOEventHandler instance
+ * Sets an explicit FOEventHandler instance which overrides the one defined
+ * by the render type setting.
+ *
+ * @param handler
+ * the FOEventHandler instance
*/
public void setFOEventHandlerOverride(FOEventHandler handler) {
this.foEventHandlerOverride = handler;
@@ -170,6 +185,7 @@
/**
* Returns the overriding FOEventHandler instance, if any.
+ *
* @return the overriding FOEventHandler or null
*/
public FOEventHandler getFOEventHandlerOverride() {
@@ -177,8 +193,10 @@
}
/**
- * Sets the producer of the document.
- * @param producer source of document
+ * Sets the producer of the document.
+ *
+ * @param producer
+ * source of document
*/
public void setProducer(String producer) {
this.producer = producer;
@@ -186,6 +204,7 @@
/**
* Returns the producer of the document
+ *
* @return producer name
*/
public String getProducer() {
@@ -193,8 +212,10 @@
}
/**
- * Sets the creator of the document.
- * @param creator of document
+ * Sets the creator of the document.
+ *
+ * @param creator
+ * of document
*/
public void setCreator(String creator) {
this.creator = creator;
@@ -202,6 +223,7 @@
/**
* Returns the creator of the document
+ *
* @return creator name
*/
public String getCreator() {
@@ -209,8 +231,10 @@
}
/**
- * Sets the creation date of the document.
- * @param creationDate date of document
+ * Sets the creation date of the document.
+ *
+ * @param creationDate
+ * date of document
*/
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
@@ -218,6 +242,7 @@
/**
* Returns the creation date of the document
+ *
* @return creation date of document
*/
public Date getCreationDate() {
@@ -225,8 +250,10 @@
}
/**
- * Sets the author of the document.
- * @param author of document
+ * Sets the author of the document.
+ *
+ * @param author
+ * of document
*/
public void setAuthor(String author) {
this.author = author;
@@ -234,6 +261,7 @@
/**
* Returns the author of the document
+ *
* @return author name
*/
public String getAuthor() {
@@ -242,8 +270,10 @@
/**
* Sets the title of the document. This will override any title coming from
- * an fo:title element.
- * @param title of document
+ * an fo:title element.
+ *
+ * @param title
+ * of document
*/
public void setTitle(String title) {
this.title = title;
@@ -251,6 +281,7 @@
/**
* Returns the title of the document
+ *
* @return title name
*/
public String getTitle() {
@@ -258,8 +289,10 @@
}
/**
- * Sets the keywords for the document.
- * @param keywords for the document
+ * Sets the keywords for the document.
+ *
+ * @param keywords
+ * for the document
*/
public void setKeywords(String keywords) {
this.keywords = keywords;
@@ -267,6 +300,7 @@
/**
* Returns the keywords for the document
+ *
* @return the keywords
*/
public String getKeywords() {
@@ -275,15 +309,18 @@
/**
* Returns the renderer options
+ *
* @return renderer options
*/
public Map getRendererOptions() {
return rendererOptions;
}
-
+
/**
* Sets the base URL.
- * @param baseUrl base URL
+ *
+ * @param baseUrl
+ * base URL
*/
public void setBaseURL(String baseUrl) {
this.base = baseUrl;
@@ -291,7 +328,9 @@
/**
* sets font base URL
- * @param fontBaseUrl font base URL
+ *
+ * @param fontBaseUrl
+ * font base URL
*/
public void setFontBaseURL(String fontBaseUrl) {
this.fontBase = fontBaseUrl;
@@ -299,6 +338,7 @@
/**
* Returns the base URL.
+ *
* @return the base URL
*/
public String getBaseURL() {
@@ -307,7 +347,9 @@
/**
* Sets the URI Resolver.
- * @param resolver the new URI resolver
+ *
+ * @param resolver
+ * the new URI resolver
*/
public void setURIResolver(URIResolver resolver) {
this.uriResolver = resolver;
@@ -315,6 +357,7 @@
/**
* Returns the URI Resolver.
+ *
* @return the URI Resolver
*/
public URIResolver getURIResolver() {
@@ -323,34 +366,40 @@
/**
* Returns the parameters for PDF encryption.
+ *
* @return the PDF encryption parameters, null if not applicable
- * @deprecated Use (PDFEncryptionParams)getRendererOptions().get("encryption-params")
+ * @deprecated Use
+ * (PDFEncryptionParams)getRendererOptions().get("encryption-params")
* instead.
*/
public PDFEncryptionParams getPDFEncryptionParams() {
- return (PDFEncryptionParams)getRendererOptions().get(PDFRenderer.ENCRYPTION_PARAMS);
+ return (PDFEncryptionParams) getRendererOptions().get(
+ PDFRenderer.ENCRYPTION_PARAMS);
}
/**
* Sets the parameters for PDF encryption.
- * @param pdfEncryptionParams the PDF encryption parameters, null to
- * disable PDF encryption
- * @deprecated Use getRendererOptions().put("encryption-params",
- * new PDFEncryptionParams(..)) instead or set every parameter separately:
- * getRendererOptions().put("noprint", Boolean.TRUE).
+ *
+ * @param pdfEncryptionParams
+ * the PDF encryption parameters, null to disable PDF encryption
+ * @deprecated Use getRendererOptions().put("encryption-params", new
+ * PDFEncryptionParams(..)) instead or set every parameter
+ * separately: getRendererOptions().put("noprint",
+ * Boolean.TRUE).
*/
public void setPDFEncryptionParams(PDFEncryptionParams pdfEncryptionParams) {
- getRendererOptions().put(PDFRenderer.ENCRYPTION_PARAMS, pdfEncryptionParams);
+ getRendererOptions().put(PDFRenderer.ENCRYPTION_PARAMS,
+ pdfEncryptionParams);
}
-
/**
- * 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
+ * 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 A {@link javax.xml.transform.Source} object, or null if the URI
- * cannot be resolved.
+ * cannot be resolved.
* @see org.apache.fop.apps.FOURIResolver
*/
public Source resolveURI(String uri) {
@@ -358,36 +407,41 @@
}
/**
- * 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
- * @param base the base URI to resolve against
+ * 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.
+ * cannot be resolved.
* @see org.apache.fop.apps.FOURIResolver
*/
- public Source resolveURI(String uri, String base) {
+ public Source resolveURI(String href, String baseUri) {
Source source = null;
- //RFC 2397 data URLs don't need to be resolved, just decode them.
- boolean bypassURIResolution = uri.startsWith("data:");
+ // RFC 2397 data URLs don't need to be resolved, just decode them.
+ boolean bypassURIResolution = href.startsWith("data:");
if (!bypassURIResolution && uriResolver != null) {
try {
- source = uriResolver.resolve(uri, base);
+ source = uriResolver.resolve(href, baseUri);
} catch (TransformerException te) {
- log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
+ log.error("Attempt to resolve URI '" + href + "' failed: ", te);
}
}
if (source == null) {
- // URI Resolver not configured or returned null, use default resolver from the factory
- source = getFactory().resolveURI(uri, base);
+ // URI Resolver not configured or returned null, use default
+ // resolver from the factory
+ source = factory.resolveURI(href, baseUri);
}
return source;
}
/**
* Sets the output File.
- * @param f the output File
+ *
+ * @param f
+ * the output File
*/
public void setOutputFile(File f) {
this.outputFile = f;
@@ -395,6 +449,7 @@
/**
* Gets the output File.
+ *
* @return the output File
*/
public File getOutputFile() {
@@ -404,44 +459,51 @@
/**
* Returns the conversion factor from pixel units to millimeters. This
* depends on the desired target resolution.
+ *
* @return float conversion factor
* @see #getTargetResolution()
*/
public float getTargetPixelUnitToMillimeter() {
- return 25.4f / this.targetResolution;
+ return 25.4f / this.targetResolution;
}
-
+
/** @return the resolution for resolution-dependant output */
public float getTargetResolution() {
return this.targetResolution;
}
/**
- * Sets the target resolution in dpi. This value defines the target resolution of
- * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
- * bitmap images generated by filter effects in Apache Batik.
- * @param dpi resolution in dpi
+ * Sets the target resolution in dpi. This value defines the target
+ * resolution of bitmap images generated by the bitmap renderers (such as
+ * the TIFF renderer) and of bitmap images generated by filter effects in
+ * Apache Batik.
+ *
+ * @param dpi
+ * resolution in dpi
*/
public void setTargetResolution(float dpi) {
this.targetResolution = dpi;
if (log.isDebugEnabled()) {
- log.debug("target-resolution set to: " + targetResolution
+ log.debug("target-resolution set to: " + targetResolution
+ "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
}
}
/**
- * Sets the target resolution in dpi. This value defines the target resolution of
- * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
- * bitmap images generated by filter effects in Apache Batik.
- * @param dpi resolution in dpi
+ * Sets the target resolution in dpi. This value defines the target
+ * resolution of bitmap images generated by the bitmap renderers (such as
+ * the TIFF renderer) and of bitmap images generated by filter effects in
+ * Apache Batik.
+ *
+ * @param dpi
+ * resolution in dpi
*/
public void setTargetResolution(int dpi) {
- setTargetResolution((float)dpi);
+ setTargetResolution((float) dpi);
}
-
+
// ---------------------------------------------- environment-level stuff
- // (convenience access to FopFactory methods)
+ // (convenience access to FopFactory methods)
/** @return the font base URL */
public String getFontBaseURL() {
@@ -451,21 +513,22 @@
/**
* Returns the conversion factor from pixel units to millimeters. This
* depends on the desired source resolution.
+ *
* @return float conversion factor
* @see #getSourceResolution()
*/
public float getSourcePixelUnitToMillimeter() {
- return getFactory().getSourcePixelUnitToMillimeter();
+ return getFactory().getSourcePixelUnitToMillimeter();
}
-
+
/** @return the resolution for resolution-dependant input */
public float getSourceResolution() {
return getFactory().getSourceResolution();
}
/**
- * Gets the default page-height to use as fallback,
- * in case page-height="auto"
+ * Gets the default page-height to use as fallback, in case
+ * page-height="auto"
*
* @return the page-height, as a String
* @see FopFactory#getPageHeight()
@@ -473,10 +536,9 @@
public String getPageHeight() {
return getFactory().getPageHeight();
}
-
+
/**
- * Gets the default page-width to use as fallback,
- * in case page-width="auto"
+ * Gets the default page-width to use as fallback, in case page-width="auto"
*
* @return the page-width, as a String
* @see FopFactory#getPageWidth()
@@ -484,9 +546,10 @@
public String getPageWidth() {
return getFactory().getPageWidth();
}
-
+
/**
* Returns whether FOP is strictly validating input XSL
+ *
* @return true of strict validation turned on, false otherwise
* @see FopFactory#validateStrictly()
*/
@@ -495,8 +558,9 @@
}
/**
- * @return true if the indent inheritance should be broken when crossing reference area
- * boundaries (for more info, see the javadoc for the relative member variable)
+ * @return true if the indent inheritance should be broken when crossing
+ * reference area boundaries (for more info, see the javadoc for the
+ * relative member variable)
* @see FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()
*/
public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
@@ -517,4 +581,3 @@
return getFactory().getXMLHandlerRegistry();
}
}
-
Index: src/java/org/apache/fop/apps/FOURIResolver.java
===================================================================
--- src/java/org/apache/fop/apps/FOURIResolver.java (revision 542841)
+++ src/java/org/apache/fop/apps/FOURIResolver.java (working copy)
@@ -30,6 +30,7 @@
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
// commons logging
@@ -41,16 +42,19 @@
import org.apache.xmlgraphics.util.io.Base64EncodeStream;
/**
- * Provides FOP specific URI resolution.
- * This is the default URIResolver {@link FOUserAgent} will use unless overidden.
+ * 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 {
-
+public class FOURIResolver implements javax.xml.transform.URIResolver {
+
// log
private Log log = LogFactory.getLog("FOP");
+ /** A user settable URI Resolver */
+ private URIResolver uriResolver = null;
+
// true if exceptions are to be thrown if the URIs cannot be resolved.
private boolean throwExceptions = false;
@@ -60,23 +64,28 @@
public FOURIResolver() {
this(false);
}
-
+
/**
* Additional constructor
- * @param throwExceptions true if exceptions are to be thrown if the URIs cannot be
- * resolved.
+ *
+ * @param throwExceptions
+ * true if exceptions are to be thrown if the URIs cannot be
+ * resolved.
*/
public FOURIResolver(boolean throwExceptions) {
this.throwExceptions = throwExceptions;
}
-
+
/**
* Handles resolve exceptions appropriately.
- * @param errorStr error string
- * @param strict strict user config
+ *
+ * @param errorStr
+ * error string
+ * @param strict
+ * strict user config
*/
private void handleException(Exception e, String errorStr, boolean strict)
- throws TransformerException {
+ throws TransformerException {
if (strict) {
throw new TransformerException(errorStr, e);
}
@@ -84,166 +93,204 @@
}
/**
- * 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
+ * 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
+ * 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 javax.xml.transform.TransformerException Never thrown by this implementation.
+ * @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 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 TransformerException {
- // data URLs can be quite long so don't try to build a File (can lead to problems)
+ public Source resolve(String href, String base) throws TransformerException {
+ // data URLs can be quite long so don't try to build a File (can lead to
+ // problems)
if (href.startsWith("data:")) {
return parseDataURI(href);
}
- URL absoluteURL = null;
- File file = new File(href);
- if (file.canRead() && file.isFile()) {
+ Source source = null;
+ // RFC 2397 data URLs don't need to be resolved, just decode them.
+ boolean bypassURIResolution = href.startsWith("data:");
+ if (!bypassURIResolution && uriResolver != null) {
try {
- absoluteURL = file.toURL();
- } catch (MalformedURLException mfue) {
- handleException(mfue,
- "Could not convert filename '" + href + "' to URL", throwExceptions);
+ // Custom uri resolution
+ source = uriResolver.resolve(href, base);
+ } catch (TransformerException te) {
+ log.error("Attempt to resolve URI '" + href + "' failed: ", te);
}
- } else {
- // no base provided
- if (base == null) {
- // We don't have a valid file protocol based URL
+ }
+ // Fallback to default resolution mechanism
+ if (source == null) {
+ URL absoluteURL = null;
+ File file = new File(href);
+ if (file.canRead() && file.isFile()) {
try {
- absoluteURL = new URL(href);
- } catch (MalformedURLException mue) {
+ absoluteURL = file.toURL();
+ } catch (MalformedURLException mfue) {
+ handleException(mfue, "Could not convert filename '" + href
+ + "' to URL", throwExceptions);
+ }
+ } else {
+ // no base provided
+ if (base == null) {
+ // We don't have a valid file protocol based URL
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);
+ 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) {
+ handleException(mfue, "Error with URL '" + href
+ + "'", throwExceptions);
+ }
+ }
+
+ // try and resolve from context of base
+ } else {
+ URL baseURL = null;
+ try {
+ baseURL = new URL(base);
} catch (MalformedURLException mfue) {
- handleException(mfue,
- "Error with URL '" + href + "'", throwExceptions);
+ handleException(mfue, "Error with base URL '" + base
+ + "'", throwExceptions);
}
- }
- // try and resolve from context of base
- } else {
- URL baseURL = null;
- try {
- baseURL = new URL(base);
- } catch (MalformedURLException mfue) {
- handleException(mfue, "Error with base URL '" + base + "'", throwExceptions);
- }
-
- /*
- * 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