2009-08-05 16 views
5

Mam plik właściwości, powiedzmy my-file.properties. Ponadto mam kilka plików konfiguracyjnych dla mojej aplikacji, w których trzeba wypełnić pewne informacje dotyczące zawartości pliku my-file.properties.Symulacja mechanizmu filtrującego Maven2 za pomocą Ant

my-file.properties:

application.version=1.0 
application.build=42 
user.name=foo 
user.password=bar 

Zatem w moich plikach konfiguracyjnych, że znajdzie jakiś ${application.version}, ${user.name} które zostaną zastąpione przez ich wartości podjętej we właściwościach pliku ...

Kiedy buduję swoją aplikację przy użyciu Maven2, muszę tylko określić plik właściwości i powiedzieć, że moje pliki zasobów są filtrowane (jak w this answer na inny problem). Jednak muszę osiągnąć to samo, używając tylko Ant.

Widziałem, że Ant oferuje filter task. Jednak zmusza mnie to do używania w moich plikach konfiguracyjnych wzorca @[email protected] (tj. @[email protected] zamiast #{user.name}), co jest niedopuszczalne w moim przypadku.

Jak mogę rozwiązać mój problem?

Odpowiedz

20

Myślę, że expandproperties jest tym, czego szukasz. Działa to tak jak Maven2's resource filters.


WEJŚCIE

Na przykład, jeśli masz src katalogu (jeden z wielu plików):

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

src/Test.txt


PROCES

A w moim pliku kompilacji ANT mamy to:

<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


WYJŚCIE

* Po uruchomieniu cel ExpandPropertiesTest będziesz w urządzeniu filtrowane są katalogu: *

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

filtrowane/test.txt

+0

Dziękuję! To było naprawdę to, czego szukałem ... – romaintaz

+0

@romaintaz pewna rzecz! Mam nadzieję, że nieco uprości to plik kompilacji. Wiem, że to moje. – leeand00

2

Ant zna koncepcję o nazwie Filterchains, która jest przydatna tutaj. Użyj filtru ReplaceTokens i podaj tekst begintoken i endtoken jako pusty (zwykle jest to znak "@"). To powinno wystarczyć.

+1

To rozwiązanie nie wydaje się działać, przynajmniej z moich prób. Begintoken i endtoken nie mogą być puste. Nie mogę ani ustawić początku słowa "$ {", ponieważ jest to uważane za błąd składni ... – romaintaz

1

Jeden hooooooorible sposób dokonać tego dzieła, inspirowane rozwiązania Mnementh jest z następującego kodu:

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

Objaśnienia:

Używam ReplaceTokens czytelnikowi spojrzeć na wszystkich $...} wzór . Nie mogę szukać wzorów ${...}, ponieważ begintoken jest znakiem, a nie łańcuchem. Następnie ustawiam listę tokenów zaczynając od {(tj. Widzę {user.name zamiast user.name). Mam nadzieję, że mam "tylko" około 20 linii w pliku my-file.properties, więc muszę zdefiniować "tylko" 20 tokenów w moim pliku Ant ...

Czy jest jakieś proste i głupie rozwiązanie, aby rozwiązać ten prosty i głupi problem?

3

Możesz zdefiniować custom FilterReader. Tak masz kilka możliwości:

  1. wysuwania/skopiowania klasę org.apache.tools.ant.filters.ReplaceTokens i zdefiniować właściwość Mapa odwołujący inny plik właściwości zawierający wszystkie zamienniki. Jest to wciąż trochę uciążliwe, ponieważ musisz zdefiniować wszystkie zamienniki.
  2. Rozszerz/skopiuj klasę org.apache.tools.ant.filters.ReplaceTokens z dodatkowym przetwarzaniem, które po prostu zastępuje dopasowany token wersją z poprawnym dodatkiem. Oczywiście musisz być bardzo ostrożny, gdy używasz tego typu, ponieważ pasuje on do wszystkiego z tokenem początkowym i końcowym.

więc w metodzie read() z ReplaceTokens wymienić:

final String replaceWith = (String) hash.get(key.toString()); 

z wezwaniem do getReplacement() metoda:

... 
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 + "}"; 
} 

Aby to wykorzystać, by upewnić się, Twoja klasa jest zapakowana i on Ant's path i zmodyfikuj swój filtr:

<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> 
Powiązane problemy