3

i18n に Bean 検証と gettext を使用しています。xgettext で抽出されるように、メッセージ文字列を翻訳用にマークするにはどうすればよいですか? 例えば

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

通常は i18n.tr を呼び出しますが、定数をマークするにはどうすればよいですか?

敬具クリスチャン

編集:実行時に、翻訳にカスタム メッセージ インターポレータを使用しています。

4

3 に答える 3

1

gettext に委譲するカスタム MessageInterpolatorの構築を試みることができます。Hibernate Validatorを使用している場合、実際の補間ロジックを再利用するためにResourceBundleMessageInterpolatorから補間実装を派生させることが理にかなっています。

そうは言っても、私はこの結果に非常に興味があります。最終的に取っているアプローチを共有できますか?これは他の人にとっても興味深いものだと想像できました。

于 2012-08-04T07:40:06.063 に答える
1

私は通常、自分自身の質問に答えません。しかし、今のところ、次の解決策を思い付きました。

追加のコメントで次のように文字列をマークしています(もうDRYではないことを知っています):

//_.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 でも動作します。

私のメッセージインターポレーターは次のとおりです。

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);
    }

}
于 2012-08-09T11:39:30.560 に答える
0

gettext と Java の統合についてはよくわかりません。たぶん、それがどのように機能するかをもっと説明できるでしょう。

Bean Validation の観点から見ると、i18n はリソース ファイルを介して処理されます。メッセージをコードに直接追加する代わりに、次のようにします。

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

次に、 ValidationMessages.propertiesとその言語固有のカウンター パーツでメッセージを定義します。gettext がここの図にどのように収まるかはわかりません。

編集

本当にxgettextを使用したい場合は、 gettext がgettext("whatever")の形式のトークンを検索することに問題があることがわかります。xgettext でできることは、-k オプションでgettextに別のキーワードを指定することです。ただし、この場合は役に立ちません。コマンドラインからこれらすべてを行う場合、sedを使用してxgettextの入力を事前解析していると想像できます。何かのようなもの:

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

このようなもの。

于 2012-08-03T14:10:35.650 に答える