扩展Properties,用mvel来解析表达式减少重复输入

有时候,Properties中总有一些Key-Value ,其中Value往往会有重复部分。
比如,我在写一个代码生成工具,
需要定义如下的属性

modelPackage = com.corp.project.model
controllerPackage = com.corp.project.controller

其中,com.corp.project是重复的。

就想着能不能象 编程一样,前面声明一个变量,后面可以用${variale}形式引用
如下面这样定义

basePackage = com.corp.project
modelPackage = ${basePackage}.model
controllerPackage = ${basePackage}.controller

本来想用 遍历Properties的entry方式。但是发现,Properties内部用hashmap存储数据,顺序与原始的不一致,不能直接处理。

看了一下Properties的load方法实现,是每读一个 key-value,调用一次 put方法。
得到结论,直接重载这个方法。在插入前,处理出所需的value。


public class EvaluateProperties extends Properties {
private Map<String, Object> context = new HashMap<String, Object>();
@Override
public synchronized Object put(Object key, Object value) {
if (key == null) {
throw new IllegalArgumentException("Key should not be null");
}
Object resultValue;
if (value != null) {
String valueText = value == null?"":value.toString();
resultValue = TemplateRuntime.eval(valueText, this.context);
} else {
resultValue = "";
}
this.context.put(key.toString(), resultValue);
return super.put(key, resultValue);
}
}


表达式解析用了MVEL2的TemplateRuntime.

<dependency>
<groupId>org.mvel</groupId>
<artifactId>mvel2</artifactId>
<version>2.0.19</version>
</dependency>

表达式处理还有很多其他选择,antlr

更新了一下,不再依赖外部库,自行解析 ${} 进行替换
public class EvaluatedProperties extends Properties {
private String expressionStart = "${";
private String expressionEnd = "}";
private Properties parent;

public EvaluatedProperties() {
}

public EvaluatedProperties(Properties parent) {
this.parent = parent;
}

@Override
public synchronized Object put(Object key, Object value) {
if (null == value) {
throw new NullPointerException("value cannot be null");
}
String strVal = value.toString();
int pos = strVal.indexOf(expressionStart);
if (pos <0) {
return super.put(key, value);
}
int endPos = strVal.lastIndexOf(expressionEnd);
if (endPos<0) {
return super.put(key, value);
}
String exp = strVal.substring(pos+expressionStart.length(), endPos);
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(exp);
EvaluationContext context = new StandardEvaluationContext();
if (null != parent) {
for (String propName : parent.stringPropertyNames()) {
context.setVariable(propName, this.getProperty(propName));
}
}
for(String propName : this.stringPropertyNames()) {
context.setVariable(propName, this.getProperty(propName));
}

String evaluated = strVal.substring(0,pos)+expression.getValue(context, String.class)+strVal.substring(endPos+1);
return super.put(key, evaluated);
}

public void setExpressionStart(String expressionStart) {
this.expressionStart = expressionStart;
}

public void setExpressionEnd(String expressionEnd) {
this.expressionEnd = expressionEnd;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值