模拟使用Ant的Maven2的过滤机制(Simulating the Maven2 filter m

2019-06-28 00:00发布

我有一个属性文件,让说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建立我的申请,我只需要指定属性文件,并说,我的资源文件进行过滤(在这个答案另一个问题)。 不过,我需要通过只使用Ant来实现同样的事情。

我见过蚂蚁提供了一个过滤器的任务 。 然而,它迫使我使用模式@property.key@ (即@user.name@代替#{user.name}在我的配置文件,这是不是在我的情况下,可以接受)。

我怎样才能解决我的问题?

Answer 1:

我想expandproperties是你在找什么。 这种行为就像在Maven2的资源过滤器 。


INPUT

举例来说,如果你有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文件


OUTPUT

*当您运行ExpandPropertiesTest目标,你会在你的过滤目录中的以下内容:*

    <link href="/css/theCSSFiles/css1.css"/>

过滤/ test.txt的



Answer 2:

您可以定义一个定制FilterReader 。 所以,你有两个选择:

  1. 扩展/复制org.apache.tools.ant.filters.ReplaceTokens类,并定义引用包含所有的替代另一种属性文件中的地图属性。 这仍然是一个有点烦琐,你必须定义所有的替代品。
  2. 扩展/与刚刚替换用正确的装饰版本匹配的令牌额外的处理复制org.apache.tools.ant.filters.ReplaceTokens类。 当然,你必须在您使用此类型非常小心,因为这将匹配的开始和结束标记任何东西。

所以在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 + "}";
}

要使用此,你会确保你的类包装和Ant的路径上 ,并修改您的过滤器:

<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>


Answer 3:

Ant知道一个名为概念Filterchains ,这里是有用的。 使用ReplaceTokens -过滤和指定begintoken和endtoken为空(通常这是“@”)。 这应该够了吧。



Answer 4:

一个hooooooorible的方式来完成这项工作,通过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是一个字符,而不是一个字符串。 于是,我开始设置与{令牌的列表(即我看到{user.name代替user.name )。 我相信,我有“只”在my-file.properties约20行,所以我需要在我的Ant文件来定义“只有” 20个令牌...

有没有简单的和愚蠢的解决方案来解决这个简单而愚蠢的问题?



文章来源: Simulating the Maven2 filter mechanism using Ant