From: Vincent Hennebert Date: Wed, 14 Feb 2007 14:24:36 +0000 (+0000) Subject: Stricter user config file validation. X-Git-Tag: fop-0_94~217 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=404013f30e23b12ab477650846eb0e65b58a1394;p=xmlgraphics-fop.git Stricter user config file validation. Add a configuration parameter (strict-configuration), enabled by default, which makes FOP throw an exception instead of logging an error when a problem occurs. Invalid resource paths should be catched now. Fixes bug #40120. Submitted by: Adrian Cumiskey (fop-dev AT cumiskey DOT com) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@507539 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/build.xml b/build.xml index 60d6537ae..cbb4276b6 100644 --- a/build.xml +++ b/build.xml @@ -776,6 +776,7 @@ list of possible build targets. + @@ -789,6 +790,24 @@ list of possible build targets. + + + + + + + + + + + + + + + + + + @@ -924,7 +943,7 @@ list of possible build targets. - + diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml index c40a64de5..7032379ca 100644 --- a/src/documentation/content/xdocs/trunk/configuration.xml +++ b/src/documentation/content/xdocs/trunk/configuration.xml @@ -64,19 +64,21 @@ Element Data Type (for the value) + Description Default Value base URL or directory Specifies the base URL based on which relative URL will be resolved. + current directory font-base URL or directory Specifies the base URL based on which relative font URLs will be resolved. - If not specified defaults to the base URL above. + base URL/directory (above) hyphenation-base @@ -85,6 +87,7 @@ files will be resolved. If not specified, support for user-supplied hyphenation patterns remains disabled. + disabled source-resolution @@ -93,6 +96,7 @@ Resolution in dpi (dots per inch) which is used internally to determine the pixel size for SVG images and bitmap images without resolution information. + 72 dpi target-resolution @@ -102,6 +106,17 @@ images generated by bitmap renderers (such as the TIFF renderer) and by bitmaps generated by Apache Batik for filter effects and such. + 72 dpi + + + strict-configuration + Boolean (true, false) + + Setting this option to 'true' will cause FOP to strictly verify the contents of the + FOP configuration file to ensure that defined resources (such as fonts and base + URLs/directories) are valid and available to FOP. Any errors found will cause FOP to + immediately raise an exception. + false strict-validation @@ -110,7 +125,8 @@ Setting this option to 'false' causes FOP to be more forgiving about XSL-FO validity, for example, you're allowed to specify a border on a region-body which is supported by some FO implementations but is non-standard. Note that such a border would - currently have no effect in Apache FOP. + currently have no effect in Apache FOP. + true break-indent-inheritance @@ -124,6 +140,7 @@ the desired behaviour and because the behaviour among the commercial implementations varies. The default for this option (i.e. false) is to behave exactly like the specification describes. + false default-page-settings @@ -132,11 +149,13 @@ Specifies the default width and height of a page if "auto" is specified for either or both values. Use "height" and "width" attributes on the default-page-settings element to specify the two values. + "height" 11 inches, "width" 8.26 inches renderers (see text below) Contains the configuration for each renderer. See below. + N/A

