如何在 Apache Commons 配置中保存填充了属性文件值的 xml 配置无法保存

How to save xml configuration filled with values from properties file in Apache Commons Configuration can't save

我正在尝试使用 groovy 脚本中的 Apache Commons 配置从一个简单的属性文件中读取值,并使用该文件中的这些值填充一个 XML 模板。此示例的目标是能够使用属性文件中定义的设置启动 Tomcat 的多个实例。 尽管 Apache Commons 配置框架非常庞大,但还是选择了它,因为它能够 read/write/validate 开箱即用的不同配置类型。

模板是tomcat的一块server.xml:

<?xml version='1.0' encoding='utf-8'?>
<Server port="${tomcat.server.port}" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <Connector port="${tomcat.http.port}"
                   address="${tomcat.http.ip}"/>
        <Engine jvmRoute="${tomcat.jvmroute}"/>
    </Service>
</Server>

和属性文件(假设 tomcat.properties):

application=someapp
tomcat.server.port=8087
tomcat.http.port=8088
tomcat.jvmroute=${application}

我使用 DefaultConfigurationBuilder 将这些文件组合到配置中。 正在动态创建定义文件。代码:

import groovy.xml.MarkupBuilder
import org.apache.commons.configuration.*

String configurationDefinition = "tomcat.configuration.xml"
File configurationDefinitionFile = new File(configurationDefinition)
FileWriter configurationDefinitionWriter = new FileWriter(configurationDefinitionFile)
MarkupBuilder fileList = new MarkupBuilder(configurationDefinitionWriter)
fileList.configuration() {
    properties(fileName:'tomcat.properties')
    xml(fileName:'server.xml')
}
configurationDefinitionWriter.close()

DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
builder.setFile(configurationDefinitionFile);
Configuration propertiesConfig = builder.getConfiguration(true);
//propertiesConfig.getKeys().each {  propertyName ->
//    println("$propertyName = ${propertiesConfig.getString(propertyName)}")
//}

XMLConfiguration conf = (XMLConfiguration)propertiesConfig.getConfiguration(1)
//conf.getKeys().each {  propertyName ->
//    println("$propertyName = ${conf.getString(propertyName)}")
//}
conf.save("server_parsed.xml")

保存的文件与上面的 server.xml 相同。例如端口=“${tomcat.server.port}” 有没有办法用属性文件中的值保存它?

对构建器方法和 userguide 的更深入研究有助于找到实现它的方法。

AbstractConfiguration provides the method interpolatedConfiguration(). This method creates a clone of the current configuration and then performs interpolation on all of its properties. So the result of this method is a configuration object with basically the same content as the original configuration, but with all variables replaced by their actual values (as far as this was possible).

所以下面这段代码可以完美运行:

import groovy.xml.MarkupBuilder
import org.apache.commons.configuration.*

String configurationDefinition = "tomcat.configuration.xml"
File configurationDefinitionFile = new File(configurationDefinition)
FileWriter configurationDefinitionWriter = new FileWriter(configurationDefinitionFile)
MarkupBuilder fileList = new MarkupBuilder(configurationDefinitionWriter)
fileList.configuration() {
    properties(fileName:'tomcat.properties')
    xml(fileName:'server.xml')
}
configurationDefinitionWriter.close()

DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
builder.setFile(configurationDefinitionFile);
Configuration propertiesConfig = builder.getConfiguration(true);

XMLConfiguration conf = (XMLConfiguration)propertiesConfig.getConfiguration(1)
XMLConfiguration  interpolatedConf = (XMLConfiguration )conf.interpolatedConfiguration()
interpolatedConf.save("server_parsed.xml")

遗憾的是google没有将插值与替换和替换联系起来。