Author: ravn
Date: Sun Dec 21 19:17:04 2008
New Revision: 1257

Modified:
   
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java

Log:
Now is robust against exceptions in parameter rendering by
keeping a WeakHashMap of those classes which cannot be rendered.




Modified: 
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
==============================================================================
--- 
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
  (original)
+++ 
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
  Sun Dec 21 19:17:04 2008
@@ -15,144 +15,152 @@
  */
 public class JavassistHelper {
 
-  /**
-   * Create a javaassist source snippet which either is empty (for anything
-   * which does not return a value) or a explanatory text around the $_
-   * javaassist return value variable.
-   * 
-   * @param method
-   *          descriptor of method
-   * @return source snippet
-   * @throws NotFoundException
-   */
-  public static String returnValue(CtBehavior method) throws NotFoundException 
{
-
-    String returnValue = "";
-    if (methodReturnsValue(method)) {
-      returnValue = " returns: \" + $_ + \".";
-    }
-    return returnValue;
-  }
-
-  /**
-   * determine if the given method returns a value, and return true if so. 
false
-   * otherwise.
-   * 
-   * @param method
-   * @return
-   * @throws NotFoundException
-   */
-  private static boolean methodReturnsValue(CtBehavior method)
-      throws NotFoundException {
-
-    if (method instanceof CtMethod == false) {
-      return false;
-    }
-
-    CtClass returnType = ((CtMethod) method).getReturnType();
-    String returnTypeName = returnType.getName();
-
-    boolean isVoidMethod = "void".equals(returnTypeName);
-
-    boolean methodReturnsValue = isVoidMethod == false;
-    return methodReturnsValue;
-  }
-
-  /**
-   * Return javaassist source snippet which lists all the parameters and their
-   * values. If available the source names are extracted from the debug
-   * information and used, otherwise just a number is shown.
-   * 
-   * @param method
-   * @return
-   * @throws NotFoundException
-   */
-  public static String getSignature(CtBehavior method) throws 
NotFoundException {
-
-    CtClass parameterTypes[] = method.getParameterTypes();
-
-    CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();
-
-    LocalVariableAttribute locals = null;
-
-    if (codeAttribute != null) {
-      AttributeInfo attribute;
-      attribute = codeAttribute.getAttribute("LocalVariableTable");
-      locals = (LocalVariableAttribute) attribute;
-    }
-
-    String methodName = method.getName();
-
-    StringBuffer sb = new StringBuffer(methodName + "(\" ");
-    for (int i = 0; i < parameterTypes.length; i++) {
-      if (i > 0) {
-        // add a comma and a space between printed values
-        sb.append(" + \", \" ");
-      }
-
-      CtClass parameterType = parameterTypes[i];
-      boolean isArray = parameterType.isArray();
-      CtClass arrayType = parameterType.getComponentType();
-      if (isArray) {
-        while (arrayType.isArray()) {
-          arrayType = arrayType.getComponentType();
-        }
-      }
-
-      sb.append(" + \"");
-      sb.append(parameterNameFor(method, locals, i));
-      sb.append("\" + \"=");
-
-      // use Arrays.asList() to render array of objects.
-      if (isArray && !arrayType.isPrimitive()) {
-        sb.append("\"+ java.util.Arrays.asList($" + (i + 1) + ")");
-      } else {
-        sb.append("\"+ $" + (i + 1));
-      }
-    }
-    sb.append("+\")");
-
-    String signature = sb.toString();
-    return signature;
-  }
-
-  /**
-   * Determine the name of parameter with index i in the given method. Use the
-   * locals attributes about local variables from the classfile. Note: This is
-   * still work in progress.
-   * 
-   * @param method
-   * @param locals
-   * @param i
-   * @return the name of the parameter if available or a number if not.
-   */
-  static String parameterNameFor(CtBehavior method,
-      LocalVariableAttribute locals, int i) {
-
-    if (locals == null) {
-      return Integer.toString(i + 1);
-    }
-
-    int modifiers = method.getModifiers();
-
-    int j = i;
-
-    if (Modifier.isSynchronized(modifiers)) {
-      // skip object to synchronize upon.
-      j++;
-      // System.err.println("Synchronized");
-    }
-    if (Modifier.isStatic(modifiers) == false) {
-      // skip "this"
-      j++;
-      // System.err.println("Instance");
-    }
-    String variableName = locals.variableName(j);
-//    if (variableName.equals("this")) {
-//      System.err.println("'this' returned as a parameter name for "
-//          + method.getName() + " index " + j
-//          + ", names are probably shifted. Please submit source for class in 
slf4j bugreport");
-//    }
-    return variableName;
-  }
+       /**
+        * Create a javaassist source snippet which either is empty (for 
anything
+        * which does not return a value) or a explanatory text around the $_
+        * javaassist return value variable.
+        * 
+        * @param method
+        *            descriptor of method
+        * @return source snippet
+        * @throws NotFoundException
+        */
+       public static String returnValue(CtBehavior method)
+                       throws NotFoundException {
+
+               String returnValue = "";
+               if (methodReturnsValue(method)) {
+                       returnValue = " returns: \" + $_ + \".";
+               }
+               return returnValue;
+       }
+
+       /**
+        * determine if the given method returns a value, and return true if so.
+        * false otherwise.
+        * 
+        * @param method
+        * @return
+        * @throws NotFoundException
+        */
+       private static boolean methodReturnsValue(CtBehavior method)
+                       throws NotFoundException {
+
+               if (method instanceof CtMethod == false) {
+                       return false;
+               }
+
+               CtClass returnType = ((CtMethod) method).getReturnType();
+               String returnTypeName = returnType.getName();
+
+               boolean isVoidMethod = "void".equals(returnTypeName);
+
+               boolean methodReturnsValue = isVoidMethod == false;
+               return methodReturnsValue;
+       }
+
+       /**
+        * Return javaassist source snippet which lists all the parameters and 
their
+        * values. If available the source names are extracted from the debug
+        * information and used, otherwise just a number is shown.
+        * 
+        * @param method
+        * @return
+        * @throws NotFoundException
+        */
+       public static String getSignature(CtBehavior method)
+                       throws NotFoundException {
+
+               CtClass parameterTypes[] = method.getParameterTypes();
+
+               CodeAttribute codeAttribute = 
method.getMethodInfo().getCodeAttribute();
+
+               LocalVariableAttribute locals = null;
+
+               if (codeAttribute != null) {
+                       AttributeInfo attribute;
+                       attribute = 
codeAttribute.getAttribute("LocalVariableTable");
+                       locals = (LocalVariableAttribute) attribute;
+               }
+
+               String methodName = method.getName();
+
+               StringBuffer sb = new StringBuffer(methodName + "(\" ");
+               for (int i = 0; i < parameterTypes.length; i++) {
+                       if (i > 0) {
+                               // add a comma and a space between printed 
values
+                               sb.append(" + \", \" ");
+                       }
+
+                       CtClass parameterType = parameterTypes[i];
+                       boolean isArray = parameterType.isArray();
+                       CtClass arrayType = parameterType.getComponentType();
+                       if (isArray) {
+                               while (arrayType.isArray()) {
+                                       arrayType = 
arrayType.getComponentType();
+                               }
+                       }
+
+                       sb.append(" + \"");
+                       try {
+                               sb.append(parameterNameFor(method, locals, i));
+                       } catch (Exception e) {
+                               sb.append("" + (i + 1));
+                       }
+                       sb.append("\" + \"=");
+
+                       if (parameterType.isPrimitive()) {
+                               // let the compiler handle primitive -> string
+                               sb.append("\"+ $" + (i + 1));
+                       } else {
+                               String s = 
"org.slf4j.instrumentation.ToStringHelper.render";
+                               sb.append("\"+ " + s + "($" + (i + 1) + ")");
+                       }
+               }
+               sb.append("+\")");
+
+               String signature = sb.toString();
+               return signature;
+       }
+
+       /**
+        * Determine the name of parameter with index i in the given method. 
Use the
+        * locals attributes about local variables from the classfile. Note: 
This is
+        * still work in progress.
+        * 
+        * @param method
+        * @param locals
+        * @param i
+        * @return the name of the parameter if available or a number if not.
+        */
+       static String parameterNameFor(CtBehavior method,
+                       LocalVariableAttribute locals, int i) {
+
+               if (locals == null) {
+                       return Integer.toString(i + 1);
+               }
+
+               int modifiers = method.getModifiers();
+
+               int j = i;
+
+               if (Modifier.isSynchronized(modifiers)) {
+                       // skip object to synchronize upon.
+                       j++;
+                       // System.err.println("Synchronized");
+               }
+               if (Modifier.isStatic(modifiers) == false) {
+                       // skip "this"
+                       j++;
+                       // System.err.println("Instance");
+               }
+               String variableName = locals.variableName(j);
+               // if (variableName.equals("this")) {
+               // System.err.println("'this' returned as a parameter name for "
+               // + method.getName() + " index " + j
+               // +
+               // ", names are probably shifted. Please submit source for 
class in slf4j bugreport");
+               // }
+               return variableName;
+       }
 }
_______________________________________________
dev mailing list
dev@slf4j.org
http://www.slf4j.org/mailman/listinfo/dev

Reply via email to