public Object get(Object key) { String attributePath = (String) key; if ("_className".equals(attributePath)) return className; if ("_obj".equals(attributePath)) return obj; if ("_querystr".equals(attributePath)) { try { Object id = ReflectionUtils.get(obj, "id"); return "?query=" + className + "&" + className + "[@id=" + id + "]"; } catch (Exception e) { log.error("Error constructing URL", e); return "#"; } } if ("displayMap".equals(attributePath)) { return getDisplayMap(); } return resolve(obj, attributePath); }
/** * Evaluates the specified path on the given object and returns the end point object in the path, * if any. This function is called recursively for each segment of the path. * * @param object A Java bean with getters. * @param path An object path as specified in the class docs. * @return The end point object, or null. */ private Object resolve(Object object, String path) { if (object == null) return null; if (path == null) return object; if ("class".equals(path)) { String cn = object.getClass().getName(); return cn.substring(cn.lastIndexOf('.') + 1).split("\\$\\$")[0]; } int d = path.indexOf('.'); String attr = (d < 0) ? path : path.substring(0, d); String constraint = getConstraint(attr); String constrainAttr = null; String constrainValue = null; int index = -1; if (constraint != null) { try { index = Integer.parseInt(constraint); } catch (NumberFormatException e) { String[] cvs = constraint.split("="); constrainAttr = cvs[0]; constrainValue = cvs[1]; } attr = attr.substring(0, attr.indexOf('[')); } Object nextObj; try { nextObj = ReflectionUtils.get(object, attr); } catch (Exception e) { log.error("Attribute error for " + path, e); return "ERROR"; } String nextPath = d < 0 ? null : path.substring(d + 1); if (nextObj instanceof List) { List nextList = (List) nextObj; // just need one element from the list if (index >= 0) { try { nextObj = nextList.get(index); } catch (IndexOutOfBoundsException e) { return ""; } return resolve(nextObj, nextPath); } // aggregate all the resolved elements in the list List resolved = new ArrayList(); for (Object e : nextList) { // constrain by an attribute if one was provided if (constrainAttr == null || resolve(e, constrainAttr).equals(constrainValue)) { Object o = resolve(e, nextPath); resolved.add(o); } } return resolved; } else { return resolve(nextObj, nextPath); } }