Имитация механизма фильтра Maven2 с использованием Ant - PullRequest
5 голосов
/ 05 августа 2009

У меня есть файл свойств, скажем, 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.

Я видел, что Ant предлагает задачу фильтра . Однако это заставляет меня использовать шаблон @property.key@ (т.е. @user.name@ вместо #{user.name}) в моих файлах конфигурации, что недопустимо в моем случае.

Как мне решить мою проблему?

Ответы [ 4 ]

20 голосов
/ 10 сентября 2009

Я думаю expandproperties - это то, что вы ищете. Это действует так же, как фильтры ресурсов Maven2 . <Ч />

ВХОД

Например, если у вас есть каталог src (один из множества файлов):

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

ЦСИ / 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

3 голосов
/ 06 августа 2009

Вы можете определить пользовательский FilterReader . Итак, у вас есть несколько вариантов:

  1. Расширьте / скопируйте класс org.apache.tools.ant.filters.ReplaceTokens и определите свойство Map, которое ссылается на другой файл свойств, содержащий все замены. Это все еще немного хлопотно, так как вы должны определить все замены.
  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>
2 голосов
/ 05 августа 2009

Ant знает концепцию с именем Filterchains , которая полезна здесь. Используйте ReplaceTokens -фильтр и укажите begintoken и endtoken как пустые (обычно это '@'). Это должно сработать.

1 голос
/ 05 августа 2009

Один из способов добиться этой работы, вдохновленный решением 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). Надеюсь, у меня «всего» около 20 строк в my-file.properties, поэтому мне нужно определить «только» 20 токенов в моем файле Ant ...

Есть ли какое-то простое и глупое решение для решения этой простой и глупой проблемы ??

...