1 16 package org.springframework.webflow.util; 17 18 import java.lang.reflect.InvocationTargetException ; 19 import java.lang.reflect.Method ; 20 import java.util.Map ; 21 22 import org.springframework.binding.method.ClassMethodKey; 23 import org.springframework.binding.method.InvalidMethodSignatureException; 24 import org.springframework.core.NestedRuntimeException; 25 import org.springframework.util.Assert; 26 import org.springframework.util.CachingMapDecorator; 27 import org.springframework.util.ClassUtils; 28 29 37 public class DispatchMethodInvoker { 38 39 42 private Object target; 43 44 47 private Class [] parameterTypes; 48 49 52 private Map methodCache = new CachingMapDecorator() { 53 public Object create(Object key) { 54 String methodName = (String )key; 55 try { 56 return new ClassMethodKey(target.getClass(), methodName, parameterTypes).getMethod(); 57 } 58 catch (InvalidMethodSignatureException e) { 59 throw new MethodLookupException("Unable to resolve dispatch method with name '" + methodName 60 + "' and signature '" + getSignatureString(methodName) 61 + "'; make sure the method name is correct and such a method is defined on targetClass " 62 + target.getClass().getName(), e); 63 } 64 } 65 }; 66 67 73 public DispatchMethodInvoker(Object target, Class [] parameterTypes) { 74 Assert.notNull(target, "The target of a dispatch method invocation is required"); 75 this.target = target; 76 this.parameterTypes = parameterTypes; 77 } 78 79 82 public Object getTarget() { 83 return target; 84 } 85 86 90 public Class [] getParameterTypes() { 91 return parameterTypes; 92 } 93 94 102 public Object invoke(String methodName, Object [] arguments) throws MethodLookupException, Exception { 103 try { 104 Method dispatchMethod = getDispatchMethod(methodName); 105 return dispatchMethod.invoke(target, arguments); 106 } 107 catch (InvocationTargetException e) { 108 Throwable t = e.getTargetException(); 110 if (t instanceof Exception ) { 111 throw (Exception )e.getTargetException(); 112 } 113 else { 114 throw (Error )e.getTargetException(); 115 } 116 } 117 } 118 119 126 private Method getDispatchMethod(String methodName) throws MethodLookupException { 127 return (Method )methodCache.get(methodName); 128 } 129 130 134 private String getSignatureString(String methodName) { 135 return methodName + "(" + getParameterTypesString() + ");"; 136 } 137 138 142 private String getParameterTypesString() { 143 StringBuffer parameterTypesString = new StringBuffer (); 144 for (int i = 0; i < parameterTypes.length; i++) { 145 parameterTypesString.append(ClassUtils.getShortName(parameterTypes[i])); 146 if (i < parameterTypes.length - 1) { 147 parameterTypesString.append(','); 148 } 149 } 150 return parameterTypesString.toString(); 151 } 152 153 156 public static class MethodLookupException extends NestedRuntimeException { 157 158 163 public MethodLookupException(String msg, Throwable ex) { 164 super(msg, ex); 165 } 166 } 167 } | Popular Tags |