/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.internal.logging; import java.lang.reflect.*; import com.db4o.ext.*; import com.db4o.internal.*; public final class LoggingWrapper<T> implements Logging<T> { private static final Class[] loggerConstructorParameterTypes = new Class[] {LoggingWrapper.class, Level.class}; private final Class<T> _logInterface; final T trace; final T debug; final T info; final T warn; final T error; final T fatal; private T _forward; private T nullImpl; private Level loggingLevel = null; private Constructor<T> _ctorLoggerClass; LoggingWrapper(Class<T> clazz) { _logInterface = clazz; try { String loggingImplBaseName = loggingSupportBaseName() + "_LoggingSupport"+ReflectPlatform.INNER_CLASS_SEPARATOR + loggingQualifiedBaseName(); String loggerClassName = ReflectPlatform.adjustClassName(loggingImplBaseName + "Logger", clazz); String nullImplClassName = ReflectPlatform.adjustClassName(loggingImplBaseName + "Adapter", clazz); Class logerClass = ReflectPlatform.forName(loggerClassName); if (logerClass == null) { throw new IllegalArgumentException("Cannot find logging support for " + ReflectPlatform.simpleName(_logInterface)); } _ctorLoggerClass = logerClass.getConstructor(loggerConstructorParameterTypes); nullImpl = (T) ReflectPlatform.createInstance(nullImplClassName); } catch (SecurityException e) { throw new java.lang.RuntimeException("Error accessing logging support for class " + clazz.getName(), e); } catch (NoSuchMethodException e) { throw new java.lang.RuntimeException("Error accessing logging support for class " + clazz.getName(), e); } trace = createProxy(Logger.TRACE); debug = createProxy(Logger.DEBUG); info = createProxy(Logger.INFO); warn = createProxy(Logger.WARN); error = createProxy(Logger.ERROR); fatal = createProxy(Logger.FATAL); } private String loggingSupportBaseName() { return ReflectPlatform.containerName(_logInterface) + "." + loggingQualifiedBaseName(); } private String loggingQualifiedBaseName() { String simpleName = ""; Class parent = _logInterface; while (parent != null) { if (simpleName.length() > 0) { simpleName = "_" + simpleName; } simpleName = ReflectPlatform.getJavaInterfaceSimpleName(parent) + simpleName; parent = parent.getEnclosingClass(); } return simpleName; } private T createProxy(Level loggingLevel) { try { return ReflectPlatform.newInstance(_ctorLoggerClass, this, loggingLevel); } catch (Db4oException e) { throw new java.lang.RuntimeException("Error creating proxy", e); } } private T selectLevel(Level level, T logger) { if (level.ordinal() < loggingLevel().ordinal()) { return nullImpl; } return logger; } @Override public final T trace() { return selectLevel(Logger.TRACE, trace); } @Override public final T debug() { return selectLevel(Logger.DEBUG, debug); } @Override public final T info() { return selectLevel(Logger.INFO, info); } @Override public final T warn() { return selectLevel(Logger.WARN, warn); } @Override public final T error() { return selectLevel(Logger.ERROR, error); } @Override public final T fatal() { return selectLevel(Logger.FATAL, fatal); } @Override public void loggingLevel(Level loggingLevel) { this.loggingLevel = loggingLevel; } @Override public Level loggingLevel() { return loggingLevel == null ? Logger.loggingLevel : loggingLevel; } @Override public void forward(T forward) { _forward = forward; } @Override public T forward() { return _forward; } public void log(Level loggingLevel, String method, Object[] args) { Logger.rootInterceptor.log(loggingLevel, method, args); } public void exceptionCaughtInForward(String methodName, Object[] args, Throwable exceptionThrown) { Logger.rootInterceptor.log(Logger.WARN, "exceptionCaughtInForward", new Object[]{methodName}); } public void pushCurrentLevel(Level level) { Logger.currentThreadLoggingLevel.set(level); } public void popCurrentLevel() { Logger.currentThreadLoggingLevel.set(null); } }