001package com.randomnoun.common.security.impl; 002 003/* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a 004 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html) 005 */ 006 007import java.io.StringReader; 008import java.util.*; 009 010import com.randomnoun.common.jexl.ast.TopLevelExpression; 011import com.randomnoun.common.jexl.eval.EvalContext; 012import com.randomnoun.common.jexl.eval.EvalFunction; 013import com.randomnoun.common.jexl.eval.Evaluator; 014import com.randomnoun.common.jexl.parser.ExpressionParser; 015import com.randomnoun.common.jexl.parser.ParseException; 016import com.randomnoun.common.jexl.parser.TokenMgrError; 017/* 018import com.randomnoun.common.jexl.sql.function.AggregateFunction; 019import com.randomnoun.common.jexl.sql.function.BetweenFunction; 020import com.randomnoun.common.jexl.sql.function.EndsWithFunction; 021import com.randomnoun.common.jexl.sql.function.IsInFunction; 022import com.randomnoun.common.jexl.sql.function.IsNullFunction; 023import com.randomnoun.common.jexl.sql.function.LikeFunction; 024import com.randomnoun.common.jexl.sql.function.PromptFunction; 025import com.randomnoun.common.jexl.sql.function.StartsWithFunction; 026*/ 027import com.randomnoun.common.security.ResourceCriteria; 028 029/** 030 * Implements the ResourceCriteria interface, using JEXL strings to represent 031 * {@link com.randomnoun.common.jexl.ast.TopLevelExpression} objects, 032 * which are then used to determine matches a given criteria context. 033 * 034 * 035 * @author knoxg 036 */ 037public class ResourceCriteriaImpl extends ResourceCriteria 038{ 039 040 /** generated serialVerisonUID */ 041 private static final long serialVersionUID = -8307206866854674839L; 042 043 /** The expression used to evaluate a criteria context. */ 044 private TopLevelExpression expression; 045 046 /** 047 * Construct a new ResourceCriteriaImpl object. The criteria is parsed using 048 * an EditableTranslator to convert it into a EditableCriteria object, 049 * and from there into an Expression object. 050 * 051 * @param criteriaString The JEX expression used to define this criteria. 052 * 053 * @throws CriteriaException if the underlying EditableTranslator throws 054 * an exception during initialisation, deserialisation or conversion. 055 */ 056 public ResourceCriteriaImpl(String criteriaString) 057 { 058 super(criteriaString); 059 060 if (criteriaString != null && !"".equals(criteriaString)) { 061 try { 062 expression = stringToExpression(criteriaString); 063 } catch (java.text.ParseException pe) { 064 throw new RuntimeException( 065 "Illegal expression found in security table: '" + criteriaString + 066 "', Error: " + pe.getMessage()); 067 } 068 } 069 } 070 071 /** Convert Java expression String to a TopLevelExpression */ 072 public static TopLevelExpression stringToExpression(String expressionString) 073 throws java.text.ParseException 074 { 075 StringReader reader = new StringReader(expressionString); 076 ExpressionParser parser = new ExpressionParser(reader); 077 TopLevelExpression root = null; 078 079 try { 080 root = parser.TopLevelExpression(); 081 } catch (ParseException pe) { 082 throw new java.text.ParseException(pe.getMessage(), -1); 083 } catch (TokenMgrError tme) { 084 throw new java.text.ParseException(tme.getMessage(), -1); 085 } 086 087 return root; 088 } 089 090 091 /** 092 * Evaluates the supplied criteria context against the criteria expression 093 * stored in this object. 094 * 095 * {@inheritdoc} 096 * 097 * @param criteriaContext {@inheritdoc} 098 * 099 * @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}