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を1つ読むたびに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);
    }
}

式解析にはMVEL 2のTemplateRuntimeを用いる.

  org.mvel
  mvel2
  2.0.19

式の処理には他にも選択肢がたくさんありますantlr