使用Ant模拟Maven2过滤机制

时间:2009-08-05 11:00:18

标签: maven-2 ant filter

我有一个属性文件,比如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}),这在我的情况下是不可接受的。

如何解决我的问题?

4 个答案:

答案 0 :(得分:20)

我认为expandproperties正是您所寻找的。这就像Maven2's resource filters一样。

<小时/>

INPUT

例如,如果您有 src 目录(许多文件之一):

<link href="${css.files.remote}/css1.css"/>

<强>的src / test.txt的


PROCESS

在我的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。所以你有几个选择:

  1. 扩展/复制org.apache.tools.ant.filters.ReplaceTokens类并定义一个Map属性,该属性引用包含所有替换的另一个属性文件。由于你必须定义所有的替换品,这仍然是一件苦差事。
  2. 使用其他处理扩展/复制org.apache.tools.ant.filters.ReplaceTokens类,该处理只是将匹配的标记替换为具有正确装饰的版本。当然,在使用此类型时,您必须非常小心,因为它会匹配任何带有开头和结尾标记的内容。
  3. 所以在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个令牌......

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