001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krad.util.spring;
017
018 import java.lang.reflect.Method;
019
020 import org.aopalliance.intercept.MethodInterceptor;
021 import org.aopalliance.intercept.MethodInvocation;
022 import org.apache.commons.lang.StringUtils;
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.logging.LogFactory;
025
026 /**
027 * This interceptor generates log message before entering and after leaving the method being intercepted.
028 *
029 *
030 */
031 public class MethodLoggingInterceptor implements MethodInterceptor {
032 private static final Log LOG = LogFactory.getLog(MethodLoggingInterceptor.class);
033
034
035 /**
036 * Surrounds the method invocation with FATAL-level log messages. Using FATAL because I want to make sure that the log messages
037 * will always show up, since the correct way to deactivate method-level logging is to remove (or comment) the bean name from
038 * the KualiTestSpringLogging.xml file.
039 *
040 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
041 */
042 public Object invoke(MethodInvocation invocation) throws Throwable {
043 long startTime = System.currentTimeMillis();
044 Object methodResult = null;
045 String invocationLabel = buildInvocationLabel(invocation);
046 try {
047 LOG.fatal("entering " + invocationLabel);
048
049 methodResult = invocation.proceed();
050 }
051 catch (Exception invocationException) {
052 String exceptionLabel = buildExceptionLabel(invocationException);
053 LOG.fatal("aborting " + invocationLabel + ": throwing " + exceptionLabel);
054
055 throw invocationException;
056 }
057 LOG.fatal(new StringBuffer("leaving ").append(invocationLabel).append(" / took ").append(System.currentTimeMillis() - startTime).append(" ms"));
058
059 return methodResult;
060 }
061
062 /**
063 * @param invocation MethodInvocation being labeled
064 * @return String used to identify this MethodInvocation
065 */
066 private String buildInvocationLabel(MethodInvocation invocation) {
067 StringBuffer invocationLabel = new StringBuffer();
068
069 Method method = invocation.getMethod();
070 Class targetClass = invocation.getThis().getClass();
071 Class declaringClass = method.getDeclaringClass();
072
073 // {targetClass} declaringClass.method
074 if (targetClass != declaringClass) {
075 invocationLabel.append("{");
076 invocationLabel.append(declaringClass.getName());
077 invocationLabel.append("} ");
078 }
079 invocationLabel.append(targetClass.getName() + "." + method.getName());
080
081
082 // (paramClass=argValue[,paramClass=argValue...])
083 Class[] paramTypes = method.getParameterTypes();
084 Object[] argValues = invocation.getArguments();
085
086 invocationLabel.append("(");
087 if (paramTypes != null) {
088 for (int i = 0; i < paramTypes.length; i++) {
089 if (i > 0) {
090 invocationLabel.append(",");
091 }
092
093 invocationLabel.append(paramTypes[i].getName());
094 invocationLabel.append("=");
095
096 // differentiate between literal null and object whose toString returns null
097 if (argValues[i] == null) {
098 invocationLabel.append("<literal null>");
099 }
100 else {
101 invocationLabel.append(argValues[i]);
102 }
103 }
104 }
105 invocationLabel.append(")");
106
107 return invocationLabel.toString();
108 }
109
110
111 /**
112 * @param e Exception being labeled
113 * @return String used to identify this Exception
114 */
115 private String buildExceptionLabel(Exception e) {
116 String className = e.getClass().getName();
117
118 String exceptionLabel = StringUtils.substringAfterLast(className, ".");
119 if (StringUtils.isBlank(exceptionLabel)) {
120 exceptionLabel = className;
121 }
122
123 return exceptionLabel;
124 }
125 }