我正在为 i18n 使用 bean 验证和 gettext。如何标记要翻译的消息字符串,以便使用 xgettext 提取它?例如
@NotNull(message="Please enter a valid string")
String string;
Normall 我调用 i18n.tr,但是如何标记一个常量?
亲切的问候克里斯蒂安
编辑:在运行时,我使用自定义消息插值器进行翻译。
我正在为 i18n 使用 bean 验证和 gettext。如何标记要翻译的消息字符串,以便使用 xgettext 提取它?例如
@NotNull(message="Please enter a valid string")
String string;
Normall 我调用 i18n.tr,但是如何标记一个常量?
亲切的问候克里斯蒂安
编辑:在运行时,我使用自定义消息插值器进行翻译。
您可以尝试构建一个委托给 gettext的自定义 MessageInterpolator 。如果您正在使用 Hibernate Validator,从ResourceBundleMessageInterpolator派生插值器实现以重用实际插值逻辑可能是有意义的。
也就是说,我会对这个结果非常感兴趣。也许您可以分享您最终采用的方法?我可以想象这对其他人也很有趣。
我通常不会回答我自己的问题。但现在我想出了以下解决方案:
我在附加评论中将我的字符串标记如下(我不再知道 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。
我的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);
}
}
我不确定 gettext 与 Java 的集成。也许你可以解释更多它是如何工作的。
从 Bean 验证的角度来看,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
像这样的东西。