簡體   English   中英

如何使用Eclipse將OSGi應用程序國際化?

[英]How do I internationalize an OSGi application using Eclipse?

我正在嘗試使用“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添加對更多語言的支持,因此解決方案應該可以通過這種方式進行擴展。


我已經閱讀了所有這些,但我沒有找到任何一致的幫助我。

此外, OSGi Alliance Tutorial ArchiveOSGi enRoute都沒有包含任何內容。

環境:

PS:我確定這不是一個復雜的任務,只是我沒有找到任何有用的(對我而言)文檔。

理論知識

本地化1

捆綁包本地化條目共享一個共同的基本名稱。 要查找潛在的本地化條目,請添加下划線('_'\\ u005F)加上一些后綴,用另一個下划線分隔,最后附加后綴.properties 后綴在java.util.Locale中定義。 后綴的順序必須是:

  • 語言

  • 國家

  • 變種

例如,以下文件提供英語,荷蘭語(比利時和荷蘭)和瑞典語的清單翻譯。

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 Bundle-Localization清單頭可用於覆蓋本地化文件的默認基本名稱。 此位置相對於包的根和包片段。

本地化條目包含本地化信息的鍵/值條目。 捆綁包清單中的所有標頭都可以進行本地化。 但是,Framework必須始終使用具有Framework語義的頭文件的非本地化版本。

可以使用以下語法將本地化密鑰指定為bundle的清單頭的值:

header-value ::= '%'text
text ::= < any value which is both a valid manifest headervalue
   and a valid property key name >

例如,請考慮以下bundle清單條目:

Bundle-Name: %acme bundle
Bundle-Vendor: %acme corporation
Bundle-Description: %acme description
Bundle-Activator: com.acme.bundle.Activator
Acme-Defined-Header: %acme special header

用戶定義的標頭也可以進行本地化。 明確允許本地化密鑰中的空格。

前面的示例清單條目可以通過清單本地化條目OSGI-INF/l10n/bundle.properties的以下條目進行本地化。

# bundle.properties
acme\ bundle=The ACME Bundle
acme\ corporation=The ACME Corporation
acme\ description=The ACME Bundle provides all of the ACME\ services
acme\ special\ header=user-defined Acme Data

在實踐中

1.首先,讓我們創建捆綁文件,包含密鑰/值對的捆綁文件。 在這種情況下,一個用於英語語言( bundle.properties ),它將是默認語言,一個用於西班牙語語言( bundle_es.properties

...
OSGI-INF
   |- l10n
        |- bundle.properties
        |- bunlde_es.properties
   |- ...

...將包含我們之前硬編碼的字符串值。

#bundle.properties
startMessage = Yeah ha, I'm logging!
endMessage = Done, I'm finishing logging!

#bundle_es.properties
startMessage = Si, Estoy registrando logs!
endMessage = Terminado, He concluido de registrar logs!

2.現在讓我們創建一個實用程序組件,它將幫助我們根據語言環境獲取與每個鍵關聯的值。

src
   ...
   |- org.example.i18n.messages
                              |- MessageProvider
                              |- MessagesProviderImpl
   ...

有兩個文件:接口和實際實現,它包含獲取鍵/值對的邏輯。

public interface MessageProvider {
    String get(String key);
}

@Component
public class MessagesProviderImpl implements MessageProvider {
    private BundleLocalization bundleLocalization;
    private LocaleProvider localeProvider;
    private ResourceBundle resourceBundle;

    @Reference
    public void bindBundleLocalization(BundleLocalization bundleLocalization) {
        this.bundleLocalization = bundleLocalization;
    }

    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
    public void bindLocaleProvider(LocaleProvider localeProvider) {
        this.localeProvider = localeProvider;
        setResourceBundle()
    }

    /*unbind methods omitted*/

    @Activate
    public void activate() {
        setResourceBundle();
    }

    @Override
    public String get(String key) {
        return resourceBundle.getString(key);
    }

    private String getLocale() {
        return localeProvider != null ? localeProvider.getLocale().toString() : Locale.getDefault().toString();
    }

    private void setResourceBundle() {
        resourceBundle = bundleLocalization.getLocalization(FrameworkUtil.getBundle(getClass()), getLocale());
    }
}

3.SimpleLoggingComponent使用MessageProvider組件。

@Component
public class SimpleLoggingComponent {

    /*previously code omitted for brevity*/

    private MessageProvider messages;

    @Reference
    public void bindMessageProvider(MessageProvider messageProvider) {
        messages = messageProvider;
    }

    /*unbind methods omitted*/

    @Activate
    public void activate() {
        simpleLogService.log(messages.get("startMessage")); // <- use now the key: startMessage
    }

    @Deactivate
    public void deactivate() {
        simpleLogService.log(messages.get("endMessage")); // <- use now the key: endMessage
    }
}

使用自定義語言啟動應用程序

在Arguments選項卡上,為此目的使用runtime參數-nl ,例如-nl en

參數-nl設置為英語的運行配置圖像:<code> -nl en </ code>


參考

完整的源代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM