1 16 17 package org.springframework.util; 18 19 import java.lang.reflect.InvocationTargetException ; 20 import java.lang.reflect.Method ; 21 import java.lang.reflect.Modifier ; 22 23 43 public class MethodInvoker { 44 45 private Class targetClass; 46 47 private Object targetObject; 48 49 private String targetMethod; 50 51 private String staticMethod; 52 53 private Object [] arguments; 54 55 56 private Method methodObject; 57 58 59 66 public void setTargetClass(Class targetClass) { 67 this.targetClass = targetClass; 68 } 69 70 73 public Class getTargetClass() { 74 return targetClass; 75 } 76 77 84 public void setTargetObject(Object targetObject) { 85 this.targetObject = targetObject; 86 if (targetObject != null) { 87 this.targetClass = targetObject.getClass(); 88 } 89 } 90 91 94 public Object getTargetObject() { 95 return targetObject; 96 } 97 98 105 public void setTargetMethod(String targetMethod) { 106 this.targetMethod = targetMethod; 107 } 108 109 112 public String getTargetMethod() { 113 return targetMethod; 114 } 115 116 123 public void setStaticMethod(String staticMethod) { 124 this.staticMethod = staticMethod; 125 } 126 127 131 public void setArguments(Object [] arguments) { 132 this.arguments = arguments; 133 } 134 135 138 public Object [] getArguments() { 139 return arguments; 140 } 141 142 143 149 public void prepare() throws ClassNotFoundException , NoSuchMethodException { 150 if (this.staticMethod != null) { 151 int lastDotIndex = this.staticMethod.lastIndexOf('.'); 152 if (lastDotIndex == -1 || lastDotIndex == this.staticMethod.length()) { 153 throw new IllegalArgumentException ( 154 "staticMethod must be a fully qualified class plus method name: " + 155 "e.g. 'example.MyExampleClass.myExampleMethod'"); 156 } 157 String className = this.staticMethod.substring(0, lastDotIndex); 158 String methodName = this.staticMethod.substring(lastDotIndex + 1); 159 this.targetClass = resolveClassName(className); 160 this.targetMethod = methodName; 161 } 162 163 if (this.targetClass == null) { 164 throw new IllegalArgumentException ("Either targetClass or targetObject is required"); 165 } 166 if (this.targetMethod == null) { 167 throw new IllegalArgumentException ("targetMethod is required"); 168 } 169 if (this.arguments == null) { 170 this.arguments = new Object [0]; 171 } 172 173 Class [] argTypes = new Class [this.arguments.length]; 174 for (int i = 0; i < this.arguments.length; ++i) { 175 argTypes[i] = (this.arguments[i] != null ? this.arguments[i].getClass() : Object .class); 176 } 177 178 try { 180 this.methodObject = this.targetClass.getMethod(this.targetMethod, argTypes); 181 } 182 catch (NoSuchMethodException ex) { 183 this.methodObject = findMatchingMethod(); 185 if (this.methodObject == null) { 186 throw ex; 187 } 188 } 189 190 if (this.targetObject == null && !Modifier.isStatic(this.methodObject.getModifiers())) { 191 throw new IllegalArgumentException ("Target method must not be non-static without a target"); 192 } 193 } 194 195 203 protected Class resolveClassName(String className) throws ClassNotFoundException { 204 return ClassUtils.forName(className); 205 } 206 207 214 protected Method findMatchingMethod() { 215 String targetMethod = getTargetMethod(); 216 Object [] arguments = getArguments(); 217 int argCount = arguments.length; 218 219 Method [] candidates = getTargetClass().getMethods(); 220 Method matchingMethod = null; 221 int numberOfMatchingMethods = 0; 222 223 for (int i = 0; i < candidates.length; i++) { 224 Method candidate = candidates[i]; 225 Class [] paramTypes = candidate.getParameterTypes(); 226 int paramCount = paramTypes.length; 227 if (candidate.getName().equals(targetMethod) && paramCount == argCount) { 228 boolean match = true; 229 for (int j = 0; j < paramCount && match; j++) { 230 match = match && ClassUtils.isAssignableValue(paramTypes[j], arguments[j]); 231 } 232 if (match) { 233 matchingMethod = candidate; 234 numberOfMatchingMethods++; 235 } 236 } 237 } 238 239 if (numberOfMatchingMethods == 1) { 241 return matchingMethod; 242 } 243 else { 244 return null; 245 } 246 } 247 248 254 public Method getPreparedMethod() { 255 return this.methodObject; 256 } 257 258 265 public Object invoke() throws InvocationTargetException , IllegalAccessException { 266 if (this.methodObject == null) { 267 throw new IllegalStateException ("prepare() must be called prior to invoke() on MethodInvoker"); 268 } 269 return this.methodObject.invoke(this.targetObject, this.arguments); 271 } 272 273 } 274 | Popular Tags |