如何使用 Eclipse 国际化 OSGi 应用程序?

我正在尝试使用“OSGi 方式”将 OSGi 应用程序国际化,但我没有取得进展。通过OSGi 的方式,我的意思是,使用框架为其提供的功能。我之前已经将 Java 应用程序国际化,但我想知道如何将其作为OSGi应用程序来实现。


我创建了这个简单的演示[GitHub repo],它旨在创建一个捆绑包,一旦它被激活就会记录一条消息,一旦它被停用就会记录另一条消息。


项目结构:


src

   |- org.example.i18n

                     |- SimpleLoggingComponent   // where the actual strings are

                     |- SimpleLogService

                     |- SimpleLogServiceImpl

META-INF

   |- MANIFEST.MF

OSGI-INF

   |- org.example.i18n.SimpleLoggingComponent

   |- org.example.i18n.SimpleLogServiceImpl

build.properties

SimpleLoggingComponent源码


@Component

public class SimpleLoggingComponent {


    private SimpleLogService simpleLogService;


    @Reference

    public void bindLogger(SimpleLogService logService) {

        this.simpleLogService = logService;

    }


    public void unbindLogger(SimpleLogService logService) {

        this.simpleLogService = null;

    }


    @Activate

    public void activate() {

        if (simpleLogService != null) {

            simpleLogService.log("Yee ha, I'm logging!"); // <-- need this message internationalized

        }

    }


    @Deactivate

    public void deactivate() {

        if (simpleLogService != null) {

            simpleLogService.log("Done, I'm finishing logging!"); // <-- need this message internationalized

        }

    }

}

目前,字符串在代码中是固定的,我希望能够将它们国际化。假设支持英语和西班牙语。


稍后我计划通过Fragment Bundles添加对更多语言的支持,因此该解决方案应该可以通过这种方式进行扩展。


皈依舞
浏览 175回答 1
1回答

神不在的星期二

