![](/img/trans.png)
[英]How do I get the OSGi BundleContext for an Eclipse RCP application?
[英]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 Archive和OSGi enRoute都沒有包含任何內容。
環境:
PS:我確定這不是一個復雜的任務,只是我沒有找到任何有用的(對我而言)文檔。
捆綁包本地化條目共享一個共同的基本名稱。 要查找潛在的本地化條目,請添加下划線('_'\\ 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
本地化值存儲在捆綁包中的屬性資源中。 捆綁軟件本地化屬性文件的默認基本名稱是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
org.eclipse.osgi.service.localization.BundleLocalization
org.eclipse.osgi.service.localization.LocaleProvider
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.