/*
* This file is part of MoleculeViewer.
*
* MoleculeViewer 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 3 of the License, or
* (at your option) any later version.
*
* MoleculeViewer 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 MoleculeViewer. If not, see <http://www.gnu.org/licenses/>.
*/
package astex;
import java.io.*;
import java.util.*;
/**
* Lightweight logging interface.
* Will attempt to discover the method name.
*/
public class Log {
/** The hard wired log level settings. */
public static final int DEBUG = 1;
public static final int DEBUG3 = 2;
public static final int DEBUG2 = 3;
public static final int DEBUG1 = 4;
public static final int INFO = 5;
public static final int WARN = 6;
public static final int ERROR = 7;
public static final int FATAL = 8;
public static final int ASSERT = 9;
/** The hard wired log level labels. */
public static final String logStrings[] = {
"ALL",
"DEBUG",
"DEBUG3",
"DEBUG2",
"DEBUG1",
"INFO",
"WARN",
"ERROR",
"FATAL",
"NOTHING",
"ASSERT"
};
/** The maps of logging levels for the classes. */
private static HashMap<String,Integer> methodLevels = new HashMap<String,Integer>(16);
/** The current global log level. */
private static int level = INFO;
/** Is the logging to show whole class name. */
private static boolean fullClass = false;
/** Set up the database. */
static {
initialise();
}
public static void debug(String s, double d){
if(level <= DEBUG && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG], String.format(s, d));
}
public static void debug3(String s, double d){
if(level <= DEBUG3 && getLoggingLevel(3) <= DEBUG3)
log(logStrings[DEBUG3], String.format(s, d));
}
public static void debug2(String s, double d){
if(level <= DEBUG2 && getLoggingLevel(3) <= DEBUG2)
log(logStrings[DEBUG2], String.format(s, d));
}
public static void debug1(String s, double d){
if(level <= DEBUG1 && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG1], String.format(s, d));
}
public static void info(String s, double d){
if(level <= INFO) log(logStrings[INFO], String.format(s, d));
}
public static void warn(String s, double d){
if(level <= WARN) log(logStrings[WARN], String.format(s, d));
}
public static void error(String s, double d){
if(level <= ERROR) log(logStrings[ERROR], String.format(s, d));
}
public static void fatal(String s, double d){
if(level <= FATAL) log(logStrings[FATAL], String.format(s, d));
}
public static void debug(String s, long d){
if(level <= DEBUG && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG], String.format(s, d));
}
public static void debug3(String s, long d){
if(level <= DEBUG3 && getLoggingLevel(3) <= DEBUG3)
log(logStrings[DEBUG3], String.format(s, d));
}
public static void debug2(String s, long d){
if(level <= DEBUG2 && getLoggingLevel(3) <= DEBUG2)
log(logStrings[DEBUG2], String.format(s, d));
}
public static void debug1(String s, long d){
if(level <= DEBUG1 && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG1], String.format(s, d));
}
public static void info(String s, long d){
if(level <= INFO) log(logStrings[INFO], String.format(s, d));
}
public static void warn(String s, long d){
if(level <= WARN) log(logStrings[WARN], String.format(s, d));
}
public static void error(String s, long d){
if(level <= ERROR) log(logStrings[ERROR], String.format(s, d));
}
public static void fatal(String s, long d){
if(level <= FATAL) log(logStrings[FATAL], String.format(s, d));
}
public static void debug(String s){
if(level <= DEBUG && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG], s);
}
public static void debug3(String s){
if(level <= DEBUG3 && getLoggingLevel(3) <= DEBUG3)
log(logStrings[DEBUG3], s);
}
public static void debug2(String s){
if(level <= DEBUG2 && getLoggingLevel(3) <= DEBUG2)
log(logStrings[DEBUG2], s);
}
public static void debug1(String s){
if(level <= DEBUG1 && getLoggingLevel(3) <= DEBUG1)
log(logStrings[DEBUG1], s);
}
public static void info(String s){
if(level <= INFO) log(logStrings[INFO], s);
}
public static void warn(String s){
if(level <= WARN) log(logStrings[WARN], s);
}
public static void error(String s){
if(level <= ERROR) log(logStrings[ERROR], s);
}
public static void fatal(String s){
if(level <= FATAL) log(logStrings[FATAL], s);
}
public static void check(boolean condition, String s){
if(!condition) logAssert(logStrings[ASSERT], s);
}
public static void check(boolean condition, String s, double d){
if(!condition) logAssert(logStrings[ASSERT], String.format(s, d));
}
public static void check(boolean condition, String s, long d){
if(!condition) logAssert(logStrings[ASSERT], String.format(s, d));
}
/** Log the assertion. */
private static void logAssert(String intro, String s){
String methodName = getMethodName(3);
if(!fullClass){
int lastDot = methodName.lastIndexOf('.');
methodName = methodName.substring(lastDot + 1,
methodName.length());
}
FILE.out.print("%-7s", intro);
if(fullClass){
FILE.out.print("%-15s - ", methodName);
}else{
FILE.out.print("%-10s - ", methodName);
}
FILE.out.println(s);
}
/** Output the log message. */
private static void log(String intro, String s){
String methodName = getMethodName(3);
if(!fullClass){
int lastDot = methodName.lastIndexOf('.');
methodName = methodName.substring(lastDot + 1,
methodName.length());
}
FILE.out.print("%-7s", intro);
if(fullClass){
FILE.out.print("%-15s - ", methodName);
}else{
FILE.out.print("%-10s - ", methodName);
}
FILE.out.println(s);
}
/** Get the logging level. */
private static int getLoggingLevel(int l){
String methodName = getMethodName(l);
Integer il = methodLevels.get(methodName);
if(il != null){
return il.intValue();
}
String className = getClassName(methodName);
il = methodLevels.get(className);
if(il != null){
return il.intValue();
}
return logStrings.length;
}
/** Return the class name from the stack trace entry. */
private static String getClassName(String methodName){
if(methodName == null){
return "unknown-class";
}
int pos = methodName.lastIndexOf('.');
if(pos == -1){
return methodName;
}else{
return methodName.substring(0, pos);
}
}
/** Find the method name that called the Logger. */
private static String getMethodName(int nline){
Exception e = new Exception();
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
e.printStackTrace(ps);
ps.close();
String exceptionString = baos.toString();
StringTokenizer st = new StringTokenizer(exceptionString, "\r\n");
int iline = 0;
boolean seenThisMethod = false;
String realLine = null;
while(st.hasMoreElements()){
String line = st.nextToken();
line = line.replace('/', '.');
if(seenThisMethod){
iline++;
}
if(iline == nline){
realLine = line;
break;
}
if(line.indexOf("astex.Log.getMethodName") != -1){
seenThisMethod = true;
}
}
String methodName = "unknown-method";
if(realLine != null){
StringBuilder sb = new StringBuilder(30);
int len = realLine.length();
for(int i = 0; i < len; i++){
char c0 = realLine.charAt(i);
if(c0 == 'a'){
char c1 = realLine.charAt(i+1);
char c2 = realLine.charAt(i+2);
if(c1 == 't' && c2 == ' '){
// found it
for(int j = i + 3; j < len; j++){
char c = realLine.charAt(j);
if(c == '('){
break;
}
sb.append(realLine.charAt(j));
}
break;
}
}
}
methodName = sb.toString();
}
return methodName;
}
/** Initialise the class defintions. */
private static void initialise(){
Properties logProperties =
FILE.loadProperties("log.properties");
if(logProperties == null){
System.out.println("Log.initialise: couldn't open log.properties");
return;
}
Enumeration<?> names = logProperties.propertyNames();
while(names.hasMoreElements()){
String property = (String)names.nextElement();
String value = (String)logProperties.get(property);
value = value.toUpperCase();
if("classname".equals(property)){
if("FULL".equals(value)){
fullClass = true;
}else if("METHOD".equals(value)){
fullClass = false;
}
}else if("level".equals(property)){
int l = string2level(value);
if(l != -1){
level = l;
}else{
System.out.println("Log.initialise: invalid log level " +
value);
}
}else{
int level = string2level(value);
if(level != -1){
Integer ilevel = Integer.valueOf(level);
methodLevels.put(property, ilevel);
}else{
System.out.println("Log.initialise: invalid log level " +
value + " for class " + property);
}
}
}
}
/** Map a string level name to the corresponding int. */
private static int string2level(String s){
for(int i = 0; i < logStrings.length; i++){
if(s.equals(logStrings[i])){
return i;
}
}
return -1;
}
}