我有一个属性文件,比如my-file.properties。 除此之外,我的应用程序还有几个配置文件,其中必须填写一些有关my-file.properties文件内容的信息。
my-file.properties:
application.version=1.0
application.build=42
user.name=foo
user.password=bar
因此,在我的配置文件中,我会发现一些${application.version}
,${user.name}
将替换为属性文件中的值......
当我使用Maven2构建我的应用程序时,我只需要指定属性文件,并说我的资源文件被过滤(如this answer中的另一个问题)。但是,我需要通过仅使用Ant来实现相同的目的。
我见过Ant提供filter task。但是,它迫使我在配置文件中使用模式@property.key@
(即@user.name@
而不是#{user.name}
),这在我的情况下是不可接受的。
如何解决我的问题?
答案 0 :(得分:20)
我认为expandproperties正是您所寻找的。这就像Maven2's resource filters一样。
<小时/>
例如,如果您有 src 目录(许多文件之一):
<link href="${css.files.remote}/css1.css"/>
<强>的src / test.txt的强>
在我的ANT构建文件中,我们有:
<project default="default">
<!-- The remote location of any CSS files -->
<property name="css.files.remote" value="/css/theCSSFiles" />
...
<target name="ExpandPropertiesTest">
<mkdir dir="./filtered"/>
<copy todir="./filtered">
<filterchain>
<expandproperties/>
</filterchain>
<fileset dir="./src" />
</copy>
</target>
</project>
<强>的build.xml 强>
<小时/>
*当您运行 ExpandPropertiesTest 目标时,您的已过滤目录中将包含以下内容:*
<link href="/css/theCSSFiles/css1.css"/>
<强>过滤/ test.txt的强>
答案 1 :(得分:3)
您可以定义custom FilterReader。所以你有几个选择:
所以在ReplaceTokens的read()方法中,替换:
final String replaceWith = (String) hash.get(key.toString());
调用getReplacement()方法:
...
final String replaceWith = getReplacement(key.toString);
...
private String getReplacement(String key) {
//first check if we have a replacement defined
if(has.containsKey(key)) {
return (String)hash.get(key);
}
//now use our built in rule, use a StringBuilder if you want to be tidy
return "$" + key + "}";
}
要使用此功能,您需要确保您的课程已打包并on Ant's path并修改您的过滤器:
<filterreader classname="my.custom.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!--Can still define explicit tokens, any not
defined explicitly will be replaced by the generic rule -->
</filterreader>
答案 2 :(得分:2)
Ant知道名为Filterchains的概念,这在这里很有用。使用ReplaceTokens - 过滤器并将begintoken和endtoken指定为空(通常是'@')。这应该可以解决问题。
答案 3 :(得分:1)
在Mnementh的解决方案的启发下,使用这种方法的一种有趣的方法是使用以下代码:
<!-- Read the property file -->
<property file="my-file.properties"/>
<copy todir="${dist-files}" overwrite="true">
<fileset dir="${src-files}">
<include name="*.properties"/>
</fileset>
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!-- Define one token per entry in the my-file.properties. Arggh -->
<param type="token" name="{application.version" value="${application.version}"/>
<param type="token" name="{user.name" value="${user.name}"/>
...
</filterreader>
</filterchain>
</copy>
说明:
我正在使用ReplaceTokens阅读器查找所有$...}
模式。我无法搜索${...}
模式,因为 begintoken 是char而不是String。然后,我设置以{开头的标记列表(即我看到{user.name
而不是user.name
)。希望我在my-file.properties中“只”大约20行,所以我需要在我的Ant文件中定义“仅”20个令牌......
有没有简单而愚蠢的解决方案来解决这个简单而愚蠢的问题?