1 33 package net.sf.jga.fn.property; 34 35 import java.lang.reflect.InvocationTargetException ; 36 import java.lang.reflect.Method ; 37 import java.text.MessageFormat ; 38 import net.sf.jga.fn.BinaryFunctor; 39 import net.sf.jga.fn.EvaluationException; 40 import net.sf.jga.fn.UnaryFunctor; 41 import net.sf.jga.fn.adaptor.ChainBinary; 42 import net.sf.jga.fn.adaptor.ChainUnary; 43 import net.sf.jga.util.ArrayUtils; 44 45 59 60 public class InvokeMethod<T,R> extends BinaryFunctor<T,Object [],R> { 61 62 static final long serialVersionUID = -4632096384509133504L; 63 64 private Class <T> _objclass; 66 67 private String _methName; 69 70 private Class [] _argtypes; 72 73 private transient Method _meth; 75 76 82 public InvokeMethod(Class <T> objClass, Method method) { 83 if (method == null) { 84 String msg = "Must supply method"; 85 throw new IllegalArgumentException (msg); 86 } 87 88 if (objClass == null) { 89 String msg = "Must supply object class"; 90 throw new IllegalArgumentException (msg); 91 } 92 93 if (!method.getDeclaringClass().isAssignableFrom(objClass)) { 94 String msg = "Method {0} not defined for class {1}"; 95 Object [] args = { method.getName(), objClass.getName() }; 96 throw new IllegalArgumentException (MessageFormat.format(msg, args)); 97 } 98 99 _objclass = objClass; 100 _meth = method; 101 _methName = method.getName(); 102 _argtypes = method.getParameterTypes(); 103 } 104 105 118 public InvokeMethod(Class <T> objClass, String methName, Class argtype) { 119 this(objClass, methName, new Class []{argtype}); 120 } 121 122 128 public InvokeMethod(Class <T> objClass, String methName, Class ... argtypes) { 129 if (methName == null || methName.length() == 0) { 130 String msg = "Must supply method name"; 131 throw new IllegalArgumentException (msg); 132 } 133 134 if (objClass == null) { 135 String msg = "Must supply object class"; 136 throw new IllegalArgumentException (msg); 137 } 138 139 _methName = methName; 140 _objclass = objClass; 141 _argtypes = argtypes; 142 143 try { 144 _meth = _objclass.getMethod(_methName, _argtypes); 145 } 146 catch (NoSuchMethodException x) { 147 String msg = "No method {0} for class {1} that takes an argument(s) of type {2}"; 148 Object [] args = 149 new Object []{_methName, _objclass.getName(), ArrayUtils.toString(_argtypes) }; 150 IllegalArgumentException iax = 151 new IllegalArgumentException (MessageFormat.format(msg,args)); 152 iax.initCause(x); 153 throw iax; 154 } 155 } 156 157 160 public Class <T> getObjectType() { 162 return _objclass; 163 } 164 165 168 public String getMethodName() { 169 return _methName; 170 } 171 172 173 176 public Class <R> getReturnType() { 177 return (Class <R>) _meth.getReturnType(); 178 } 179 180 181 184 public synchronized Method getMethod() throws NoSuchMethodException { 185 if (_meth == null) 186 _meth = _objclass.getMethod(_methName, _argtypes); 187 188 return _meth; 189 } 190 191 192 194 public R fn(T obj, Object [] args) { 195 try { 196 200 201 return (R) getMethod().invoke(obj, args); 202 } 203 catch (NoSuchMethodException x) { 204 String msg = "No method {0} for class {1} that takes an argument(s) of type {2}"; 205 Object [] msgargs = 206 new Object []{_methName, _objclass.getName(), ArrayUtils.toString(_argtypes) }; 207 throw new EvaluationException(MessageFormat.format(msg,msgargs), x); 208 } 209 catch (ClassCastException x) { 210 String msg = "ClassCastException: " +_objclass +"." +_methName 211 +"("+ArrayUtils.toString(args)+")"; 212 throw new EvaluationException(msg, x); 213 } 214 catch (IllegalAccessException x) { 215 String msg = _objclass +"." +_methName +" is not accessible"; 216 throw new EvaluationException(msg, x); 217 } 218 catch (InvocationTargetException x) { 219 String xmsg = x.getMessage(); 220 String msg = "InvocationException: " +_objclass +"." +_methName 221 +"("+ArrayUtils.toString(args)+")"+(xmsg != null ? (":"+xmsg) : ""); 222 throw new EvaluationException(msg, x); 223 } 224 } 225 226 230 public void accept(net.sf.jga.fn.Visitor v) { 231 if (v instanceof InvokeMethod.Visitor) 232 ((InvokeMethod.Visitor)v).visit(this); 233 else 234 v.visit(this); 235 } 236 237 239 public String toString() { 240 return "InvokeMethod("+_meth+")"; 241 } 242 243 245 249 public interface Visitor extends net.sf.jga.fn.Visitor { 250 public void visit(InvokeMethod host); 251 } 252 } 253 | Popular Tags |