@@ -145,6 +164,12 @@ + + true + + + true + ./ diff --git a/src/foschema/fop-configuration.xsd b/src/foschema/fop-configuration.xsd index c5a12d27f..ad959f947 100644 --- a/src/foschema/fop-configuration.xsd +++ b/src/foschema/fop-configuration.xsd @@ -38,6 +38,7 @@ type="xsd:positiveInteger" minOccurs="0"> + diff --git a/src/java/org/apache/fop/apps/FOURIResolver.java b/src/java/org/apache/fop/apps/FOURIResolver.java index 925cd62f8..db0cae75e 100644 --- a/src/java/org/apache/fop/apps/FOURIResolver.java +++ b/src/java/org/apache/fop/apps/FOURIResolver.java @@ -84,7 +84,7 @@ public class FOURIResolver try { absoluteURL = f.toURL(); } catch (MalformedURLException mfue) { - log.error("Could not convert filename to URL: " + mfue.getMessage(), mfue); + log.error("Could not convert filename to URL: " + mfue.getMessage()); } } else { URL baseURL = toBaseURL(base); @@ -98,7 +98,7 @@ public class FOURIResolver // 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); + log.error("Error with URL '" + href + "': " + mue.getMessage()); return null; } } @@ -137,7 +137,7 @@ public class FOURIResolver } absoluteURL = new URL(baseURL, href); } catch (MalformedURLException mfue) { - log.error("Error with URL '" + href + "': " + mfue.getMessage(), mfue); + log.error("Error with URL '" + href + "': " + mfue.getMessage()); return null; } } @@ -155,7 +155,7 @@ public class FOURIResolver //Note: This is on "debug" level since the caller is supposed to handle this log.debug("File not found: " + effURL); } catch (java.io.IOException ioe) { - log.error("Error with opening URL '" + href + "': " + ioe.getMessage(), ioe); + log.error("Error with opening URL '" + href + "': " + ioe.getMessage()); } return null; } diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index 63a3859ac..f15ddcc31 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -27,10 +27,6 @@ import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; -// avalon configuration -import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.configuration.ConfigurationException; - // commons logging import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -67,7 +63,7 @@ import org.apache.fop.render.pdf.PDFRenderer; public class FOUserAgent { /** Defines the default target resolution (72dpi) for FOP */ - public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi + public static final float DEFAULT_TARGET_RESOLUTION = FopFactory.DEFAULT_TARGET_RESOLUTION; private static Log log = LogFactory.getLog("FOP"); @@ -109,11 +105,12 @@ public class FOUserAgent { /** * Default constructor + * @throws FOPException * @see org.apache.fop.apps.FopFactory * @deprecated Provided for compatibility only. Please use the methods from * FopFactory to construct FOUserAgent instances! */ - public FOUserAgent() { + public FOUserAgent() throws FOPException { this(FopFactory.newInstance()); } @@ -128,9 +125,8 @@ public class FOUserAgent { throw new NullPointerException("The factory parameter must not be null"); } this.factory = factory; - if (factory.getUserConfig() != null) { - configure(factory.getUserConfig()); - } + setBaseURL(factory.getBaseURL()); + setTargetResolution(factory.getTargetResolution()); } /** @return the associated FopFactory instance */ @@ -278,55 +274,7 @@ public class FOUserAgent { public Map getRendererOptions() { return rendererOptions; } - - /** - * Configures the FOUserAgent through the factory's configuration. - * @param cfg Avalon Configuration Object - * @see org.apache.avalon.framework.configuration.Configurable - */ - protected void configure(Configuration cfg) { - setBaseURL(FopFactory.getBaseURLfromConfig(cfg, "base")); - if (cfg.getChild("target-resolution", false) != null) { - this.targetResolution - = cfg.getChild("target-resolution").getValueAsFloat( - DEFAULT_TARGET_RESOLUTION); - log.info("Target resolution set to: " + targetResolution - + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")"); - } - } - /** - * Returns the configuration subtree for a specific renderer. - * @param mimeType MIME type of the renderer - * @return the requested configuration subtree, null if there's no configuration - */ - public Configuration getUserRendererConfig(String mimeType) { - - Configuration cfg = getFactory().getUserConfig(); - if (cfg == null || mimeType == null) { - return null; - } - - Configuration userRendererConfig = null; - - Configuration[] cfgs - = cfg.getChild("renderers").getChildren("renderer"); - for (int i = 0; i < cfgs.length; ++i) { - Configuration child = cfgs[i]; - try { - if (child.getAttribute("mime").equals(mimeType)) { - userRendererConfig = child; - break; - } - } catch (ConfigurationException e) { - // silently pass over configurations without mime type - } - } - log.debug((userRendererConfig == null ? "No u" : "U") - + "ser configuration found for MIME type " + mimeType); - return userRendererConfig; - } - /** * Sets the base URL. * @param baseURL base URL @@ -460,8 +408,20 @@ public class FOUserAgent { * bitmap images generated by filter effects in Apache Batik. * @param dpi resolution in dpi */ - public void setTargetResolution(int dpi) { + public void setTargetResolution(float dpi) { this.targetResolution = dpi; + log.info("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 + */ + public void setTargetResolution(int dpi) { + setTargetResolution((float)dpi); } // ---------------------------------------------- environment-level stuff @@ -470,7 +430,7 @@ public class FOUserAgent { /** @return the font base URL */ public String getFontBaseURL() { String fontBaseURL = getFactory().getFontBaseURL(); - return fontBaseURL != null ? fontBaseURL : this.baseURL; + return fontBaseURL != null ? fontBaseURL : getBaseURL(); } /** @@ -541,6 +501,5 @@ public class FOUserAgent { public XMLHandlerRegistry getXMLHandlerRegistry() { return getFactory().getXMLHandlerRegistry(); } - } diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java index 363d68059..f7a3bd251 100644 --- a/src/java/org/apache/fop/apps/FopFactory.java +++ b/src/java/org/apache/fop/apps/FopFactory.java @@ -55,18 +55,33 @@ import org.apache.fop.render.XMLHandlerRegistry; 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. + * 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 { + + /** Defines the default target resolution (72dpi) for FOP */ + public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi /** Defines the default source resolution (72dpi) for FOP */ private static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi + /** Defines the default page-height */ private static final String DEFAULT_PAGE_HEIGHT = "11in"; + /** Defines the default page-width */ private static final String DEFAULT_PAGE_WIDTH = "8.26in"; + + /** Defines if FOP should use strict validation for FO and user config */ + private static final boolean DEFAULT_STRICT_FO_VALIDATION = true; + + /** Defines if FOP should validate the user config strictly */ + private static final boolean DEFAULT_STRICT_USERCONFIG_VALIDATION = true; + + /** Defines if FOP should use an alternative rule to determine text indents */ + private static final boolean DEFAULT_BREAK_INDENT_INHERITANCE = false; /** logger instance */ private static Log log = LogFactory.getLog(FopFactory.class); @@ -86,6 +101,7 @@ public class FopFactory { /** Our default resolver if none is set */ private URIResolver foURIResolver = new FOURIResolver(); + /** A user settable URI Resolver */ private URIResolver uriResolver = null; @@ -97,27 +113,50 @@ public class FopFactory { /** user configuration */ private Configuration userConfig = null; - /** The base URL for all font URL resolutions */ + /** + * The base URL for all URL resolutions, especially for + * external-graphics. + */ + private String baseURL; + + /** The base URL for all font URL resolutions. */ private String fontBaseURL; - + + /** The base URL for all hyphen URL resolutions. */ + private String hyphenBaseURL; + /** * 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. + * ability for FOP to halt on all content model violations if desired. */ - private boolean strictValidation = true; + private boolean strictFOValidation = 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 = DEFAULT_STRICT_USERCONFIG_VALIDATION; + /** Allows enabling kerning on the base 14 fonts, default is false */ private boolean enableBase14Kerning = false; /** Source resolution in dpi */ private float sourceResolution = DEFAULT_SOURCE_RESOLUTION; + + /** Target resolution in dpi */ + private float targetResolution = DEFAULT_TARGET_RESOLUTION; + + /** Page height */ private String pageHeight = DEFAULT_PAGE_HEIGHT; + + /** Page width */ private String pageWidth = DEFAULT_PAGE_WIDTH; /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */ - private boolean breakIndentInheritanceOnReferenceAreaBoundary = false; + private boolean breakIndentInheritanceOnReferenceAreaBoundary + = DEFAULT_BREAK_INDENT_INHERITANCE; /** Optional overriding LayoutManagerMaker */ private LayoutManagerMaker lmMakerOverride = null; @@ -149,6 +188,7 @@ public class FopFactory { * 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); @@ -295,6 +335,22 @@ public class FopFactory { return this.lmMakerOverride; } + /** + * Sets the base URL. + * @param baseURL base URL + */ + void setBaseURL(String baseURL) { + this.baseURL = baseURL; + } + + /** + * Returns the base URL. + * @return the base URL + */ + public String getBaseURL() { + return this.baseURL; + } + /** * Sets the font base URL. * @param fontBaseURL font base URL @@ -308,6 +364,26 @@ public class FopFactory { return this.fontBaseURL; } + /** @return the hyphen base URL */ + public String getHyphenBaseURL() { + return hyphenBaseURL; + } + + /** + * Sets the hyphen base URL. + * @param hyphenBaseURL hythen base URL + */ + public void setHyphenBaseURL(final String hyphenBaseURL) { + if (hyphenBaseURL != null) { + this.hyphResolver = new HyphenationTreeResolver() { + public Source resolve(String href) { + return resolveURI(href, hyphenBaseURL); + } + }; + } + this.hyphenBaseURL = hyphenBaseURL; + } + /** * 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. @@ -336,7 +412,7 @@ public class FopFactory { * @param validateStrictly true to turn on strict validation */ public void setStrictValidation(boolean validateStrictly) { - this.strictValidation = validateStrictly; + this.strictFOValidation = validateStrictly; } /** @@ -344,7 +420,7 @@ public class FopFactory { * @return true of strict validation turned on, false otherwise */ public boolean validateStrictly() { - return strictValidation; + return strictFOValidation; } /** @@ -399,14 +475,49 @@ public class FopFactory { public float getSourcePixelUnitToMillimeter() { return 25.4f / 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(int dpi) { + public void setSourceResolution(float dpi) { this.sourceResolution = dpi; + log.info("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 25.4f / 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); } /** @@ -427,6 +538,7 @@ public class FopFactory { */ public void setPageHeight(String pageHeight) { this.pageHeight = pageHeight; + log.info("Default page-height set to: " + pageHeight); } /** @@ -447,6 +559,7 @@ public class FopFactory { */ public void setPageWidth(String pageWidth) { this.pageWidth = pageWidth; + log.info("Default page-width set to: " + pageWidth); } /** @@ -491,14 +604,12 @@ public class FopFactory { * @throws IOException if an I/O error occurs * @throws SAXException if a parsing error occurs */ - public void setUserConfig(File userConfigFile) - throws SAXException, IOException { + public void setUserConfig(File userConfigFile) throws SAXException, IOException { try { DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); setUserConfig(cfgBuilder.buildFromFile(userConfigFile)); - } catch (ConfigurationException cfge) { - log.error("Error loading configuration: " - + cfge.getMessage()); + } catch (ConfigurationException e) { + throw new FOPException(e); } } @@ -508,28 +619,26 @@ public class FopFactory { * @throws IOException if an I/O error occurs * @throws SAXException if a parsing error occurs */ - public void setUserConfig(String uri) - throws SAXException, IOException { + public void setUserConfig(String uri) throws SAXException, IOException { try { DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); setUserConfig(cfgBuilder.build(uri)); - } catch (ConfigurationException cfge) { - log.error("Error loading configuration: " - + cfge.getMessage()); + } catch (ConfigurationException e) { + throw new FOPException(e); } } /** * Set the user configuration. * @param userConfig configuration + * @throws FOPException if a configuration problem occurs */ - public void setUserConfig(Configuration userConfig) { + public void setUserConfig(Configuration userConfig) throws FOPException { this.userConfig = userConfig; try { - initUserConfig(); - } catch (ConfigurationException cfge) { - log.error("Error initializing factory configuration: " - + cfge.getMessage()); + configure(userConfig); + } catch (ConfigurationException e) { + throw new FOPException(e); } } @@ -540,47 +649,105 @@ public class FopFactory { public Configuration getUserConfig() { return userConfig; } - + + /** + * Returns the configuration subtree for a specific renderer. + * @param mimeType MIME type of the renderer + * @return the requested configuration subtree, null if there's no configuration + */ + public Configuration getUserRendererConfig(String mimeType) { + if (userConfig == null || mimeType == null) { + return null; + } + + Configuration userRendererConfig = null; + + Configuration[] cfgs + = userConfig.getChild("renderers").getChildren("renderer"); + for (int i = 0; i < cfgs.length; ++i) { + Configuration child = cfgs[i]; + try { + if (child.getAttribute("mime").equals(mimeType)) { + userRendererConfig = child; + break; + } + } catch (ConfigurationException e) { + // silently pass over configurations without mime type + } + } + log.debug((userRendererConfig == null ? "No u" : "U") + + "ser configuration found for MIME type " + mimeType); + return userRendererConfig; + } + /** * Initializes user agent settings from the user configuration * file, if present: baseURL, resolution, default page size,... * * @throws ConfigurationException when there is an entry that * misses the required attribute + * Configures the FopFactory. + * @param cfg Avalon Configuration Object + * @see org.apache.avalon.framework.configuration.Configurable */ - public void initUserConfig() throws ConfigurationException { - log.debug("Initializing User Agent Configuration"); - setFontBaseURL(getBaseURLfromConfig(userConfig, "font-base")); - final String hyphBase = getBaseURLfromConfig(userConfig, "hyphenation-base"); - if (hyphBase != null) { - this.hyphResolver = new HyphenationTreeResolver() { - public Source resolve(String href) { - return resolveURI(href, hyphBase); + public void configure(Configuration cfg) throws ConfigurationException { + log.info("Initializing FopFactory Configuration"); + + if (cfg.getChild("strict-configuration", false) != null) { + this.strictUserConfigValidation + = cfg.getChild("strict-configuration").getValueAsBoolean(); + } + if (cfg.getChild("strict-validation", false) != null) { + this.strictFOValidation = cfg.getChild("strict-validation").getValueAsBoolean(); + } + if (cfg.getChild("base", false) != null) { + try { + setBaseURL(getBaseURLfromConfig(cfg, "base")); + } catch (ConfigurationException e) { + if (strictUserConfigValidation) { + throw e; } - }; + log.error(e.getMessage()); + } } - if (userConfig.getChild("source-resolution", false) != null) { - this.sourceResolution - = userConfig.getChild("source-resolution").getValueAsFloat( - DEFAULT_SOURCE_RESOLUTION); - log.info("Source resolution set to: " + sourceResolution - + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")"); + if (cfg.getChild("font-base", false) != null) { + try { + setFontBaseURL(getBaseURLfromConfig(cfg, "font-base")); + } catch (ConfigurationException e) { + if (strictUserConfigValidation) { + throw e; + } + log.error(e.getMessage()); + } } - if (userConfig.getChild("strict-validation", false) != null) { - this.strictValidation = userConfig.getChild("strict-validation").getValueAsBoolean(); + if (cfg.getChild("hyphenation-base", false) != null) { + try { + setHyphenBaseURL(getBaseURLfromConfig(cfg, "hyphenation-base")); + } catch (ConfigurationException e) { + if (strictUserConfigValidation) { + throw e; + } + log.error(e.getMessage()); + } + } + if (cfg.getChild("source-resolution", false) != null) { + setSourceResolution( + cfg.getChild("source-resolution").getValueAsFloat(DEFAULT_SOURCE_RESOLUTION)); } - if (userConfig.getChild("break-indent-inheritance", false) != null) { - this.breakIndentInheritanceOnReferenceAreaBoundary - = userConfig.getChild("break-indent-inheritance").getValueAsBoolean(); + if (cfg.getChild("target-resolution", false) != null) { + setTargetResolution( + cfg.getChild("target-resolution").getValueAsFloat(DEFAULT_TARGET_RESOLUTION)); } - Configuration pageConfig = userConfig.getChild("default-page-settings"); + if (cfg.getChild("break-indent-inheritance", false) != null) { + setBreakIndentInheritanceOnReferenceAreaBoundary( + cfg.getChild("break-indent-inheritance").getValueAsBoolean()); + } + Configuration pageConfig = cfg.getChild("default-page-settings"); if (pageConfig.getAttribute("height", null) != null) { - setPageHeight(pageConfig.getAttribute("height")); - log.info("Default page-height set to: " + pageHeight); + setPageHeight(pageConfig.getAttribute("height", DEFAULT_PAGE_HEIGHT)); } if (pageConfig.getAttribute("width", null) != null) { - setPageWidth(pageConfig.getAttribute("width")); - log.info("Default page-width set to: " + pageWidth); + setPageWidth(pageConfig.getAttribute("width", DEFAULT_PAGE_WIDTH)); } } @@ -589,26 +756,53 @@ public class FopFactory { * @param cfg The Configuration object to retrieve the base URL from * @param name the element name for the base URL * @return the requested base URL or null if not available - */ - public static String getBaseURLfromConfig(Configuration cfg, String name) { + * @throws ConfigurationException + */ + public static String getBaseURLfromConfig(Configuration cfg, String name) + throws ConfigurationException { if (cfg.getChild(name, false) != null) { try { - String cfgBaseDir = cfg.getChild(name).getValue(null); - if (cfgBaseDir != null) { - File dir = new File(cfgBaseDir); + String cfgBasePath = cfg.getChild(name).getValue(null); + if (cfgBasePath != null) { + // Is the path a dirname? + File dir = new File(cfgBasePath); +// if (!dir.exists()) { +// throw new ConfigurationException("Base URL '" + name +// + "' references non-existent resource '" +// + cfgBasePath + "'"); +// } else if (dir.isDirectory()) { if (dir.isDirectory()) { - cfgBaseDir = dir.toURL().toExternalForm(); + // Yes, convert it into a URL + cfgBasePath = dir.toURL().toExternalForm(); } + // Otherwise, this is already a URL } - log.info(name + " set to: " + cfgBaseDir); - return cfgBaseDir; + log.info(name + " set to: " + cfgBasePath); + return cfgBasePath; } catch (MalformedURLException mue) { - log.error("Base URL in user config is malformed!"); + throw new ConfigurationException("Base URL '" + name + + "' in user config is malformed!"); } } return null; } + /** + * Is the user configuration to be validated? + * @param strictUserConfigValidation strict user config validation + */ + public void setStrictUserConfigValidation(boolean strictUserConfigValidation) { + this.strictUserConfigValidation = strictUserConfigValidation; + } + + /** + * Is the user configuration to be validated? + * @return if the user configuration should be validated + */ + public boolean validateUserConfigStrictly() { + return this.strictUserConfigValidation; + } + //------------------------------------------- URI resolution /** @@ -700,5 +894,4 @@ public class FopFactory { } return colorSpace; } - } diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java index 3362ce334..bd3e81d4f 100644 --- a/src/java/org/apache/fop/fonts/FontSetup.java +++ b/src/java/org/apache/fop/fonts/FontSetup.java @@ -34,6 +34,7 @@ import org.apache.fop.fonts.base14.CourierOblique; import org.apache.fop.fonts.base14.CourierBoldOblique; import org.apache.fop.fonts.base14.Symbol; import org.apache.fop.fonts.base14.ZapfDingbats; +import org.apache.fop.render.PrintRenderer; // commons logging import org.apache.commons.logging.Log; @@ -247,46 +248,130 @@ public class FontSetup { }; } + /** * Builds a list of EmbedFontInfo objects for use with the setup() method. + * * @param cfg Configuration object + * @param renderer calling Renderer object * @return List the newly created list of fonts * @throws ConfigurationException if something's wrong with the config data */ - public static List buildFontListFromConfiguration(Configuration cfg) + public static List buildFontListFromConfiguration(Configuration cfg, PrintRenderer renderer) throws ConfigurationException { List fontList = new java.util.ArrayList(); - Configuration[] font = cfg.getChild("fonts").getChildren("font"); - for (int i = 0; i < font.length; i++) { - Configuration[] triple = font[i].getChildren("font-triplet"); - List tripleList = new java.util.ArrayList(); - for (int j = 0; j < triple.length; j++) { - int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight")); - tripleList.add(FontInfo.createFontKey(triple[j].getAttribute("name"), - triple[j].getAttribute("style"), - weight)); - } - - EmbedFontInfo efi; - efi = new EmbedFontInfo(font[i].getAttribute("metrics-url", null), - font[i].getAttributeAsBoolean("kerning", false), - tripleList, font[i].getAttribute("embed-url", null)); - - if (log.isDebugEnabled()) { - log.debug("Adding font " + efi.getEmbedFile() - + ", metric file " + efi.getMetricsFile()); - for (int j = 0; j < tripleList.size(); ++j) { - FontTriplet triplet = (FontTriplet) tripleList.get(j); - log.debug("Font triplet " - + triplet.getName() + ", " - + triplet.getStyle() + ", " - + triplet.getWeight()); + + FontResolver fontResolver = renderer.getFontResolver(); + if (fontResolver == null) { + //Ensure that we have minimal font resolution capabilities + fontResolver = FontSetup.createMinimalFontResolver(); + } + + boolean strict + = renderer.getUserAgent().getFactory().validateUserConfigStrictly(); + + Configuration[] fonts = cfg.getChildren("fonts"); + for (int f = 0; f < fonts.length; f++) { + + Configuration[] font = fonts[f].getChildren("font"); + for (int i = 0; i < font.length; i++) { + + String metricsUrl = font[i].getAttribute("metrics-url", null); + String embedUrl = font[i].getAttribute("embed-url", null); + + if (metricsUrl == null && embedUrl == null) { + if (strict) { + throw new ConfigurationException( + "Font configuration without metric-url or embed-url"); + } + log.error("Font configuration without metric-url or embed-url"); + continue; + } + + if (metricsUrl != null && fontResolver.resolve(metricsUrl) == null) { + if (strict) { + throw new ConfigurationException("Failed to resolve font metric-url '" + + metricsUrl + "'"); + } + log.error("Failed to resolve font metric-url '" + metricsUrl + "'"); + continue; + } + + if (embedUrl != null && fontResolver.resolve(embedUrl) == null) { + if (strict) { + throw new ConfigurationException("Failed to resolve font with embed-url '" + + embedUrl + "'"); + } + log.error("Failed to resolve font with embed-url '" + embedUrl + "'"); + continue; + } + + boolean useKerning = font[i].getAttributeAsBoolean("kerning", false); + + Configuration[] triple = font[i].getChildren("font-triplet"); + List tripleList = new java.util.ArrayList(); + for (int j = 0; j < triple.length; j++) { + String name = triple[j].getAttribute("name"); + if (name == null) { + if (strict) { + throw new ConfigurationException("font-triplet without name"); + } + log.error("font-triplet without name"); + continue; + } + + String weightStr = triple[j].getAttribute("weight"); + if (weightStr == null) { + if (strict) { + throw new ConfigurationException("font-triplet without weight"); + } + log.error("font-triplet without weight"); + continue; + } + int weight = FontUtil.parseCSS2FontWeight(weightStr); + + String style = triple[j].getAttribute("style"); + if (style == null) { + if (strict) { + throw new ConfigurationException("font-triplet without style"); + } + log.error("font-triplet without style"); + continue; + } + + tripleList.add(FontInfo.createFontKey(name, + style, weight)); + } + + EmbedFontInfo configFontInfo = new EmbedFontInfo(metricsUrl, + useKerning, tripleList, embedUrl); + + if (log.isDebugEnabled()) { + log.debug("Adding font " + configFontInfo.getEmbedFile() + + ", metric file " + configFontInfo.getMetricsFile()); + for (int j = 0; j < tripleList.size(); ++j) { + FontTriplet triplet = (FontTriplet) tripleList.get(j); + log.debug("Font triplet " + + triplet.getName() + ", " + + triplet.getStyle() + ", " + + triplet.getWeight()); + } } + fontList.add(configFontInfo); } - - fontList.add(efi); } return fontList; + } + + /** + * Builds a list of EmbedFontInfo objects for use with the setup() method. + * + * @param cfg Configuration object + * @return List the newly created list of fonts + * @throws ConfigurationException if something's wrong with the config data + */ + public static List buildFontListFromConfiguration(Configuration cfg) + throws ConfigurationException { + return buildFontListFromConfiguration(cfg, null); } } - diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 562666bdc..91cfe7bfa 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -88,7 +88,7 @@ public abstract class AbstractRenderer /** * user agent */ - protected FOUserAgent userAgent; + protected FOUserAgent userAgent = null; /** * block progression position @@ -135,6 +135,13 @@ public abstract class AbstractRenderer userAgent = agent; } + /** + * @see org.apache.fop.render.Renderer#getUserAgent() + */ + public FOUserAgent getUserAgent() { + return userAgent; + } + /** @see org.apache.fop.render.Renderer#startRenderer(OutputStream) */ public void startRenderer(OutputStream outputStream) throws IOException { } @@ -845,7 +852,7 @@ public abstract class AbstractRenderer if (handler != null) { try { //Optional XML handler configuration - Configuration cfg = userAgent.getUserRendererConfig(getMimeType()); + Configuration cfg = userAgent.getFactory().getUserRendererConfig(getMimeType()); if (cfg != null) { cfg = getHandlerConfig(cfg, namespace); if (cfg != null) { diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java index ddb335564..6a3cdf2c6 100644 --- a/src/java/org/apache/fop/render/PrintRenderer.java +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -41,9 +41,12 @@ public abstract class PrintRenderer extends AbstractRenderer { /** Font configuration */ protected FontInfo fontInfo; + /** Font resolver */ + protected FontResolver fontResolver = null; + /** list of fonts */ protected List fontList = null; - + /** * Set up the font info * @@ -51,8 +54,7 @@ public abstract class PrintRenderer extends AbstractRenderer { */ public void setupFontInfo(FontInfo inFontInfo) { this.fontInfo = inFontInfo; - FontResolver resolver = new DefaultFontResolver(userAgent); - FontSetup.setup(fontInfo, fontList, resolver, + FontSetup.setup(fontInfo, fontList, fontResolver, userAgent.getFactory().isBase14KerningEnabled()); } @@ -147,5 +149,16 @@ public abstract class PrintRenderer extends AbstractRenderer { renderXML(context, doc, ns); } - + + /** + * Get FontResolver + * + * @return FontResolver + */ + public FontResolver getFontResolver() { + if (this.fontResolver == null) { + this.fontResolver = new DefaultFontResolver(super.userAgent); + } + return this.fontResolver; + } } diff --git a/src/java/org/apache/fop/render/RendererFactory.java b/src/java/org/apache/fop/render/RendererFactory.java index 8c35ec65a..4d3f3a12c 100644 --- a/src/java/org/apache/fop/render/RendererFactory.java +++ b/src/java/org/apache/fop/render/RendererFactory.java @@ -189,7 +189,7 @@ public class RendererFactory { Configuration userRendererConfig = null; if (mimeType != null) { userRendererConfig - = userAgent.getUserRendererConfig(mimeType); + = userAgent.getFactory().getUserRendererConfig(mimeType); } if (userRendererConfig != null) { try { diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 966aef2e5..481ce844c 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -243,7 +243,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { this.filterMap = PDFFilterList.buildFilterMapFromConfiguration(cfg); //Font configuration - List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg); + List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this); if (this.fontList == null) { this.fontList = cfgFonts; } else { diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 75c3817f1..6553f06b6 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -129,7 +129,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda this.autoRotateLandscape = cfg.getChild("auto-rotate-landscape").getValueAsBoolean(false); //Font configuration - List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg); + List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this); if (this.fontList == null) { this.fontList = cfgFonts; } else { diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index c1f85be87..857847e10 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -145,7 +145,7 @@ public class XMLRenderer extends PrintRenderer { public void configure(Configuration cfg) throws ConfigurationException { super.configure(cfg); //Font configuration - List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg); + List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this); if (this.fontList == null) { this.fontList = cfgFonts; } else { diff --git a/status.xml b/status.xml index 4a4ffabae..f7e330aec 100644 --- a/status.xml +++ b/status.xml @@ -28,6 +28,9 @@ + + Stricter FOP user configuration checking + Fix parsing 'url(...)' when the URL itself contains a bracketed part. diff --git a/test/config/test_embedurl_bad.xconf b/test/config/test_embedurl_bad.xconf new file mode 100644 index 000000000..3636454fe --- /dev/null +++ b/test/config/test_embedurl_bad.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/config/test_embedurl_malformed.xconf b/test/config/test_embedurl_malformed.xconf new file mode 100644 index 000000000..b11d086d2 --- /dev/null +++ b/test/config/test_embedurl_malformed.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/config/test_fontattributes_missing.xconf b/test/config/test_fontattributes_missing.xconf new file mode 100644 index 000000000..f186d802a --- /dev/null +++ b/test/config/test_fontattributes_missing.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/config/test_fontbase_bad.xconf b/test/config/test_fontbase_bad.xconf new file mode 100644 index 000000000..850f343bb --- /dev/null +++ b/test/config/test_fontbase_bad.xconf @@ -0,0 +1,23 @@ + + + + true + + + ./ + + + ./doesnotexist/ + + + + + + + + + + + + diff --git a/test/config/test_fonttripletattribute_missing.xconf b/test/config/test_fonttripletattribute_missing.xconf new file mode 100644 index 000000000..4e1387493 --- /dev/null +++ b/test/config/test_fonttripletattribute_missing.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/config/test_metricsurl_bad.xconf b/test/config/test_metricsurl_bad.xconf new file mode 100644 index 000000000..a792834d3 --- /dev/null +++ b/test/config/test_metricsurl_bad.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/config/test_metricsurl_malformed.xconf b/test/config/test_metricsurl_malformed.xconf new file mode 100644 index 000000000..7dc6dacb6 --- /dev/null +++ b/test/config/test_metricsurl_malformed.xconf @@ -0,0 +1,22 @@ + + + + true + + + ./ + + + ./ + + + + + + + + + + + + diff --git a/test/java/org/apache/fop/config/BaseUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseUserConfigTestCase.java new file mode 100644 index 000000000..3a97f4303 --- /dev/null +++ b/test/java/org/apache/fop/config/BaseUserConfigTestCase.java @@ -0,0 +1,125 @@ +/* + * 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.config; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.render.pdf.BasePDFTestCase; +import org.xml.sax.SAXException; + +/** + * Basic runtime test for FOP's font configuration. It is used to verify that + * nothing obvious is broken after compiling. + */ +public abstract class BaseUserConfigTestCase extends BasePDFTestCase { + + protected static DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); + + /** logging instance */ + protected Log log = LogFactory.getLog(BaseUserConfigTestCase.class); + + + /** + * @see junit.framework.TestCase#TestCase(String) + */ + public BaseUserConfigTestCase(String name) { + super(name); + } + + /** + * @see org.apache.fop.render.pdf.BasePDFTestCase#init() + */ + protected void init() { + // do nothing + } + + /** + * Test using a standard FOP font + * @throws Exception checkstyle wants a comment here, even a silly one + */ + public void testUserConfig() throws Exception { + try { + fopFactory.setUserConfig(getUserConfig()); + final File baseDir = getBaseDir(); + final String fontFOFilePath = getFontFOFilePath(); + File foFile = new File(baseDir, fontFOFilePath); + final boolean dumpOutput = false; + FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); + convertFO(foFile, foUserAgent, dumpOutput); + fail( getName() + ": Expected Configuration Exception" ); + } catch (FOPException e) { + // this *should* happen! + } catch (Exception e) { + fail( getName() + ": Expected FOPException but got: " + e.getMessage() ); + } + } + + + /** + * get test FOP config File + * @return fo test filepath + */ + protected String getFontFOFilePath() { + return "test/xml/bugtests/font.fo"; + } + + /** + * get test FOP Configuration + * @return fo test filepath + * @throws IOException + * @throws SAXException + * @throws ConfigurationException + */ + protected Configuration getUserConfig(String configString) + throws ConfigurationException, SAXException, IOException { + return cfgBuilder.build(new ByteArrayInputStream(configString.getBytes())); + } + + /** + * get test FOP Configuration + * @return fo test filepath + * @throws IOException + * @throws SAXException + * @throws ConfigurationException + */ + protected Configuration getUserConfig() + throws ConfigurationException, SAXException, IOException { + return cfgBuilder.buildFromFile(getUserConfigFile()); + } + + /** get base config directory */ + protected String getBaseConfigDir() { + return "test/config"; + } + + /** + * @return user config File + */ + protected abstract File getUserConfigFile(); +} diff --git a/test/java/org/apache/fop/config/EmbedUrlBadTestCase.java b/test/java/org/apache/fop/config/EmbedUrlBadTestCase.java new file mode 100644 index 000000000..2934004fd --- /dev/null +++ b/test/java/org/apache/fop/config/EmbedUrlBadTestCase.java @@ -0,0 +1,41 @@ +/* + * 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.config; + +import java.io.File; + +// +/** + * this font has an embed-url that does not exist on filesystem. + */ +public class EmbedUrlBadTestCase extends BaseUserConfigTestCase { + + public EmbedUrlBadTestCase(String name) { + super(name); + } + + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_embedurl_bad.xconf"); + } + + public String getName() { + return "test_embedurl_bad.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java b/test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java new file mode 100644 index 000000000..ab622fd69 --- /dev/null +++ b/test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java @@ -0,0 +1,38 @@ +/* + * 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.config; + +import java.io.File; + +// this font has a malformed embed-url +public class EmbedUrlMalformedTestCase extends BaseUserConfigTestCase { + + public EmbedUrlMalformedTestCase(String name) { + super(name); + } + + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_embedurl_malformed.xconf"); + } + + public String getName() { + return "test_embedurl_malformed.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java new file mode 100644 index 000000000..fc5b10a60 --- /dev/null +++ b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java @@ -0,0 +1,38 @@ +/* + * 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.config; + +import java.io.File; + +// this font is without a metrics-url or an embed-url +public class FontAttributesMissingTestCase extends BaseUserConfigTestCase { + + public FontAttributesMissingTestCase(String name) { + super(name); + } + + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_fontattributes_missing.xconf"); + } + + public String getName() { + return "test_fontattributes_missing.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/FontBaseBadTestCase.java b/test/java/org/apache/fop/config/FontBaseBadTestCase.java new file mode 100644 index 000000000..d22670d8a --- /dev/null +++ b/test/java/org/apache/fop/config/FontBaseBadTestCase.java @@ -0,0 +1,44 @@ +/* + * 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.config; + +import java.io.File; + +// this font base does not exist and a relative font path is used +public class FontBaseBadTestCase extends BaseUserConfigTestCase { + + public FontBaseBadTestCase(String name) { + super(name); + } + + /** + * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFile() + */ + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_fontbase_bad.xconf"); + } + + /** + * @return configuration filename + */ + public String getName() { + return "test_fontbase_bad.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java new file mode 100644 index 000000000..c321926f8 --- /dev/null +++ b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java @@ -0,0 +1,38 @@ +/* + * 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.config; + +import java.io.File; + +// this font has an embed-url that does not exist on filesystem +public class FontTripletAttributeMissingTestCase extends BaseUserConfigTestCase { + + public FontTripletAttributeMissingTestCase(String name) { + super(name); + } + + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_fonttripletattribute_missing.xconf"); + } + + public String getName() { + return "test_fonttripletattribute_missing.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/MetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/MetricsUrlBadTestCase.java new file mode 100644 index 000000000..80f7e285b --- /dev/null +++ b/test/java/org/apache/fop/config/MetricsUrlBadTestCase.java @@ -0,0 +1,44 @@ +/* + * 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.config; + +import java.io.File; + +// this font has a metrics-url that does not exist on filesystem +public class MetricsUrlBadTestCase extends BaseUserConfigTestCase { + + /** + * @see junit.framework.TestCase#TestCase(String) + */ + public MetricsUrlBadTestCase(String name) { + super(name); + } + + /** + * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFile() + */ + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_metricsurl_bad.xconf"); + } + + public String getName() { + return "test_metricsurl_bad.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java new file mode 100644 index 000000000..6b623e06e --- /dev/null +++ b/test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java @@ -0,0 +1,38 @@ +/* + * 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.config; + +import java.io.File; + +// this font has a malformed metrics-url +public class MetricsUrlMalformedTestCase extends BaseUserConfigTestCase { + + public MetricsUrlMalformedTestCase(String name) { + super(name); + } + + protected File getUserConfigFile() { + return new File( getBaseConfigDir() + "/test_metricsurl_malformed.xconf"); + } + + public String getName() { + return "test_metricsurl_malformed.xconf"; + } +} diff --git a/test/java/org/apache/fop/config/UserConfigTestSuite.java b/test/java/org/apache/fop/config/UserConfigTestSuite.java new file mode 100644 index 000000000..ab612d043 --- /dev/null +++ b/test/java/org/apache/fop/config/UserConfigTestSuite.java @@ -0,0 +1,49 @@ +/* + * 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.config; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for font configuration. + */ +public class UserConfigTestSuite { + + /** + * Builds the test suite + * @return the test suite + */ + public static Test suite() { + TestSuite suite = new TestSuite( + "Basic functionality test suite for user configuration"); + //$JUnit-BEGIN$ + suite.addTest(new TestSuite(FontBaseBadTestCase.class)); + suite.addTest(new TestSuite(FontAttributesMissingTestCase.class)); + suite.addTest(new TestSuite(FontTripletAttributeMissingTestCase.class)); + suite.addTest(new TestSuite(MetricsUrlBadTestCase.class)); + suite.addTest(new TestSuite(EmbedUrlBadTestCase.class)); + suite.addTest(new TestSuite(MetricsUrlMalformedTestCase.class)); + suite.addTest(new TestSuite(EmbedUrlMalformedTestCase.class)); + //$JUnit-END$ + return suite; + } + +} diff --git a/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java b/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java index 54e2ba9d8..3e399e064 100644 --- a/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java +++ b/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java @@ -29,17 +29,16 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.fop.AbstractFOPTestCase; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; -import junit.framework.TestCase; - /** * Base class for automated tests that create PDF files */ -public class BasePDFTestCase extends TestCase { +public class BasePDFTestCase extends AbstractFOPTestCase { /** the FopFactory */ protected final FopFactory fopFactory = FopFactory.newInstance(); @@ -53,7 +52,13 @@ public class BasePDFTestCase extends TestCase { */ protected BasePDFTestCase(String name) { super(name); + init(); + } + /** + * initalizes the test + */ + protected void init() { final File uc = getUserConfigFile(); try {