2012-08-02 60 views
3

我正在爲i18n使用bean驗證和gettext。如何標記消息字符串進行翻譯,以便用xgettext提取? 例如如何在xgettext的bean驗證註釋中標記字符串消息?

@NotNull(message="Please enter a valid string") 
String string; 

Normall我打電話i18n.tr,但如何標記一個常數?

親切的問候 基督教

編輯: 在運行時我使用翻譯的自定義消息插值。

+0

我有一個github上的項目(https://github.com/jhorstmann/i18n)從Java字節碼而不是源中提取信息,它不應該太難以修改它來考慮註釋值。讓我知道這是否會有用。 – 2012-08-05 19:41:20

+0

這當然是一個很好的圖書館。如果可以考慮註釋值,則應該完整。也許只有帶有花括號的註釋值?還應該添加一個GettextMessageInterpolator以實現JSR303兼容性。 – Christian 2012-08-06 06:43:39

回答

1

我通常不會回答我自己的問題。但是現在,我想出了以下解決方案:

我標誌着我的字符串作爲一個額外的評論如下(我知道不幹燥了):

//_.trans("Please enter a valid string"); 
@NotNull(message="Please enter a valid string") 
String string; 

我打電話我POM以下腳本:

#!/bin/bash 

# $1 -> java source directory 
# $2 -> output file 
# $3 -> po directory 

echo "Source Directory: $1" 
echo "Keys File: $2" 
echo "PO Directory: $3" 

xgettext --from-code utf-8 -L Java --force-po -ktrc:1c,2 -ktrnc:1c,2,3 -ktr -kmarktr -ktrn:1,2 -k -o "$2" $(find "$1" -name "*.java") 
sed "s/\/\/_/_/g" $(find "$1" -name "*.java") | xgettext -F --from-code utf-8 -L Java -ktrans -k -j -o "$2" - 

pofiles=$3/*.po 
shopt -s nullglob 
for i in $pofiles 
do 
    echo "msgmerge $i" 
    msgmerge --backup=numbered -U $i $2 
done 

該腳本首先調用xgettext,然後調用sed將註釋斜線和管道移除到xgettext。因此,我在keys.pot中擁有所有的密鑰。

pom。XML - 簡介:

<profile> 
     <id>translate</id> 
     <build> 
      <plugins> 
       <plugin> 
        <artifactId>exec-maven-plugin</artifactId> 
        <groupId>org.codehaus.mojo</groupId> 
        <version>1.2.1</version> 
        <executions> 
         <execution> 
          <id>xgettext</id> 
          <phase>generate-resources</phase> 
          <goals> 
           <goal>exec</goal> 
          </goals> 
          <configuration> 
           <executable>sh</executable> 
           <arguments> 
            <argument>${project.basedir}/extractkeys.sh</argument> 
            <argument>src/main/java</argument> 
            <argument>src/main/resources/po/keys.pot</argument> 
            <argument>src/main/resources/po</argument> 
           </arguments> 
           <workingDirectory>${project.basedir}</workingDirectory> 
          </configuration> 
         </execution> 
        </executions> 
       </plugin> 
       <plugin> 
        <groupId>org.xnap.commons</groupId> 
        <artifactId>maven-gettext-plugin</artifactId> 
        <version>1.2.3</version> 
        <configuration> 
         <keysFile>${project.basedir}/src/main/resources/po/keys.pot</keysFile> 
         <outputDirectory>${project.basedir}/src/main/resources</outputDirectory> 
         <outputFormat>properties</outputFormat> 
         <poDirectory>${project.basedir}/src/main/resources/po</poDirectory> 
         <sourceDirectory>${project.build.sourceDirectory}/ch/sympany/tourist</sourceDirectory> 
         <sourceLocale>en</sourceLocale> 
         <targetBundle>${project.groupId}.Messages</targetBundle> 
        </configuration> 
        <executions> 
         <execution> 
          <goals> 
           <goal>dist</goal> 
          </goals> 
          <phase>generate-resources</phase> 
         </execution> 
        </executions> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 

我知道的版本是不獨立的平臺了,但在一個單獨的配置文件我可以住在一起。然而,它也適用於Windows傢伙的cygwin。

我messageinterpolator如下:

public class GettextMessageInterpolator implements MessageInterpolator { 

    private final MessageInterpolator delegate; 

    public GettextMessageInterpolator() { 
     this.delegate = new ResourceBundleMessageInterpolator(); 
    } 

    @Override 
    public String interpolate(String message, Context context) { 
     return this.interpolate(message, context, ClientLocalLocator.get()); 
    } 

    @Override 
    public String interpolate(String message, Context context, Locale locale) { 
     I18n i18n = ClientLocalLocator.getI18n(); 
     String retVal = i18n.tr(message); 
     if (StringUtils.isNotBlank(retVal)) 
      return retVal; 
     return delegate.interpolate(message, context, locale); 
    } 

} 
0

我不確定gettext與Java的集成。也許你可以更多地解釋它是如何工作的。

從Bean驗證的角度來看,i18n是通過資源文件處理的。除了直接添加消息的代碼,你會怎麼做:

@NotNull(message="{my.notNull.message}") 
String string; 

你再ValidationMessages.properties及其特定語言的零件計數器定義你的消息。不確定gettext如何適合這裏的圖片。

編輯

如果你真的想用了xgettext我看到在gettext的問題查找形式gettext的(「什麼」)的令牌。你可以通過xgettext做的是通過-k選項爲gettext指定一個不同的關鍵字。這在這種情況下不會有幫助。如果你通過命令行完成所有這些,我可以想象你使用sed來準備輸入xgettext。類似於:

find . -name "*.java" | xargs sed -e 's/message="\(.*\)"/gettext("\1")/' | xgettext 

就像這樣。

+0

我正在使用自定義MessageInterpolator來轉換郵件。我想在所有方面都有統一的i18n方法(javascript,java,annotations等)。 – Christian 2012-08-06 06:37:27

1

您可以嘗試構建代表gettext的custom MessageInterpolator。如果您使用的是Hibernate Validator,那麼從ResourceBundleMessageInterpolator派生您的插補器實現以重新使用實際插值邏輯可能是有意義的。

這就是說,我對這個結果非常感興趣。也許你可以分享你最終採取的方法?我可以想象這對其他人也很有趣。

+0

我正在使用自定義MessageInterpolator。這不是問題。問題是關於xgettext,如何標記字符串,因此xgettext可以識別它,並且字符串自動進入翻譯器生成的po文件。 – Christian 2012-08-06 06:35:39