1 package com.randomnoun.common.security.impl;
2
3 /* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a
4 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html)
5 */
6
7 import java.io.StringReader;
8 import java.util.*;
9
10 import com.randomnoun.common.jexl.ast.TopLevelExpression;
11 import com.randomnoun.common.jexl.eval.EvalContext;
12 import com.randomnoun.common.jexl.eval.EvalFunction;
13 import com.randomnoun.common.jexl.eval.Evaluator;
14 import com.randomnoun.common.jexl.parser.ExpressionParser;
15 import com.randomnoun.common.jexl.parser.ParseException;
16 import com.randomnoun.common.jexl.parser.TokenMgrError;
17 /*
18 import com.randomnoun.common.jexl.sql.function.AggregateFunction;
19 import com.randomnoun.common.jexl.sql.function.BetweenFunction;
20 import com.randomnoun.common.jexl.sql.function.EndsWithFunction;
21 import com.randomnoun.common.jexl.sql.function.IsInFunction;
22 import com.randomnoun.common.jexl.sql.function.IsNullFunction;
23 import com.randomnoun.common.jexl.sql.function.LikeFunction;
24 import com.randomnoun.common.jexl.sql.function.PromptFunction;
25 import com.randomnoun.common.jexl.sql.function.StartsWithFunction;
26 */
27 import com.randomnoun.common.security.ResourceCriteria;
28
29 /**
30 * Implements the ResourceCriteria interface, using JEXL strings to represent
31 * {@link com.randomnoun.common.jexl.ast.TopLevelExpression} objects,
32 * which are then used to determine matches a given criteria context.
33 *
34 *
35 * @author knoxg
36 */
37 public class ResourceCriteriaImpl extends ResourceCriteria
38 {
39
40 /** generated serialVerisonUID */
41 private static final long serialVersionUID = -8307206866854674839L;
42
43 /** The expression used to evaluate a criteria context. */
44 private TopLevelExpression expression;
45
46 /**
47 * Construct a new ResourceCriteriaImpl object. The criteria is parsed using
48 * an EditableTranslator to convert it into a EditableCriteria object,
49 * and from there into an Expression object.
50 *
51 * @param criteriaString The JEX expression used to define this criteria.
52 *
53 * @throws CriteriaException if the underlying EditableTranslator throws
54 * an exception during initialisation, deserialisation or conversion.
55 */
56 public ResourceCriteriaImpl(String criteriaString)
57 {
58 super(criteriaString);
59
60 if (criteriaString != null && !"".equals(criteriaString)) {
61 try {
62 expression = stringToExpression(criteriaString);
63 } catch (java.text.ParseException pe) {
64 throw new RuntimeException(
65 "Illegal expression found in security table: '" + criteriaString +
66 "', Error: " + pe.getMessage());
67 }
68 }
69 }
70
71 /** Convert Java expression String to a TopLevelExpression */
72 public static TopLevelExpression stringToExpression(String expressionString)
73 throws java.text.ParseException
74 {
75 StringReader reader = new StringReader(expressionString);
76 ExpressionParser parser = new ExpressionParser(reader);
77 TopLevelExpression root = null;
78
79 try {
80 root = parser.TopLevelExpression();
81 } catch (ParseException pe) {
82 throw new java.text.ParseException(pe.getMessage(), -1);
83 } catch (TokenMgrError tme) {
84 throw new java.text.ParseException(tme.getMessage(), -1);
85 }
86
87 return root;
88 }
89
90
91 /**
92 * Evaluates the supplied criteria context against the criteria expression
93 * stored in this object.
94 *
95 * {@inheritdoc}
96 *
97 * @param criteriaContext {@inheritdoc}
98 *
99 * @return {@inheritdoc}
100 */
101 public boolean evaluate(Map<String, Object> criteriaContext)
102 {
103 EvalContext evalContext = new EvalContext();
104
105 Map<String, EvalFunction> functions = new HashMap<String, EvalFunction>();
106 /*
107 functions.put("all", new AggregateFunction("all", "AND", false, false));
108 functions.put("anyTrue", new AggregateFunction("anyTrue", "OR", false, false));
109 functions.put("anyFalse", new AggregateFunction("anyFalse", "OR", false, true));
110 functions.put("none", new AggregateFunction("none", "AND", true, false));
111 functions.put("like", new LikeFunction());
112 functions.put("startsWith", new StartsWithFunction());
113 functions.put("endsWith", new EndsWithFunction());
114 functions.put("prompt", new PromptFunction());
115 functions.put("between", new BetweenFunction());
116 functions.put("isNull", new IsNullFunction());
117 functions.put("isIn", new IsInFunction());
118 */
119 evalContext.setFunctions(functions);
120
121 // put security-specific resources, functions, etc... in here
122 evalContext.setVariables(criteriaContext);
123
124 if (expression == null) {
125 // always return true for null expressions
126 return true;
127 }
128
129 Evaluator evaluator = new Evaluator();
130 Object result = evaluator.visit(expression, evalContext);
131 return ((Boolean) result).booleanValue();
132 // return ExpressionUtils.evaluateBooleanExpression(expression, evalContext);
133 }
134 }