I solved the above problem using the following:
- I used SpEL as provided by Spring.
- SpEL supports property replacement.
Code for replacement:
Inventor tesla = new Inventor("Nikola Tesla");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name == Nikola Tesla");
String name = (String) exp.getValue(tesla);
Here, the name
property will be replaced by Nikola Tesla.
This should be used when the name property has different value each time the expression is evaluated.
If the value of name
property is the same every time, consider using EvaluationContext
.
Now talking about the boolean expressions, you will have to compulsorily substitute values for properties, because in above example, property name
can take null
as the default value, but a string role can't take true
or false
without substitution.
And let's suppose that the SpEL contains some roles which I am not aware of, I won't be able to replace them with true
and false
. To solve this, I used something similar to @PreAuthorize which has the method hasRole()
.
Code for reference:
String roles = "(hasRole('admin') or hasRole('superAdmin')) and hasRole('modifier')"
Expression roleExpression = parser.parseExpression(roles);
StandardEvaluationContext roleContext = new StandardEvaluationContext(new SpelHelper());
roleContext.addPropertyAccessor(new MapAccessor()); // this line might be useless
Boolean hasCorrectRole = roleExpression.getValue(roleContext, Boolean.class);
class SpelHelper {
public boolean hasRole(String role) {
// some logic like current user roles have the role passed as argument
return true;
}
}
Full documentation at:
https://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/expressions.html
Also, refer Boolean Expression Evaluation in Java
This answer suggests using JEXL and the answer will give you a fair idea what to do to replace properties.