/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This 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; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.log.impl;
import org.slf4j.Marker;
import org.slf4j.spi.LocationAwareLogger;
import java.lang.reflect.Method;
/**
* This is an utility class allowing to use in runtime either 1.5.x or
* 1.6.x slf4j libraries. As their log method signature differs,
* we use reflection library to invoke it.
*
* @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry Kuleshov</a>
*/
public class DynamicLocationAwareLogger
{
/**
* To keep log method instance
*/
private Method log;
/**
* Message to show if log method invocation has failed for some reasons.
*/
private final static String LOG_METHOD_INVOKE_ERROR_MSG =
"LocationAwareLogger had some issues on method 'log' invocation. Using location unaware methods.\n";
/**
* To trace if new parameter is supported
* 1.5.x slf4j lib does not support
* 1.6.x slf4j lib supports
*/
private boolean parameterSupported = false;
/**
* Logger
*/
private LocationAwareLogger logger;
/**
* Simple constructor with one parameter is used to pull out log {@link Method}
* an determine which version of slf4j library is currently used.
*
* @param logger location aware logger to be wrapped
*/
public DynamicLocationAwareLogger(LocationAwareLogger logger)
{
this.logger = logger;
// here we're going to retrieve 'log' method instance from logger's class
// using java reflection library
// also we're determining number of parameters of 'log' method to know
// what slf4j library version we're dealing with
for (Method m : LocationAwareLogger.class.getDeclaredMethods())
{
if ("log".equals(m.getName()))
{
log = m;
if (log.getParameterTypes().length == 6)
{
parameterSupported = true;
}
break;
}
}
// if no method named 'log' is determined for currently used logger class
// we throw an exception to warn that something is definitely going wrong
if (log == null)
{
throw new UnsupportedOperationException("Currently used logger does not have log method.");
}
}
/**
* Printing method with support for location information.
* Encapsulates slf4j lib log {@link Method} invocation and passing it the correct parameters.
*/
public void log(Marker marker, String fqcn, int level, String message, Throwable t)
{
try
{
if (!parameterSupported)
{
log.invoke(logger, marker, fqcn, level, message, t);
}
else
{
log.invoke(logger, marker, fqcn, level, message, null, t);
}
}
catch (Exception e)
{
switch( level)
{
case LocationAwareLogger.TRACE_INT :
logger.trace(LOG_METHOD_INVOKE_ERROR_MSG + message, t);
break;
case LocationAwareLogger.DEBUG_INT :
logger.debug(LOG_METHOD_INVOKE_ERROR_MSG + message, t);
break;
case LocationAwareLogger.INFO_INT :
logger.info(LOG_METHOD_INVOKE_ERROR_MSG + message, t);
break;
case LocationAwareLogger.WARN_INT :
logger.warn(LOG_METHOD_INVOKE_ERROR_MSG + message, t);
break;
case LocationAwareLogger.ERROR_INT :
logger.error(LOG_METHOD_INVOKE_ERROR_MSG + message, t);
break;
}
}
}
/**
* {@inheritDoc}
*/
public boolean isDebugEnabled()
{
return logger.isDebugEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isErrorEnabled()
{
return logger.isErrorEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isFatalEnabled()
{
return logger.isErrorEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isInfoEnabled()
{
return logger.isInfoEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isTraceEnabled()
{
return logger.isTraceEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isWarnEnabled()
{
return logger.isWarnEnabled();
}
}