使用带变量的config / property文件

时间:2012-08-10 12:17:54

标签: java variables configuration import configuration-files

我使用像这样的简单文本文件

BMG-P   (someLongComplicatedExpression)(.*P)
BMG T   (someLongComplicatedExpression)(.*[Tt])
BMG MPA (someLongComplicatedExpression)(.*MPA)

配置我的应用程序(使用bufferedReader.readLine().split("\t")进行简单导入)。困扰我的是冗余

我正在考虑这样的解决方案:

%s=(someLongComplicatedExpression)
BMG-P   %s(.*P)
BMG T   %s(.*[Tt])
BMG MPA %s(.*MPA)

我读取变量的值(如%s),然后在导入后替换它们在字符串中的出现次数。

我的问题是:

  • 您知道哪些替代方法?
  • 在我的代码中实现替换变量的简单方法是什么?
  • 你能指点我那些支持属性文件的框架吗?

1 个答案:

答案 0 :(得分:1)

我将这个简单的扩展写入了Java Properties类:

import java.io.Serializable;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Allows properties to contain expansions of the form ${propertyName}. This
 * class makes no attempt to detect circular references, so be careful.
 */
public class ExpandingProperties extends Properties implements PropertySource {

    private static final long serialVersionUID = 259782782423517925L;
    private final Expander expander = new Expander();

    @Override
    public String getProperty(String key) {
        return expander.expand(super.getProperty(key), this);
    }
}

class Expander implements Serializable {

    private static final long serialVersionUID = -2229337918353092460L;
    private final Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");

    /**
     * Expands variables of the form "${variableName}" within the
     * specified string, using the property source to lookup the
     * relevant value.
     */
    public String expand(final String s, final PropertySource propertySource) {
        if (s == null) {
            return null;
        }
        final StringBuffer sb = new StringBuffer();
        final Matcher matcher = pattern.matcher(s);
        while (matcher.find()) {
            final String variableName = matcher.group(1);
            final String value = propertySource.getProperty(variableName);
            if (value == null) {
                throw new RuntimeException("No property found for: " + variableName);
            }
            matcher.appendReplacement(sb, value.replace("$", "\\$"));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}

interface PropertySource {

    String getProperty(String key);
}

使用示例:

public static void main(String[] args) {
    Properties properties = new ExpandingProperties();
    properties.put("myVar", "myLongExpression");
    properties.put("foo", "${myVar}_1");
    properties.put("bar", "${foo}_abc");

    System.out.println(properties.getProperty("bar"));
}

打印:

myLongExpression_1_abc

由于ExpandingPropertiesProperties的扩展,它继承了从属性文件加载值的所有load...()方法。

另一种选择是EProperties,它与上面的代码做了类似的事情,但更进一步,允许你嵌套属性文件等。我发现它对于我需要的东西来说太过分了。