From f7d5393a79bc58683b3d63632bd235932b37d9d6 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Sat, 11 Sep 2004 18:56:20 +0000 Subject: [PATCH] Bugzilla patch 31162: Better command-line logging without losing the possibility to fine-tune Commons Logging from outside. Submitted by: Finn Bock plus using the new CommandLineLogger for PFMReader and TTFReader, too. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197940 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/apps/CommandLineOptions.java | 42 ++- src/java/org/apache/fop/apps/Fop.java | 21 +- .../org/apache/fop/fonts/apps/PFMReader.java | 57 ++-- .../org/apache/fop/fonts/apps/TTFReader.java | 69 ++--- .../apache/fop/util/CommandLineLogger.java | 261 ++++++++++++++++++ 5 files changed, 369 insertions(+), 81 deletions(-) create mode 100644 src/java/org/apache/fop/util/CommandLineLogger.java diff --git a/src/java/org/apache/fop/apps/CommandLineOptions.java b/src/java/org/apache/fop/apps/CommandLineOptions.java index f8614c4f3..a2e8ebd9e 100644 --- a/src/java/org/apache/fop/apps/CommandLineOptions.java +++ b/src/java/org/apache/fop/apps/CommandLineOptions.java @@ -25,6 +25,7 @@ import java.util.Locale; import java.util.Vector; import org.apache.fop.fo.Constants; +import org.apache.fop.util.CommandLineLogger; // commons logging import org.apache.commons.logging.Log; @@ -74,13 +75,27 @@ public class CommandLineOptions implements Constants { * Construct a command line option object from command line arguments * @param args command line parameters * @throws FOPException for general errors - * @throws FileNotFoundException if an input file wasn't found. + * @throws FileNotFoundException if an input file wasn't found + * @throws IOException if the the configuration file could not be loaded */ - public CommandLineOptions(String[] args) - throws FOPException, FileNotFoundException, IOException { + public CommandLineOptions(String[] args) throws FOPException, IOException { + LogFactory logFactory = LogFactory.getFactory(); + + // Enable the simple command line logging when no other logger is + // defined. + if (System.getProperty("org.apache.commons.logging.Log") == null) { + logFactory.setAttribute("org.apache.commons.logging.Log", + CommandLineLogger.class.getName()); + setLogLevel("info"); + } log = LogFactory.getLog("FOP"); + parse(args); + } + + private void parse(String[] args) + throws FOPException, IOException { boolean optionsParsed = true; foUserAgent = new FOUserAgent(); @@ -130,6 +145,10 @@ public class CommandLineOptions implements Constants { i = i + parseLanguageOption(args, i); } else if (args[i].equals("-s")) { suppressLowLevelAreas = Boolean.TRUE; + } else if (args[i].equals("-d")) { + setLogLevel("debug"); + } else if (args[i].equals("-q") || args[i].equals("--quiet")) { + setLogLevel("error"); } else if (args[i].equals("-fo")) { i = i + parseFOInputOption(args, i); } else if (args[i].equals("-xsl")) { @@ -363,6 +382,15 @@ public class CommandLineOptions implements Constants { } } + private void setLogLevel(String level) { + // Set the evel for future loggers. + LogFactory.getFactory().setAttribute("level", level); + if (log instanceof CommandLineLogger) { + // Set the level for the logger creates already. + ((CommandLineLogger) log).setLogLevel(level); + } + } + /** * checks whether all necessary information has been given in a consistent way */ @@ -376,8 +404,8 @@ public class CommandLineOptions implements Constants { } if ((outputmode == RENDER_AWT || outputmode == RENDER_PRINT) && outfile != null) { - throw new FOPException("Output file may not be specified " + - "for AWT or PRINT output"); + throw new FOPException("Output file may not be specified " + + "for AWT or PRINT output"); } if (inputmode == XSLT_INPUT) { @@ -477,7 +505,7 @@ public class CommandLineOptions implements Constants { /** * Create an InputHandler object based on command-line parameters * @return a new InputHandler instance - * @throws IllegalStateException if invalid/missing parameters + * @throws IllegalArgumentException if invalid/missing parameters */ private InputHandler createInputHandler() throws IllegalArgumentException { switch (inputmode) { @@ -577,7 +605,9 @@ public class CommandLineOptions implements Constants { "\nUSAGE\nFop [options] [-fo|-xml] infile [-xsl file] " + "[-awt|-pdf|-mif|-rtf|-pcl|-ps|-txt|-at|-print] \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" diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java index a80647f0d..b9b52ec43 100644 --- a/src/java/org/apache/fop/apps/Fop.java +++ b/src/java/org/apache/fop/apps/Fop.java @@ -162,24 +162,9 @@ public class Fop implements Constants { if (options.getOutputMode() != CommandLineOptions.RENDER_AWT) { System.exit(0); } - } catch (FOPException e) { - if (e.getMessage() == null) { - System.err.println("Exception occured with a null error message"); - } else { - System.err.println("" + e.getMessage()); - } - if (options != null && options.getLogger().isDebugEnabled()) { - e.printStackTrace(); - } else { - System.err.println("Turn on debugging for more information"); - } - System.exit(1); - } catch (java.io.IOException e) { - System.err.println("" + e.getMessage()); - if (options != null && options.getLogger().isDebugEnabled()) { - e.printStackTrace(); - } else { - System.err.println("Turn on debugging for more information"); + } catch (Exception e) { + if (options != null) { + options.getLogger().error("Exception", e); } System.exit(1); } diff --git a/src/java/org/apache/fop/fonts/apps/PFMReader.java b/src/java/org/apache/fop/fonts/apps/PFMReader.java index 38d652ab2..83eb0879a 100644 --- a/src/java/org/apache/fop/fonts/apps/PFMReader.java +++ b/src/java/org/apache/fop/fonts/apps/PFMReader.java @@ -38,6 +38,7 @@ import org.apache.commons.logging.LogFactory; //FOP import org.apache.fop.apps.Fop; import org.apache.fop.fonts.type1.PFMFile; +import org.apache.fop.util.CommandLineLogger; /** * A tool which reads PFM files from Adobe Type 1 fonts and creates @@ -48,7 +49,7 @@ public class PFMReader { /** * logging instance */ - protected Log log = LogFactory.getLog(TTFReader.class); + protected static Log log; /** * Parse commandline arguments. put options in the HashMap and return @@ -61,7 +62,9 @@ public class PFMReader { List arguments = new java.util.ArrayList(); for (int i = 0; i < args.length; i++) { if (args[i].startsWith("-")) { - if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { + if ("-d".equals(args[i]) || "-q".equals(args[i])) { + options.put(args[i], ""); + } else if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { options.put(args[i], args[i + 1]); i++; } else { @@ -80,8 +83,8 @@ public class PFMReader { "java " + PFMReader.class.getName() + " [options] metricfile.pfm xmlfile.xml"); System.out.println(); System.out.println("where options can be:"); - System.out.println("-d "); - System.out.println(" Set debug level (default: WARN)."); + System.out.println("-d Debug mode"); + System.out.println("-q Quiet mode"); System.out.println("-fn "); System.out.println(" default is to use the fontname in the .pfm file, but"); System.out.println(" you can override that name to make sure that the"); @@ -119,32 +122,27 @@ public class PFMReader { Map options = new java.util.HashMap(); String[] arguments = parseArguments(options, args); - //Setup simple logger for this command-line application - System.setProperty("org.apache.commons.logging.Log", - "org.apache.commons.logging.impl.SimpleLog"); - System.setProperty("org.apache.commons.logging.simplelog.showShortLogname", - "false"); + // Enable the simple command line logging when no other logger is + // defined. + LogFactory logFactory = LogFactory.getFactory(); + if (System.getProperty("org.apache.commons.logging.Log") == null) { + logFactory.setAttribute("org.apache.commons.logging.Log", + CommandLineLogger.class.getName()); + } //Determine log level - String level; if (options.get("-d") != null) { - String lev = (String)options.get("-d"); - if ("DEBUG".equalsIgnoreCase(lev)) { - level = "debug"; - } else if ("INFO".equalsIgnoreCase(lev)) { - level = "info"; - } else { - level = "warn"; - } + setLogLevel("debug"); + } else if (options.get("-q") != null) { + setLogLevel("error"); } else { - level = "warn"; + setLogLevel("info"); } - System.setProperty("org.apache.commons.logging.simplelog.defaultlog", - level); + log = LogFactory.getLog(PFMReader.class); PFMReader app = new PFMReader(); - System.out.println("PFM Reader for Apache FOP " + Fop.getVersion() + "\n"); + log.info("PFM Reader for Apache FOP " + Fop.getVersion() + "\n"); if (options.get("-ef") != null) { embFile = (String)options.get("-ef"); @@ -167,7 +165,7 @@ public class PFMReader { displayUsage(); } else { try { - System.out.println("Parsing font..."); + log.info("Parsing font..."); PFMFile pfm = app.loadPFM(arguments[0]); if (pfm != null) { app.preview(pfm); @@ -177,15 +175,22 @@ public class PFMReader { app.writeFontXML(doc, arguments[1]); } - System.out.println("\nXML font metrics file successfullly created."); + log.info("XML font metrics file successfullly created."); } catch (Exception e) { - System.err.println("Error while building XML font metrics file"); - e.printStackTrace(System.err); + log.error("Error while building XML font metrics file", e); System.exit(-1); } } } + private static void setLogLevel(String level) { + // Set the evel for future loggers. + LogFactory.getFactory().setAttribute("level", level); + if (log instanceof CommandLineLogger) { + // Set the level for the logger creates already. + ((CommandLineLogger) log).setLogLevel(level); + } + } /** * Read a PFM file and returns it as an object. diff --git a/src/java/org/apache/fop/fonts/apps/TTFReader.java b/src/java/org/apache/fop/fonts/apps/TTFReader.java index 3cc7f4871..1755a491d 100644 --- a/src/java/org/apache/fop/fonts/apps/TTFReader.java +++ b/src/java/org/apache/fop/fonts/apps/TTFReader.java @@ -39,6 +39,7 @@ import org.apache.fop.apps.Fop; import org.apache.fop.fonts.truetype.FontFileReader; import org.apache.fop.fonts.truetype.TTFCmapEntry; import org.apache.fop.fonts.truetype.TTFFile; +import org.apache.fop.util.CommandLineLogger; /** * A tool which reads TTF files and generates @@ -49,7 +50,7 @@ public class TTFReader { /** * logging instance */ - protected Log log = LogFactory.getLog(TTFReader.class); + protected static Log log; /** * Parse commandline arguments. put options in the HashMap and return @@ -62,7 +63,9 @@ public class TTFReader { List arguments = new java.util.ArrayList(); for (int i = 0; i < args.length; i++) { if (args[i].startsWith("-")) { - if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { + if ("-d".equals(args[i]) || "-q".equals(args[i])) { + options.put(args[i], ""); + } else if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { options.put(args[i], args[i + 1]); i++; } else { @@ -82,8 +85,8 @@ public class TTFReader { "java " + TTFReader.class.getName() + " [options] fontfile.ttf xmlfile.xml"); System.out.println(); System.out.println("where options can be:"); - System.out.println("-d "); - System.out.println(" Set debug level (default: WARN)."); + System.out.println("-d Debug mode"); + System.out.println("-q Quiet mode"); System.out.println("-enc ansi"); System.out.println(" With this option you create a WinAnsi encoded font."); System.out.println(" The default is to create a CID keyed font."); @@ -135,32 +138,27 @@ public class TTFReader { Map options = new java.util.HashMap(); String[] arguments = parseArguments(options, args); - //Setup simple logger for this command-line application - System.setProperty("org.apache.commons.logging.Log", - "org.apache.commons.logging.impl.SimpleLog"); - System.setProperty("org.apache.commons.logging.simplelog.showShortLogname", - "false"); - + // Enable the simple command line logging when no other logger is + // defined. + LogFactory logFactory = LogFactory.getFactory(); + if (System.getProperty("org.apache.commons.logging.Log") == null) { + logFactory.setAttribute("org.apache.commons.logging.Log", + CommandLineLogger.class.getName()); + } + //Determine log level - String level; if (options.get("-d") != null) { - String lev = (String)options.get("-d"); - if ("DEBUG".equalsIgnoreCase(lev)) { - level = "debug"; - } else if ("INFO".equalsIgnoreCase(lev)) { - level = "info"; - } else { - level = "warn"; - } + setLogLevel("debug"); + } else if (options.get("-q") != null) { + setLogLevel("error"); } else { - level = "warn"; + setLogLevel("info"); } - System.setProperty("org.apache.commons.logging.simplelog.defaultlog", - level); + log = LogFactory.getLog(TTFReader.class); TTFReader app = new TTFReader(); - System.out.println("TTF Reader for Apache FOP " + Fop.getVersion() + "\n"); + log.info("TTF Reader for Apache FOP " + Fop.getVersion() + "\n"); if (options.get("-enc") != null) { String enc = (String)options.get("-enc"); @@ -194,7 +192,7 @@ public class TTFReader { displayUsage(); } else { try { - System.out.println("Parsing font..."); + log.info("Parsing font..."); TTFFile ttf = app.loadTTF(arguments[0], ttcName); if (ttf != null) { org.w3c.dom.Document doc = app.constructFontXML(ttf, @@ -202,9 +200,9 @@ public class TTFReader { ttcName); if (isCid) { - System.out.println("Creating CID encoded metrics..."); + log.info("Creating CID encoded metrics..."); } else { - System.out.println("Creating WinAnsi encoded metrics..."); + log.info("Creating WinAnsi encoded metrics..."); } if (doc != null) { @@ -212,21 +210,30 @@ public class TTFReader { } if (ttf.isEmbeddable()) { - System.out.println("This font contains no embedding license restrictions."); + log.info("This font contains no embedding license restrictions."); } else { - System.out.println("** Note: This font contains license retrictions for\n" + log.info("** Note: This font contains license retrictions for\n" + " embedding. This font shouldn't be embedded."); } } - System.out.println("\nXML font metrics file successfullly created."); + log.info(""); + log.info("XML font metrics file successfullly created."); } catch (Exception e) { - System.err.println("Error while building XML font metrics file."); - e.printStackTrace(System.err); + log.error("Error while building XML font metrics file.", e); System.exit(-1); } } } + private static void setLogLevel(String level) { + // Set the evel for future loggers. + LogFactory.getFactory().setAttribute("level", level); + if (log instanceof CommandLineLogger) { + // Set the level for the logger creates already. + ((CommandLineLogger) log).setLogLevel(level); + } + } + /** * Read a TTF file and returns it as an object. * diff --git a/src/java/org/apache/fop/util/CommandLineLogger.java b/src/java/org/apache/fop/util/CommandLineLogger.java new file mode 100644 index 000000000..20ba4e9f1 --- /dev/null +++ b/src/java/org/apache/fop/util/CommandLineLogger.java @@ -0,0 +1,261 @@ +/* Copyright 2004 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. + */ + +/* $Id$ */ + +package org.apache.fop.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This is a commons-logging logger for command line use. + */ +public class CommandLineLogger implements Log { + /** "Trace" level logging. */ + public static final int LOG_LEVEL_TRACE = 1; + /** "Debug" level logging. */ + public static final int LOG_LEVEL_DEBUG = 2; + /** "Info" level logging. */ + public static final int LOG_LEVEL_INFO = 3; + /** "Warn" level logging. */ + public static final int LOG_LEVEL_WARN = 4; + /** "Error" level logging. */ + public static final int LOG_LEVEL_ERROR = 5; + /** "Fatal" level logging. */ + public static final int LOG_LEVEL_FATAL = 6; + + private int logLevel; + private String logName; + + /** + * Construct the logger with a default log level taken from the LogFactory + * attribute "level". + * @param logName the logger name. + */ + public CommandLineLogger(String logName) { + this.logName = logName; + setLogLevel((String) LogFactory.getFactory().getAttribute("level")); + } + + /** + * Set a log level for the logger. + * @param level the log level + */ + public void setLogLevel(String level) { + if ("fatal".equals(level)) { + logLevel = LOG_LEVEL_FATAL; + } else if ("error".equals(level)) { + logLevel = LOG_LEVEL_ERROR; + } else if ("warn".equals(level)) { + logLevel = LOG_LEVEL_WARN; + } else if ("info".equals(level)) { + logLevel = LOG_LEVEL_INFO; + } else if ("debug".equals(level)) { + logLevel = LOG_LEVEL_DEBUG; + } else if ("trace".equals(level)) { + logLevel = LOG_LEVEL_TRACE; + } else { + logLevel = LOG_LEVEL_INFO; + } + } + + /** + * @see org.apache.commons.logging.Log#isTraceEnabled() + */ + public final boolean isTraceEnabled() { + return logLevel <= LOG_LEVEL_TRACE; + } + + /** + * @see org.apache.commons.logging.Log#isDebugEnabled() + */ + public final boolean isDebugEnabled() { + return logLevel <= LOG_LEVEL_DEBUG; + } + + /** + * @see org.apache.commons.logging.Log#isInfoEnabled() + */ + public final boolean isInfoEnabled() { + return logLevel <= LOG_LEVEL_INFO; + } + + /** + * @see org.apache.commons.logging.Log#isWarnEnabled() + */ + public final boolean isWarnEnabled() { + return logLevel <= LOG_LEVEL_WARN; + } + + /** + * @see org.apache.commons.logging.Log#isErrorEnabled() + */ + public final boolean isErrorEnabled() { + return logLevel <= LOG_LEVEL_ERROR; + } + + /** + * @see org.apache.commons.logging.Log#isFatalEnabled() + */ + public final boolean isFatalEnabled() { + return logLevel <= LOG_LEVEL_FATAL; + } + + /** + * @see org.apache.commons.logging.Log#trace(java.lang.Object) + */ + public final void trace(Object message) { + if (isTraceEnabled()) { + log(LOG_LEVEL_TRACE, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#trace(java.lang.Object, java.lang.Throwable) + */ + public final void trace(Object message, Throwable t) { + if (isTraceEnabled()) { + log(LOG_LEVEL_TRACE, message, t); + } + } + + /** + * @see org.apache.commons.logging.Log#debug(java.lang.Object) + */ + public final void debug(Object message) { + if (isDebugEnabled()) { + log(LOG_LEVEL_DEBUG, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#debug(java.lang.Object, java.lang.Throwable) + */ + public final void debug(Object message, Throwable t) { + if (isDebugEnabled()) { + log(LOG_LEVEL_DEBUG, message, t); + } + } + + /** + * @see org.apache.commons.logging.Log#info(java.lang.Object) + */ + public final void info(Object message) { + if (isInfoEnabled()) { + log(LOG_LEVEL_INFO, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#info(java.lang.Object, java.lang.Throwable) + */ + public final void info(Object message, Throwable t) { + if (isInfoEnabled()) { + log(LOG_LEVEL_INFO, message, t); + } + } + + /** + * @see org.apache.commons.logging.Log#warn(java.lang.Object) + */ + public final void warn(Object message) { + if (isWarnEnabled()) { + log(LOG_LEVEL_WARN, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#warn(java.lang.Object, java.lang.Throwable) + */ + public final void warn(Object message, Throwable t) { + if (isWarnEnabled()) { + log(LOG_LEVEL_WARN, message, t); + } + } + + /** + * @see org.apache.commons.logging.Log#error(java.lang.Object) + */ + public final void error(Object message) { + if (isErrorEnabled()) { + log(LOG_LEVEL_ERROR, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#error(java.lang.Object, java.lang.Throwable) + */ + public final void error(Object message, Throwable t) { + if (isErrorEnabled()) { + log(LOG_LEVEL_ERROR, message, t); + } + } + + /** + * @see org.apache.commons.logging.Log#fatal(java.lang.Object) + */ + public final void fatal(Object message) { + if (isFatalEnabled()) { + log(LOG_LEVEL_FATAL, message, null); + } + } + + /** + * @see org.apache.commons.logging.Log#fatal(java.lang.Object, java.lang.Throwable) + */ + public final void fatal(Object message, Throwable t) { + if (isFatalEnabled()) { + log(LOG_LEVEL_FATAL, message, t); + } + } + + /** + * Do the actual logging. + * This method assembles the message and prints it to + * and then calls write() to cause it to be written.

+ * + * @param type One of the LOG_LEVEL_XXX constants defining the log level + * @param message The message itself (typically a String) + * @param t The exception whose stack trace should be logged + */ + protected void log(int type, Object message, Throwable t) { + StringBuffer buf = new StringBuffer(); + // Append the message + buf.append(String.valueOf(message)); + if (t != null) { + buf.append("\n"); + // Append a stack trace or just the stack trace message. + if (!isDebugEnabled()) { + buf.append(t.toString()); + buf.append("\n"); + } else { + java.io.StringWriter sw = new java.io.StringWriter(1024); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + t.printStackTrace(pw); + pw.close(); + buf.append(sw.toString()); + } + } + + // Print to the appropriate destination + if (type >= LOG_LEVEL_WARN) { + System.err.println(buf); + } else { + System.out.println(buf); + } + + } +} -- 2.39.5