| 1 |  |   | 
    
      | 2 |  |   | 
    
      | 3 |  |   | 
    
      | 4 |  |   | 
    
      | 5 |  |   | 
    
      | 6 |  |   | 
    
      | 7 |  |   | 
    
      | 8 |  |   | 
    
      | 9 |  |   | 
    
      | 10 |  |   | 
    
      | 11 |  |   | 
    
      | 12 |  |   | 
    
      | 13 |  |   | 
    
      | 14 |  |   | 
    
      | 15 |  |   | 
    
      | 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.util.Iterator; | 
    
      | 30 |  |  import java.util.Collection; | 
    
      | 31 |  |  import java.util.Map; | 
    
      | 32 |  |  import java.util.Enumeration; | 
    
      | 33 |  |  import java.util.ArrayList; | 
    
      | 34 |  |   | 
    
      | 35 |  |   | 
    
      | 36 |  |   | 
    
      | 37 |  |   | 
    
      | 38 |  |   | 
    
      | 39 |  |   | 
    
      | 40 |  |   | 
    
      | 41 |  |   | 
    
      | 42 |  |   | 
    
      | 43 | 4 |  public class UberspectImpl implements Uberspect, UberspectLoggable { | 
    
      | 44 |  |       | 
    
      | 45 |  |      private static final int PROPERTY_START_INDEX = 3; | 
    
      | 46 |  |   | 
    
      | 47 |  |       | 
    
      | 48 |  |   | 
    
      | 49 |  |   | 
    
      | 50 |  |      private Log rlog; | 
    
      | 51 |  |   | 
    
      | 52 |  |       | 
    
      | 53 |  |   | 
    
      | 54 |  |   | 
    
      | 55 |  |      private static Introspector introspector; | 
    
      | 56 |  |   | 
    
      | 57 |  |       | 
    
      | 58 |  |   | 
    
      | 59 |  |   | 
    
      | 60 |  |   | 
    
      | 61 |  |   | 
    
      | 62 |  |   | 
    
      | 63 |  |      public void init() throws Exception { | 
    
      | 64 | 0 |      } | 
    
      | 65 |  |   | 
    
      | 66 |  |       | 
    
      | 67 |  |   | 
    
      | 68 |  |   | 
    
      | 69 |  |   | 
    
      | 70 |  |   | 
    
      | 71 |  |      public void setRuntimeLogger(Log runtimeLogger) { | 
    
      | 72 | 4 |          rlog = runtimeLogger; | 
    
      | 73 | 4 |          introspector = new Introspector(rlog); | 
    
      | 74 | 4 |      } | 
    
      | 75 |  |   | 
    
      | 76 |  |       | 
    
      | 77 |  |   | 
    
      | 78 |  |   | 
    
      | 79 |  |      public Iterator getIterator(Object obj, Info i) throws Exception { | 
    
      | 80 | 8 |          if (obj.getClass().isArray()) { | 
    
      | 81 | 2 |              return new ArrayIterator(obj); | 
    
      | 82 | 6 |          } else if (obj instanceof Collection) { | 
    
      | 83 | 3 |              return ((Collection) obj).iterator(); | 
    
      | 84 | 3 |          } else if (obj instanceof Map) { | 
    
      | 85 | 1 |              return ((Map) obj).values().iterator(); | 
    
      | 86 | 2 |          } else if (obj instanceof Iterator) { | 
    
      | 87 | 1 |              rlog.warn("Warning! The iterative " + " is an Iterator in the #foreach() loop at [" + i.getLine() + "," | 
    
      | 88 |  |                  + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable," | 
    
      | 89 |  |                  + " if used in more than once, this may lead to" + " unexpected results."); | 
    
      | 90 |  |   | 
    
      | 91 | 1 |              return ((Iterator) obj); | 
    
      | 92 | 1 |          } else if (obj instanceof Enumeration) { | 
    
      | 93 | 1 |              rlog.warn("Warning! The iterative " + " is an Enumeration in the #foreach() loop at [" + i.getLine() + "," | 
    
      | 94 |  |                  + i.getColumn() + "]" + " in template " + i.getTemplateName() + ". Because it's not resetable," | 
    
      | 95 |  |                  + " if used in more than once, this may lead to" + " unexpected results."); | 
    
      | 96 |  |   | 
    
      | 97 | 1 |              return new EnumerationIterator((Enumeration) obj); | 
    
      | 98 |  |          } | 
    
      | 99 |  |   | 
    
      | 100 |  |           | 
    
      | 101 | 0 |          rlog.warn("Could not determine type of iterator in " + "#foreach loop " + " at [" + i.getLine() + "," | 
    
      | 102 |  |              + i.getColumn() + "]" + " in template " + i.getTemplateName()); | 
    
      | 103 |  |   | 
    
      | 104 | 0 |          return null; | 
    
      | 105 |  |      } | 
    
      | 106 |  |   | 
    
      | 107 |  |       | 
    
      | 108 |  |   | 
    
      | 109 |  |   | 
    
      | 110 |  |      public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { | 
    
      | 111 | 47 |          if (obj == null) { | 
    
      | 112 | 0 |              return null; | 
    
      | 113 |  |          } | 
    
      | 114 |  |   | 
    
      | 115 | 47 |          Method m = introspector.getMethod(obj.getClass(), methodName, args); | 
    
      | 116 | 47 |          if (m == null && obj instanceof Class) { | 
    
      | 117 | 1 |              m = introspector.getMethod((Class) obj, methodName, args); | 
    
      | 118 |  |          } | 
    
      | 119 |  |   | 
    
      | 120 | 47 |          return (m == null) ? class="keyword">null : new VelMethodImpl(m); | 
    
      | 121 |  |      } | 
    
      | 122 |  |   | 
    
      | 123 |  |       | 
    
      | 124 |  |   | 
    
      | 125 |  |   | 
    
      | 126 |  |      public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { | 
    
      | 127 |  |          AbstractExecutor executor; | 
    
      | 128 |  |   | 
    
      | 129 | 23 |          Class claz = obj.getClass(); | 
    
      | 130 |  |   | 
    
      | 131 |  |           | 
    
      | 132 |  |   | 
    
      | 133 |  |   | 
    
      | 134 |  |   | 
    
      | 135 | 23 |          executor = new PropertyExecutor(rlog, introspector, claz, identifier); | 
    
      | 136 |  |   | 
    
      | 137 |  |           | 
    
      | 138 |  |   | 
    
      | 139 |  |   | 
    
      | 140 |  |   | 
    
      | 141 | 23 |          if (!executor.isAlive()) { | 
    
      | 142 | 3 |              executor = new BooleanPropertyExecutor(rlog, introspector, claz, identifier); | 
    
      | 143 |  |          } | 
    
      | 144 |  |   | 
    
      | 145 |  |           | 
    
      | 146 |  |   | 
    
      | 147 |  |   | 
    
      | 148 |  |   | 
    
      | 149 | 23 |          if (!executor.isAlive()) { | 
    
      | 150 | 1 |              executor = new GetExecutor(rlog, introspector, claz, identifier); | 
    
      | 151 |  |          } | 
    
      | 152 |  |   | 
    
      | 153 | 23 |          return (executor == null) ? class="keyword">null : new VelGetterImpl(executor); | 
    
      | 154 |  |      } | 
    
      | 155 |  |   | 
    
      | 156 |  |       | 
    
      | 157 |  |   | 
    
      | 158 |  |   | 
    
      | 159 |  |      public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { | 
    
      | 160 | 0 |          Class claz = obj.getClass(); | 
    
      | 161 |  |   | 
    
      | 162 | 0 |          VelMethod vm = null; | 
    
      | 163 |  |          try { | 
    
      | 164 |  |               | 
    
      | 165 |  |   | 
    
      | 166 |  |   | 
    
      | 167 |  |   | 
    
      | 168 | 0 |              Object[] params = {arg}; | 
    
      | 169 |  |   | 
    
      | 170 |  |              try { | 
    
      | 171 | 0 |                  vm = getMethod(obj, "set" + identifier, params, i); | 
    
      | 172 |  |   | 
    
      | 173 | 0 |                  if (vm == null) { | 
    
      | 174 | 0 |                      throw new NoSuchMethodException(); | 
    
      | 175 |  |                  } | 
    
      | 176 | 0 |              } catch (NoSuchMethodException nsme2) { | 
    
      | 177 | 0 |                  StringBuffer sb = new StringBuffer("set"); | 
    
      | 178 | 0 |                  sb.append(identifier); | 
    
      | 179 |  |   | 
    
      | 180 | 0 |                  if (Character.isLowerCase(sb.charAt(PROPERTY_START_INDEX))) { | 
    
      | 181 | 0 |                      sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(sb.charAt(PROPERTY_START_INDEX))); | 
    
      | 182 |  |                  } else { | 
    
      | 183 | 0 |                      sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(sb.charAt(PROPERTY_START_INDEX))); | 
    
      | 184 |  |                  } | 
    
      | 185 |  |   | 
    
      | 186 | 0 |                  vm = getMethod(obj, sb.toString(), params, i); | 
    
      | 187 |  |   | 
    
      | 188 | 0 |                  if (vm == null) { | 
    
      | 189 | 0 |                      throw new NoSuchMethodException(); | 
    
      | 190 |  |                  } | 
    
      | 191 |  |              } | 
    
      | 192 | 0 |          } catch (NoSuchMethodException nsme) { | 
    
      | 193 |  |               | 
    
      | 194 |  |   | 
    
      | 195 |  |   | 
    
      | 196 |  |   | 
    
      | 197 | 0 |              if (Map.class.isAssignableFrom(claz)) { | 
    
      | 198 | 0 |                  Object[] params = {new Object(), class="keyword">new Object()}; | 
    
      | 199 |  |   | 
    
      | 200 | 0 |                  vm = getMethod(obj, "put", params, i); | 
    
      | 201 |  |   | 
    
      | 202 | 0 |                  if (vm != null) { | 
    
      | 203 | 0 |                      return new VelSetterImpl(vm, identifier); | 
    
      | 204 |  |                  } | 
    
      | 205 |  |              } | 
    
      | 206 |  |          } | 
    
      | 207 |  |   | 
    
      | 208 | 0 |          return (vm == null) ? class="keyword">null : new VelSetterImpl(vm); | 
    
      | 209 |  |      } | 
    
      | 210 |  |   | 
    
      | 211 |  |       | 
    
      | 212 |  |   | 
    
      | 213 |  |   | 
    
      | 214 |  |      public class VelMethodImpl implements VelMethod { | 
    
      | 215 |  |           | 
    
      | 216 |  |          protected Method method = null; | 
    
      | 217 |  |           | 
    
      | 218 |  |   | 
    
      | 219 |  |   | 
    
      | 220 |  |   | 
    
      | 221 |  |   | 
    
      | 222 |  |          public VelMethodImpl(Method m) { | 
    
      | 223 |  |              method = m; | 
    
      | 224 |  |          } | 
    
      | 225 |  |   | 
    
      | 226 |  |           | 
    
      | 227 |  |   | 
    
      | 228 |  |   | 
    
      | 229 |  |          public Object invoke(Object o, Object[] params) throws Exception { | 
    
      | 230 |  |              try { | 
    
      | 231 |  |                  return method.invoke(o, params); | 
    
      | 232 |  |              } catch (InvocationTargetException e) { | 
    
      | 233 |  |                  final Throwable t = e.getTargetException(); | 
    
      | 234 |  |   | 
    
      | 235 |  |                  if (t instanceof Exception) { | 
    
      | 236 |  |                      throw (Exception) t; | 
    
      | 237 |  |                  } else if (t instanceof Error) { | 
    
      | 238 |  |                      throw (Error) t; | 
    
      | 239 |  |                  } else { | 
    
      | 240 |  |                      throw e; | 
    
      | 241 |  |                  } | 
    
      | 242 |  |              } | 
    
      | 243 |  |          } | 
    
      | 244 |  |   | 
    
      | 245 |  |           | 
    
      | 246 |  |   | 
    
      | 247 |  |   | 
    
      | 248 |  |          public boolean isCacheable() { | 
    
      | 249 |  |              return true; | 
    
      | 250 |  |          } | 
    
      | 251 |  |   | 
    
      | 252 |  |           | 
    
      | 253 |  |   | 
    
      | 254 |  |   | 
    
      | 255 |  |          public String getMethodName() { | 
    
      | 256 |  |              return method.getName(); | 
    
      | 257 |  |          } | 
    
      | 258 |  |   | 
    
      | 259 |  |           | 
    
      | 260 |  |   | 
    
      | 261 |  |   | 
    
      | 262 |  |          public Class getReturnType() { | 
    
      | 263 |  |              return method.getReturnType(); | 
    
      | 264 |  |          } | 
    
      | 265 |  |      } | 
    
      | 266 |  |   | 
    
      | 267 |  |       | 
    
      | 268 |  |   | 
    
      | 269 |  |   | 
    
      | 270 |  |      public class VelGetterImpl implements VelPropertyGet { | 
    
      | 271 |  |           | 
    
      | 272 |  |          protected AbstractExecutor ae = null; | 
    
      | 273 |  |   | 
    
      | 274 |  |           | 
    
      | 275 |  |   | 
    
      | 276 |  |   | 
    
      | 277 |  |   | 
    
      | 278 |  |   | 
    
      | 279 |  |          public VelGetterImpl(AbstractExecutor exec) { | 
    
      | 280 |  |              ae = exec; | 
    
      | 281 |  |          } | 
    
      | 282 |  |   | 
    
      | 283 |  |           | 
    
      | 284 |  |   | 
    
      | 285 |  |   | 
    
      | 286 |  |          public Object invoke(Object o) throws Exception { | 
    
      | 287 |  |              return ae.execute(o); | 
    
      | 288 |  |          } | 
    
      | 289 |  |   | 
    
      | 290 |  |           | 
    
      | 291 |  |   | 
    
      | 292 |  |   | 
    
      | 293 |  |          public boolean isCacheable() { | 
    
      | 294 |  |              return true; | 
    
      | 295 |  |          } | 
    
      | 296 |  |   | 
    
      | 297 |  |           | 
    
      | 298 |  |   | 
    
      | 299 |  |   | 
    
      | 300 |  |          public String getMethodName() { | 
    
      | 301 |  |              return ae.getMethod().getName(); | 
    
      | 302 |  |          } | 
    
      | 303 |  |      } | 
    
      | 304 |  |   | 
    
      | 305 |  |       | 
    
      | 306 |  |   | 
    
      | 307 |  |   | 
    
      | 308 |  |      public class VelSetterImpl implements VelPropertySet { | 
    
      | 309 |  |           | 
    
      | 310 |  |          protected VelMethod vm = null; | 
    
      | 311 |  |           | 
    
      | 312 |  |          protected String putKey = null; | 
    
      | 313 |  |   | 
    
      | 314 |  |           | 
    
      | 315 |  |   | 
    
      | 316 |  |   | 
    
      | 317 |  |   | 
    
      | 318 |  |          public VelSetterImpl(VelMethod velmethod) { | 
    
      | 319 |  |              this.vm = velmethod; | 
    
      | 320 |  |          } | 
    
      | 321 |  |   | 
    
      | 322 |  |           | 
    
      | 323 |  |   | 
    
      | 324 |  |   | 
    
      | 325 |  |   | 
    
      | 326 |  |   | 
    
      | 327 |  |   | 
    
      | 328 |  |          public VelSetterImpl(VelMethod velmethod, String key) { | 
    
      | 329 |  |              this.vm = velmethod; | 
    
      | 330 |  |              putKey = key; | 
    
      | 331 |  |          } | 
    
      | 332 |  |   | 
    
      | 333 |  |           | 
    
      | 334 |  |          public Object invoke(Object o, Object value) throws Exception { | 
    
      | 335 |  |              ArrayList al = new ArrayList(); | 
    
      | 336 |  |   | 
    
      | 337 |  |              if (putKey == null) { | 
    
      | 338 |  |                  al.add(value); | 
    
      | 339 |  |              } else { | 
    
      | 340 |  |                  al.add(putKey); | 
    
      | 341 |  |                  al.add(value); | 
    
      | 342 |  |              } | 
    
      | 343 |  |   | 
    
      | 344 |  |              return vm.invoke(o, al.toArray()); | 
    
      | 345 |  |          } | 
    
      | 346 |  |   | 
    
      | 347 |  |           | 
    
      | 348 |  |          public boolean isCacheable() { | 
    
      | 349 |  |              return true; | 
    
      | 350 |  |          } | 
    
      | 351 |  |   | 
    
      | 352 |  |           | 
    
      | 353 |  |          public String getMethodName() { | 
    
      | 354 |  |              return vm.getMethodName(); | 
    
      | 355 |  |          } | 
    
      | 356 |  |   | 
    
      | 357 |  |      } | 
    
      | 358 |  |  } |