/*
 * 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;

    /** Complex scripts support enabled */
    private boolean useComplexScriptFeatures
        = FopFactoryConfigurator.DEFAULT_COMPLEX_SCRIPT_FEATURES;

    /** @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;
    }

    /**
     * Sets complex script support.
     * @param value <code>true</code> to enable complex script features,
     * <code>false</code> otherwise
     */
    void setComplexScriptFeaturesEnabled(boolean value) {
        this.useComplexScriptFeatures = value;
    }

    boolean isComplexScriptFeaturesEnabled() {
        return useComplexScriptFeatures;
    }

    /**
     * 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;
    }

}
