Top / Eclipse / プラグイン開発のTIPS集 / 文字列を外部化する

Eclipseを使って文字列の外部化をする。

Eclipseは、ハードコーディングされた文字列を外部ファイル(*.properties)に外出しするというリファクタリングをすることができます。この機能を使って、Eclipseプラグインの文字列を外部化してみたいと思います。

Eclipseで文字列を外部化する方法は2通りあります。

通常の外部化の方法
通常の外部化の方法とはEclipseのフレームワークに依存しない外部化方法です。Eclipseプラグインの開発でない場合(通常のJava開発とかJ2EE開発とか)はこちらを使用します。
Eclipseのストリング外部化機構を使用する方法
Eclipseフレームワークに依存した方法で外部化します。Ecilpseプラグイン開発をしている場合は、こちらの方法を適用することもできます。

今回はEclipseプラグイン開発なので、後者の方法でやってみました。サンプルとして、

package nu.mine.kino.plugin.messagesamples;
public class Samples1 {
   public static final String hoge1 = "ほげ1";
   public static final String hoge2 = "ほげ2";
}
package nu.mine.kino.plugin.messagesamples;
public class Samples2 {
   public static final String fuga1 = "ふが1";
   public static final String fuga2 = "ふが2";
}

という二つのファイルをプラグイン内に作成しておきました。

やってみる

外部化のやり方は以下の通り:

プロジェクトを選択して、

ソース >> 外部化するストリングの検索

とすると、外部化できるストリングがあるソースコードの一覧がダイアログとしてあがります。

pic01.png

まずはSamples1.javaを選択し、外部化をクリックすると、以下のようなゴテゴテしたダイアログがあがります。

pic02.png

今回は「Eclipseのストリング外部化機構」を使用するので、「Eclipseのストリング外部化機構を使用する」にチェックを入れます。

また、その他の項目は以下の通りとしました。

生成キーの共通接頭部の入力
外部化する際のキー値に共通で指定する接頭文字。とりあえず、クラス名にしておきます。
値と、キー
外部化したい文字列と、置換するキー値を指定します。ここでは
ほげ1Sample1_HOGE1
ほげ2Sample1_HOGE2
としました。また横にある各ボタンの意味は以下の通り。
チェック外部化外部化する
×無視以後無視するよう、//$NON-NLS-1$ をつける
×'内部化//$NON-NLS-1$ をはずすもしくはなにもしない
この//$NON-NLS-1$は後述します。

結局のところ以下のような状態になりました。

pic03.png

あとは次へ次へで完成です。生成、変更されたソースコードは以下の通りです。

・Samples1クラス

package nu.mine.kino.plugin.messagesamples;
public class Samples1 {
   public static final String hoge1 = Messages.Sample1_HOGE1; <-変更
   public static final String hoge2 = Messages.Sample1_HOGE2; <-変更
}

・messages.properties

Sample1_HOGE1=ほげ1 <-実際はascii文字
Sample1_HOGE2=ほげ2 <-実際はascii文字

・Messagesクラス

package nu.mine.kino.plugin.messagesamples;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
    private static final String BUNDLE_NAME = 
      "nu.mine.kino.plugin.messagesamples.messages"; //$NON-NLS-1$
    private Messages() {
    }
    static {
        // initialize resource bundle
        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
    }
    public static String Sample1_HOGE1;
    public static String Sample1_HOGE2;
}

以上で外部化が完了しました。以後、"ほげ1" という文字列を使用したい箇所にはMessages.Sample1_HOGE1と書けばよいわけです。

無視とかをやってみる

次に、Samples2クラスをやってみます。先のダイアログでSamples2.javaを選択し、ゴテゴテしたダイアログを出します。そこで「ふが2」に対して、無視を選択し、次へ次へで終了します。生成されたコードは以下の通りです。

・Samples2クラス

package nu.mine.kino.plugin.messagesamples;
public class Samples2 {
    public static final String fuga1 = Messages.Samples2_FUGA1;
    public static final String fuga2 = "ふが2"; //$NON-NLS-1$
}

・messages.properties

Sample1_HOGE1=ほげ1
Sample1_HOGE2=ほげ2
Samples2_FUGA1=ふが1

・Messagesクラス

package nu.mine.kino.plugin.messagesamples;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
    private static final String BUNDLE_NAME = 
      "nu.mine.kino.plugin.messagesamples.messages"; //$NON-NLS-1$
    private Messages() {
    }
    static {
        // initialize resource bundle
        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
    }
    public static String Sample1_HOGE1;
    public static String Sample1_HOGE2;
    public static String Samples2_FUGA1;
}

このように「無視」を選択した文字列については、今後このストリング外部化ではこの文字列は無視してね、という意味の //$NON-NLS-1$ が付与されます。以後、外部化をやってもこれは無視されます。でも無視されちゃうと、やっぱり外部化しようと思ったときにちょっと困るわけですが、どうもプロジェクトを選択して全体で外部化文字列を探すと無視されちゃうけど、明示的にそのソースを選択して外部化をすると、一応出てくるみたいです。また、ゴテゴテしたダイアログでフィルタをかけて非表示にすることもできるみたいですね。

pic04.png

以上で完了です。これは国際化とかするときにむちゃくちゃ便利そうです。自分らでStringを外部化しよーってゴリゴリやるのはアホくさいけど、これならやる気になりますねえ。

プレースホルダをつかう

外部化文字列にはプレースホルダを使用することができます。Pluginクラスに以下のメソッドを追加します。

public void exe() {
  String foo = "こんにちは {0}さんと {1} さん";
  System.out.println(foo);
}

この文字列を外部化します。messages.propertiesには

MessagesamplesPlugin_HELLO=こんにちは {0}さんと {1} さん

が追加されました。上のメソッドはfooが外部化されましたが、さらに以下のようにプレースホルダを使用するよう変更しました。

public void exe() {
  String foo = Messages.MessagesamplesPlugin_HELLO;
  System.out.println(NLS.bind(foo, new String[] { "AAA", "BBB" }));
}

テストクラスを作って、このメソッドを呼び出してみます。実行結果は以下の通り。

こんにちは AAAさんと BBB さん

たしかに{0},{1}が置換されました。

って書いてて思ったんですが、これ別に外部化の話と関係なかったですね。

ルールを考えてみる。

さてキー値はルールを考えておいた方が良さそうです。つっても、

  • messages.propertiesはパッケージ毎に作成する
  • Messages.javaはパッケージ内で共有化されるから、キー値は「クラス名_任意」としておく

くらいですかね。Eclipseのソースをちょこっと見てみましたが、Eclipseも上の考え方でやってるところと、とくに接頭文字を指定してないところ両方あるみたいです。

でもプラグインの国際化とかを考えると、Pluginクラス*1のディレクトリに一個おいて、プラグイン内全てで共有するってやり方もあるみたいですね。


この記事は

選択肢 投票
おもしろかった 50  
そうでもない 2  

Top / Eclipse / プラグイン開発のTIPS集 / 文字列を外部化する

現在のアクセス:24543


*1 Activatorのサブクラス

添付ファイル: filepic04.png 1093件 [詳細] filepic03.png 1295件 [詳細] filepic02.png 1431件 [詳細] filepic01.png 1232件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-10-11 (金) 13:11:01 (1883d)