01: package org.vraptor.introspector;
02:
03: import java.lang.reflect.Method;
04: import java.util.HashMap;
05: import java.util.Map;
06:
07: import org.vraptor.LogicRequest;
08:
09: /**
10: * A simple expression evaluator.
11: *
12: * @author Guilherme Silveira
13: */
14: public class ExpressionEvaluator {
15:
16: private final Map<String, Method> cache = new HashMap<String, Method>();
17:
18: public String parseExpression(String expression,
19: LogicRequest request) throws ExpressionEvaluationException {
20: boolean in = false;
21: int start = 0;
22: StringBuilder result = new StringBuilder();
23: for (int i = 0; i < expression.length(); i++) {
24: char c = expression.charAt(i);
25: if (c == '$') {
26: if (in || expression.length() - 1 == i
27: || expression.charAt(i + 1) != '{') {
28: throw new ExpressionEvaluationException(
29: "Invalid expression " + expression);
30: } else {
31: in = true;
32: i++;
33: start = i + 1;
34: }
35: } else if (c == '}' && in) {
36: in = false;
37: result.append(evaluate(expression.substring(start, i),
38: request));
39: } else if (!in) {
40: result.append(c);
41: }
42: }
43: return result.toString();
44: }
45:
46: private String evaluate(String expression, LogicRequest request)
47: throws ExpressionEvaluationException {
48: if ("".equals(expression)) {
49: return "";
50: }
51: String[] parts = expression.split("\\.");
52: Object current = request.findAttribute(parts[0]);
53: for (int i = 1; i < parts.length; i++) {
54: if (current == null) {
55: throw new ExpressionEvaluationException(
56: "Invalid redirection");
57: }
58: current = invokeGetter(current, parts[i]);
59: }
60: return current == null ? null : current.toString();
61: }
62:
63: private Object invokeGetter(Object obj, String property)
64: throws ExpressionEvaluationException {
65: property = "get" + Character.toUpperCase(property.charAt(0))
66: + property.substring(1);
67: String key = obj.getClass().getName().toString() + "."
68: + property;
69: try {
70: if (!cache.containsKey(key)) {
71: cache.put(key, obj.getClass().getDeclaredMethod(
72: property));
73: }
74: return cache.get(key).invoke(obj);
75: } catch (Exception e) {
76: throw new ExpressionEvaluationException(
77: "Invalid expression " + property, e);
78: }
79: }
80: }
|