View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.devtools.util;
17  
18  import java.lang.reflect.Method;
19  
20  import org.aopalliance.intercept.MethodInterceptor;
21  import org.aopalliance.intercept.MethodInvocation;
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  /**
27   * This interceptor generates log message before entering and after leaving the method being intercepted.
28   * 
29   * 
30   */
31  public class MethodLoggingInterceptor implements MethodInterceptor {
32      private static final Log LOG = LogFactory.getLog(MethodLoggingInterceptor.class);
33  
34  
35      /**
36       * Surrounds the method invocation with FATAL-level log messages. Using FATAL because I want to make sure that the log messages
37       * will always show up, since the correct way to deactivate method-level logging is to remove (or comment) the bean name from
38       * the KualiTestSpringLogging.xml file.
39       * 
40       * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
41       */
42      public Object invoke(MethodInvocation invocation) throws Throwable {
43          long startTime = System.currentTimeMillis();
44          Object methodResult = null;
45          String invocationLabel = buildInvocationLabel(invocation);
46          try {
47              LOG.fatal("entering " + invocationLabel);
48  
49              methodResult = invocation.proceed();
50          }
51          catch (Exception invocationException) {
52              String exceptionLabel = buildExceptionLabel(invocationException);
53              LOG.fatal("aborting " + invocationLabel + ": throwing " + exceptionLabel);
54  
55              throw invocationException;
56          }
57          LOG.fatal(new StringBuffer("leaving  ").append(invocationLabel).append(" / took ").append(System.currentTimeMillis() - startTime).append(" ms"));
58  
59          return methodResult;
60      }
61  
62      /**
63       * @param invocation MethodInvocation being labeled
64       * @return String used to identify this MethodInvocation
65       */
66      private String buildInvocationLabel(MethodInvocation invocation) {
67          StringBuffer invocationLabel = new StringBuffer();
68  
69          Method method = invocation.getMethod();
70          Class targetClass = invocation.getThis().getClass();
71          Class declaringClass = method.getDeclaringClass();
72  
73          // {targetClass} declaringClass.method
74          if (targetClass != declaringClass) {
75              invocationLabel.append("{");
76              invocationLabel.append(declaringClass.getName());
77              invocationLabel.append("} ");
78          }
79          invocationLabel.append(targetClass.getName() + "." + method.getName());
80  
81  
82          // (paramClass=argValue[,paramClass=argValue...])
83          Class[] paramTypes = method.getParameterTypes();
84          Object[] argValues = invocation.getArguments();
85  
86          invocationLabel.append("(");
87          if (paramTypes != null) {
88              for (int i = 0; i < paramTypes.length; i++) {
89                  if (i > 0) {
90                      invocationLabel.append(",");
91                  }
92  
93                  invocationLabel.append(paramTypes[i].getName());
94                  invocationLabel.append("=");
95  
96                  // differentiate between literal null and object whose toString returns null
97                  if (argValues[i] == null) {
98                      invocationLabel.append("<literal null>");
99                  }
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 }