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 41 55 56 60 public class SetProperty<T,R> extends BinaryFunctor<T,R,R> { 61 62 static final long serialVersionUID = 5305970242256716550L; 63 64 private Class <R> _propClass; 66 67 private String _propName; 69 70 private String _methName; 72 73 private transient Method _meth; 75 76 82 public SetProperty(Class <T> argType, String propName, Class <R> propType) { 83 if (propName == null || propName.length() == 0) { 84 throw new IllegalArgumentException ("Must supply property name"); 85 } 86 if (propType == null) { 87 throw new IllegalArgumentException ("Must supply property type"); 88 } 89 90 if (propName.startsWith("set")) { 91 _methName = propName; 92 _propName = propName.substring(3); 93 } 94 else { 95 _propName = propName; 96 _methName = "set" + propName; 97 } 98 99 _propClass = propType; 100 101 try { 102 Class [] car = new Class []{propType}; 103 _meth = argType.getMethod(_methName, car); 104 } 105 catch (NoSuchMethodException x) { 106 String msg = "class {0} does not have property \"{1}\" of type {2}"; 107 Object [] args = new Object []{ argType.getName(), propName, propType.getName() }; 108 IllegalArgumentException iax = 109 new IllegalArgumentException (MessageFormat.format(msg,args)); 110 iax.initCause(x); 111 throw iax; 112 } 113 } 114 115 116 119 public String getPropertyName() { 120 return _propName; 121 } 122 123 125 135 public R fn(T arg, R val) { 136 try { 137 R ret = (R) getMethod(arg).invoke(arg, new Object [] {val}); 141 return ret; 142 } 143 catch (ClassCastException x) { 144 String msg = "{0}.{1} returns type {2}"; 145 Method m = getMethod(arg); 146 Object [] args = new Object []{ arg.getClass().getName(), m.getName(), 147 m.getReturnType().getName() }; 148 throw new EvaluationException(MessageFormat.format(msg,args), x); 149 } 150 catch (IllegalAccessException x) { 151 String msg = "{0}.{1} is not accessible"; 152 Object [] args = new Object []{ arg.getClass().getName(), getMethod(arg).getName()}; 153 throw new EvaluationException(MessageFormat.format(msg,args), x); 154 } 155 catch (InvocationTargetException x) { 156 String msg = "{0}.{1}({2}) failed : "+x.getMessage(); 157 Object [] args = new Object []{ arg.getClass().getName(), getMethod(arg).getName(), val}; 158 throw new EvaluationException(MessageFormat.format(msg,args), x); 159 } 160 } 161 162 private Method getMethod(T arg) { 163 if (_meth == null) { 164 try { 165 Class [] car = new Class []{_propClass}; _meth = arg.getClass().getMethod(_methName, car); 167 } 168 catch (NoSuchMethodException x) { 169 throw new EvaluationException(x);} 170 } 171 172 return _meth; 173 } 174 175 179 public void accept(net.sf.jga.fn.Visitor v) { 180 if (v instanceof SetProperty.Visitor) 181 ((SetProperty.Visitor)v).visit(this); 182 else 183 v.visit(this); 184 } 185 186 188 public String toString() { 189 return "SetProperty("+_methName+")"; 190 } 191 192 194 198 public interface Visitor extends net.sf.jga.fn.Visitor { 199 public void visit(SetProperty host); 200 } 201 } 202 | Popular Tags |