/**
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the latest version of the GNU Lesser General
* Public License as published by the Free Software Foundation;
*
* 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 (LICENSE.txt); if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.jamwiki.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This class provides a wrapper around the {@link java.util.logging.Logger}
* class, allowing additional utility methods to be included such as allowing
* a log message to include a Throwable object. From an implementation
* standpoint it would have been much easier to simply sub-class the Logger
* class, but that class is implemented in such a way to make sub-classes
* exceedingly difficult to create.
*
* @see org.jamwiki.utils.WikiLogFormatter
*/
public class WikiLogger {
private final Logger logger;
// private static FileHandler DEFAULT_LOG_HANDLER = null;
private static Level DEFAULT_LOG_LEVEL = null;
/** Log configuration property file. */
public final static String LOG_PROPERTIES_FILENAME = "logging.properties";
public final static String DEFAULT_LOG_FILENAME = "jamwiki.log.0";
static {
initializeLogParams();
}
/**
*
*/
private WikiLogger(Logger logger) {
this.logger = logger;
}
/**
* Return the current ClassLoader. First try to get the current thread's
* ClassLoader, and if that fails return the ClassLoader that loaded this
* class instance.
*
* @return An instance of the current ClassLoader.
*/
private static ClassLoader getClassLoader() {
// NOTE: This method duplicates the Utilities.getClassLoader method, but
// is copied here to prevent this class from having any dependencies on
// other JAMWiki classes.
ClassLoader loader = null;
try {
loader = Thread.currentThread().getContextClassLoader();
} catch (Exception e) {
// ignore, try the current class's ClassLoader
}
if (loader == null) {
loader = WikiLogger.class.getClassLoader();
}
return loader;
}
/**
*
*/
public static String getDefaultLogFile() {
System.out.println(System.getProperties());
String logFile = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + DEFAULT_LOG_FILENAME;
return logFile;
}
/**
*
*/
public static String getLogConfigFile() {
String logConfig = System.getProperty("file.separator") + "WEB-INF" + System.getProperty("file.separator") + "classes" + System.getProperty("file.separator") + LOG_PROPERTIES_FILENAME;
return logConfig;
}
/**
* Retrieve a named <code>WikiLogger</code> object.
*
* @param name The name of the log object to retrieve or create.
* @return A logger instance for the given name.
*/
public static WikiLogger getLogger(String name) {
Logger logger = Logger.getLogger(name);
// if (WikiLogger.DEFAULT_LOG_HANDLER != null) {
// logger.addHandler(WikiLogger.DEFAULT_LOG_HANDLER);
// logger.setLevel(DEFAULT_LOG_LEVEL);
// }
return new WikiLogger(logger);
}
/**
*
*/
private static void initializeLogParams() {
FileInputStream stream = null;
try {
File propertyFile = WikiLogger.loadProperties();
stream = new FileInputStream(propertyFile);
Properties properties = new Properties();
properties.load(stream);
String pattern = properties.getProperty("org.jamwiki.pattern");
int limit = Integer.valueOf(properties.getProperty("org.jamwiki.limit"));
int count = Integer.valueOf(properties.getProperty("org.jamwiki.count"));
boolean append = Boolean.valueOf(properties.getProperty("org.jamwiki.append"));
String datePattern = properties.getProperty("org.jamwiki.timestamp");
DEFAULT_LOG_LEVEL = Level.parse(properties.getProperty("org.jamwiki.level"));
// WikiLogger.DEFAULT_LOG_HANDLER = new FileHandler(pattern, limit, count, append);
// DEFAULT_LOG_HANDLER.setFormatter(new WikiLogFormatter(datePattern));
// DEFAULT_LOG_HANDLER.setLevel(DEFAULT_LOG_LEVEL);
// test the logger to verify permissions are OK
Logger logger = Logger.getLogger(WikiLogger.class.getName());
// logger.addHandler(WikiLogger.DEFAULT_LOG_HANDLER);
logger.setLevel(DEFAULT_LOG_LEVEL);
logger.config("JAMWiki log initialized from " + propertyFile.getPath() + " with pattern " + pattern);
} catch (Exception e) {
System.out.println("WARNING: Unable to load custom JAMWiki logging configuration, using system default " + e.getMessage());
// WikiLogger.DEFAULT_LOG_HANDLER = null;
} finally {
if (stream != null) {
try {
stream.close();
} catch (Exception ex) {}
}
}
}
/**
*
*/
private static File loadProperties() throws FileNotFoundException {
ClassLoader loader = WikiLogger.getClassLoader();
URL url = loader.getResource(LOG_PROPERTIES_FILENAME);
if (url == null) {
throw new FileNotFoundException("Log initialization file " + LOG_PROPERTIES_FILENAME + " could not be found");
}
String fileName = url.getFile();
try {
fileName = URLDecoder.decode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
// this should never happen
throw new IllegalStateException("Unsupporting encoding UTF-8");
}
File propertyFile = new File(fileName);
if (!propertyFile.exists()) {
throw new FileNotFoundException("Log initialization file " + LOG_PROPERTIES_FILENAME + " could not be found");
}
return propertyFile;
}
/**
* Log a message at the {@link java.util.logging.Level#CONFIG} level,
* provided that the current log level is {@link java.util.logging.Level#CONFIG}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void config(String msg) {
this.logger.config(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#CONFIG}
* level, provided that the current log level is {@link java.util.logging.Level#CONFIG}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void config(String msg, Throwable thrown) {
this.logger.log(Level.CONFIG, msg, thrown);
}
/**
* Log a message at the {@link java.util.logging.Level#FINE} level,
* provided that the current log level is {@link java.util.logging.Level#FINE}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void fine(String msg) {
this.logger.fine(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#FINE}
* level, provided that the current log level is {@link java.util.logging.Level#FINE}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void fine(String msg, Throwable thrown) {
this.logger.log(Level.FINE, msg, thrown);
}
/**
* Log a message at the {@link java.util.logging.Level#FINER} level,
* provided that the current log level is {@link java.util.logging.Level#FINER}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void finer(String msg) {
this.logger.finer(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#FINER}
* level, provided that the current log level is {@link java.util.logging.Level#FINER}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void finer(String msg, Throwable thrown) {
this.logger.log(Level.FINER, msg, thrown);
}
/**
* Log a message at the {@link java.util.logging.Level#FINEST} level,
* provided that the current log level is {@link java.util.logging.Level#FINEST}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void finest(String msg) {
this.logger.finest(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#FINEST}
* level, provided that the current log level is {@link java.util.logging.Level#FINEST}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void finest(String msg, Throwable thrown) {
this.logger.log(Level.FINEST, msg, thrown);
}
/**
* Log a message at the {@link java.util.logging.Level#INFO} level,
* provided that the current log level is {@link java.util.logging.Level#INFO}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void info(String msg) {
this.logger.info(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#INFO}
* level, provided that the current log level is {@link java.util.logging.Level#INFO}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void info(String msg, Throwable thrown) {
this.logger.log(Level.INFO, msg, thrown);
}
/**
* Return <code>true</code> if a log message of level CONFIG can be logged.
*/
public boolean isConfigEnabled() {
return this.logger.isLoggable(Level.CONFIG);
}
/**
* Return <code>true</code> if a log message of level FINE can be logged.
*/
public boolean isFineEnabled() {
return this.logger.isLoggable(Level.FINE);
}
/**
* Return <code>true</code> if a log message of level FINER can be logged.
*/
public boolean isFinerEnabled() {
return this.logger.isLoggable(Level.FINER);
}
/**
* Return <code>true</code> if a log message of level FINEST can be logged.
*/
public boolean isFinestEnabled() {
return this.logger.isLoggable(Level.FINEST);
}
/**
* Return <code>true</code> if a log message of level INFO can be logged.
*/
public boolean isInfoEnabled() {
return this.logger.isLoggable(Level.INFO);
}
/**
* Log a message at the {@link java.util.logging.Level#SEVERE} level,
* provided that the current log level is {@link java.util.logging.Level#SEVERE}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void severe(String msg) {
this.logger.severe(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#SEVERE}
* level, provided that the current log level is {@link java.util.logging.Level#SEVERE}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void severe(String msg, Throwable thrown) {
this.logger.log(Level.SEVERE, msg, thrown);
}
/**
* Log a message at the {@link java.util.logging.Level#WARNING} level,
* provided that the current log level is {@link java.util.logging.Level#WARNING}
* or greater.
*
* @param msg The message to be written to the log.
*/
public void warning(String msg) {
this.logger.warning(msg);
}
/**
* Log a message and an exception at the {@link java.util.logging.Level#WARNING}
* level, provided that the current log level is {@link java.util.logging.Level#WARNING}
* or greater.
*
* @param msg The message to be written to the log.
* @param thrown An exception to be written to the log.
*/
public void warning(String msg, Throwable thrown) {
this.logger.log(Level.WARNING, msg, thrown);
}
}