/* Copyright (C) 2003-2009 Egon Willighagen <egonw@users.sf.net>
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program 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 program 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 program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.openscience.cdk.tools;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
/**
* Implementation of the {@link ILoggingTool} interface that sends output to
* the {@link System}.out channel.
*
* @cdk.module core
*/
@TestClass("org.openscience.cdk.tools.SystemOutLoggingToolTest")
public class SystemOutLoggingTool implements ILoggingTool {
/** Boolean which is true when debug messages are send to System.out. */
private boolean doDebug = false;
/** Logger used to report internal problems. */
private static ILoggingTool logger;
/** Name of the class for which this {@link ILoggingTool} is reporting. */
private String classname;
/** Length of the stack to print for reported {@link Exception}s. */
private int stackLength;
/**
* Constructs a ILoggingTool which produces log lines indicating them to be
* for the given Class.
*
* @param classInst Class from which the log messages originate
*/
public SystemOutLoggingTool(Class<?> classInst) {
this.classname = classInst.getName();
doDebug = false;
if (System.getProperty("cdk.debugging", "false").equals("true") ||
System.getProperty("cdk.debug.stdout", "false").equals("true")) {
doDebug = true;
}
}
/** {@inheritDoc} */
@TestMethod("testDumpSystemProperties")
public void dumpSystemProperties() {
debug("os.name : " + System.getProperty("os.name"));
debug("os.version : " + System.getProperty("os.version"));
debug("os.arch : " + System.getProperty("os.arch"));
debug("java.version : " + System.getProperty("java.version"));
debug("java.vendor : " + System.getProperty("java.vendor"));
}
/** {@inheritDoc} */
@TestMethod("testSetStackLength_int")
public void setStackLength(int length) {
this.stackLength = length;
}
/** {@inheritDoc} */
@TestMethod("testDumpClasspath")
public void dumpClasspath() {
debug("java.class.path: " + System.getProperty("java.class.path"));
}
/** {@inheritDoc} */
@TestMethod("testDebug_Object")
public void debug(Object object) {
if (doDebug) {
if (object instanceof Throwable) {
debugThrowable((Throwable)object);
} else {
debugString("" + object);
}
}
}
private void debugString(String string) {
printToSTDOUT("DEBUG", string);
}
/** {@inheritDoc} */
@TestMethod("testDebug_Object_Object")
public void debug(Object object, Object... objects) {
if (doDebug) {
StringBuilder result = new StringBuilder();
result.append(object.toString());
for (Object obj : objects) {
result.append(obj.toString());
}
debugString(result.toString());
}
}
private void debugThrowable(Throwable problem) {
if (problem != null) {
if (problem instanceof Error) {
debug("Error: ", problem.getMessage());
} else {
debug("Exception: ", problem.getMessage());
}
StringWriter stackTraceWriter = new StringWriter();
problem.printStackTrace(new PrintWriter(stackTraceWriter));
String trace = stackTraceWriter.toString();
try {
BufferedReader reader = new BufferedReader(
new StringReader(trace)
);
if (reader.ready()) {
String traceLine = reader.readLine();
int counter = 0;
while (reader.ready() && traceLine != null &&
(counter < stackLength)) {
debug(traceLine);
traceLine = reader.readLine();
counter++;
}
}
} catch (Exception ioException) {
error("Serious error in LoggingTool while printing exception " +
"stack trace: ", ioException.getMessage());
logger.debug(ioException);
}
Throwable cause = problem.getCause();
if (cause != null) {
debug("Caused by: ");
debugThrowable(cause);
}
}
}
/** {@inheritDoc} */
@TestMethod("testError_Object")
public void error(Object object) {
if (doDebug) {
errorString("" + object);
}
}
/** {@inheritDoc} */
@TestMethod("testError_Object_int")
public void error(Object object, Object... objects) {
if (doDebug) {
StringBuilder result = new StringBuilder();
result.append(object.toString());
for (Object obj : objects) {
result.append(obj.toString());
}
errorString(result.toString());
}
}
private void errorString(String string) {
printToSTDOUT("ERROR", string);
}
/** {@inheritDoc} */
@TestMethod("testFatal_Object")
public void fatal(Object object) {
if (doDebug) {
printToSTDOUT("FATAL", object.toString());
}
}
/** {@inheritDoc} */
@TestMethod("testInfo_Object")
public void info(Object object) {
if (doDebug) {
infoString("" + object);
}
}
/** {@inheritDoc} */
@TestMethod("testInfo_Object_int")
public void info(Object object, Object... objects) {
if (doDebug) {
StringBuilder result = new StringBuilder();
result.append(object.toString());
for (Object obj : objects) {
result.append(obj.toString());
}
infoString(result.toString());
}
}
private void infoString(String string) {
printToSTDOUT("INFO", string);
}
/** {@inheritDoc} */
@TestMethod("testWarn_Object")
public void warn(Object object) {
if (doDebug) {
warnString("" + object);
}
}
private void warnString(String string) {
printToSTDOUT("WARN", string);
}
/** {@inheritDoc} */
@TestMethod("testWarn_Object_int")
public void warn(Object object, Object... objects) {
if (doDebug) {
StringBuilder result = new StringBuilder();
result.append(object.toString());
for (Object obj : objects) {
result.append(obj.toString());
}
warnString(result.toString());
}
}
/** {@inheritDoc} */
@TestMethod("testIsDebugEnabled")
public boolean isDebugEnabled() {
return doDebug;
}
private void printToSTDOUT(String level, String message) {
System.out.print(classname);
System.out.print(" ");
System.out.print(level);
System.out.print(": ");
System.out.println(message);
}
/**
* Creates a new {@link SystemOutLoggingTool} for the given class.
*
* @param sourceClass Class for which logging messages are recorded.
* @return A {@link SystemOutLoggingTool}.
*/
@TestMethod("testCreate")
public static ILoggingTool create(Class<?> sourceClass) {
return new SystemOutLoggingTool(sourceClass);
}
/**
* Protected method which must not be used, except for testing purposes.
*/
@TestMethod("testIsDebugEnabled")
protected void setDebugEnabled(boolean enabled) {
doDebug = enabled;
}
}