理论知识本地化1Bundle 本地化条目共享一个通用的基本名称。为了找到一个潜在的本地化条目,添加一个下划线 ('_' \u005F) 和一些后缀,用另一个下划线分隔,最后附加后缀.properties.&nbsp;后缀定义在java.util.Locale.&nbsp;后缀的顺序必须是:语国家变体例如,以下文件提供英语、荷兰语(比利时和荷兰)和瑞典语的清单翻译。OSGI-INF/l10n/bundle_en.properties OSGI-INF/l10n/bundle_nl_BE.properties OSGI-INF/l10n/bundle_nl_NL.properties OSGI-INF/l10n/bundle_sv.properties清单本地化2本地化值存储在包内的属性资源中。包本地化属性文件的默认基本名称是OSGI-INF/l10n/bundle.&nbsp;Bundle-Localization清单标头可用于覆盖本地化文件的默认基本名称。此位置相对于捆绑包和捆绑包片段的根。本地化条目包含本地化信息的键/值条目。捆绑包清单中的所有标头都可以本地化。但是,框架必须始终使用具有框架语义的标头的非本地化版本。可以使用以下语法将本地化键指定为包的清单标头的值:header-value ::= '%'texttext ::= < any value which is both a valid manifest headervalue&nbsp; &nbsp;and a valid property key name >例如,考虑以下捆绑清单条目:Bundle-Name: %acme bundleBundle-Vendor: %acme corporationBundle-Description: %acme descriptionBundle-Activator: com.acme.bundle.ActivatorAcme-Defined-Header: %acme special header用户定义的标题也可以本地化。本地化键中的空格是明确允许的。前面的示例清单条目可以通过清单本地化条目中的以下条目进行本地化OSGI-INF/l10n/bundle.properties。# bundle.propertiesacme\ bundle=The ACME Bundleacme\ corporation=The ACME Corporationacme\ description=The ACME Bundle provides all of the ACME\ servicesacme\ special\ header=user-defined Acme Data在实践中1.首先,让我们创建捆绑文件,这些文件将包含键/值对。在这种情况下,一种用于英语 ( bundle.properties),这将是默认的一种,另一种用于西班牙语 ( bundle_es.properties)...OSGI-INF&nbsp; &nbsp;|- l10n&nbsp; &nbsp; &nbsp; &nbsp; |- bundle.properties&nbsp; &nbsp; &nbsp; &nbsp; |- bunlde_es.properties&nbsp; &nbsp;|- ......这将包含我们之前硬编码的字符串值。#bundle.propertiesstartMessage = Yeah ha, I'm logging!endMessage = Done, I'm finishing logging!#bundle_es.propertiesstartMessage = Si, Estoy registrando logs!endMessage = Terminado, He concluido de registrar logs!2.现在让我们创建一个实用组件,它将帮助我们根据语言环境获取与每个键关联的值。src&nbsp; &nbsp;...&nbsp; &nbsp;|- org.example.i18n.messages&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |- MessageProvider&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |- MessagesProviderImpl&nbsp; &nbsp;...有两个文件:接口和实际实现,它包含获取键/值对的逻辑。public interface MessageProvider {&nbsp; &nbsp; String get(String key);}@Componentpublic class MessagesProviderImpl implements MessageProvider {&nbsp; &nbsp; private BundleLocalization bundleLocalization;&nbsp; &nbsp; private LocaleProvider localeProvider;&nbsp; &nbsp; private ResourceBundle resourceBundle;&nbsp; &nbsp; @Reference&nbsp; &nbsp; public void bindBundleLocalization(BundleLocalization bundleLocalization) {&nbsp; &nbsp; &nbsp; &nbsp; this.bundleLocalization = bundleLocalization;&nbsp; &nbsp; }&nbsp; &nbsp; @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)&nbsp; &nbsp; public void bindLocaleProvider(LocaleProvider localeProvider) {&nbsp; &nbsp; &nbsp; &nbsp; this.localeProvider = localeProvider;&nbsp; &nbsp; &nbsp; &nbsp; setResourceBundle()&nbsp; &nbsp; }&nbsp; &nbsp; /*unbind methods omitted*/&nbsp; &nbsp; @Activate&nbsp; &nbsp; public void activate() {&nbsp; &nbsp; &nbsp; &nbsp; setResourceBundle();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public String get(String key) {&nbsp; &nbsp; &nbsp; &nbsp; return resourceBundle.getString(key);&nbsp; &nbsp; }&nbsp; &nbsp; private String getLocale() {&nbsp; &nbsp; &nbsp; &nbsp; return localeProvider != null ? localeProvider.getLocale().toString() : Locale.getDefault().toString();&nbsp; &nbsp; }&nbsp; &nbsp; private void setResourceBundle() {&nbsp; &nbsp; &nbsp; &nbsp; resourceBundle = bundleLocalization.getLocalization(FrameworkUtil.getBundle(getClass()), getLocale());&nbsp; &nbsp; }}3.使用中的MessageProvider组件SimpleLoggingComponent。@Componentpublic class SimpleLoggingComponent {&nbsp; &nbsp; /*previously code omitted for brevity*/&nbsp; &nbsp; private MessageProvider messages;&nbsp; &nbsp; @Reference&nbsp; &nbsp; public void bindMessageProvider(MessageProvider messageProvider) {&nbsp; &nbsp; &nbsp; &nbsp; messages = messageProvider;&nbsp; &nbsp; }&nbsp; &nbsp; /*unbind methods omitted*/&nbsp; &nbsp; @Activate&nbsp; &nbsp; public void activate() {&nbsp; &nbsp; &nbsp; &nbsp; simpleLogService.log(messages.get("startMessage")); // <- use now the key: startMessage&nbsp; &nbsp; }&nbsp; &nbsp; @Deactivate&nbsp; &nbsp; public void deactivate() {&nbsp; &nbsp; &nbsp; &nbsp; simpleLogService.log(messages.get("endMessage")); // <- use now the key: endMessage&nbsp; &nbsp; }}使用自定义语言启动应用程序在 Arguments 选项卡上-nl,为此目的使用 runtime 参数,例如-nl en
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java