`
dwangel
  • 浏览: 267427 次
社区版块
存档分类
最新评论

扩展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
分享到:
评论

相关推荐

    C#表达式解析器-1.0

    它们包含了项目的配置和依赖信息,而Expression目录可能包含了表达式解析相关的类库,CSFormularTest可能是测试代码,用于验证解析器的正确性,Properties目录则包含项目的属性设置。 总的来说,C#表达式解析器1.0...

    C# 表达式解析器源代码(修正)

    C#表达式解析器是一个程序,它能够分析输入的字符串表达式,并将其转换为计算机可以理解的形式,以便执行计算或逻辑操作。 首先,让我们了解什么是表达式解析。在编程中,表达式是包含变量、常量、运算符和函数的...

    C# 表达式解析器源代码

    本项目"**C# 表达式解析器源代码**"提供了一个用C#实现的简单表达式解析器,特别强调了对算术运算符的优先级处理、括号的正确识别以及函数的支持。这个解析器对于理解编译原理、开发计算引擎或进行动态计算等场景...

    Properties文件解析.zip

    本主题将深入探讨`properties`文件的解析过程,以及如何创建一个工具来帮助我们方便地读取和操作这些文件。 首先,`properties`文件的格式非常简单,由键值对组成,每行一个键值对,键和值之间通过等号(=)或冒号...

    js读取properties文件

    由于.js直接解析.properties文件并不方便,因此通常会使用第三方库,如`js-properties`,它提供了一个简单的API来读取和写入.properties文件。首先,你需要通过npm安装这个库: ``` npm install js-properties ...

    解析properties文件demo

    在Java中,我们可以使用`java.util.Properties`类来加载和处理`properties`文件。首先,需要创建一个`Properties`对象,然后使用`load()`方法从输入流中加载文件内容。以下是一个简单的例子: ```java ...

    java解析Properties配置文件为对象Bean

    利用java的反射解析Properties文件转成对象 /** * 解析properties文件为对象 * @param * @param propPath * @param cls * @return * @throws InstantiationException * @throws ...

    java解析读取properties文件的6中方法总结

    你可以使用`Files.newBufferedReader()`来读取文件,然后按需解析。 ```java Path path = Paths.get("config.properties"); try (BufferedReader reader = Files.newBufferedReader(path)) { Properties props ...

    properties文件编辑插件

    2. **自动完成**:在输入键或值时,插件可以提供自动补全功能,减少手动输入错误,提高开发效率。 3. **编码支持**:`properties`文件经常需要处理多种字符编码,插件通常会提供选择和切换编码的功能,确保文件正确...

    替换文本文件中Ant表达式的Ant扩展任务

    该程序为Ant的扩展任务,在拷贝文本格式的文件的同时替换文件中的Ant表达式,类似于 ${property.name},属性值来自于Ant脚本加载的属性文件,如果没有属性文件中没有定义相关属性,那么保留原来的表达式;...

    cron表达式自动生成页面版

    在Java世界中,Spring框架也广泛使用cron表达式来实现定时任务。这个"cron表达式自动生成页面版"是一个实用的工具,它允许用户在网页界面上自定义时间规则,然后生成对应的cron表达式,方便地用于各种定时任务的配置...

    Cron表达式生成器

    - **Cron解析**:用户输入一个Cron表达式,生成器会解析并解释其含义,使得理解表达式更加直观。 在项目中,我们可以看到一些关键文件: - **CalcRunTime.ashx**:这可能是一个HTTP处理程序,用于计算Cron表达式...

    读取properties返回map并写入文件

    以下是一个简单的示例,展示如何使用Properties类加载文件并将其内容转换为Map: ```java import java.io.*; import java.util.*; public class PropertyHandler { public static Map, String&gt; loadProperties...

    myeclipse properties Editor 插件

    它支持常见的键值对格式,并且能智能提示键名,减少重复输入,提高编码速度。 其次,该插件具有强大的搜索和替换功能。开发者可以通过关键字快速查找特定的属性,同时进行全局或局部的替换操作,这对于大型项目中...

    vue实现手工调薪输入表达式特效源码.zip

    在这个项目中,"vue实现手工调薪输入表达式特效源码.zip" 提供了一个利用Vue.js来实现手动调整薪资输入时的动态计算表达式效果的示例。这个项目可能包含一个Vue组件或者一个完整的应用,用于处理员工薪资调整的输入...

    Python实现读取Properties配置文件的方法

    本篇文章将详细探讨如何通过Python来读取并解析`.properties`配置文件。 首先,了解`.properties`文件的格式。这种文件通常用于存储配置信息,其中键值对以等号`=`分隔,每一行代表一个键值对,注释以`#`或`!`开始...

    Python实现加载及解析properties配置文件的方法

    我们都是在java里面遇到要解析properties文件,在python中基本没有遇到这中情况,今天用python跑深度学习的时候,发现有些参数可以放在一个global.properties全局文件中,这样使用的时候更加方便。原理都是加载文件...

    正则表达式匹配小工具源码

    总结来说,这个正则表达式匹配小工具源码是一个实用的辅助开发工具,它通过直观的界面和便捷的功能,帮助用户快速验证正则表达式的正确性,同时具备保存常用表达式和个性化界面的特性,提高了学习和工作的效率。...

    java修改Properties文件,让输出格式与输入格式保持不变

    总结来说,这篇博客主要介绍了如何通过扩展Java的Properties类来保持Properties文件的原始格式。通过自定义的`SafeProperties`类,我们可以确保在处理配置文件时,无论是加载还是保存,都不会破坏原有的注释和行顺序...

    Spring_SpEl表达式使用用例

    Spring允许在配置中使用SpEL表达式作为占位符,如`@Value("#{systemProperties['java.version']}")`,这将注入Java版本号到bean的属性中。 7. **T()和P()函数** `T()`函数用于引入类型,如`T(java.util.Date)`...

Global site tag (gtag.js) - Google Analytics