/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;

import org.xml.sax.SAXException;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fonts.FontCache;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.hyphenation.HyphenationTreeResolver;
import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.util.ColorSpaceCache;
import org.apache.fop.util.ContentHandlerFactoryRegistry;

/**
 * Factory class which instantiates new Fop and FOUserAgent instances. This
 * class also holds environmental information and configuration used by FOP.
 * Information that may potentially be different for each rendering run can be
 * found and managed in the FOUserAgent.
 */
public class FopFactory implements ImageContext {

    /** logger instance */
    private static Log log = LogFactory.getLog(FopFactory.class);

    /** Factory for Renderers and FOEventHandlers */
    private RendererFactory rendererFactory;

    /** Registry for XML handlers */
    private XMLHandlerRegistry xmlHandlers;

    /** Registry for image handlers */
    private ImageHandlerRegistry imageHandlers;

    /** The registry for ElementMapping instances */
    private ElementMappingRegistry elementMappingRegistry;

    /** The registry for ContentHandlerFactory instance */
    private ContentHandlerFactoryRegistry contentHandlerFactoryRegistry
                = new ContentHandlerFactoryRegistry();

    /** The resolver for user-supplied hyphenation patterns */
    private HyphenationTreeResolver hyphResolver = null;

    private ColorSpaceCache colorSpaceCache = null;

    /** Image manager for loading and caching image objects */
    private ImageManager imageManager;

    /** Font manager for font substitution, autodetection and caching **/
    private FontManager fontManager;

    /** Configuration layer used to configure fop */
    private FopFactoryConfigurator config = null;

    /**
     *  The base URL for all URL resolutions, especially for
     *  external-graphics.
     */
    private String base = null;

    /**
     *  Controls if accessibility is turned on or off
     */
    private boolean accessibility = false;

    /** The base URL for all hyphen URL resolutions. */
    private String hyphenBase = null;

    /**
     * Map of configured names of hyphenation pattern file names: ll_CC => name
     */
    private Map/*<String,String>*/ hyphPatNames = null;

    /**
     * FOP has the ability, for some FO's, to continue processing even if the
     * input XSL violates that FO's content model.  This is the default
     * behavior for FOP.  However, this flag, if set, provides the user the
     * ability for FOP to halt on all content model violations if desired.
     */
    private boolean strictFOValidation = FopFactoryConfigurator.DEFAULT_STRICT_FO_VALIDATION;

    /**
     * FOP will validate the contents of the user configuration strictly
     * (e.g. base-urls and font urls/paths).
     */
    private boolean strictUserConfigValidation
        = FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION;

    /** Source resolution in dpi */
    private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION;

    /** Target resolution in dpi */
    private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;

    /** Page height */
    private String pageHeight = FopFactoryConfigurator.DEFAULT_PAGE_HEIGHT;

    /** Page width */
    private String pageWidth = FopFactoryConfigurator.DEFAULT_PAGE_WIDTH;

    /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
    private boolean breakIndentInheritanceOnReferenceAreaBoundary
        = FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE;

    /** Optional overriding LayoutManagerMaker */
    private LayoutManagerMaker lmMakerOverride = null;

    private Set<String> ignoredNamespaces;

    private FOURIResolver foURIResolver;

    /**
     * Main constructor.
     */
    protected FopFactory() {
        this.config = new FopFactoryConfigurator(this);
        this.elementMappingRegistry = new ElementMappingRegistry(this);
        this.foURIResolver = new FOURIResolver(validateUserConfigStrictly());
        this.fontManager = new FontManager() {

            /** {@inheritDoc} */
            @Override
            public void setFontBaseURL(String fontBase) throws MalformedURLException {
                super.setFontBaseURL(getFOURIResolver().checkBaseURL(fontBase));
            }

        };
        this.colorSpaceCache = new ColorSpaceCache(foURIResolver);
        this.imageManager = new ImageManager(this);
        this.rendererFactory = new RendererFactory();
        this.xmlHandlers = new XMLHandlerRegistry();
        this.imageHandlers = new ImageHandlerRegistry();
        this.ignoredNamespaces = new java.util.HashSet<String>();
    }

