/**
* Logback: the generic, reliable, fast and flexible logging framework.
*
* Copyright (C) 1999-2006, QOS.ch
*
* 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.
*/
package org.slf4j.impl;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.Util;
import org.slf4j.spi.LoggerFactoryBinder;
import ch.qos.logback.classic.ClassicGlobal;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.selector.ContextJNDISelector;
import ch.qos.logback.classic.selector.ContextSelector;
import ch.qos.logback.classic.selector.DefaultContextSelector;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
import ch.qos.logback.core.util.StatusPrinter;
/**
*
* The binding of {@link LoggerFactory} class with an actual instance of
* {@link ILoggerFactory} is performed using information returned by this class.
*
* @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
*/
public class StaticLoggerBinder implements LoggerFactoryBinder {
/**
* Declare the version of the SLF4J API this implementation is compiled
* against. The value of this field is usually modified with each release.
*/
// to avoid constant folding by the compiler, this field must *not* be final
public static String REQUESTED_API_VERSION = "1.5.6"; // !final
final static String NULL_CS_URL = CoreConstants.CODES_URL + "#null_CS";
/**
* The unique instance of this class.
*/
private static StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
static {
SINGLETON.init();
}
private boolean initialized = false;
private LoggerContext defaultLoggerContext = new LoggerContext();
private ContextSelector contextSelector;
private StaticLoggerBinder() {
defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
}
public static StaticLoggerBinder getSingleton() {
return SINGLETON;
}
/**
* Package access for testing purposes.
*/
static void reset() {
SINGLETON = new StaticLoggerBinder();
SINGLETON.init();
}
/**
* Package access for testing purposes.
*/
void init() {
try {
try {
new ContextInitializer(defaultLoggerContext).autoConfig();
} catch (JoranException je) {
Util.reportFailure("Failed to auto configure default logger context",
je);
}
StatusPrinter.printIfErrorsOccured(defaultLoggerContext);
// See if a special context selector is needed
String contextSelectorStr = OptionHelper
.getSystemProperty(ClassicGlobal.LOGBACK_CONTEXT_SELECTOR);
if (contextSelectorStr == null) {
contextSelector = new DefaultContextSelector(defaultLoggerContext);
} else if (contextSelectorStr.equals("JNDI")) {
// if jndi is specified, let's use the appropriate class
contextSelector = new ContextJNDISelector(defaultLoggerContext);
} else {
contextSelector = dynamicalContextSelector(defaultLoggerContext,
contextSelectorStr);
}
initialized = true;
} catch (Throwable t) {
// we should never get here
Util.reportFailure("Failed to instantiate ["
+ LoggerContext.class.getName() + "]", t);
}
}
static ContextSelector dynamicalContextSelector(
LoggerContext defaultLoggerContext, String contextSelectorStr)
throws ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException {
Class<?> contextSelectorClass = Loader.loadClass(contextSelectorStr);
Constructor cons = contextSelectorClass
.getConstructor(new Class[] { LoggerContext.class });
return (ContextSelector) cons.newInstance(defaultLoggerContext);
}
public ILoggerFactory getLoggerFactory() {
if(!initialized) {
return defaultLoggerContext;
}
if (contextSelector == null) {
throw new IllegalStateException(
"contextSelector cannot be null. See also " + NULL_CS_URL);
}
return contextSelector.getLoggerContext();
}
public String getLoggerFactoryClassStr() {
return contextSelector.getClass().getName();
}
/**
* Return the {@link ContextSelector} instance in use.
*
* @return the ContextSelector instance in use
*/
public ContextSelector getContextSelector() {
return contextSelector;
}
}