/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, version 2 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 General Public License for more details.
*/
package org.pentaho.platform.engine.security;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.engine.security.messages.Messages;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
/**
* Logger that uses AOP to log debugging information.
*
* <p><strong>Do not use this in production! It logs passwords in plain text!</strong></p>
* @author mlowery
*/
public class LoggingInterceptor implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {
public void before(final Method method, final Object[] args, final Object target) throws Throwable {
Log logger = LogFactory.getLog(target.getClass());
if (logger.isDebugEnabled()) {
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_BEGIN_METHOD")); //$NON-NLS-1$
log(method, args, target);
}
}
public void afterReturning(final Object returnValue, final Method method, final Object[] args, final Object target)
throws Throwable {
Log logger = LogFactory.getLog(target.getClass());
if (logger.isDebugEnabled()) {
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_END_METHOD")); //$NON-NLS-1$
log(method, args, target);
logger.debug(Messages.getInstance().getString(
"LoggingInterceptor.DEBUG_RETURN_VALUE", returnValue.getClass().getName(), toString(returnValue))); //$NON-NLS-1$
}
}
public void afterThrowing(final Method method, final Object[] args, final Object target, final Throwable exception) {
Log logger = LogFactory.getLog(target.getClass());
if (logger.isDebugEnabled()) {
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_EXCEPTION_IN_METHOD")); //$NON-NLS-1$
log(method, args, target);
logger.debug(Messages.getInstance().getString(
"LoggingInterceptor.DEBUG_EXCEPTION", exception.getClass().getName(), exception.getMessage())); //$NON-NLS-1$
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_STACK_TRACE"), exception); //$NON-NLS-1$
}
}
private void log(final Method method, final Object[] args, final Object target) {
Log logger = LogFactory.getLog(target.getClass());
if (logger.isDebugEnabled()) {
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_METHOD_NAME", method.getName())); //$NON-NLS-1$
logger.debug(Messages.getInstance().getString(
"LoggingInterceptor.DEBUG_TARGET_OBJECT", target.getClass().getName(), toString(target))); //$NON-NLS-1$
logger.debug(Messages.getInstance().getString("LoggingInterceptor.DEBUG_METHOD_ARGS", arrayToString(args))); //$NON-NLS-1$
}
}
/**
* Returns a string representation of the given object. This is useful when third-party objects do not have
* <code>toString()</code> implementations that meet your needs.
*/
protected String toString(final Object object) {
/**
* This impl uses reflection to print fields and it also skips sensitive fields.
*/
return (new ReflectionToStringBuilder(object) {
@Override
protected boolean accept(final Field f) {
return super.accept(f) && !f.getName().equals("password") && !f.getName().equals("credentials"); //$NON-NLS-1$ //$NON-NLS-2$
}
}).toString();
}
/**
* Returns a string representation of the given array. Instead of overriding this method, try overriding
* <code>toString(object)</code> instead.
*/
protected String arrayToString(final Object[] objects) {
StringBuffer buf = new StringBuffer();
if (null == objects) {
return "null"; //$NON-NLS-1$
} else {
for (int i = 0; i < objects.length; i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
buf.append(toString(objects[i]));
}
return buf.toString();
}
}
}