PART 2:
Notice that:
(1) Coupe of callbacks with 'instanceof''s help take place in the setParameters() method;
(2) Utilizing TreeMap via Comparator;
(3) for (Map.Entry<String, Object> entry : acceptableParameters.entrySet());
protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) { ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware) ? (ParameterNameAware) action : null; Map<String, Object> params; Map<String, Object> acceptableParameters; if (ordered) { params = new TreeMap<String, Object>(getOrderedComparator()); acceptableParameters = new TreeMap<String, Object>(getOrderedComparator()); params.putAll(parameters); } else { params = new TreeMap<String, Object>(parameters); acceptableParameters = new TreeMap<String, Object>(); } //Derek: Do this iteration to filter out unacceptable entries for (Map.Entry<String, Object> entry : params.entrySet()) { String name = entry.getKey(); boolean acceptableName = acceptableName(name) || (parameterNameAware != null && parameterNameAware.acceptableParameterName(name)); if (acceptableName) { acceptableParameters.put(name, entry.getValue()); } } ValueStack newStack = valueStackFactory.createValueStack(stack); boolean clearableStack = newStack instanceof ClearableValueStack; if (clearableStack) { //if the stack's context can be cleared, do that to prevent OGNL //from having access to objects in the stack, see XW-641 ((ClearableValueStack)newStack).clearContextValues(); Map<String, Object> context = newStack.getContext(); ReflectionContextState.setCreatingNullObjects(context, true); ReflectionContextState.setDenyMethodExecution(context, true); ReflectionContextState.setReportingConversionErrors(context, true); //keep locale from original context context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE)); } boolean memberAccessStack = newStack instanceof MemberAccessValueStack; if (memberAccessStack) { //block or allow access to properties //see WW-2761 for more details MemberAccessValueStack accessValueStack = (MemberAccessValueStack) newStack; accessValueStack.setAcceptProperties(acceptParams); accessValueStack.setExcludeProperties(excludeParams); } //Derek: Puts entries from treemap to valuestack object, no utility method applied here to do such set operation? for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) { String name = entry.getKey(); Object value = entry.getValue(); try { newStack.setParameter(name, value); } catch (RuntimeException e) { if (devMode) { String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{ "Unexpected Exception caught setting '" + name + "' on '" + action.getClass() + ": " + e.getMessage() }); LOG.error(developerNotification); if (action instanceof ValidationAware) { ((ValidationAware) action).addActionMessage(developerNotification); } } } } if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null)) stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS)); addParametersToContext(ActionContext.getContext(), acceptableParameters); }
PART 3:
static private int countOGNLCharacters(String s) { int count = 0; for (int i = s.length() - 1; i >= 0; i--) { char c = s.charAt(i); if (c == '.' || c == '[') count++; } return count; } /** * Compares based on number of '.' and '[' characters (fewer is higher) */ static final Comparator<String> rbCollator = new Comparator<String>() { public int compare(String s1, String s2) { int l1 = countOGNLCharacters(s1), l2 = countOGNLCharacters(s2); return l1 < l2 ? -1 : (l2 < l1 ? 1 : s1.compareTo(s2)); } };Note: This comparator would be applied to TreeMap structure.