/* * JCarder -- cards Java programs to keep threads disentangled * * Copyright (C) 2006-2007 Enea AB * Copyright (C) 2007 Ulrik Svensson * Copyright (C) 2007 Joel Rosdahl * * This program is made available under the GNU GPL version 2, with a special * exception for linking with JUnit. See the accompanying file LICENSE.txt for * details. * * 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. */ package com.enea.jcarder.util.logging; import java.util.ArrayList; import java.util.Collection; /** * A simple logging framework. * * We use our own simple Logging framework for several reasons: * - To avoid interfering with logging from the user application. Even if we * were using Log4J instead of java.util.Logging.*, JCarder might interfere with * for example Log4J system properties. * - The default java.util.logging.LogManager is reset by a shutdown hook and * there is no fixed order in which the shutdown hooks are executed. * - Minimizing the usage of the Java standard library improves performance and * minimizes the risk of deadlock if the standard library is instrumented by * JCarder. */ public final class Logger { public static enum Level { SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST; /** * Parse a string and return the corresponding log level. * * @param string The string to parse. * @return */ public static Level fromString(String string) { for (Level level : values()) { if (string.equalsIgnoreCase(level.toString())) { return level; } } return null; } public static String getEnumeration() { StringBuffer sb = new StringBuffer(); boolean first = true; for (Level level : values()) { if (first) { first = false; } else { sb.append(", "); } sb.append(level.toString()); } return sb.toString(); } } final Collection<Handler> mHandlers; final Level mLevel; /** * Constructor setting default value of log level. * * The default is to log everything, i.e., log level FINEST. * * @param handlers Log handlers. null means no handlers. */ public Logger(Collection<Handler> handlers) { this(handlers, Level.FINEST); } /** * Constructor. * * @param handlers Log handlers. null means no handlers. * @param logLevel Log level. */ public Logger(Collection<Handler> handlers, Level logLevel) { mLevel = logLevel; mHandlers = new ArrayList<Handler>(); if (handlers != null) { // Create a copy of the provided collection instead of sharing // it, in order to make sure that mHandlers is immutable and // thread safe. mHandlers.addAll(handlers); } } /** * Check whether a message with a certain level would be logged. * * @param level The level. * @return True if the message would be logged, otherwise false. */ public boolean isLoggable(Level level) { return level.compareTo(mLevel) <= 0; } /** * Log a message with level SEVERE. * * @param message The message. */ public void severe(String message) { publishLog(Level.SEVERE, message); } /** * Log a message with level WARNING. * * @param message The message. */ public void warning(String message) { publishLog(Level.WARNING, message); } /** * Log a message with level INFO. * * @param message The message. */ public void info(String message) { publishLog(Level.INFO, message); } /** * Log a message with level CONFIG. * * @param message The message. */ public void config(String message) { publishLog(Level.CONFIG, message); } /** * Log a message with level FINE. * * @param message The message. */ public void fine(String message) { publishLog(Level.FINE, message); } /** * Log a message with level FINER. * * @param message The message. */ public void finer(String message) { publishLog(Level.FINER, message); } /** * Log a message with level FINEST. * * @param message The message. */ public void finest(String message) { publishLog(Level.FINEST, message); } private void publishLog(Level level, String message) { if (isLoggable(level)) { for (Handler handler : mHandlers) { handler.publish(level, message); } } } }