/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2001 Intersect Software Corporation This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.foundation; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.Date; /** * NSLog is foundation's built-in logging facility: IMPLEMENTED, BUT NOT TESTED. * By default, all groups are enabled, and debug level is DebugLevelOff. * * @author michael@mpowers.net * @author $Author: cgruber $ * @version $Revision: 893 $ */ public class NSLog { public static long DebugGroupApplicationGeneration = 1L << 3; public static long DebugGroupArchiving = 1L << 6; public static long DebugGroupAssociations = 1L << 19; public static long DebugGroupComponentBindings = 1L << 9; public static long DebugGroupControllers = 1L << 20; public static long DebugGroupComponents = 1L << 26; public static long DebugGroupDatabaseAccess = 1L << 16; public static long DebugGroupDeployment = 1L << 22; public static long DebugGroupEnterpriseObjects = 1L << 1; public static long DebugGroupFormatting = 1L << 10; public static long DebugGroupIO = 1L << 13; public static long DebugGroupJSPServlets = 1L << 27; public static long DebugGroupKeyValueCoding = 1L << 8; public static long DebugGroupModel = 1L << 15; public static long DebugGroupMultithreading = 1L << 4; public static long DebugGroupParsing = 1L << 23; public static long DebugGroupQualifiers = 1L << 11; public static long DebugGroupReflection = 1L << 24; public static long DebugGroupRequestHandling = 1L << 25; public static long DebugGroupResources = 1L << 5; public static long DebugGroupRules = 1L << 21; public static long DebugGroupSQLGeneration = 1L << 17; public static long DebugGroupTiming = 1L << 14; public static long DebugGroupUserInterface = 1L << 18; public static long DebugGroupValidation = 1L << 7; public static long DebugGroupWebObjects = 1L << 2; public static long DebugGroupWebServices = 1L << 2; public static int DebugLevelOff = 0; public static int DebugLevelCritical = 1; public static int DebugLevelInformational = 2; public static int DebugLevelDetailed = 3; /** * The logger to which debug statements should be conditionally written. By * default, these messages appear on the standard error stream. */ public static Logger debug; /** * The logger to which error messages should be written, which may not always be * user-visible. By default, these messages appear on the standard error stream. */ public static Logger err; /** * The logger to which user-visible messages should be written. By default, * these messages appear on the standard output stream. */ public static Logger out; private static long allowedGroups; private static int allowedLevel; static { debug = new PrintStreamLogger(System.err); err = new PrintStreamLogger(System.err); out = new PrintStreamLogger(System.out); // TODO: need to initialize the debug level and groups based // on the value of the NSDebugLevel and NSDebugGroup properties allowedGroups = Long.MAX_VALUE; allowedLevel = 0; } /** * Adds the specified group masks to those allowed for logging. */ public static void allowDebugLoggingForGroups(long aDebugGroups) { allowedGroups = allowedGroups | aDebugGroups; } /** * Returns the current logging debug level. */ public static int allowedDebugLevel() { return allowedLevel; } /** * Returns whether logging is allowed for the specified groups masks. */ public static boolean debugLoggingAllowedForGroups(long aDebugGroups) { return (allowedGroups == (allowedGroups | aDebugGroups)); } /** * Returns whether logging is allowed for the specified level. */ public static boolean debugLoggingAllowedForLevel(int aDebugLevel) { return (allowedLevel >= aDebugLevel); } /** * Returns whether logging allowed for the specified groups masks at the * specified level. Convenience method. */ public static boolean debugLoggingAllowedForLevelAndGroups(int aDebugLevel, long aDebugGroups) { return ((allowedLevel >= aDebugLevel) && (allowedGroups == (allowedGroups | aDebugGroups))); } /** * Convenience to obtain a java PrintStream for the specified file path. Returns * null if the stream could not be created. */ public static PrintStream printStreamForPath(String aPath) { try { return new PrintStream(new FileOutputStream(aPath)); } catch (Throwable t) { } return null; } /** * Removes the specified group masks from those allowed for logging. */ public static void refuseDebugLoggingForGroups(long aDebugGroups) { allowedGroups = (allowedGroups | aDebugGroups) ^ aDebugGroups; } /** * Sets the allowed groups to only those specified by the mask. */ public static void setAllowedDebugGroups(long aDebugGroups) { allowedGroups = aDebugGroups; } /** * Sets the current debug level. */ public static void setAllowedDebugLevel(int aDebugLevel) { allowedLevel = aDebugLevel; } /** * Sets the current debug logger. Does nothing if logger is null. */ public static void setDebug(NSLog.Logger logger) { if (logger != null) { debug = logger; } } /** * Sets the current error logger. Does nothing if logger is null. */ public static void setErr(NSLog.Logger logger) { if (logger != null) { err = logger; } } /** * Sets the current output logger. Does nothing if logger is null. */ public static void setOut(NSLog.Logger logger) { if (logger != null) { out = logger; } } /** * Convenience to write the throwable's stack trace to a string. */ public static String throwableAsString(Throwable t) { ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(os); t.printStackTrace(ps); return os.toString(); } /** * The abstract superclass of all Logger implementations. */ static abstract public class Logger { private boolean enabled; private boolean verbose; /** * Default constructor sets enabled and verbose to true. */ public Logger() { enabled = true; verbose = true; } /** * Convenience to append a Boolean. */ public void appendln(boolean aValue) { appendln(Boolean.valueOf(aValue)); } /** * Convenience to append a Byte. */ public void appendln(byte aValue) { appendln(Byte.valueOf(aValue)); } /** * Convenience to write a String comprised of the byte array using the default * encoding. */ public void appendln(byte[] aValue) { appendln(new String(aValue)); } /** * Convenience to append a Character. */ public void appendln(char aValue) { appendln(Character.valueOf(aValue)); } /** * Convenience to append a String comprised of the character array. */ public void appendln(char[] aValue) { appendln(new String(aValue)); } /** * Convenience to append a Double. */ public void appendln(double aValue) { appendln(Double.valueOf(aValue)); } /** * Convenience to append a Float. */ public void appendln(float aValue) { appendln(Float.valueOf(aValue)); } /** * Convenience to append a Integer. */ public void appendln(int aValue) { appendln(Integer.valueOf(aValue)); } /** * Convenience to append a Long. */ public void appendln(long aValue) { appendln(Long.valueOf(aValue)); } /** * Convenience to append a Short */ public void appendln(short aValue) { appendln(Short.valueOf(aValue)); } /** * Convenience to append a Throwable. */ public void appendln(Throwable aValue) { appendln(NSLog.throwableAsString(aValue)); } /** * Writes the object to the log. */ public abstract void appendln(Object aValue); /** * Appends a line to the log. */ public abstract void appendln(); /** * Flushes any buffered output to the log. */ public abstract void flush(); /** * Returns whether the logger is enabled, the meaning of which is defined by the * implementing class. */ public boolean isEnabled() { return enabled; } /** * Returns whether the logger is verbose, the meaning of which is defined by the * implementing class. */ public boolean isVerbose() { return verbose; } /** * Sets whether the logger is enabled, the meaning of which is defined by the * implementing class. */ public void setIsEnabled(boolean aBool) { enabled = aBool; } /** * Sets whether the logger is verbose, the meaning of which is defined by the * implementing class. */ public void setIsVerbose(boolean aBool) { verbose = aBool; } } /** * The default implementation of Logger that writes to a Java PrintStream. If * not enabled, no output is written. If verbose, output is in format: "[time] * message". */ static public class PrintStreamLogger extends Logger { private PrintStream thePrintStream; /** * Constructor takes a PrintStream. */ public PrintStreamLogger(PrintStream ps) { thePrintStream = ps; } /** * Sends a newline to the print stream. */ @Override public void appendln() { if (isEnabled()) { thePrintStream.println(); } } /** * Writes the throwable to the print stream. */ @Override public void appendln(Throwable aValue) { appendln(NSLog.throwableAsString(aValue)); } /** * Writes aValue.toString to the print stream. */ @Override public void appendln(Object aValue) { if (isEnabled()) { if (isVerbose()) { thePrintStream.print('[' + new Date().toString() + "] <" + Thread.currentThread().getName() + "> "); } if (aValue == null) aValue = "null"; thePrintStream.println(aValue.toString()); } } /** * Flushes the print stream. */ @Override public void flush() { thePrintStream.flush(); } /** * Returns the current print stream. */ public PrintStream printStream() { return thePrintStream; } /** * Replaces the current print stream. */ public void setPrintStream(PrintStream aStream) { thePrintStream = aStream; } } } /* * $Log$ Revision 1.2 2006/02/16 13:15:00 cgruber Check in all sources in * eclipse-friendly maven-enabled packages. * * Revision 1.1 2003/01/31 22:33:00 mpowers Contributing NSLog. * * */