【问题标题】:Eclipse-RCP: Getting Resourcebundles using custom ResourceBundle.ControlEclipse-RCP:使用自定义 ResourceBundle.Control 获取资源包
【发布时间】:2014-02-14 10:15:10
【问题描述】:

我们从我们的数据库中加载我们的翻译。要检索捆绑包,我们有一个自定义 java.util.ResourceBundle.Control

为了翻译我们的 e4 RCP 应用程序,我已经创建了一个 TranslationService,我使用插件将其添加到根上下文中。这没问题(只是我不得不复制 95% 的 BundleTranslationProvider,因为我没有看到任何其他方式)。

现在我想使用new Message Extension(Eclipse Luna 附带)来翻译其余部分。据我从默认MessageFactoryServiceImpl 的来源中可以看出,似乎也没有一种简单的方法可以在那里注入我的 ResourceBundle.Control。

linked blog series 中,描述了从数据库获取资源包的用例,但通过使用基于类的资源包来解决。这是没有选择的,因为我不能为每个资源包和每个语言环境实现一个类。从数据库加载资源包的原因是能够在不重新部署应用程序的情况下将翻译部署为语言。

是通过复制默认MessageFactoryServiceImpl 的99% 来创建我自己的IMessageFactoryService 来实现此目的的唯一方法,只是为了将我们的控制权传递给对ResourceBundleHelper 的调用?

【问题讨论】:

    标签: java internationalization eclipse-rcp e4


    【解决方案1】:

    在对此进行一些调查后,我发现了一种无需大量修改或复制代码即可支持您的用例的方法。

    您需要交换 BundleLocalization 以按您的方式加载 ResourceBundle。在您的情况下,使用您的自定义 ResourceBundle.Control。通过这样做,您可以覆盖平台正在寻找 MANIFEST 指定的 ResourceBundle。

    目前,您还必须实现一个使用您的 BundleLocalization 的自定义 TranslationService。现有的 BundleTranslationProvider 不会将 BundleLocalization 排除在上下文之外。而且你需要在那里复制很多代码,因为 getBundle() 是私有的。我将与开发人员讨论可能的修改。

    你可以在这里找到一个例子:https://github.com/fipro78/e4classbasedtranslation

    希望能帮助您解决您的特定需求。

    【讨论】:

    • 啊,我不知道 BundleTranslationProvider 已导出。我认为因为它在一个内部包中,所以它是私有的。扩展该类是否可以节省?但是太糟糕了,getBundle 方法是私有的,所以我还是要复制它。
    • ResourceBundleHelper 和 BundleTranslationProvider 中似乎有一些重复的代码,用于从contributionUri 中检索Bundle。
    • 像魅力一样工作。非常感谢你。我没有使用 LifecycleManager,而是使用插件将我的 BundleLocalisation 和 TranslationService 设置为 IEclipseContext。你觉得这有什么问题吗? gist.github.com/tschulte/9003397
    • 对于重复的代码,这是因为 BundleTranslationProvider 在 ResourceBundleHelper 之前存在,并且最初 ResourceBundleHelper 只存在于 e4.tools 中,因此无法以某种方式合并它。关于如何设置服务,AFAIK 应该没有问题。形成生命周期透视模型插件在@ProcessAdditions 中处理,这仍然是在调用渲染器之前。所以使用插件而不是生命周期处理程序应该没问题。
    • 为了保持最新:Luna M6 将发布一些修改 1. 引入 ResourceBundleProvider 服务以抽象出 BundleLocalization。有了这个,您不应该更改 BundleLocalization 实现,而应该更改 ResourceBundleProvider 实现。这是因为您不应该交换 OSGi 服务。 2. 一些 API 更改允许扩展 TranslationService 和自定义 ResourceBundle.Control 的用例,使得无论如何都不需要注册自定义 TranslationService。 GitHub 上的示例已经针对 Luna M6 进行了更新
    【解决方案2】:

    AFAIK ResourceBundle.Control 用于加载 ResourceBundle。在新的消息扩展中,我们使用自定义 ResourceBundle.Control 来启用在 OSGi 上下文中加载 ResourceBundles,并且可以通过注释进行配置。

    AFAICS 交换 ResourceBundle.Control 将破坏新消息扩展支持的任何其他用例。

    问题是,为什么要使用自定义 ResourceBundle.Control 而不是创建基于类的 ResourceBundle?我还没有尝试过,但也许可以只创建基本 ResourceBundle(没有 Locale 信息)并以不同于使用 getLocale() 的方式确定 Locale。

    但在不知道您在自定义 ResourceBundle.Control 中做什么的情况下,我不知道该回答什么以及建议什么。当然,我们可以为此打开 API,但正如我之前所说,使用默认实现的所有其他插件都会失败。

    也许你可以给出一些关于你正在做什么的提示,我可以向你展示一种以另一种方式实现目标的方法。

    【讨论】:

    • 我们的控件确实从服务器加载资源包。此外,它还支持 UTF-8 资源包。如果可以在基于类的资源包中使用我们的 Control,并且如果创建一个基础资源包类并以另一种方式确定语言环境就足够了,我可以接受这一点。我已经计划从资源包生成消息类,我可以添加包类的生成。所以它不会增加任何额外的开发时间开销。我会试试这个。
    • 据我了解,使用基于类的 rb 不适用于应用模型。
    • 您不能简单地将基于类的资源包用于应用模型。因为默认的 TranslationService 是 BundleTranslationProvider,它只使用基于属性文件的资源包,可以通过 MANIFEST.MF 进行配置。但是您可以创建一个在基于类的资源包上运行的新 TranslationService 并注册它。
    • 但是,如果我想从贡献 uri 中获取捆绑包以从清单中获取捆绑包名称,我必须再次复制 95% 的默认实现。
    • 需要复制什么代码?您可以使用 ResourceBundleHelper 和静态辅助方法。但是,如果您想在应用程序模型的清单中引入一种指定基于类的资源包的通用方法,那么可以。我为您的特定用例想到了一种静态方式。对于平台中的通用方式,请随时创建增强票证以添加对应用程序模型的基于类的资源包的支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多