私がしようとしているOSGiアプリケーションを国際化「のOSGi道」を使用するが、私は進歩を持っていませんでした。OSGiの道私は、フレームワークがそれを提供機能を使用して、意味します。私は前にJavaアプリケーションを国際化しているが、私はとしてそれを行う方法を知りたいのOSGiアプリケーション。
私はこの簡単なデモ作成しました[GitHubのレポ]それが非アクティブ化されたら、それがアクティブになるとメッセージを記録しますバンドルと別のメッセージを作成することを目的とします。
プロジェクト構造:
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
}
}
}
今のところ、文字列がコードに固定され、私はこれらを国際化することができるようにしたいと思います。レッツ言うには、英語とスペイン語の言語がサポートされています。
その後、私はによってより多くの言語のサポートを追加する予定ですフラグメントバンドル、その解決策は、この手段によって拡張できるように準備する必要があります。
私はこれらすべてを読みましたが、私は私を助け一貫性のあるものを発見していません。
- 戦争の内部リソースバンドルとしてOSGiのWABを使用します
- サービス変更ロケールとしてのOSGiを使用してJSP春の国際化は正常に動作していません
- 私の日食RCPアプリケーションを国際化するには?
- RAPでの国際化
- EclipseのRCPとプラグインの国際化-チュートリアル。何かが約ここで言及された(...)のOSGiリソースバンドル(...)しかし、私はそれについて移動するかどうかはわかりません。
- Eclipseの国際化パート2/4 - 新規メッセージの拡張
また、どちらのOSGiアライアンスチュートリアルアーカイブやOSGiの途中には、それについて何が含まれています。
環境:
- 彼岸の中日
- Eclipseのバージョン:2019から03(4.11.0)、ビルドID:20190314から1200(ここからダウンロード)
- ターゲットプラットフォーム(openhab.target)
- Eclipseの実行構成
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
。バンドルローカライゼーションマニフェストヘッダは、ローカリゼーションファイルのデフォルトベース名を上書きするために使用することができます。この場所は、バンドル、バンドルフラグメントのルートからの相対です。
ローカリゼーションエントリは、ローカライズされた情報のためのキー/値のエントリが含まれています。バンドルのマニフェストのすべてのヘッダーをローカライズすることができます。しかし、フレームワークは常にフレームワークのセマンティクスを持つヘッダの非ローカライズバージョンを使用する必要があります。
ローカライズキーは、次の構文を使用して、バンドルのマニフェストヘッダの値として指定することができます。
header-value ::= '%'text
text ::= < any value which is both a valid manifest headervalue
and a valid property key name >
たとえば、以下のバンドルのマニフェストのエントリを考えてみます。
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.まず、聞かせてのは、キー/値のペアが含まれますものをバンドル・ファイルを作成します。英語(のために、この場合の1でbundle.properties
スペイン語のデフォルトの1と1になります)( 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
...
2つのファイルがあります:キー/値のペアを取得するためのロジックを含むものであるインターフェイスと実際の実装。
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.使用MessageProvider
中のコンポーネントSimpleLoggingComponent
。
@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
}
}
カスタム言語でアプリケーションを起動します
引数]タブで、ランタイム・パラメータを使用し-nl
、この目的のために例えば-nl en
リファレンス
- OSGiのコア仕様
org.eclipse.osgi.service.localization.BundleLocalization
org.eclipse.osgi.service.localization.LocaleProvider