From d5f3476deda6a8db416dfdedc48255328f732ec6 Mon Sep 17 00:00:00 2001 From: Peter Bernard West Date: Sat, 6 Mar 2004 05:53:16 +0000 Subject: [PATCH] Aligned Alt-Design apps more with HEAD. Made Configuration instance. Echoed HEAD in using of InputHandler, FOFileHandler and XSLTInputHandler Used org.apache.commons.cli.Options for CLI processing. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP_0-20-0_Alt-Design@197414 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/Driver.java | 66 +- .../org/apache/fop/apps/FOFileHandler.java | 44 +- .../org/apache/fop/apps/FOInputHandler.java | 49 - src/java/org/apache/fop/apps/FOPOptions.java | 1164 +++++++++++++++++ src/java/org/apache/fop/apps/Fop.java | 43 +- .../org/apache/fop/apps/InputHandler.java | 93 +- src/java/org/apache/fop/apps/Options.java | 886 ------------- .../org/apache/fop/apps/XSLTInputHandler.java | 21 +- 8 files changed, 1310 insertions(+), 1056 deletions(-) delete mode 100644 src/java/org/apache/fop/apps/FOInputHandler.java create mode 100644 src/java/org/apache/fop/apps/FOPOptions.java delete mode 100644 src/java/org/apache/fop/apps/Options.java diff --git a/src/java/org/apache/fop/apps/Driver.java b/src/java/org/apache/fop/apps/Driver.java index c9ec9df43..336788d7d 100644 --- a/src/java/org/apache/fop/apps/Driver.java +++ b/src/java/org/apache/fop/apps/Driver.java @@ -42,8 +42,34 @@ import org.apache.fop.xml.XmlEventReader; */ public class Driver { + + /** private constant to indicate renderer was not defined. */ + private static final int NOT_SET = 0; + /** Render to PDF. OutputStream must be set */ + public static final int RENDER_PDF = 1; + /** Render to a GUI window. No OutputStream neccessary */ + public static final int RENDER_AWT = 2; + /** Render to MIF. OutputStream must be set */ + public static final int RENDER_MIF = 3; + /** Render to XML. OutputStream must be set */ + public static final int RENDER_XML = 4; + /** Render to PRINT. No OutputStream neccessary */ + public static final int RENDER_PRINT = 5; + /** Render to PCL. OutputStream must be set */ + public static final int RENDER_PCL = 6; + /** Render to Postscript. OutputStream must be set */ + public static final int RENDER_PS = 7; + /** Render to Text. OutputStream must be set */ + public static final int RENDER_TXT = 8; + /** Render to SVG. OutputStream must be set */ + public static final int RENDER_SVG = 9; + /** Render to RTF. OutputStream must be set */ + public static final int RENDER_RTF = 10; + /** If true, full error stacks are reported */ - private static boolean _errorDump = false; + private boolean _errorDump = false; + private Configuration configuration = null; + private FOPOptions options = null; private InputHandler inputHandler; private XMLReader parser; @@ -67,9 +93,18 @@ public class Driver { * Error handling, version and logging initialization. */ public Driver() { - _errorDump = - Configuration.getBooleanValue("debugMode").booleanValue(); String version = Version.getVersion(); + configuration = new Configuration(); + options = new FOPOptions(configuration); + _errorDump = configuration.isTrue("debugMode"); + Fop.logger.config(version); + } + + public Driver(String[] args, Configuration config, FOPOptions options) { + String version = Version.getVersion(); + configuration = config; + this.options = options; + _errorDump = configuration.isTrue("debugMode"); Fop.logger.config(version); } @@ -103,7 +138,7 @@ public class Driver { * @throws FOPException */ public void run () throws FOPException { - setInputHandler(Options.getInputHandler()); + setInputHandler(options.getInputHandler()); parser = inputHandler.getParser(); saxSource = inputHandler.getInputSource(); // Setting of namespace-prefixes feature no longer required @@ -140,26 +175,7 @@ public class Driver { } /** - * Gets the parser Class name. - * - * @return a String with the value of the property - * org.xml.sax.parser or the default value - * org.apache.xerces.parsers.SAXParser. - */ - public static final String getParserClassName() { - String parserClassName = null; - try { - parserClassName = System.getProperty("org.xml.sax.parser"); - } catch (SecurityException se) {} - - if (parserClassName == null) { - parserClassName = "org.apache.xerces.parsers.SAXParser"; - } - return parserClassName; - } - - /** - * Sets the InputHandler for XML imput as specified in Options. + * Sets the InputHandler for XML imput as specified in FOPOptions. * @param inputHandler the InputHandler */ public void setInputHandler(InputHandler inputHandler) { @@ -180,7 +196,7 @@ public class Driver { * Prints stack trace of an exception * @param e the exception to trace */ - public static void dumpError(Exception e) { + public void dumpError(Exception e) { if (_errorDump) { if (e instanceof SAXException) { e.printStackTrace(); diff --git a/src/java/org/apache/fop/apps/FOFileHandler.java b/src/java/org/apache/fop/apps/FOFileHandler.java index 28226e677..3ebe2b7fa 100644 --- a/src/java/org/apache/fop/apps/FOFileHandler.java +++ b/src/java/org/apache/fop/apps/FOFileHandler.java @@ -21,12 +21,6 @@ package org.apache.fop.apps; // Imported SAX classes import org.xml.sax.InputSource; import org.xml.sax.XMLReader; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotSupportedException; - -// java -import javax.xml.parsers.SAXParserFactory; -import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.net.URL; @@ -74,26 +68,30 @@ public class FOFileHandler extends InputHandler { } /** - * Creates XMLReader object using default - * SAXParserFactory - * @return the created XMLReader - * @throws FOPException if the parser couldn't be created or configured for proper operation. + * creates a SAX parser, using the value of org.xml.sax.parser + * defaulting to org.apache.xerces.parsers.SAXParser + * + * @return the created SAX parser */ protected static XMLReader createParser() throws FOPException { + String parserClassName = System.getProperty("org.xml.sax.parser"); + if (parserClassName == null) { + parserClassName = "org.apache.xerces.parsers.SAXParser"; + } + Fop.logger.config("using SAX parser " + parserClassName); + try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setFeature( - "http://xml.org/sax/features/namespace-prefixes", true); - return factory.newSAXParser().getXMLReader(); - } catch (SAXNotSupportedException se) { - throw new FOPException("Error: You need a parser which allows the" - + " http://xml.org/sax/features/namespace-prefixes" - + " feature to be set to true to support namespaces", se); - } catch (SAXException se) { - throw new FOPException("Couldn't create XMLReader", se); - } catch (ParserConfigurationException pce) { - throw new FOPException("Couldn't create XMLReader", pce); + return (XMLReader)Class.forName(parserClassName).newInstance(); + } catch (ClassNotFoundException e) { + throw new FOPException(e); + } catch (InstantiationException e) { + throw new FOPException("Could not instantiate " + + parserClassName, e); + } catch (IllegalAccessException e) { + throw new FOPException("Could not access " + parserClassName, e); + } catch (ClassCastException e) { + throw new FOPException(parserClassName + " is not a SAX driver", + e); } } diff --git a/src/java/org/apache/fop/apps/FOInputHandler.java b/src/java/org/apache/fop/apps/FOInputHandler.java deleted file mode 100644 index 883c18b2e..000000000 --- a/src/java/org/apache/fop/apps/FOInputHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * $Id$ - * - * - * Copyright 1999-2003 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package org.apache.fop.apps; - -// Imported SAX classes -import java.io.File; - -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; - -/** - * Manages input if it is an xsl:fo file - */ -public class FOInputHandler extends InputHandler { - - File fofile; - public FOInputHandler(File fofile) { - this.fofile = fofile; - } - - public InputSource getInputSource() { - return super.fileInputSource(fofile); - } - - public XMLReader getParser() throws FOPException { - return super.createParser(); - } - -} - diff --git a/src/java/org/apache/fop/apps/FOPOptions.java b/src/java/org/apache/fop/apps/FOPOptions.java new file mode 100644 index 000000000..d867a3679 --- /dev/null +++ b/src/java/org/apache/fop/apps/FOPOptions.java @@ -0,0 +1,1164 @@ +/* + * $Id$ + * + * + * Copyright 1999-2003 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package org.apache.fop.apps; + +// sax +import org.xml.sax.InputSource; + +// java +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Locale; +import java.util.Set; +import java.util.Iterator; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; +// fop +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.OptionGroup; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.fop.configuration.Configuration; +import org.apache.fop.configuration.ConfigurationReader; + +/** + * FOPOptions handles loading of configuration files and + * additional setting of commandline options + */ +public class FOPOptions { + + /** input / output not set */ + public static final int NOT_SET = 0; + /** input: fo file */ + public static final int FO_INPUT = 1; + /** input: xml+xsl file */ + public static final int XSLT_INPUT = 2; + /** output: pdf file */ + public static final int PDF_OUTPUT = 1; + /** output: screen using swing */ + public static final int AWT_OUTPUT = 2; + /** output: mif file */ + public static final int MIF_OUTPUT = 3; + /** output: sent swing rendered file to printer */ + public static final int PRINT_OUTPUT = 4; + /** output: pcl file */ + public static final int PCL_OUTPUT = 5; + /** output: postscript file */ + public static final int PS_OUTPUT = 6; + /** output: text file */ + public static final int TXT_OUTPUT = 7; + /** output: svg file */ + public static final int SVG_OUTPUT = 8; + /** output: XML area tree */ + public static final int AREA_OUTPUT = 9; + /** output: RTF file */ + public static final int RTF_OUTPUT = 10; + + private static final int LAST_INPUT_MODE = XSLT_INPUT; + private static final int LAST_OUTPUT_MODE = RTF_OUTPUT; + + private Configuration configuration = null; + + /* Show debug info. Boolean object set from configuration files. */ + private boolean debug = false; + /* show configuration information */ + private boolean dumpConfig = false; + /* suppress any progress information */ + /* for area tree XML output, only down to block area level */ + /* name of user configuration file */ + private File userConfigFile = null; + /* name of input fo file */ + private File foFile = null; + /* name of xsltFile (xslt transformation as input) */ + private File xsltFile = null; + /* name of xml file (xslt transformation as input) */ + private File xmlFile = null; + /* name of output file */ + private File outputFile = null; + /* name of buffer file */ + private File bufferFile = null; + /* input mode */ + private int inputmode = NOT_SET; + /* output mode */ + private int outputmode = NOT_SET; + /* buffer mode */ + private int buffermode = NOT_SET; + /* language for user information */ + // baseDir (set from the config files + private String baseDir = null; + + private java.util.HashMap rendererOptions; + + private Logger log; + + private Vector xsltParams = null; + + private Options options = new Options(); + + private static final String defaultConfigFile = "config.xml"; + private static final String defaultUserConfigFile = "userconfig.xml"; + + /** + * An array of String indexed by the integer constants representing + * the various input modes. Provided so that integer modes can be + * mapped to a more descriptive string, and vice versa. + */ + private String[] inputModes; + /** + * An array of String indexed by the integer constants representing + * the various output modes. Provided so that integer modes can be + * mapped to a more descriptive string, and vice versa. + */ + private String[] outputModes; + + /** + * Parser variables + */ + private HashMap arguments = new HashMap(); + + /** + * + */ + public FOPOptions(Configuration configuration) { + setup(); + this.configuration = configuration; + try { + configure(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (FOPException e) { + throw new RuntimeException(e); + } + } + + public FOPOptions(Configuration configuration, String[] args) { + setup(); + this.configuration = configuration; + try { + configure(args); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (FOPException e) { + throw new RuntimeException(e); + } + } + + private void setup() { + inputModes = new String[LAST_INPUT_MODE + 1]; + inputModes[NOT_SET] = "NotSet"; + inputModes[FO_INPUT] = "fo"; + inputModes[XSLT_INPUT] = "xslt"; + + outputModes = new String[LAST_OUTPUT_MODE + 1]; + outputModes[NOT_SET] = "NotSet"; + outputModes[PDF_OUTPUT] = "pdf"; + outputModes[PS_OUTPUT] = "ps"; + outputModes[PCL_OUTPUT] = "pcl"; + outputModes[PRINT_OUTPUT] = "print"; + outputModes[AWT_OUTPUT] = "awt"; + outputModes[MIF_OUTPUT] = "mif"; + outputModes[RTF_OUTPUT] = "rtf"; + outputModes[SVG_OUTPUT] = "svg"; + outputModes[TXT_OUTPUT] = "txt"; + outputModes[AREA_OUTPUT] = "at"; + } + + /** + * @param mode the mode whose index in the array inputModes is to be + * returned. + * @return the int index of the mode string in the array, or -1 if the + * mode string is not found in the array + */ + public int inputModeIndex(String mode) + throws FOPException { + for (int i = 0; i <= LAST_INPUT_MODE; i++) { + if (inputModes[i] != null) + if (mode.equals(inputModes[i])) + return i; + } + throw new FOPException("Input mode " + mode + " not known"); + } + + /** + * @param mode the mode whose index in the array outputModes is to be + * returned. + * @return the int index of the mode string in the array, or -1 if the + * mode string is not found in the array + */ + public int outputModeIndex(String mode) + throws FOPException { + for (int i = 0; i <= LAST_INPUT_MODE; i++) { + if (outputModes[i] != null) + if (mode.equals(outputModes[i])) + return i; + } + throw new FOPException("Output mode " + mode + " not known"); + } + + /** + * Configure the system according to the system configuration file + * config.xml and the user configuration file if it is specified in the + * system configuration file. + */ + public void configure() + throws FOPException, FileNotFoundException { + loadConfigFiles(); + loadArguments(); + initOptions(); + try { + checkSettings(); + } catch (java.io.FileNotFoundException e) { + printUsage(); + throw e; + } + } + + public void configure(String[] args) + throws FOPException, FileNotFoundException { + parseOptions(args); + configure(); + } + + /** + * Method to map an inputMode name to an inputmode index. + * @param name a String containing the name of an input mode + * @return the index of that name in the array of input mode names, + * or -1 if not found + */ + public int inputModeNameToIndex(String name) { + for (int i = 0; i <= LAST_INPUT_MODE; i++) { + if (name.equals(inputModes[i])) return i; + } + return -1; + } + + /** + * Method to map an outputMode name to an outputmode index. + * @param name a String containing the name of an output mode + * @return the index of that name in the array of output mode names, + * or -1 if not found + */ + public int outputModeNameToIndex(String name) { + for (int i = 0; i <= LAST_INPUT_MODE; i++) { + if (name.equals(outputModes[i])) return i; + } + return -1; + } + + /** + * parseOptions() parses the command line into a + * HashMap which is + * passed to this method. All key-Object pairs are installed in the + * Configuration maps. + */ + void loadArguments() { + String key = null; + if (arguments != null) { + Set keys = arguments.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + key = (String)iter.next(); + configuration.put(key, arguments.get(key)); + } + } + } + + + /** + * Finish initialization of options. The command line options, if + * present, have been parsed and stored in the HashMap arguments. + * The ints inputmode and outputmode will have been set as a side- + * effect of command line parsing. + * + * The standard configuration file has been read and its contents + * stored in the Configuration HashMaps. If a user configuration file + * was specified in the command line arguments, or, failing that, in + * the standard configuration file, it had been read and its contents + * have overridden the Configuration maps. + * + * It remains for any related variables defined in this class to be set. + * + * @exception FOPException + */ + void initOptions() throws FOPException { + String str = null; + + // show configuration settings + dumpConfig = configuration.isTrue("dumpConfiguration"); + + if ((str = getFoFileName()) != null) + foFile = new File(str); + if ((str = getXmlFileName()) != null) + xmlFile = new File(str); + if ((str = getXsltFileName()) != null) + xsltFile = new File(str); + if ((str = getOutputFileName()) != null) + outputFile = new File(str); + if ((str = getBufferFileName()) != null) + bufferFile = new File(str); + // userConfigFile may be set in the process of loading said file + if (userConfigFile == null && (str = getUserConfigFileName()) != null) + userConfigFile = new File(str); + + if ((str = getInputMode()) != null) + inputmode = inputModeIndex(str); + if ((str = getOutputMode()) != null) + outputmode = outputModeIndex(str); + + // set base directory + // This is not set directly from the command line, but may be set + // indirectly from the input file setting if not set in the standard + // or user configuration files + baseDir = configuration.getStringValue("baseDir"); + if (baseDir == null) { + try { + baseDir = new File(getInputFile().getAbsolutePath()) + .getParentFile().toURL().toExternalForm(); + configuration.put("baseDir", baseDir); + } catch (Exception e) {} + } + if (debug) { + Fop.logger.config("base directory: " + baseDir); + } + + if (dumpConfig) { + configuration.dumpConfiguration(); + System.exit(0); + } + + // quiet mode - this is the last setting, so there is no way to + // supress the logging of messages during options processing + if (configuration.isTrue("quiet")) { + Fop.logger.setLevel(Level.OFF); + } + + } + + /** + * Load the standard configuration file and the user-defined configuration + * file if one has been defined. The definition can occur in either the + * standard file or as a command line argument. + * @exception FOPException + */ + private void loadConfigFiles() throws FOPException { + String str = null; + loadConfiguration(defaultConfigFile); + // load user configuration file,if there is one + // Has the userConfigFile been set from the command line? + if (arguments != null) { + if ((str = (String)arguments.get("userConfigFileName")) != null) { + configuration.put("userConfigFileName", str); + } + } + if ((str = configuration.getStringValue("userConfigFileName")) + != null) { // No + System.out.println("userConfigFileName"); + loadUserConfiguration(str); + } + } + + /** + * Convenience class for common functionality required by the config + * files. + * @param fname the configuration file name. + * @param classob the requesting class + * @return an InputStream generated through a call to + * getResourceAsStream on the context ClassLoader + * or the ClassLoader for the conf class provided as an argument. + */ + public InputStream getConfResourceFile(String fname, Class classob) + throws FOPException + { + InputStream configfile = null; + + // Try to use Context Class Loader to load the properties file. + try { + java.lang.reflect.Method getCCL = + Thread.class.getMethod("getContextClassLoader", new Class[0]); + if (getCCL != null) { + ClassLoader contextClassLoader = + (ClassLoader)getCCL.invoke(Thread.currentThread(), + new Object[0]); + configfile = contextClassLoader.getResourceAsStream("conf/" + + fname); + } + } catch (Exception e) {} + + // the entry /conf/config.xml refers to a directory conf + // which is a sibling of org + if (configfile == null) + configfile = classob.getResourceAsStream("/conf/" + fname); + if (configfile == null) { + throw new FOPException( + "can't find configuration file " + fname); + } + return configfile; + } + + /** + * Loads configuration file from a system standard place. + * The context class loader and the ConfigurationReader + * class loader are asked in turn to getResourceAsStream + * on fname from a directory called conf. + * @param fname the name of the configuration file to load. + * @exception FOPException if the configuration file + * cannot be discovered. + */ + public void loadConfiguration(String fname) + throws FOPException { + InputStream configfile = + getConfResourceFile(fname, ConfigurationReader.class); + + if (debug) { + Fop.logger.config( + "reading configuration file " + fname); + } + ConfigurationReader reader = new ConfigurationReader( + new InputSource(configfile), configuration); + } + + + /** + * Load a user-defined configuration file. + * An initial attempt is made to use a File generated from + * userConfigFileName as the configuration reader file input + * source. If this fails, an attempt is made to load the file using + * loadConfiguration. + * @param userConfigFileName the name of the user configuration file. + */ + public void loadUserConfiguration(String userConfigFileName) { + // read user configuration file + boolean readOk = true; + userConfigFile = new File(userConfigFileName); + if (userConfigFile == null) { + return; + } + Fop.logger.config( + "reading user configuration file " + userConfigFileName); + try { + ConfigurationReader reader = new ConfigurationReader( + InputHandler.fileInputSource(userConfigFile), + configuration); + } catch (FOPException ex) { + Fop.logger.warning("Can't find user configuration file " + + userConfigFile + " in user locations"); + if (debug) { + ex.printStackTrace(); + } + readOk = false; + } + if (! readOk) { + try { + // Try reading the file using loadConfig() + loadConfiguration(userConfigFileName); + } catch (FOPException ex) { + Fop.logger.warning("Can't find user configuration file " + + userConfigFile + " in system locations"); + if (debug) { + ex.printStackTrace(); + } + } + } + } + + /** + * Get the logger. + * @return the logger + */ + public Logger getLogger() { + return log; + } + + private static final boolean TAKES_ARG = true; + private static final boolean NO_ARG = false; + private Options makeOptions() { + // Create the Options object that will be returned + Options options = new Options(); + // The mutually exclusive verbosity group includes the -d and -q flags + OptionGroup verbosity = new OptionGroup(); + verbosity.addOption( + OptionBuilder + .withArgName("debug mode") + .withLongOpt("full-error-dump") + .withDescription("Debug mode: verbose reporting") + .create("d")); + verbosity.addOption( + OptionBuilder + .withArgName("quiet mode") + .withLongOpt("quiet") + .withDescription("Quiet mode: report errors only") + .create("q")); + verbosity.setRequired(false); + // Add verbosity to options + options.addOptionGroup(verbosity); + // Add the dump-config option directly + options.addOption(new Option( + "x", "dump-config", NO_ARG, "Dump configuration settings")); + // Add the config-file option directly + options.addOption( + OptionBuilder + .withArgName("config file") + .withLongOpt("config-file") + .hasArg() + .withDescription("Configuration file") + .create("c")); + // Add the language option directly + options.addOption( + OptionBuilder + .withArgName("language") + .withLongOpt("language") + .hasArg() + .withDescription("ISO639 language code") + .create("l")); + // Create the mutually exclusive input group + OptionGroup input = new OptionGroup(); + input.addOption( + OptionBuilder + .withArgName("fo:file") + .withLongOpt("fo") + .hasArg() + .withDescription("XSL-FO input file") + .create("fo")); + input.addOption( + OptionBuilder + .withArgName("xml file") + .withLongOpt("xml") + .hasArg() + .withDescription("XML source file for generating XSL-FO input") + .create("xml")); + // Add the input group to the options + options.addOptionGroup(input); + // The xsl option depends on the xml input option. There is no + // simple way to express this relationship + options.addOption( + OptionBuilder + .withArgName("xsl stylesheet") + .withLongOpt("xsl") + .hasArg() + .withDescription("XSL stylesheet for transforming XML to XSL-FO") + .create("xsl")); + // Work-around for the xsl parameters + // Allow multiple arguments (does this apply to multiple instances + // of the argument specifier?) of the form , using '=' + // as a value separator + options.addOption( + OptionBuilder + .withArgName("name=value") + .withValueSeparator() + .withLongOpt("xsl-param") + .hasArgs(Option.UNLIMITED_VALUES) + .withDescription("Parameter to XSL stylesheet") + .create("param")); + + // Create the mutually exclusive output group + OptionGroup output = new OptionGroup(); + output.addOption( + OptionBuilder + .withLongOpt("awt") + .withDescription("Input will be renderered to display") + .create("awt")); + output.addOption( + OptionBuilder + .withArgName("pdf output file") + .withLongOpt("pdf") + .hasArg() + .withDescription("Input will be rendered as PDF to named file") + .create("pdf")); + output.addOption( + OptionBuilder + .withArgName("postscript output file") + .withLongOpt("ps") + .hasArg() + .withDescription("Input will be rendered as Postscript to named file") + .create("ps")); + output.addOption( + OptionBuilder + .withArgName("pcl output file") + .withLongOpt("pcl") + .hasArg() + .withDescription("Input will be rendered as PCL to named file") + .create("pcl")); + output.addOption( + OptionBuilder + .withArgName("rtf output file") + .withLongOpt("rtf") + .hasArg() + .withDescription("Input will be rendered as RTF to named file") + .create("rtf")); + output.addOption( + OptionBuilder + .withArgName("mif output file") + .withLongOpt("mif") + .hasArg() + .withDescription("Input will be rendered as MIF to named file") + .create("mif")); + output.addOption( + OptionBuilder + .withArgName("svg output file") + .withLongOpt("svg") + .hasArg() + .withDescription("Input will be rendered as SVG to named file") + .create("svg")); + output.addOption( + OptionBuilder + .withArgName("text output file") + .withLongOpt("plain-text") + .hasArg() + .withDescription("Input will be rendered as plain text to named file") + .create("txt")); + output.addOption( + OptionBuilder + .withArgName("area tree output file") + .withLongOpt("area-tree") + .hasArg() + .withDescription("Area tree will be output as XML to named file") + .create("at")); + output.addOption( + OptionBuilder + .withArgName("help") + .withLongOpt("print") + .hasOptionalArg() + .withDescription("Input will be rendered and sent to the printer. " + + "Requires extra arguments to the \"java\" command. " + + "See options with \"-print help\".") + .create("print")); + + // -s option relevant only to -at area tree output. Again, no way + // to express this directly + options.addOption( + OptionBuilder + .withArgName("supress low-level areas") + .withLongOpt("only-block-areas") + .withDescription("Suppress non-block areas in XML renderer") + .create("s")); + return options; + } + + private static final boolean STOP_AT_NON_OPTION = true; + + /** + * parses the commandline arguments + * @return true if parse was successful and processing can continue, false + * if processing should stop + * @exception FOPException if there was an error in the format of the options + */ + private boolean parseOptions(String[] args) throws FOPException { + options = makeOptions(); + CommandLineParser parser = new PosixParser(); + CommandLine cli; + String[] xslParams = null; + String[] remArgs = null; + try { + cli = parser.parse(options, args, STOP_AT_NON_OPTION); + } catch (ParseException e) { + throw new FOPException(e); + } + // Find out what we have + // Miscellaneous + if (cli.hasOption("d")) { + arguments.put("debugMode", Boolean.TRUE); + //log.setLevel(Level.FINE); + } + if (cli.hasOption("q")) { + arguments.put("quiet", Boolean.TRUE); + //log.setLevel(Level.SEVERE); + } + if (cli.hasOption("x")) { + arguments.put("dumpConfiguration", Boolean.TRUE); + } + if (cli.hasOption("c")) { + arguments.put("userConfigFileName", cli.getOptionValue("c")); + } + if (cli.hasOption("l")) { + arguments.put("language", cli.getOptionValue("l")); + //Locale.setDefault(new Locale(cli.getOptionValue("l"))); + } + if (cli.hasOption("s")) { + arguments.put("noLowLevelAreas", Boolean.TRUE); + } + if (cli.hasOption("fo")) { + setInputMode(FO_INPUT); + arguments.put("foFileName", cli.getOptionValue("fo")); + } + if (cli.hasOption("xml")) { + if (cli.hasOption("xsl")) { + setInputMode(XSLT_INPUT); + arguments.put("xslFileName", cli.getOptionValue("xsl")); + } else { + throw new FOPException( + "XSLT file must be specified for the transform mode"); + } + arguments.put("xmlFileName", cli.getOptionValue("xml")); + } else { + if (cli.hasOption("xsl")) { + throw new FOPException( + "XML file must be specified for the transform mode"); + } + } + // Any parameters? + if (cli.hasOption("param")) { + // TODO Don't know how to handle these yet + xslParams = cli.getOptionValues("param"); + } + + // Output arguments + if (cli.hasOption("awt")) { + setOutputMode(AWT_OUTPUT); + } + if (cli.hasOption("pdf")) { + setOutputMode(PDF_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("pdf")); + } + if (cli.hasOption("mif")) { + setOutputMode(MIF_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("mif")); + } + if (cli.hasOption("rtf")) { + setOutputMode(RTF_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("rtf")); + } + if (cli.hasOption("pcl")) { + setOutputMode(PCL_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("pcl")); + } + if (cli.hasOption("ps")) { + setOutputMode(PS_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("ps")); + } + if (cli.hasOption("txt")) { + setOutputMode(TXT_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("txt")); + } + if (cli.hasOption("svg")) { + setOutputMode(SVG_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("svg")); + } + if (cli.hasOption("at")) { + setOutputMode(AREA_OUTPUT); + arguments.put("outputFileName", cli.getOptionValue("at")); + } + if (cli.hasOption("print")) { + setOutputMode(PRINT_OUTPUT); + if (cli.getOptionValue("print").toLowerCase(Locale.getDefault()) + == "help") { + printUsagePrintOutput(); + throw new FOPException("Usage only"); + } + } + // Get any remaining non-options + remArgs = cli.getArgs(); + if (remArgs != null) { + int i = 0; + if (inputmode == NOT_SET && i < remArgs.length + && args[i].charAt(0) != '-') { + setInputMode(FO_INPUT); + arguments.put("foFileName", remArgs[i++]); + } + if (outputmode == NOT_SET && i < remArgs.length + && args[i].charAt(0) != '-') { + setOutputMode(PDF_OUTPUT); + arguments.put("outputFileName", remArgs[i++]); + } + if (i < remArgs.length) { + throw new FOPException("Don't know what to do with " + + remArgs[i]); + } + } + return true; + } // end parseOptions + + + /** + * If the String value for the key inputMode + * has not been installed in Configuration, install the + * value passed in the parameter, and set the field inputmode + * to the integer value associated with mode. + * If the key already exists with the same value as mode, + * do nothing. + * If the key already exists with a different value to mode, + * throw an exception. + * @param mode the input mode code + * @exception FOPException + */ + private void setInputMode(int mode) throws FOPException { + String tempMode = null; + if ((tempMode = getInputMode()) == null) { + arguments.put("inputMode", inputModes[mode]); + inputmode = mode; + } else if (tempMode.equals(inputModes[mode])) { + return; + } else { + throw new FOPException("you can only set one input method"); + } + } + + /** + * If the String value for the key outputMode + * has not been installed in Configuration, install the + * value passed in the parameter, and set the field outputmode + * to the integer value associated with mode. + * If the key already exists with the same value as mode, + * do nothing. + * If the key already exists with a different value to mode, + * throw an exception. + * @param mode the output mode code + * @exception FOPException + */ + private void setOutputMode(int mode) throws FOPException { + String tempMode = null; + if ((tempMode = getOutputMode()) == null) { + arguments.put("outputMode", outputModes[mode]); + outputmode = mode; + } else if (tempMode.equals(outputModes[mode])) { + return; + } else { + throw new FOPException("you can only set one output method"); + } + } + + /** + * checks whether all necessary information has been given in a consistent way + */ + private void checkSettings() throws FOPException, FileNotFoundException { + if (inputmode == NOT_SET) { + throw new FOPException("No input file specified"); + } + + if (outputmode == NOT_SET) { + throw new FOPException("No output file specified"); + } + + if (inputmode == XSLT_INPUT) { + if (!xmlFile.exists()) { + throw new FileNotFoundException("Error: xml file " + + xmlFile.getAbsolutePath() + + " not found "); + } + if (!xsltFile.exists()) { + throw new FileNotFoundException("Error: xsl file " + + xsltFile.getAbsolutePath() + + " not found "); + } + + } else if (inputmode == FO_INPUT) { + if (!foFile.exists()) { + throw new FileNotFoundException("Error: fo file " + + foFile.getAbsolutePath() + + " not found "); + } + } + } // end checkSettings + + /** + * @return the type chosen renderer + * @throws FOPException for invalid output modes + */ + public int getRenderer() throws FOPException { + switch (outputmode) { + case NOT_SET: + throw new FOPException("Renderer has not been set!"); + case PDF_OUTPUT: + return Driver.RENDER_PDF; + case AWT_OUTPUT: + return Driver.RENDER_AWT; + case MIF_OUTPUT: + return Driver.RENDER_MIF; + case PRINT_OUTPUT: + return Driver.RENDER_PRINT; + case PCL_OUTPUT: + return Driver.RENDER_PCL; + case PS_OUTPUT: + return Driver.RENDER_PS; + case TXT_OUTPUT: + return Driver.RENDER_TXT; + case SVG_OUTPUT: + return Driver.RENDER_SVG; + case AREA_OUTPUT: + rendererOptions.put("fineDetail", coarseAreaXmlValue()); + return Driver.RENDER_XML; + case RTF_OUTPUT: + return Driver.RENDER_RTF; + default: + throw new FOPException("Invalid Renderer setting!"); + } + } + + /** + * Get the input handler. + * @return the input handler + * @throws FOPException if creating the InputHandler fails + */ + public InputHandler getInputHandler() throws FOPException { + switch (inputmode) { + case FO_INPUT: + return new FOFileHandler(foFile); + case XSLT_INPUT: + return new XSLTInputHandler(xmlFile, xsltFile, xsltParams); + default: + throw new FOPException("Invalid inputmode setting!"); + } + } + + /** + * Get the renderer specific options. + * @return hash map with option/value pairs. + */ + public java.util.HashMap getRendererOptions() { + return rendererOptions; + } + + + public String getInputMode() { + return configuration.getStringValue("inputMode"); + } + + /** + * Returns the input mode (type of input data, ex. NOT_SET or FO_INPUT) + * @return the input mode + */ + public int getInputModeIndex() throws FOPException { + String mode; + if ((mode = getInputMode()) == null) return NOT_SET; + return inputModeIndex(mode); + } + + public String getOutputMode() { + return configuration.getStringValue("outputMode"); + } + + /** + * Returns the output mode (output format, ex. NOT_SET or PDF_OUTPUT) + * @return the output mode + */ + public int getOutputModeIndex() throws FOPException { + String mode; + if ((mode = getOutputMode()) == null) return NOT_SET; + return outputModeIndex(mode); + } + + + public String getFoFileName() { + return configuration.getStringValue("foFileName"); + } + + public File getFoFile() { + return foFile; + } + + public String getXmlFileName() { + return configuration.getStringValue("xmlFileName"); + } + + public File getXmlFile() { + return xmlFile; + } + + public String getXsltFileName() { + return configuration.getStringValue("xsltFileName"); + } + + public File getXsltFile() { + return xsltFile; + } + + public String getOutputFileName() { + return configuration.getStringValue("outputFileName"); + } + + public File getOutputFile() { + return outputFile; + } + + public String getUserConfigFileName() { + return configuration.getStringValue("userConfigFileName"); + } + + public File getUserConfigFile() { + return userConfigFile; + } + + public String getBufferFileName() { + return configuration.getStringValue("bufferFileName"); + } + + public File getBufferFile() { + return bufferFile; + } + + public String getLanguage() { + return configuration.getStringValue("language"); + } + + public boolean isQuiet() { + return configuration.isTrue("quiet"); + } + + public Boolean doDumpConfiguration() { + return configuration.getBooleanObject("dumpConfiguration"); + } + + public boolean isDebugMode() { + return configuration.isTrue("debugMode"); + } + + public Boolean coarseAreaXmlValue() { + return configuration.getBooleanObject("noLowLevelAreas"); + } + + public boolean isCoarseAreaXml() { + return configuration.isTrue("noLowLevelAreas"); + } + + /** + * return either the foFile or the xmlFile + */ + public File getInputFile() { + switch (inputmode) { + case FO_INPUT: + return foFile; + case XSLT_INPUT: + return xmlFile; + default: + return foFile; + } + } + + /** + * shows the commandline syntax including a summary of all available options and some examples + */ + public void printUsage() { + HelpFormatter help = new HelpFormatter(); + help.printHelp("FOP", options, true); + } + + /** + * shows the options for print output + */ + public void printUsagePrintOutput() { + System.err.println("USAGE: -print [-Dstart=i] [-Dend=i] [-Dcopies=i] [-Deven=true|false] " + + " org.apache.fop.apps.Fop (..) -print \n" + + "Example:\n" + + "java -Dstart=1 -Dend=2 org.apache.Fop.apps.Fop infile.fo -print "); + } + + + /** + * debug mode. outputs all commandline settings + */ + private void debug() { + log.fine("Input mode: "); + switch (inputmode) { + case NOT_SET: + log.fine("not set"); + break; + case FO_INPUT: + log.fine("FO "); + log.fine("fo input file: " + foFile.toString()); + break; + case XSLT_INPUT: + log.fine("xslt transformation"); + log.fine("xml input file: " + xmlFile.toString()); + log.fine("xslt stylesheet: " + xsltFile.toString()); + break; + default: + log.fine("unknown input type"); + } + log.fine("Output mode: "); + switch (outputmode) { + case NOT_SET: + log.fine("not set"); + break; + case PDF_OUTPUT: + log.fine("pdf"); + log.fine("output file: " + outputFile.toString()); + break; + case AWT_OUTPUT: + log.fine("awt on screen"); + if (outputFile != null) { + log.severe("awt mode, but outfile is set:"); + log.fine("out file: " + outputFile.toString()); + } + break; + case MIF_OUTPUT: + log.fine("mif"); + log.fine("output file: " + outputFile.toString()); + break; + case RTF_OUTPUT: + log.fine("rtf"); + log.fine("output file: " + outputFile.toString()); + break; + case PRINT_OUTPUT: + log.fine("print directly"); + if (outputFile != null) { + log.severe("print mode, but outfile is set:"); + log.severe("out file: " + outputFile.toString()); + } + break; + case PCL_OUTPUT: + log.fine("pcl"); + log.fine("output file: " + outputFile.toString()); + break; + case PS_OUTPUT: + log.fine("PostScript"); + log.fine("output file: " + outputFile.toString()); + break; + case TXT_OUTPUT: + log.fine("txt"); + log.fine("output file: " + outputFile.toString()); + break; + case SVG_OUTPUT: + log.fine("svg"); + log.fine("output file: " + outputFile.toString()); + break; + default: + log.fine("unknown input type"); + } + + + log.fine("OPTIONS"); + if (userConfigFile != null) { + log.fine("user configuration file: " + + userConfigFile.toString()); + } else { + log.fine("no user configuration file is used [default]"); + } + if (dumpConfig == true) { + log.fine("dump configuration"); + } else { + log.fine("don't dump configuration [default]"); + } + if (configuration.isTrue("quiet")) { + log.fine("quiet mode on"); + } else { + log.fine("quiet mode off [default]"); + } + + } +} diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java index d05f1df63..f037adc07 100644 --- a/src/java/org/apache/fop/apps/Fop.java +++ b/src/java/org/apache/fop/apps/Fop.java @@ -20,8 +20,11 @@ package org.apache.fop.apps; +import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.fop.configuration.Configuration; + public class Fop { public static Runtime runtime; @@ -37,11 +40,18 @@ public class Fop { public static final String fopPackage = "org.apache.fop"; public static final Logger logger = Logger.getLogger(fopPackage); + static { + logger.setLevel(Level.INFO); + } + + public Configuration configuration = new Configuration(); public static void main(String[] args) { long endtotal, endfree, gctotal, gcfree; Driver driver; + Configuration configuration; + FOPOptions options = null; Boolean bool = null; runtime = Runtime.getRuntime(); @@ -50,8 +60,9 @@ public class Fop { startTime = System.currentTimeMillis(); try { - Options.configure(args); - driver = new Driver(); + configuration = new Configuration(); + options = new FOPOptions(configuration, args); + driver = new Driver(args, configuration, options); driver.run(); System.out.println("Back from driver.run()"); System.out.println("Elapsed time: " + @@ -85,19 +96,31 @@ public class Fop { } catch (FOPException e) { logger.warning(e.getMessage()); - if ((bool = Options.isDebugMode()) != null - && bool.booleanValue()) { - e.printStackTrace(); - } - } catch (java.io.FileNotFoundException e) { - logger.warning(e.getMessage()); - if ((bool = Options.isDebugMode()) != null - && bool.booleanValue()) { + if (options.isDebugMode()) { e.printStackTrace(); } } } + /** + * Gets the parser Class name. + * + * @return a String with the value of the property + * org.xml.sax.parser or the default value + * org.apache.xerces.parsers.SAXParser. + */ + public static final String getParserClassName() { + String parserClassName = null; + try { + parserClassName = System.getProperty("org.xml.sax.parser"); + } catch (SecurityException se) {} + + if (parserClassName == null) { + parserClassName = "org.apache.xerces.parsers.SAXParser"; + } + return parserClassName; + } + private Fop() { } diff --git a/src/java/org/apache/fop/apps/InputHandler.java b/src/java/org/apache/fop/apps/InputHandler.java index 07019af5e..9597ee324 100644 --- a/src/java/org/apache/fop/apps/InputHandler.java +++ b/src/java/org/apache/fop/apps/InputHandler.java @@ -1,54 +1,75 @@ /* - * $Id$ + * Copyright 1999-2004 The Apache Software Foundation. * - * - * Copyright 1999-2003 The Apache Software Foundation. - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * + * 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; // SAX -import java.io.File; -import java.net.URL; - import org.xml.sax.InputSource; import org.xml.sax.XMLReader; +// Java +import java.net.URL; +import java.io.File; -abstract public class InputHandler { +/** + * Abstract super class for input handlers. + * Should be used to abstract the various possibilities on how input + * can be provided to FOP (but actually isn't). + */ +public abstract class InputHandler { + /** + * Get the input source associated with this input handler. + * @return the input source + */ + public abstract InputSource getInputSource(); - abstract public InputSource getInputSource(); - abstract public XMLReader getParser() throws FOPException; + /** + * Get the SAX parser associated with this input handler. + * @return the SAX parser + * @throws FOPException in case of an error determining the SAX parser + */ + public abstract XMLReader getParser() throws FOPException; /** - * create an InputSource from a File - * - * @param file the File - * @return the InputSource created + * Creates an InputSource from a URL. + * @param url URL to use + * @return the newly created InputSource */ - static public InputSource fileInputSource(File file) { + public static InputSource urlInputSource(URL url) { + return new InputSource(url.toString()); + } + + /** + * Creates an InputSource from a File + * @param file the File + * @return the InputSource created + */ + public static InputSource fileInputSource(File file) { /* this code adapted from James Clark's in XT */ String path = file.getAbsolutePath(); String fSep = System.getProperty("file.separator"); - if (fSep != null && fSep.length() == 1) + if (fSep != null && fSep.length() == 1) { path = path.replace(fSep.charAt(0), '/'); - if (path.length() > 0 && path.charAt(0) != '/') + } + if (path.length() > 0 && path.charAt(0) != '/') { path = '/' + path; + } try { return new InputSource(new URL("file", null, path).toString()); } catch (java.net.MalformedURLException e) { @@ -56,33 +77,5 @@ abstract public class InputHandler { } } - /** - * creates a SAX parser, using the value of org.xml.sax.parser - * defaulting to org.apache.xerces.parsers.SAXParser - * - * @return the created SAX parser - */ - protected static XMLReader createParser() throws FOPException { - String parserClassName = System.getProperty("org.xml.sax.parser"); - if (parserClassName == null) { - parserClassName = "org.apache.xerces.parsers.SAXParser"; - } - Fop.logger.config("using SAX parser " + parserClassName); - - try { - return (XMLReader)Class.forName(parserClassName).newInstance(); - } catch (ClassNotFoundException e) { - throw new FOPException(e); - } catch (InstantiationException e) { - throw new FOPException("Could not instantiate " - + parserClassName, e); - } catch (IllegalAccessException e) { - throw new FOPException("Could not access " + parserClassName, e); - } catch (ClassCastException e) { - throw new FOPException(parserClassName + " is not a SAX driver", - e); - } - } - } diff --git a/src/java/org/apache/fop/apps/Options.java b/src/java/org/apache/fop/apps/Options.java deleted file mode 100644 index bcf589515..000000000 --- a/src/java/org/apache/fop/apps/Options.java +++ /dev/null @@ -1,886 +0,0 @@ -/* - * $Id$ - * - * - * Copyright 1999-2003 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package org.apache.fop.apps; - -// sax -import org.xml.sax.InputSource; - -// java -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Set; -import java.util.Iterator; -import java.util.logging.Level; -// fop -import org.apache.fop.configuration.Configuration; -import org.apache.fop.configuration.ConfigurationReader; - -/** - * Options handles loading of configuration files and - * additional setting of commandline options - */ -public class Options { - - /** - * Render to PDF. OutputStream must be set - */ - public static final int RENDER_PDF = 1; - - /* input / output not set */ - private static final int NOT_SET = 0; - /* input: fo file */ - private static final int FO_INPUT = 1; - /* input: xml+xsl file */ - private static final int XSLT_INPUT = 2; - private static final int LAST_INPUT_MODE = XSLT_INPUT; - - /* output: pdf file */ - private static final int PDF_OUTPUT = 1; - private static final int LAST_OUTPUT_MODE = PDF_OUTPUT; - - private static final String defaultConfigFile = "config.xml"; - private static final String defaultUserConfigFile = "userconfig.xml"; - - /** - * An array of String indexed by the integer constants representing - * the various input modes. Provided so that integer modes can be - * mapped to a more descriptive string, and vice versa. - */ - public static final String[] inputModes; - /** - * An array of String indexed by the integer constants representing - * the various output modes. Provided so that integer modes can be - * mapped to a more descriptive string, and vice versa. - */ - public static final String[] outputModes; - - static { - inputModes = new String[LAST_INPUT_MODE + 1]; - inputModes[NOT_SET] = "NotSet"; - inputModes[FO_INPUT] = "fo"; - inputModes[XSLT_INPUT] = "xslt"; - - outputModes = new String[LAST_OUTPUT_MODE + 1]; - outputModes[NOT_SET] = "NotSet"; - outputModes[PDF_OUTPUT] = "pdf"; - } - - /** - * @param mode the mode whose index in the array inputModes is to be - * returned. - * @return the int index of the mode string in the array, or -1 if the - * mode string is not found in the array - */ - public static int inputModeIndex(String mode) - throws FOPException { - for (int i = 0; i <= LAST_INPUT_MODE; i++) { - if (inputModes[i] != null) - if (mode.equals(inputModes[i])) - return i; - } - throw new FOPException("Input mode " + mode + " not known"); - } - - /** - * @param mode the mode whose index in the array outputModes is to be - * returned. - * @return the int index of the mode string in the array, or -1 if the - * mode string is not found in the array - */ - public static int outputModeIndex(String mode) - throws FOPException { - for (int i = 0; i <= LAST_INPUT_MODE; i++) { - if (outputModes[i] != null) - if (mode.equals(outputModes[i])) - return i; - } - throw new FOPException("Output mode " + mode + " not known"); - } - - - /* Show debug info. Boolean object set from configuration files. */ - static boolean debug = false; - /* show configuration information */ - static boolean dumpConfig = false; - /* suppress any progress information */ - /* for area tree XML output, only down to block area level */ - /* name of user configuration file */ - static File userConfigFile = null; - /* name of input fo file */ - static File foFile = null; - /* name of xsltFile (xslt transformation as input) */ - static File xsltFile = null; - /* name of xml file (xslt transformation as input) */ - static File xmlFile = null; - /* name of output file */ - static File outputFile = null; - /* name of buffer file */ - static File bufferFile = null; - /* input mode */ - static int inputmode = NOT_SET; - /* output mode */ - static int outputmode = NOT_SET; - /* buffer mode */ - static int buffermode = NOT_SET; - /* language for user information */ - // baseDir (set from the config files - static String baseDir = null; - - /** - * Parser variables - */ - private static HashMap arguments = null; - - /** - * This class cannot be instantiated - */ - private Options() {} - - /** - * Configure the system according to the system configuration file - * config.xml and the user configuration file if it is specified in the - * system configuration file. - */ - public static void configure() - throws FOPException, FileNotFoundException { - loadConfigFiles(); - loadArguments(); - initOptions(); - try { - checkSettings(); - } catch (java.io.FileNotFoundException e) { - printUsage(); - throw e; - } - if (debug) debug(); - } - - public static void configure(String[] args) - throws FOPException, FileNotFoundException { - parseOptions(args); - configure(); - } - - /** - * Method to map an inputMode name to an inputmode index. - * @param name a String containing the name of an input mode - * @return the index of that name in the array of input mode names, - * or -1 if not found - */ - public static int inputModeNameToIndex(String name) { - for (int i = 0; i <= LAST_INPUT_MODE; i++) { - if (name.equals(inputModes[i])) return i; - } - return -1; - } - - /** - * Method to map an outputMode name to an outputmode index. - * @param name a String containing the name of an output mode - * @return the index of that name in the array of output mode names, - * or -1 if not found - */ - public static int outputModeNameToIndex(String name) { - for (int i = 0; i <= LAST_INPUT_MODE; i++) { - if (name.equals(outputModes[i])) return i; - } - return -1; - } - - /** - * parseOptions() parses the command line into a - * HashMap which is - * passed to this method. All key-Object pairs are installed in the - * Configuration maps. - */ - static void loadArguments() { - String key = null; - if (arguments != null) { - Set keys = arguments.keySet(); - Iterator iter = keys.iterator(); - while (iter.hasNext()) { - key = (String)iter.next(); - Configuration.put(key, arguments.get(key)); - } - } - } - - - /** - * Finish initialization of options. The command line options, if - * present, have been parsed and stored in the HashMap arguments. - * The ints inputmode and outputmode will have been set as a side- - * effect of command line parsing. - * - * The standard configuration file has been read and its contents - * stored in the Configuration HashMaps. If a user configuration file - * was specified in the command line arguments, or, failing that, in - * the standard configuration file, it had been read and its contents - * have overridden the Configuration maps. - * - * It remains for any related variables defined in this class to be set. - * - * @exception FOPException - */ - static void initOptions() throws FOPException { - Boolean bool = null; - String str = null; - // debug mode - if ((bool = Configuration.getBooleanValue("debugMode")) != null) { - debug = bool.booleanValue(); - } - - // show configuration settings - if ((bool = Configuration.getBooleanValue("dumpConfiguration")) - != null) - dumpConfig = bool.booleanValue(); - - if ((str = getFoFileName()) != null) - foFile = new File(str); - if ((str = getXmlFileName()) != null) - xmlFile = new File(str); - if ((str = getXsltFileName()) != null) - xsltFile = new File(str); - if ((str = getOutputFileName()) != null) - outputFile = new File(str); - if ((str = getBufferFileName()) != null) - bufferFile = new File(str); - // userConfigFile may be set in the process of loading said file - if (userConfigFile == null && (str = getUserConfigFileName()) != null) - userConfigFile = new File(str); - - if ((str = getInputMode()) != null) - inputmode = inputModeIndex(str); - if ((str = getOutputMode()) != null) - outputmode = outputModeIndex(str); - - // set base directory - // This is not set directly from the command line, but may be set - // indirectly from the input file setting if not set in the standard - // or user configuration files - baseDir = Configuration.getStringValue("baseDir"); - if (baseDir == null) { - try { - baseDir = new File(getInputFile().getAbsolutePath()) - .getParentFile().toURL().toExternalForm(); - Configuration.put("baseDir", baseDir); - } catch (Exception e) {} - } - if (debug) { - Fop.logger.config("base directory: " + baseDir); - } - - if (dumpConfig) { - Configuration.dumpConfiguration(); - System.exit(0); - } - - // quiet mode - this is the last setting, so there is no way to - // supress the logging of messages during options processing - if ((bool = isQuiet()) != null) { - if (bool.booleanValue()) { - Fop.logger.setLevel(Level.OFF); - } - } - - } - - /** - * Load the standard configuration file and the user-defined configuration - * file if one has been defined. The definition can occur in either the - * standard file or as a command line argument. - * @exception FOPException - */ - private static void loadConfigFiles() throws FOPException { - String str = null; - loadConfiguration(defaultConfigFile); - // load user configuration file,if there is one - // Has the userConfigFile been set from the command line? - if (arguments != null) { - if ((str = (String)arguments.get("userConfigFileName")) != null) { - Configuration.put("userConfigFileName", str); - } - } - if ((str = Configuration.getStringValue("userConfigFileName")) - != null) { // No - System.out.println("userConfigFileName"); - loadUserConfiguration(str); - } - } - - /** - * Convenience class for common functionality required by the config - * files. - * @param fname the configuration file name. - * @param classob the requesting class - * @return an InputStream generated through a call to - * getResourceAsStream on the context ClassLoader - * or the ClassLoader for the conf class provided as an argument. - */ - public static InputStream getConfResourceFile(String fname, Class classob) - throws FOPException - { - InputStream configfile = null; - - // Try to use Context Class Loader to load the properties file. - try { - java.lang.reflect.Method getCCL = - Thread.class.getMethod("getContextClassLoader", new Class[0]); - if (getCCL != null) { - ClassLoader contextClassLoader = - (ClassLoader)getCCL.invoke(Thread.currentThread(), - new Object[0]); - configfile = contextClassLoader.getResourceAsStream("conf/" - + fname); - } - } catch (Exception e) {} - - // the entry /conf/config.xml refers to a directory conf - // which is a sibling of org - if (configfile == null) - configfile = classob.getResourceAsStream("/conf/" + fname); - if (configfile == null) { - throw new FOPException( - "can't find configuration file " + fname); - } - return configfile; - } - - /** - * Loads configuration file from a system standard place. - * The context class loader and the ConfigurationReader - * class loader are asked in turn to getResourceAsStream - * on fname from a directory called conf. - * @param fname the name of the configuration file to load. - * @exception FOPException if the configuration file - * cannot be discovered. - */ - public static void loadConfiguration(String fname) - throws FOPException { - InputStream configfile = - getConfResourceFile(fname, ConfigurationReader.class); - - if (debug) { - Fop.logger.config( - "reading configuration file " + fname); - } - ConfigurationReader reader = - new ConfigurationReader(new InputSource(configfile)); - if (debug) { - reader.setDumpError(true); - } - reader.start(); - } - - - /** - * Load a user-defined configuration file. - * An initial attempt is made to use a File generated from - * userConfigFileName as the configuration reader file input - * source. If this fails, an attempt is made to load the file using - * loadConfiguration. - * @param userConfigFileName the name of the user configuration file. - */ - public static void loadUserConfiguration(String userConfigFileName) { - // read user configuration file - boolean readOk = true; - userConfigFile = new File(userConfigFileName); - if (userConfigFile != null) { - Fop.logger.config( - "reading user configuration file " + userConfigFileName); - ConfigurationReader reader = new ConfigurationReader( - InputHandler.fileInputSource(userConfigFile)); - if (debug) { - reader.setDumpError(true); - } - try { - reader.start(); - } catch (org.apache.fop.apps.FOPException error) { - Fop.logger.config( - "Can't find user configuration file " - + userConfigFile + " in user locations"); - if (debug) { - reader.dumpError(error); - } - readOk = false; - } - if (! readOk) { - try { - // Try reading the file using loadConfig() - loadConfiguration(userConfigFileName); - } catch (FOPException ex) { - Fop.logger.warning("Can't find user configuration file " - + userConfigFile + " in system locations"); - if (debug) { - reader.dumpError(ex); - } - } - } - } - } - - /** - * parses the commandline arguments into the Hashmap - * arguments. Special case processing is done for debug mode, - * so that debugging output is immediately available. - * The boolean field debug is - * set true if the debug flag is passed in the command line args. - * @exception FOPException if there was an error in the format of the - * options - */ - private static void parseOptions(String args[]) throws FOPException { - arguments = new HashMap(8); - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-d") || args[i].equals("--full-error-dump")) { - arguments.put("debugMode", new Boolean(true)); - // SPECIAL CASE - debug = true; - } else if (args[i].equals("-x") - || args[i].equals("--dump-config")) { - arguments.put("dumpConfiguration", new Boolean(true)); - } else if (args[i].equals("-q") || args[i].equals("--quiet")) { - arguments.put("quiet", new Boolean(true)); - } else if (args[i].equals("-c")) { - if ((i + 1 == args.length) - || (args[i + 1].charAt(0) == '-')) { - throw new FOPException( - "if you use '-c', you must specify the name of the " - + "configuration file"); - } else { - arguments.put("userConfigFileName", args[++i]); - } - } else if (args[i].equals("-l")) { - if ((i + 1 == args.length) - || (args[i + 1].charAt(0) == '-')) { - throw new FOPException( - "if you use '-l', you must specify a language"); - } else { - arguments.put("language", args[++i]); - } - } else if (args[i].equals("-s")) { - arguments.put("noLowLevelAreas", new Boolean(true)); - } else if (args[i].equals("-fo")) { - setInputMode(FO_INPUT); - if ((i + 1 == args.length) - || (args[i + 1].charAt(0) == '-')) { - throw new FOPException( - "you must specify the fo file for the '-fo' option"); - } else { - arguments.put("foFileName", args[++i]); - } - } else if (args[i].equals("-pdf")) { - setOutputMode(PDF_OUTPUT); - if ((i + 1 == args.length) - || (args[i + 1].charAt(0) == '-')) { - throw new FOPException( - "you must specify the pdf output file"); - } else { - arguments.put("outputFileName", args[++i]); - } - } else if (args[i].charAt(0) != '-') { - if (inputmode == NOT_SET) { - setInputMode(FO_INPUT); - arguments.put("foFileName", args[i]); - } else if (outputmode == NOT_SET) { - setOutputMode(PDF_OUTPUT); - arguments.put("outputFileName", args[i]); - } else { - throw new FOPException("Don't know what to do with " - + args[i]); - } - } else { - throw new FOPException("Don't know what to do with " - + args[i]); - } - } - } // end parseOptions - - /** - * If the String value for the key inputMode - * has not been installed in Configuration, install the - * value passed in the parameter, and set the field inputmode - * to the integer value associated with mode. - * If the key already exists with the same value as mode, - * do nothing. - * If the key already exists with a different value to mode, - * throw an exception. - * @param mode the input mode code - * @exception FOPException - */ - private static void setInputMode(int mode) throws FOPException { - String tempMode = null; - if ((tempMode = getInputMode()) == null) { - arguments.put("inputMode", inputModes[mode]); - inputmode = mode; - } else if (tempMode.equals(inputModes[mode])) { - return; - } else { - throw new FOPException("you can only set one input method"); - } - } - - /** - * If the String value for the key outputMode - * has not been installed in Configuration, install the - * value passed in the parameter, and set the field outputmode - * to the integer value associated with mode. - * If the key already exists with the same value as mode, - * do nothing. - * If the key already exists with a different value to mode, - * throw an exception. - * @param mode the output mode code - * @exception FOPException - */ - private static void setOutputMode(int mode) throws FOPException { - String tempMode = null; - if ((tempMode = getOutputMode()) == null) { - arguments.put("outputMode", outputModes[mode]); - outputmode = mode; - } else if (tempMode.equals(outputModes[mode])) { - return; - } else { - throw new FOPException("you can only set one output method"); - } - } - - /** - * checks whether all necessary information has been given in a - * consistent way - */ - private static void checkSettings() - throws FOPException, FileNotFoundException { - if (inputmode == NOT_SET) { - throw new FOPException("No input file specified"); - } - - if (outputmode == NOT_SET) { - throw new FOPException("No output file specified"); - } - - if (inputmode == XSLT_INPUT) { - // check whether xml *and* xslt file have been set - if (xmlFile == null) { - throw new FOPException( - "XML file must be specified for the tranform mode"); - } - if (xsltFile == null) { - throw new FOPException( - "XSLT file must be specified for the tranform mode"); - } - - // warning if foFile has been set in xslt mode - if (foFile != null) { - Fop.logger.warning( - "Can't use fo file with transform mode! Ignoring.\n" - + "Your input is " + "\n xmlFile: " - + xmlFile.getAbsolutePath() - + "\nxsltFile: " - + xsltFile.getAbsolutePath() - + "\n foFile: " - + foFile.getAbsolutePath()); - } - if (!xmlFile.exists()) { - throw new FileNotFoundException("xml file " - + xmlFile.getAbsolutePath() - + " not found "); - } - if (!xsltFile.exists()) { - throw new FileNotFoundException("xsl file " - + xsltFile.getAbsolutePath() - + " not found "); - } - - } else if (inputmode == FO_INPUT) { - if (xmlFile != null || xsltFile != null) { - Fop.logger.warning( - "fo input mode, but xmlFile or xslt file are set:" - ); - Fop.logger.warning("xml file: " + xmlFile.toString()); - Fop.logger.warning("xslt file: " + xsltFile.toString()); - } - if (!foFile.exists()) { - throw new FileNotFoundException("fo file " - + foFile.getAbsolutePath() - + " not found "); - } - - } - } // end checkSettings - - /** - * returns the chosen renderer, throws FOPException - */ - public static int getRenderer() throws FOPException { - switch (outputmode) { - case NOT_SET: - throw new FOPException("Renderer has not been set!"); - case PDF_OUTPUT: - return RENDER_PDF; - default: - throw new FOPException("Invalid Renderer setting!"); - } - } - - /** - * - */ - public static InputHandler getInputHandler() { - switch (inputmode) { - case FO_INPUT: - return new FOInputHandler(foFile); - default: - return new FOInputHandler(foFile); - } - } - - public static String getInputMode() { - return Configuration.getStringValue("inputMode"); - } - - public static int getInputModeIndex() throws FOPException { - String mode; - if ((mode = getInputMode()) == null) return NOT_SET; - return inputModeIndex(mode); - } - - public static String getOutputMode() { - return Configuration.getStringValue("outputMode"); - } - - public static int getOutputModeOutdex() throws FOPException { - String mode; - if ((mode = getOutputMode()) == null) return NOT_SET; - return outputModeIndex(mode); - } - - public static String getFoFileName() { - return Configuration.getStringValue("foFileName"); - } - - public static File getFoFile() { - return foFile; - } - - public static String getXmlFileName() { - return Configuration.getStringValue("xmlFileName"); - } - - public static File getXmlFile() { - return xmlFile; - } - - public static String getXsltFileName() { - return Configuration.getStringValue("xsltFileName"); - } - - public static File getXsltFile() { - return xsltFile; - } - - public static String getOutputFileName() { - return Configuration.getStringValue("outputFileName"); - } - - public static File getOutputFile() { - return outputFile; - } - - public static String getUserConfigFileName() { - return Configuration.getStringValue("userConfigFileName"); - } - - public static File getUserConfigFile() { - return userConfigFile; - } - - public static String getBufferFileName() { - return Configuration.getStringValue("bufferFileName"); - } - - public static File getBufferFile() { - return bufferFile; - } - - public static String getLanguage() { - return Configuration.getStringValue("language"); - } - - public static Boolean isQuiet() { - return Configuration.getBooleanValue("quiet"); - } - - public static Boolean doDumpConfiguration() { - return Configuration.getBooleanValue("dumpConfiguration"); - } - - public static Boolean isDebugMode() { - return Configuration.getBooleanValue("debugMode"); - } - - public static Boolean isCoarseAreaXml() { - return Configuration.getBooleanValue("noLowLevelAreas"); - } - - /** - * return either the foFile or the xmlFile - */ - public static File getInputFile() { - switch (inputmode) { - case FO_INPUT: - return foFile; - default: - return foFile; - } - } - - /** - * shows the commandline syntax including a summary of all available - * options and some examples - */ - public static void printUsage() { - Fop.logger.info( - "\nUSAGE\n" - + "Fop [options] [-fo|-xml] infile [-xsl file] " - + "[-awt|-pdf|-mif|-pcl|-ps|-txt|-at|-print] [outputFile]\n" - + " [OPTIONS] \n" - + " -d debug mode \n" - + " -x dump configuration settings \n" - + " -q quiet mode \n" - + " -c cfg.xml use additional configuration file cfg.xml\n" - + " -l lang the language to use for user information \n" - + " -s for area tree XML, down to block areas only\n\n" - + " [INPUT] \n" - + " infile xsl:fo input file (the same as the next) \n" - + " -fo infile xsl:fo input file \n" - + " -xml infile " - + "xml input file, must be used together with -xsl \n" - + " -xsl stylesheet xslt stylesheet \n \n" - + " [OUTPUT] \n" - + " outputFile " - + "input will be rendered as pdf file into outputFile \n" - + " -pdf outputFile " - + "input will be rendered as pdf file (outputFile req'd) \n" - + " -awt " - + "input will be displayed on screen \n" - + " -mif outputFile " - + "input will be rendered as mif file (outputFile req'd)\n" - + " -pcl outputFile " - + "input will be rendered as pcl file (outputFile req'd) \n" - + " -ps outputFile " - + "input will be rendered as PostScript file (outputFile req'd) \n" - + " -txt outputFile " - + "input will be rendered as text file (outputFile req'd) \n" - + " -at outputFile " - + "representation of area tree as XML (outputFile req'd) \n" - + " -print " - + "input file will be rendered and sent to the printer \n" - + " see options with \"-print help\" \n\n" - + " [Examples]\n" + " Fop foo.fo foo.pdf \n" - + " Fop -fo foo.fo -pdf foo.pdf " - + "(does the same as the previous line)\n" - + " Fop -xsl foo.xsl -xml foo.xml -pdf foo.pdf\n" - + " Fop foo.fo -mif foo.mif\n" - + " Fop foo.fo -print or Fop -print foo.fo \n" - + " Fop foo.fo -awt \n"); - } - - /** - * shows the options for print output - */ - public static void printUsagePrintOutput() { - Fop.logger.info( - "USAGE:" - + " -print [-Dstart=i] [-Dend=i] [-Dcopies=i] [-Deven=true|false]" - + " org.apache.fop.apps.Fop (..) -print \n" - + "Example:\n" - + "java -Dstart=1 -Dend=2 org.apache.Fop.apps.Fop infile.fo -print" - ); - } - - - /** - * debug mode. outputs all commandline settings - */ - private static void debug() { - Boolean bool; - System.out.println("Version: " - + Configuration.getStringValue("version")); - System.out.print("Input mode: "); - switch (inputmode) { - case NOT_SET: - Fop.logger.config("not set"); - break; - case FO_INPUT: - Fop.logger.config("fo "); - Fop.logger.config("fo input file: " + foFile.toString()); - break; - default: - Fop.logger.config("unknown input type"); - } - System.out.print("Output mode: "); - switch (outputmode) { - case NOT_SET: - Fop.logger.config("not set"); - break; - case PDF_OUTPUT: - Fop.logger.config("pdf"); - Fop.logger.config("output file: " + outputFile.toString()); - break; - default: - Fop.logger.config("unknown input type"); - } - - - Fop.logger.config("OPTIONS"); - if (userConfigFile != null) { - Fop.logger.config("user configuration file: " - + userConfigFile.toString()); - } else { - Fop.logger.config( - "no user configuration file is used [default]"); - } - if ((bool = isDebugMode()) != null && bool.booleanValue()) { - Fop.logger.config("debug mode on"); - } else { - Fop.logger.config("debug mode off [default]"); - } - if ((bool = doDumpConfiguration()) != null && bool.booleanValue()) { - Fop.logger.config("dump configuration"); - } else { - Fop.logger.config("don't dump configuration [default]"); - } - if ((bool = isCoarseAreaXml()) != null && bool.booleanValue()) { - Fop.logger.config("no low level areas"); - } else { - Fop.logger.config("low level areas generated[default]"); - } - if ((bool = isQuiet()) != null && bool.booleanValue()) { - Fop.logger.config("quiet mode on"); - } else { - Fop.logger.config("quiet mode off [default]"); - } - - } - -} diff --git a/src/java/org/apache/fop/apps/XSLTInputHandler.java b/src/java/org/apache/fop/apps/XSLTInputHandler.java index 9634f073f..dd2a7e022 100644 --- a/src/java/org/apache/fop/apps/XSLTInputHandler.java +++ b/src/java/org/apache/fop/apps/XSLTInputHandler.java @@ -24,7 +24,6 @@ import java.util.Vector; // Imported TraX classes import javax.xml.transform.Source; -import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.sax.SAXResult; @@ -52,9 +51,8 @@ public class XSLTInputHandler extends InputHandler { * @param xsltfile XSLT file * @param params Vector of command-line parameters (name, value, * name, value, ...) for XSL stylesheet - * @throws FOPException if initializing the Transformer fails */ - public XSLTInputHandler(File xmlfile, File xsltfile, Vector params) throws FOPException { + public XSLTInputHandler(File xmlfile, File xsltfile, Vector params) { this.xmlSource = new StreamSource(xmlfile); this.xsltSource = new StreamSource(xsltfile); xsltParams = params; @@ -64,10 +62,9 @@ public class XSLTInputHandler extends InputHandler { * Constructor for files as input * @param xmlfile XML file * @param xsltfile XSLT file - * @throws FOPException if initializing the Transformer fails * @deprecated Use JAXP instead. */ - public XSLTInputHandler(File xmlfile, File xsltfile) throws FOPException { + public XSLTInputHandler(File xmlfile, File xsltfile) { this.xmlSource = new StreamSource(xmlfile); this.xsltSource = new StreamSource(xsltfile); } @@ -76,10 +73,9 @@ public class XSLTInputHandler extends InputHandler { * Constructor with URIs/URLs as input. * @param xmlURL XML URL * @param xsltURL XSLT URL - * @throws FOPException if initializing the Transformer fails * @deprecated Use JAXP instead. */ - public XSLTInputHandler(String xmlURL, String xsltURL) throws FOPException { + public XSLTInputHandler(String xmlURL, String xsltURL) { this.xmlSource = new StreamSource(xmlURL); this.xsltSource = new StreamSource(xsltURL); } @@ -88,11 +84,9 @@ public class XSLTInputHandler extends InputHandler { * Constructor with InputSources as input. * @param xmlSource XML InputSource * @param xsltSource XSLT InputSource - * @throws FOPException if initializing the Transformer fails * @deprecated Use JAXP instead. */ - public XSLTInputHandler(InputSource xmlSource, InputSource xsltSource) - throws FOPException { + public XSLTInputHandler(InputSource xmlSource, InputSource xsltSource) { this.xmlSource = new StreamSource(xmlSource.getByteStream(), xmlSource.getSystemId()); this.xsltSource = new StreamSource(xsltSource.getByteStream(), @@ -128,12 +122,13 @@ public class XSLTInputHandler extends InputHandler { * XMLReaders or XMLFilters * @throws FOPException if setting up the XMLFilter fails */ - public static XMLFilter getXMLFilter(Source xsltSource, Vector inParams) throws FOPException { + public static XMLFilter getXMLFilter(Source xsltSource, Vector inParams) + throws FOPException { try { // Instantiate a TransformerFactory. TransformerFactory tFactory = TransformerFactory.newInstance(); - // Determine whether the TransformerFactory supports The use of SAXSource - // and SAXResult + // Determine whether the TransformerFactory supports the use of + // SAXSource and SAXResult if (tFactory.getFeature(SAXSource.FEATURE) && tFactory.getFeature(SAXResult.FEATURE)) { // Cast the TransformerFactory to SAXTransformerFactory. -- 2.39.5