有时候,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;
}
}
分享到:
相关推荐
它们包含了项目的配置和依赖信息,而Expression目录可能包含了表达式解析相关的类库,CSFormularTest可能是测试代码,用于验证解析器的正确性,Properties目录则包含项目的属性设置。 总的来说,C#表达式解析器1.0...
C#表达式解析器是一个程序,它能够分析输入的字符串表达式,并将其转换为计算机可以理解的形式,以便执行计算或逻辑操作。 首先,让我们了解什么是表达式解析。在编程中,表达式是包含变量、常量、运算符和函数的...
本项目"**C# 表达式解析器源代码**"提供了一个用C#实现的简单表达式解析器,特别强调了对算术运算符的优先级处理、括号的正确识别以及函数的支持。这个解析器对于理解编译原理、开发计算引擎或进行动态计算等场景...
本主题将深入探讨`properties`文件的解析过程,以及如何创建一个工具来帮助我们方便地读取和操作这些文件。 首先,`properties`文件的格式非常简单,由键值对组成,每行一个键值对,键和值之间通过等号(=)或冒号...
由于.js直接解析.properties文件并不方便,因此通常会使用第三方库,如`js-properties`,它提供了一个简单的API来读取和写入.properties文件。首先,你需要通过npm安装这个库: ``` npm install js-properties ...
在Java中,我们可以使用`java.util.Properties`类来加载和处理`properties`文件。首先,需要创建一个`Properties`对象,然后使用`load()`方法从输入流中加载文件内容。以下是一个简单的例子: ```java ...
2. **自动完成**:在输入键或值时,插件可以提供自动补全功能,减少手动输入错误,提高开发效率。 3. **编码支持**:`properties`文件经常需要处理多种字符编码,插件通常会提供选择和切换编码的功能,确保文件正确...
利用java的反射解析Properties文件转成对象 /** * 解析properties文件为对象 * @param * @param propPath * @param cls * @return * @throws InstantiationException * @throws ...
你可以使用`Files.newBufferedReader()`来读取文件,然后按需解析。 ```java Path path = Paths.get("config.properties"); try (BufferedReader reader = Files.newBufferedReader(path)) { Properties props ...
该程序为Ant的扩展任务,在拷贝文本格式的文件的同时替换文件中的Ant表达式,类似于 ${property.name},属性值来自于Ant脚本加载的属性文件,如果没有属性文件中没有定义相关属性,那么保留原来的表达式;...
在Java世界中,Spring框架也广泛使用cron表达式来实现定时任务。这个"cron表达式自动生成页面版"是一个实用的工具,它允许用户在网页界面上自定义时间规则,然后生成对应的cron表达式,方便地用于各种定时任务的配置...
- **Cron解析**:用户输入一个Cron表达式,生成器会解析并解释其含义,使得理解表达式更加直观。 在项目中,我们可以看到一些关键文件: - **CalcRunTime.ashx**:这可能是一个HTTP处理程序,用于计算Cron表达式...
以下是一个简单的示例,展示如何使用Properties类加载文件并将其内容转换为Map: ```java import java.io.*; import java.util.*; public class PropertyHandler { public static Map, String> loadProperties...
它支持常见的键值对格式,并且能智能提示键名,减少重复输入,提高编码速度。 其次,该插件具有强大的搜索和替换功能。开发者可以通过关键字快速查找特定的属性,同时进行全局或局部的替换操作,这对于大型项目中...
本篇文章将详细探讨如何通过Python来读取并解析`.properties`配置文件。 首先,了解`.properties`文件的格式。这种文件通常用于存储配置信息,其中键值对以等号`=`分隔,每一行代表一个键值对,注释以`#`或`!`开始...
在这个项目中,"vue实现手工调薪输入表达式特效源码.zip" 提供了一个利用Vue.js来实现手动调整薪资输入时的动态计算表达式效果的示例。这个项目可能包含一个Vue组件或者一个完整的应用,用于处理员工薪资调整的输入...
我们都是在java里面遇到要解析properties文件,在python中基本没有遇到这中情况,今天用python跑深度学习的时候,发现有些参数可以放在一个global.properties全局文件中,这样使用的时候更加方便。原理都是加载文件...
总结来说,这个正则表达式匹配小工具源码是一个实用的辅助开发工具,它通过直观的界面和便捷的功能,帮助用户快速验证正则表达式的正确性,同时具备保存常用表达式和个性化界面的特性,提高了学习和工作的效率。...
总结来说,这篇博客主要介绍了如何通过扩展Java的Properties类来保持Properties文件的原始格式。通过自定义的`SafeProperties`类,我们可以确保在处理配置文件时,无论是加载还是保存,都不会破坏原有的注释和行顺序...
Spring允许在配置中使用SpEL表达式作为占位符,如`@Value("#{systemProperties['java.version']}")`,这将注入Java版本号到bean的属性中。 7. **T()和P()函数** `T()`函数用于引入类型,如`T(java.util.Date)`...