/** * Evaluate the Array expression 'loc' on the given object, o. e.g. in 'a[2]', <code>2</code> is * 'loc' and <code>a</code> is 'o'. * * <p>If o or loc are null, null is returned. If o is a Map, o.get(loc) is returned. If o is a * List, o.get(loc) is returned. loc must resolve to an int value. If o is an Array, o[loc] is * returned. loc must resolve to an int value. Otherwise loc is treated as a bean property of o. * * @param o an object to be accessed using the array operator or '.' operator. * @param loc the index of the object to be returned. * @return the resulting value. * @throws Exception on any error. */ public static Object evaluateExpr(Object o, Object loc) throws Exception { /* * following the JSTL EL rules */ if (o == null) { return null; } if (loc == null) { return null; } if (o instanceof Map) { if (!((Map) o).containsKey(loc)) { return null; } return ((Map) o).get(loc); } else if (o instanceof List) { int idx = Coercion.coerceInteger(loc).intValue(); try { return ((List) o).get(idx); } catch (IndexOutOfBoundsException iobe) { return null; } } else if (o.getClass().isArray()) { int idx = Coercion.coerceInteger(loc).intValue(); try { return Array.get(o, idx); } catch (ArrayIndexOutOfBoundsException aiobe) { return null; } } else { /* * "Otherwise (a JavaBean object)..." huh? :) */ String s = loc.toString(); VelPropertyGet vg = Introspector.getUberspect().getPropertyGet(o, s, DUMMY); if (vg != null) { return vg.invoke(o); } } throw new Exception("Unsupported object type for array [] accessor"); }