    /**
     * Returns a new FopFactory instance.
     * @return the requested FopFactory instance.
     */
    public static FopFactory newInstance() {
        return new FopFactory();
    }

    /**
     * Returns a new FOUserAgent instance. Use the FOUserAgent to configure special values that
     * are particular to a rendering run. Don't reuse instances over multiple rendering runs but
     * instead create a new one each time and reuse the FopFactory.
     * @return the newly created FOUserAgent instance initialized with default values
     * @throws FOPException
     */
    public FOUserAgent newFOUserAgent() {
        FOUserAgent userAgent = new FOUserAgent(this);
        return userAgent;
    }

    /**
     * Sets accessibility support.
     *
     * @param value <code>true</code> to enable accessibility, <code>false</code> otherwise
     */
    void setAccessibility(boolean value) {
        this.accessibility = value;
    }

    boolean isAccessibilityEnabled() {
        return accessibility;
    }

    /**
     * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
     * instance.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat) throws FOPException {
        return newFop(outputFormat, newFOUserAgent());
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if you want to configure this
     * very rendering run, i.e. if you want to set some metadata like the title and author of the
     * document you want to render. In that case, create a new {@link FOUserAgent}
     * instance using {@link #newFOUserAgent()}.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param userAgent the user agent that will be used to control the rendering run
     * @return the new Fop instance
     * @throws FOPException  when the constructor fails
     */
    public Fop newFop(String outputFormat, FOUserAgent userAgent) throws FOPException {
        return newFop(outputFormat, userAgent, null);
    }

    /**
     * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
     * instance. Use this factory method if your output type requires an output stream.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param stream the output stream
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat, OutputStream stream) throws FOPException {
        return newFop(outputFormat, newFOUserAgent(), stream);
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if your output type
     * requires an output stream and you want to configure this very rendering run,
     * i.e. if you want to set some metadata like the title and author of the document
     * you want to render. In that case, create a new {@link FOUserAgent} instance
     * using {@link #newFOUserAgent()}.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param userAgent the user agent that will be used to control the rendering run
     * @param stream the output stream
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat, FOUserAgent userAgent, OutputStream stream)
                throws FOPException {
        if (userAgent == null) {
            throw new NullPointerException("The userAgent parameter must not be null!");
        }
        return new Fop(outputFormat, userAgent, stream);
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if you want to supply your
     * own {@link org.apache.fop.render.Renderer Renderer} or
     * {@link org.apache.fop.fo.FOEventHandler FOEventHandler}
     * instance instead of the default ones created internally by FOP.
     * @param userAgent the user agent that will be used to control the rendering run
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(FOUserAgent userAgent) throws FOPException {
        if (userAgent.getRendererOverride() == null
                && userAgent.getFOEventHandlerOverride() == null
                && userAgent.getDocumentHandlerOverride() == null) {
            throw new IllegalStateException("An overriding renderer,"
                    + " FOEventHandler or IFDocumentHandler must be set on the user agent"
                    + " when this factory method is used!");
        }
        return newFop(null, userAgent);
    }

    /** @return the RendererFactory */
    public RendererFactory getRendererFactory() {
        return this.rendererFactory;
    }

    /** @return the XML handler registry */
    public XMLHandlerRegistry getXMLHandlerRegistry() {
        return this.xmlHandlers;
    }

    /** @return the image handler registry */
    public ImageHandlerRegistry getImageHandlerRegistry() {
        return this.imageHandlers;
    }

    /** @return the element mapping registry */
    public ElementMappingRegistry getElementMappingRegistry() {
        return this.elementMappingRegistry;
    }

