View Javadoc
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 }