1 16 17 package org.apache.commons.jexl.util.introspection; 18 19 import org.apache.commons.jexl.util.ArrayIterator; 20 import org.apache.commons.jexl.util.EnumerationIterator; 21 import org.apache.commons.jexl.util.AbstractExecutor; 22 import org.apache.commons.jexl.util.GetExecutor; 23 import org.apache.commons.jexl.util.BooleanPropertyExecutor; 24 import org.apache.commons.jexl.util.PropertyExecutor; 25 import org.apache.commons.logging.Log; 26 27 import java.lang.reflect.Method ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.lang.reflect.Field ; 30 import java.util.Iterator ; 31 import java.util.Collection ; 32 import java.util.Map ; 33 import java.util.Enumeration ; 34 import java.util.ArrayList ; 35 36 44 public class UberspectImpl implements Uberspect, UberspectLoggable { 45 46 private static final int PROPERTY_START_INDEX = 3; 47 48 51 private Log rlog; 52 53 56 private static Introspector introspector; 57 58 64 public void init() throws Exception { 65 } 66 67 72 public void setRuntimeLogger(Log runtimeLogger) { 73 rlog = runtimeLogger; 74 introspector = new Introspector(rlog); 75 } 76 77 80 public Iterator getIterator(Object obj, Info i) throws Exception { 81 if (obj.getClass().isArray()) { 82 return new ArrayIterator(obj); 83 } else if (obj instanceof Collection ) { 84 return ((Collection ) obj).iterator(); 85 } else if (obj instanceof Map ) { 86 return ((Map ) obj).values().iterator(); 87 } else if (obj instanceof Iterator) { 88 rlog.warn("Warning! The iterative " + " is an Iterator in the #foreach() loop at [" + i.getLine() + "," 89 + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable," 90 + " if used in more than once, this may lead to" + " unexpected results."); 91 92 return ((Iterator) obj); 93 } else if (obj instanceof Enumeration ) { 94 rlog.warn("Warning! The iterative " + " is an Enumeration in the #foreach() loop at [" + i.getLine() + "," 95 + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable," 96 + " if used in more than once, this may lead to" + " unexpected results."); 97 98 return new EnumerationIterator((Enumeration ) obj); 99 } 100 101 102 rlog.warn("Could not determine type of iterator in " + "#foreach loop " + " at [" + i.getLine() + "," 103 + i.getColumn() + "]" + " in template " + i.getTemplateName()); 104 105 return null; 106 } 107 108 111 public VelMethod getMethod(Object obj, String methodName, Object [] args, Info i) throws Exception { 112 if (obj == null) { 113 return null; 114 } 115 116 Method m = introspector.getMethod(obj.getClass(), methodName, args); 117 if (m == null && obj instanceof Class ) { 118 m = introspector.getMethod((Class ) obj, methodName, args); 119 } 120 121 return (m == null) ? null : new VelMethodImpl(m); 122 } 123 124 127 public VelPropertyGet getPropertyGet(Object obj, final String identifier, Info i) throws Exception { 128 AbstractExecutor executor; 129 130 Class claz = obj.getClass(); 131 132 135 136 executor = new PropertyExecutor(rlog, introspector, claz, identifier); 137 138 141 142 if (!executor.isAlive()) { 143 executor = new BooleanPropertyExecutor(rlog, introspector, claz, identifier); 144 } 145 146 149 150 if (!executor.isAlive()) { 151 executor = new GetExecutor(rlog, introspector, claz, identifier); 152 } 153 154 if (!executor.isAlive()) { 156 try { 157 final Field field = obj.getClass().getField(identifier); 158 return new VelPropertyGet() { 159 public Object invoke(Object o) throws Exception { 160 return field.get(o); 161 } 162 163 public boolean isCacheable() { 164 return false; 165 } 166 167 public String getMethodName() { 168 return identifier; 169 } 170 }; 171 } catch (NoSuchFieldException e) { 172 } 174 } 175 176 177 return (executor == null) ? null : new VelGetterImpl(executor); 178 } 179 180 183 public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { 184 Class claz = obj.getClass(); 185 186 VelMethod vm = null; 187 try { 188 191 192 Object [] params = {arg}; 193 194 try { 195 vm = getMethod(obj, "set" + identifier, params, i); 196 197 if (vm == null) { 198 throw new NoSuchMethodException (); 199 } 200 } catch (NoSuchMethodException nsme2) { 201 StringBuffer sb = new StringBuffer ("set"); 202 sb.append(identifier); 203 204 if (Character.isLowerCase(sb.charAt(PROPERTY_START_INDEX))) { 205 sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(sb.charAt(PROPERTY_START_INDEX))); 206 } else { 207 sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(sb.charAt(PROPERTY_START_INDEX))); 208 } 209 210 vm = getMethod(obj, sb.toString(), params, i); 211 212 if (vm == null) { 213 throw new NoSuchMethodException (); 214 } 215 } 216 } catch (NoSuchMethodException nsme) { 217 220 221 if (Map .class.isAssignableFrom(claz)) { 222 Object [] params = {new Object (), new Object ()}; 223 224 vm = getMethod(obj, "put", params, i); 225 226 if (vm != null) { 227 return new VelSetterImpl(vm, identifier); 228 } 229 } 230 } 231 232 return (vm == null) ? null : new VelSetterImpl(vm); 233 } 234 235 238 public class VelMethodImpl implements VelMethod { 239 240 protected Method method = null; 241 246 public VelMethodImpl(Method m) { 247 method = m; 248 } 249 250 253 public Object invoke(Object o, Object [] params) throws Exception { 254 try { 255 return method.invoke(o, params); 256 } catch (InvocationTargetException e) { 257 final Throwable t = e.getTargetException(); 258 259 if (t instanceof Exception ) { 260 throw (Exception ) t; 261 } else if (t instanceof Error ) { 262 throw (Error ) t; 263 } else { 264 throw e; 265 } 266 } 267 } 268 269 272 public boolean isCacheable() { 273 return true; 274 } 275 276 279 public String getMethodName() { 280 return method.getName(); 281 } 282 283 286 public Class getReturnType() { 287 return method.getReturnType(); 288 } 289 } 290 291 294 public class VelGetterImpl implements VelPropertyGet { 295 296 protected AbstractExecutor ae = null; 297 298 303 public VelGetterImpl(AbstractExecutor exec) { 304 ae = exec; 305 } 306 307 310 public Object invoke(Object o) throws Exception { 311 return ae.execute(o); 312 } 313 314 317 public boolean isCacheable() { 318 return true; 319 } 320 321 324 public String getMethodName() { 325 return ae.getMethod().getName(); 326 } 327 } 328 329 332 public class VelSetterImpl implements VelPropertySet { 333 334 protected VelMethod vm = null; 335 336 protected String putKey = null; 337 338 342 public VelSetterImpl(VelMethod velmethod) { 343 this.vm = velmethod; 344 } 345 346 352 public VelSetterImpl(VelMethod velmethod, String key) { 353 this.vm = velmethod; 354 putKey = key; 355 } 356 357 358 public Object invoke(Object o, Object value) throws Exception { 359 ArrayList al = new ArrayList (); 360 361 if (putKey == null) { 362 al.add(value); 363 } else { 364 al.add(putKey); 365 al.add(value); 366 } 367 368 return vm.invoke(o, al.toArray()); 369 } 370 371 372 public boolean isCacheable() { 373 return true; 374 } 375 376 377 public String getMethodName() { 378 return vm.getMethodName(); 379 } 380 381 } 382 } 383 | Popular Tags |