    /** @return the content handler factory registry */
    public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
        return this.contentHandlerFactoryRegistry;
    }

    /**
     * Returns the image manager.
     * @return the image manager
     */
    public ImageManager getImageManager() {
        return this.imageManager;
    }

    /**
     * Add the element mapping with the given class name.
     * @param elementMapping the class name representing the element mapping.
     */
    public void addElementMapping(ElementMapping elementMapping) {
        this.elementMappingRegistry.addElementMapping(elementMapping);
    }

    /**
     * Sets an explicit LayoutManagerMaker instance which overrides the one
     * defined by the AreaTreeHandler.
     * @param lmMaker the LayoutManagerMaker instance
     */
    public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
        this.lmMakerOverride = lmMaker;
    }

    /**
     * Returns the overriding LayoutManagerMaker instance, if any.
     * @return the overriding LayoutManagerMaker or null
     */
    public LayoutManagerMaker getLayoutManagerMakerOverride() {
        return this.lmMakerOverride;
    }

    /**
     * Sets the base URL.
     * @param base the base URL
     * @throws MalformedURLException if there's a problem with a file URL
     */
    public void setBaseURL(String base) throws MalformedURLException {
        this.base = foURIResolver.checkBaseURL(base);
    }

    /**
     * Returns the base URL.
     * @return the base URL
     */
    public String getBaseURL() {
        return this.base;
    }

    /**
     * Sets the font base URL.
     * @param fontBase font base URL
     * @throws MalformedURLException if there's a problem with a file URL
     * @deprecated use getFontManager().setFontBaseURL(fontBase) instead
     */
    @Deprecated
    public void setFontBaseURL(String fontBase) throws MalformedURLException {
        getFontManager().setFontBaseURL(fontBase);
    }

    /**
     * @return the font base URL
     * @deprecated use getFontManager().setFontBaseURL(fontBase) instead
     */
    @Deprecated
    public String getFontBaseURL() {
        return getFontManager().getFontBaseURL();
    }

    /** @return the hyphen base URL */
    public String getHyphenBaseURL() {
        return this.hyphenBase;
    }

    /**
     * Sets the hyphen base URL.
     * @param hyphenBase hythen base URL
     * @throws MalformedURLException if there's a problem with a file URL
     * */
    public void setHyphenBaseURL(final String hyphenBase) throws MalformedURLException {
        if (hyphenBase != null) {
            setHyphenationTreeResolver(
            new HyphenationTreeResolver() {
                public Source resolve(String href) {
                    return resolveURI(href, hyphenBase);
                }
            });
        }
        this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase);
    }

    /**
     * @return the hyphPatNames
     */
    public Map getHyphPatNames() {
        return hyphPatNames;
    }

    /**
     * @param hyphPatNames the hyphPatNames to set
     */
    public void setHyphPatNames(Map hyphPatNames) {
        if (hyphPatNames == null) {
            hyphPatNames = new HashMap();
        }
        this.hyphPatNames = hyphPatNames;
    }

    /**
     * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
     * patterns and as backup for URI resolution performed during a rendering run.
     * @param uriResolver the new URI resolver
     */
    public void setURIResolver(URIResolver uriResolver) {
        foURIResolver.setCustomURIResolver(uriResolver);
    }

    /**
     * Returns the URI Resolver.
     * @return the URI Resolver
     */
    public URIResolver getURIResolver() {
        return foURIResolver;
    }

    /**
     * Returns the FO URI Resolver.
     * @return the FO URI Resolver
     */
    public FOURIResolver getFOURIResolver() {
        return foURIResolver;
    }

    /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
    public HyphenationTreeResolver getHyphenationTreeResolver() {
        return this.hyphResolver;
    }

    /**
     * Sets the HyphenationTreeResolver to be used for resolving user-supplied hyphenation files.
     * @param hyphResolver the HyphenationTreeResolver instance
     */
    public void setHyphenationTreeResolver(HyphenationTreeResolver hyphResolver) {
        this.hyphResolver = hyphResolver;
    }

    /**
     * Activates strict XSL content model validation for FOP
     * Default is false (FOP will continue processing where it can)
     * @param validateStrictly true to turn on strict validation
     */
    public void setStrictValidation(boolean validateStrictly) {
        this.strictFOValidation = validateStrictly;
    }

    /**
     * Returns whether FOP is strictly validating input XSL
     * @return true of strict validation turned on, false otherwise
     */
    public boolean validateStrictly() {
        return strictFOValidation;
    }

    /**
     * @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)
     */
    public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
        return breakIndentInheritanceOnReferenceAreaBoundary;
    }

    /**
     * Controls whether to enable a feature that breaks indent inheritance when crossing
     * reference area boundaries.
     * <p>
     * This flag controls whether FOP will enable special code that breaks property
     * inheritance for start-indent and end-indent when the evaluation of the inherited
     * value would cross a reference area. This is described under
     * http://wiki.apache.org/xmlgraphics-fop/IndentInheritance as is intended to
     * improve interoperability with commercial FO implementations and to produce
     * results that are more in line with the expectation of unexperienced FO users.
     * Note: Enabling this features violates the XSL specification!
     * @param value true to enable the feature
     */
    public void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value) {
        this.breakIndentInheritanceOnReferenceAreaBoundary = value;
    }

    /**
     * @return true if kerning on base 14 fonts is enabled
     * @deprecated use getFontManager().isBase14KerningEnabled() instead
     */
    @Deprecated
    public boolean isBase14KerningEnabled() {
        return getFontManager().isBase14KerningEnabled();
    }

    /**
     * Controls whether kerning is activated on base 14 fonts.
     * @param value true if kerning should be activated
     * @deprecated use getFontManager().setBase14KerningEnabled(boolean) instead
     */
    @Deprecated
    public void setBase14KerningEnabled(boolean value) {
        getFontManager().setBase14KerningEnabled(value);
    }

    /** @return the resolution for resolution-dependant input */
    public float getSourceResolution() {
        return this.sourceResolution;
    }

    /**
     * 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 UnitConv.IN2MM / getSourceResolution();
    }

    /**
     * Sets the source resolution in dpi. This value is used to interpret the pixel size
     * of source documents like SVG images and bitmap images without resolution information.
     * @param dpi resolution in dpi
     */
    public void setSourceResolution(float dpi) {
        this.sourceResolution = dpi;
        if (log.isDebugEnabled()) {
            log.debug("source-resolution set to: " + sourceResolution
                    + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
        }
    }

    /** @return the resolution for resolution-dependant output */
    public float getTargetResolution() {
        return this.targetResolution;
    }

    /**
     * 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 UnitConv.IN2MM / this.targetResolution;
    }

    /**
     * Sets the source resolution in dpi. This value is used to interpret the pixel size
     * of source documents like SVG images and bitmap images without resolution information.
     * @param dpi resolution in dpi
     */
    public void setTargetResolution(float dpi) {
        this.targetResolution = dpi;
    }

    /**
     * Sets the source resolution in dpi. This value is used to interpret the pixel size
     * of source documents like SVG images and bitmap images without resolution information.
     * @param dpi resolution in dpi
     */
    public void setSourceResolution(int dpi) {
        setSourceResolution((float)dpi);
    }

    /**
     * Gets the default page-height to use as fallback,
     * in case page-height="auto"
     *
     * @return the page-height, as a String
     */
    public String getPageHeight() {
        return this.pageHeight;
    }

    /**
     * Sets the page-height to use as fallback, in case
     * page-height="auto"
     *
     * @param pageHeight    page-height as a String
     */
    public void setPageHeight(String pageHeight) {
        this.pageHeight = pageHeight;
        if (log.isDebugEnabled()) {
            log.debug("Default page-height set to: " + pageHeight);
        }
    }

    /**
     * Gets the default page-width to use as fallback,
     * in case page-width="auto"
     *
     * @return the page-width, as a String
     */
    public String getPageWidth() {
        return this.pageWidth;
    }

    /**
     * Sets the page-width to use as fallback, in case
     * page-width="auto"
     *
     * @param pageWidth    page-width as a String
     */
    public void setPageWidth(String pageWidth) {
        this.pageWidth = pageWidth;
        if (log.isDebugEnabled()) {
            log.debug("Default page-width set to: " + pageWidth);
        }
    }

    /**
     * Adds a namespace to the set of ignored namespaces.
     * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
     * namespace is in the ignored set.
     * @param namespaceURI the namespace URI
     */
    public void ignoreNamespace(String namespaceURI) {
        this.ignoredNamespaces.add(namespaceURI);
    }

    /**
     * Adds a collection of namespaces to the set of ignored namespaces.
     * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
     * namespace is in the ignored set.
     * @param namespaceURIs the namespace URIs
     */
    public void ignoreNamespaces(Collection<String> namespaceURIs) {
        this.ignoredNamespaces.addAll(namespaceURIs);
    }

    /**
     * Indicates whether a namespace URI is on the ignored list.
     * @param namespaceURI the namespace URI
     * @return true if the namespace is ignored by FOP
     */
    public boolean isNamespaceIgnored(String namespaceURI) {
        return this.ignoredNamespaces.contains(namespaceURI);
    }

    /** @return the set of namespaces that are ignored by FOP */
    public Set<String> getIgnoredNamespace() {
        return Collections.unmodifiableSet(this.ignoredNamespaces);
    }

    //------------------------------------------- Configuration stuff

    /**
     * Set the user configuration.
     * @param userConfigFile the configuration file
     * @throws IOException if an I/O error occurs
     * @throws SAXException if a parsing error occurs
     */
    public void setUserConfig(File userConfigFile) throws SAXException, IOException {
        config.setUserConfig(userConfigFile);
    }

    /**
     * Set the user configuration from an URI.
     * @param uri the URI to the configuration file
     * @throws IOException if an I/O error occurs
     * @throws SAXException if a parsing error occurs
     */
    public void setUserConfig(String uri) throws SAXException, IOException {
        config.setUserConfig(uri);
    }

    /**
     * Set the user configuration.
     * @param userConfig configuration
     * @throws FOPException if a configuration problem occurs
     */
    public void setUserConfig(Configuration userConfig) throws FOPException {
        config.setUserConfig(userConfig);
    }

    /**
     * Set the base URI for the user configuration
     * Useful for programmatic configurations
     * @param baseURI the base URI
     */
    public void setUserConfigBaseURI(URI baseURI) {
        config.setBaseURI(baseURI);
    }

    /**
     * Get the user configuration.
     * @return the user configuration
     */
    public Configuration getUserConfig() {
        return config.getUserConfig();
    }

    /**
     * Is the user configuration to be validated?
     * @param strictUserConfigValidation strict user config validation
     */
    public void setStrictUserConfigValidation(boolean strictUserConfigValidation) {
        this.strictUserConfigValidation = strictUserConfigValidation;
        this.foURIResolver.setThrowExceptions(strictUserConfigValidation);
    }

    /**
     * Is the user configuration to be validated?
     * @return if the user configuration should be validated
     */
    public boolean validateUserConfigStrictly() {
        return this.strictUserConfigValidation;
    }

    //------------------------------------------- Font related stuff

    /**
     * Whether or not to cache results of font triplet detection/auto-config
     * @param useCache use cache or not
     * @deprecated use getFontManager().setUseCache(boolean) instead
     */
    @Deprecated
    public void setUseCache(boolean useCache) {
        getFontManager().setUseCache(useCache);
    }

    /**
     * Cache results of font triplet detection/auto-config?
     * @return whether this factory is uses the cache
     * @deprecated use getFontManager().useCache() instead
     */
    @Deprecated
    public boolean useCache() {
        return getFontManager().useCache();
    }

    /**
     * Returns the font cache instance used by this factory.
     * @return the font cache
     * @deprecated use getFontManager().getFontCache() instead
     */
    @Deprecated
    public FontCache getFontCache() {
        return getFontManager().getFontCache();
    }

    /**
     * Returns the font manager.
     * @return the font manager
     */
    public FontManager getFontManager() {
        return this.fontManager;
    }

    /**
     * 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.
     * @see org.apache.fop.apps.FOURIResolver
     */
    public Source resolveURI(String href, String baseUri) {
        Source source = null;
        try {
            source = foURIResolver.resolve(href, baseUri);
        } catch (TransformerException e) {
            log.error("Attempt to resolve URI '" + href + "' failed: ", e);
        }
        return source;
    }

    /**
     * Returns the color space cache for this instance.
     * <p>
     * Note: this method should not be considered as part of FOP's external API.
     * @return the color space cache
     */
    public ColorSpaceCache getColorSpaceCache() {
        return this.colorSpaceCache;
    }

}
