更正java.util.ResourceBundle组织

时间:2012-07-10 15:09:47

标签: java inheritance internationalization module resourcebundle

我有一个包含许多模块的国际化项目。每个模块都有自己的一组包:

- database-module
    + com_naugler_project_database.properties
    + com_naugler_project_database_fr.properties
- mapping-module
    + com_naugler_project_mapping.properties
    + com_naugler_project_mapping_fr.properties

但是,许多国际化术语都是多余的(例如“确定”或“取消”),我希望将这些术语放在一个地方,以便于维护和开发。

我找到了ResourceBundle继承的this helpful explanation,但看起来好像(不是?)共同的祖先不能正确国际化,因为:

- common-module
    + com_naugler_project.properties
    + com_naugler_project_fr.properties          <-- this is not an ancestor
- database-module
    + com_naugler_project_database.properties
    + com_naugler_project_database_fr.properties <-- of this

我的捆绑组织是否可以离开基地?提供共同的国际化祖先的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

你想要的似乎是资源的层次结构,也就是说,你可能希望从一个类派生出来(或者由某个特定部分和一些常见部分组成)。

基本上,ResourceBundle不是为它设计的,而是你自己的。

但我想,你想要一些建议。

  • 确保常见字词 真正 常见。这就是“OK”,“Cancel”,“Next&gt;”,“&lt; Previous”,“Open”,“File”等在其上下文中将具有共同的翻译。我的意思是将这些标准项只翻译一次是相当安全的,但如果你想在不同的上下文中使用它们,你还需要另一个条目。为什么?因为“打开”按钮的翻译与不同语言的“打开”对话框标题翻译不同。

  • 将所有.properties文件移动到一个位置(例如名为“resources”的目录)。当然,模块特定的文件应该分成不同的子目录......

    • 创建一个资源工厂,它将返回ResourceBundle类的实例(或您自己的Facade - 这种方法实际上会让您共享一些常见的包)。
  • 大型应用程序的良好实践是创建一些语言包,即将语言资源分离到它们自己的目录(即/ resources / en,/ resources / fr,/ resources / zh-Hans)。然而,这种方法的问题在于您需要自己实现资源回退(借助于您在问题中提到的文章,层次结构实际上是资源加载层次结构)。这意味着一些特殊情况,比如从语言标签“nb”退回到“no”但不从“nn”退回;从“zh-CN”和“zh-SG”回到“zh-Hans”然后回到“zh”但从“zh-HK”和“zh-TW”和“zh-MO”回到“zh” -Hant“然后是你的默认语言,不是从”pt-BR“下降到”pt“(而是回到默认语言)。

好像很多工作似乎?好吧,但之后的维护工作很少。

有一件事可能派上用场PropertyResourceBundle有两个构造函数可以让你加载你想要的任何属性文件,即:PropertyResourceBundle(InputStream stream)PropertyResourceBundle(Reader reader)。老实说,在大型项目中,标准的Res​​ourceBundle机制有太多限制,所以你真的需要自己的资源访问层......

答案 1 :(得分:1)

正如PawełDyda指出的那样,资源包本身不支持类层次结构解析。但是,我公司刚刚发布的Rincl项目应该可以满足您的需求 - 并处理UTF-8 .properties文件和XML属性文件。它甚至可以即时为您进行消息格式化。

正如Rincl quick start中所述,您只需实施Rincled,然后致电getResources();即使在父类或接口中声明,Rincl也会加载您的资源包:

public class MyClass extends BaseClass implements Rincled {
  …

    final String userName = "Jane Doe";
    //Retrieve the formatted user label based upon the current locale.
    //en-US: "Settings for user Jane Doe."
    //pt-BR: "Definições para usuário Jane Doe."
    final String userLabel = getResources().getString("user-label", userName);
  …

Rincl在http://rincl.io/上可用intro,甚至可以在Java国际化中获得完整lesson。有许多新功能即将推出,但最新版本应该已经适合您。如果您有任何问题或疑问,请告诉我。