TestLoggerFactory.java
package uk.org.lidalia.slf4jtest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.ILoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import uk.org.lidalia.lang.LazyValue;
import uk.org.lidalia.lang.ThreadLocal;
import uk.org.lidalia.slf4jext.Level;
import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Preconditions.checkNotNull;
public final class TestLoggerFactory implements ILoggerFactory {
private static final LazyValue<TestLoggerFactory> INSTANCE = new LazyValue<>(new TestLoggerFactoryMaker());
public static TestLoggerFactory getInstance() {
return INSTANCE.call();
}
public static TestLogger getTestLogger(final Class<?> aClass) {
return getInstance().getLogger(aClass);
}
public static TestLogger getTestLogger(final String name) {
return getInstance().getLogger(name);
}
public static Map<String, TestLogger> getAllTestLoggers() {
return getInstance().getAllLoggers();
}
public static void clear() {
getInstance().clearLoggers();
}
public static void clearAll() {
getInstance().clearAllLoggers();
}
static void reset() {
getInstance().doReset();
}
public static List<LoggingEvent> getLoggingEvents() {
return getInstance().getLoggingEventsFromLoggers();
}
public static List<LoggingEvent> getAllLoggingEvents() {
return getInstance().getAllLoggingEventsFromLoggers();
}
private final ConcurrentMap<String, TestLogger> loggers = new ConcurrentHashMap<>();
private final List<LoggingEvent> allLoggingEvents = new CopyOnWriteArrayList<>();
private final ThreadLocal<List<LoggingEvent>> loggingEvents =
new ThreadLocal<>(Suppliers.<LoggingEvent>makeEmptyMutableList());
private volatile Level printLevel;
private TestLoggerFactory(final Level printLevel) {
this.printLevel = checkNotNull(printLevel);
}
public Level getPrintLevel() {
return printLevel;
}
public ImmutableMap<String, TestLogger> getAllLoggers() {
return ImmutableMap.copyOf(loggers);
}
public TestLogger getLogger(final Class<?> aClass) {
return getLogger(aClass.getName());
}
public TestLogger getLogger(final String name) {
final TestLogger newLogger = new TestLogger(name, this);
return fromNullable(loggers.putIfAbsent(name, newLogger)).or(newLogger);
}
public void clearLoggers() {
for (final TestLogger testLogger: loggers.values()) {
testLogger.clear();
}
loggingEvents.get().clear();
}
public void clearAllLoggers() {
for (final TestLogger testLogger: loggers.values()) {
testLogger.clearAll();
}
loggingEvents.reset();
allLoggingEvents.clear();
}
void doReset() {
clearAllLoggers();
loggers.clear();
}
public ImmutableList<LoggingEvent> getLoggingEventsFromLoggers() {
return ImmutableList.copyOf(loggingEvents.get());
}
public List<LoggingEvent> getAllLoggingEventsFromLoggers() {
return allLoggingEvents;
}
void addLoggingEvent(final LoggingEvent event) {
loggingEvents.get().add(event);
allLoggingEvents.add(event);
}
public void setPrintLevel(final Level printLevel) {
this.printLevel = checkNotNull(printLevel);
}
@SuppressWarnings("PMD.AccessorClassGeneration")
private static class TestLoggerFactoryMaker implements Callable<TestLoggerFactory> {
@Override
public TestLoggerFactory call() throws IOException {
try {
final String level = new OverridableProperties("slf4jtest").getProperty("print.level", "OFF");
final Level printLevel = Level.valueOf(level);
return new TestLoggerFactory(printLevel);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Invalid level name in property print.level of file slf4jtest.properties " +
"or System property slf4jtest.print.level", e);
}
}
}
}