1 33 package net.sf.jga.fn.property; 34 35 import java.lang.reflect.InvocationTargetException ; 36 import java.lang.reflect.Field ; 37 import java.text.MessageFormat ; 38 import net.sf.jga.fn.BinaryFunctor; 39 import net.sf.jga.fn.EvaluationException; 40 41 54 55 59 public class SetField<T,R> extends BinaryFunctor<T,R,R> { 60 61 static final long serialVersionUID = -5051261348109487737L; 62 63 private Class <R> _fieldType; 65 66 private String _fieldName; 68 69 private transient Field _field; 71 72 77 public SetField(Field field) { 78 this((Class <T>) field.getDeclaringClass(), field, (Class <R>) field.getType()); 79 } 80 81 82 87 public SetField(Class <T> argType, Field field) { 88 this(argType, field, (Class <R>)field.getType()); 89 } 90 91 92 97 public SetField(Class <T> argType, Field field, Class <R> fieldType) { 98 if (field == null) { 99 throw new IllegalArgumentException ("Must supply field"); 100 } 101 102 if (!field.getDeclaringClass().isAssignableFrom(argType)) { 103 throw new IllegalArgumentException (buildNoSuchFieldMessage(field.getName(), argType)); 104 } 105 106 _fieldName = field.getName(); 107 _fieldType = fieldType; 108 _field = checkFieldType(field, fieldType); 109 } 110 111 112 118 public SetField(Class <T> argType, String fieldName, Class <R> fieldType) { 119 if (fieldName == null || fieldName.length() == 0) { 120 throw new IllegalArgumentException ("Must supply field name"); 121 } 122 if (fieldType == null) { 123 throw new IllegalArgumentException ("Must supply field type"); 124 } 125 126 _fieldName = fieldName; 127 _fieldType = fieldType; 128 129 try { 130 _field = checkFieldType(argType.getField(_fieldName), fieldType); 131 } 132 catch (NoSuchFieldException x) { 133 IllegalArgumentException iax = 134 new IllegalArgumentException (buildNoSuchFieldMessage(fieldName, argType)); 135 iax.initCause(x); 136 throw iax; 137 } 138 } 139 140 141 private Field checkFieldType(Field field, Class <R> fieldType) throws IllegalArgumentException { 142 if (!field.getType().isAssignableFrom(fieldType)) { 143 String msg = "Field {0} is of the wrong type: is {1}, expected {2}"; 144 Object [] args = new Object [] { field.getName(), field.getType().getName(), 145 fieldType.getName() }; 146 throw new IllegalArgumentException (MessageFormat.format(msg, args)); 147 } 148 149 return field; 150 } 151 152 153 156 public String getFieldName() { 157 return _fieldName; 158 } 159 160 162 170 public R fn(T arg, R val) { 171 try { 172 getField(arg).set(arg, val); 173 return null; 174 } 175 catch (ClassCastException x) { 176 String msg = "{0}.{1} is of type {2}"; 177 Field f = getField(arg); 178 Object [] args = new Object []{ arg.getClass().getName(), f.getName(), 179 f.getType().getName() }; 180 throw new EvaluationException(MessageFormat.format(msg,args), x); 181 } 182 catch (IllegalAccessException x) { 183 String msg = "{0}.{1} is not accessible"; 184 Object [] args = new Object []{ arg.getClass().getName(), getField(arg).getName()}; 185 throw new EvaluationException(MessageFormat.format(msg,args), x); 186 } 187 } 188 189 private Field getField(T arg) { 190 if (_field == null) { 191 try { 192 _field = arg.getClass().getField(_fieldName); 193 } 194 catch (NoSuchFieldException x) { 195 throw new EvaluationException(x);} 196 } 197 198 return _field; 199 } 200 201 private String buildNoSuchFieldMessage(String fieldname, Class clasz) { 202 String msg = "class {0} does not have field {1}"; 203 Object [] args = new Object []{ clasz.getName(), fieldname }; 204 return MessageFormat.format(msg,args); 205 } 206 207 211 public void accept(net.sf.jga.fn.Visitor v) { 212 if (v instanceof SetField.Visitor) 213 ((SetField.Visitor)v).visit(this); 214 else 215 v.visit(this); 216 } 217 218 220 public String toString() { 221 return "SetField("+_fieldName+")"; 222 } 223 224 226 230 public interface Visitor extends net.sf.jga.fn.Visitor { 231 public void visit(SetField host); 232 } 233 } 234 | Popular Tags |