表达式解析
本文介绍macula支持的表达式
表达式说明
macula使用标准的Spring EL表达式,具体语法可以参考。macula支持表达式的功能有
用户规则定义的规则表达式
数据集、数据参数的SQL语句(#() #[]# 里面可以用表达式)
默认情况下,macula表达式可以使用的变量有:
- user:代表是当前用户的userPrincipal
- 系统参数:为参数表中定义的内容,引用时使用DataParam$前缀加DataParamCode的方式。
- 自定义参数:通过new UserContextWrapper(userContext, params)添加自定义参数。
- 实现ValueEntryResolver接口扩展表达式。
实现ValueEntryResolver接口
可以通过实现ValueEntryResolver接口,使得表达式中可以直接使用该接口实现对应的KEY,也可以通过UserContext.resolve()方法获取该接口实现提供的数据。
public interface ValueEntryResolver extends Ordered, Comparable<ValueEntryResolver> {
/**
* 是否能解析.
*/
boolean support(String key);
/**
* 解析指定的值.
*/
ValueEntry resolve(String attribute, UserContext userContext);
}
需要注意的是,为了提高resolve接口对数据的解析速度,可以在resolve的实现中,对返回的ValueEntry设置合理的缓存级别。
表达式解析
表达式的解析都是通过UserContextImpl中的如下方法:
@Override
public EvaluationContext createEvaluationContext() {
EvaluationContext evalutionContext = new StandardEvaluationContext(this);
// 可以通过user.ORG等获取数据,具体是调用user.getCatlogCodes('xxx')
evalutionContext.getPropertyAccessors().add(
new CustomMethodPropertyAccessor(UserPrincipal.class, "getCatalogCodes", UserContextStaticServiceHolder
.getSecurityCatalogService().getAvaliableProviderNames()));
// 可以通过user.MENU等获取数据,具体是调用user.getResourceCodes('xxx')
evalutionContext.getPropertyAccessors().add(
new CustomMethodPropertyAccessor(UserPrincipal.class, "getResourceCodes",
UserContextStaticServiceHolder.getSecurityResourceService().getAvaliableProviderNames()));
// 不能识别的属性会调用resolve
evalutionContext.getPropertyAccessors().add(
new CustomMethodPropertyAccessor(UserContext.class, "resolve", null));
return evalutionContext;
}
EvaluationContext是Spring EL解析表达式的上下文,Spring EL表达式解析过程如下:
ExpressionParser parser = new SpelExpressionParser();
org.springframework.expression.Expression exp = parser.parseExpression(expressionText());
return exp.getValue(EvaluationContext, Result.class);
在需要解析表达式的地方都是如上述代码处理的。所以UserContext中的getXXX()都是可以作为表达式中的变量的,比如getUser()方法可以在表达式中直接写成 user,获取用户名可以写表达式“user.name",user就是UserPrincipal。
上述evaluationContext还注册了:
user.ORG等价于user.getCatlogCodes(‘xxx’);
user.MENU等价于user.getResourceCodes(‘xxx’);
不能识别的属性会调用UserContext中的resolve方法,该方法调用ValueEntryResolver接口的实现去解析表达式。