2009-03-23 17 views
7

私のプロジェクトには複数のプラグインが含まれており、すべてのプラグインには20個近くの翻訳が含まれているplugin.propertiesファイルが含まれています。 MANIFEST.MFファイルは、外部プラグイン文字列が格納されているプロパティファイルの名前を定義します。eclipseのplugin.propertiesメカニズムRCP

Bundle-Localization: plugin 

私はEclipseは、実行時にplugin.propertiesファイルの中の "%plugin.name" を検索します

%plugin.name 

のように定義するプラグインの名前。

"plugin.properties"ファイルで、どのクラスがMANIFEST.MF Bundle-Localizationエントリを読み、どのポイントに '%'という接尾辞が付いた文字列が読み込まれていますか?

こういったクラスを見つけてパッチしたいのですが、最初に "%plugin.name"という識別子の他のディレクトリやファイルを調べることができます。これらの新しいメカニズムを使用すると、オリジナルのプラグインを変更せずに、製品にフラグメントを追加して、 "plugin.properties"ファイルに1行を上書きすることができます。 これらのメカニズムを使用すると、異なるフラグメントを追加するだけで、複数の顧客のビルドプロセスを作成できます。変更したい顧客名と特殊文字列を含むフラグメント。

フラグメントメカニズムは元のプラグインにファイルを追加するだけなので、このようにしたいと思います。 "plugin.properties"ファイルがプラグインに存在する場合、フラグメント "plugin.properties"ファイルは無視されます。

UPDATE 1:

class ManifestLocalization{ 
... 
protected ResourceBundle getResourceBundle(String localeString) { 
} 
... 
} 

リターン特性のリソースバンドルは、指定されたロケール文字列のファイル

方法。 誰かが最初にフラグメントを調べてリソースパスを取得できるようになったら、投稿してください。

UPDATE 2:クラスのプロパティの

private URL findInResolved(String filePath, AbstractBundle bundleHost) { 

     URL result = findInBundle(filePath, bundleHost); 
     if (result != null) 
      return result; 
     return findInFragments(filePath, bundleHost); 
    } 

検索設定をファイルManifestLocalizationとキャッシュそれで

方法。翻訳は、キャッシュされたファイルから取得することができます。問題は、完全なファイルがキャッシュされ、単一の翻訳ではないことです。

解決策は、バンドルファイルを読み取るよりも、まずフラグメントファイルを読み取ることです。両方のファイルが既存の場合は、それらを1つのファイルにマージし、新しいプロパティファイルをディスクに書き込みます。新しいプロパティファイルのURLが返され、新しいpropetriesファイルがキャッシュされます。

答えて

3

私は間違った情報を得ましたが...私は全く同じ問題を抱えていました。プラグインは2回アクティブ化されていないので、フラグメントBundle-Localizationキーにはアクセスできません。

plugin.propertiesにすべての言語翻訳が欲しいです(私はこれが気になりませんが、1つのファイルを管理するほうがずっと簡単です)。

I(半分)は

public void populate(Bundle bundle) { 
    String localisation = (String) bundle.getHeaders().get("Bundle-Localization"); 
    Locale locale = Locale.getDefault(); 

    populate(bundle.getEntry(getFileName(localisation))); 
    populate(bundle.getEntry(getFileName(localisation, locale.getLanguage()))); 
    populate(bundle.getEntry(getFileName(localisation, locale.getLanguage(), locale.getCountry()))); 
    populate(bundle.getResource(getFileName("fragment"))); 
    populate(bundle.getResource(getFileName("fragment", locale.getLanguage()))); 
    populate(bundle.getResource(getFileName("fragment", locale.getLanguage(), locale.getCountry()))); 
} 

を使用して問題を解決し、単に私のフラグメントのローカリゼーションファイル名 'fragment.properties' と呼んでいます。

これは特に優雅ではありませんが、機能します。

ところで、フラグメントからファイルを取得するには、getResourceが必要です。フラグメントファイルがクラスパス上にあるか、getResourceを使用している場合にのみ検索されるようです。

誰かがより良いアプローチをしている場合は、私を修正してください。

すべて最高、

マーク。インストール - - フラグメントを望んでいたプロパティファイルで

+0

私は、ポピュレートメソッドを見つけることができますか?または私はそれを書く必要がありますか? –

+0

あなたの答えにもっと情報を入れてください。ありがとうございました! –

0

フラグメントplugin.propertiesの名前を別のものに変更します。あなたのフラグメントでfragment.properties

バンドル-ローカライズを変更マニフェスト:プラグイン にバンドル-ローカライズ:フラグメント

あなたのプラグインがplugin.propertiesを使用して、二回初めてアクティブになり、使用して、第2のfragment.properties。

+0

しかし、私は別の値に同じキーを使用することはできません。プラグインキーのみが検索され、返されます。検索されたキーがプラグインで見つかると、フラグメントは決して開かれません。 –

0

プラグインのアクティブ化は、OSGiランタイムEquinoxによって処理されます。しかし、私は強く特定の動作を作成するためにそこに任意のファイルをパッチしようとすることをお勧めします。マークの示唆された方法は、あなたの問題をはるかに元気なアプローチに見えるでしょう。

+0

Mark MillerまたはMarkとの提携方法を意味しますか? :) – Peteter

1
/** 
* The Hacked NLS (National Language Support) system. 
* <p> 
* Singleton. 
* 
* @author mima 
*/ 
public final class HackedNLS { 
    private static final HackedNLS instance = new HackedNLS(); 

    private final Map<String, String> translations; 

    private final Set<String> knownMissing; 

    /** 
    * Create the NLS singleton. 
    */ 
    private HackedNLS() { 
     translations = new HashMap<String, String>(); 
     knownMissing = new HashSet<String>(); 
    } 

    /** 
    * Populates the NLS key/value pairs for the current locale. 
    * <p> 
    * Plugin localization files may have any name as long as it is declared in the Manifest under 
    * the Bundle-Localization key. 
    * <p> 
    * Fragments <b>MUST</b> define their localization using the base name 'fragment'. 
    * This is due to the fact that I have no access to the Bundle-Localization key for the 
    * fragment. 
    * This may change. 
    * 
    * @param bundle The bundle to use for population. 
    */ 
    public void populate(Bundle bundle) { 
     String baseName = (String) bundle.getHeaders().get("Bundle-Localization"); 

     populate(getLocalizedEntry(baseName, bundle)); 
     populate(getLocalizedEntry("fragment", bundle)); 
    } 

    private URL getLocalizedEntry(String baseName, Bundle bundle) { 
     Locale locale = Locale.getDefault(); 
     URL entry = bundle.getEntry(getFileName(baseName, locale.getLanguage(), locale.getCountry())); 
     if (entry == null) { 
      entry = bundle.getResource(getFileName(baseName, locale.getLanguage(), locale.getCountry())); 
     } 
     if (entry == null) { 
      entry = bundle.getEntry(getFileName(baseName, locale.getLanguage())); 
     } 
     if (entry == null) { 
      entry = bundle.getResource(getFileName(baseName, locale.getLanguage())); 
     } 
     if (entry == null) { 
      entry = bundle.getEntry(getFileName(baseName)); 
     } 
     if (entry == null) { 
      entry = bundle.getResource(getFileName(baseName)); 
     } 
     return entry; 
    } 

    private String getFileName(String baseName, String...arguments) { 
     String name = baseName; 
     for (int index = 0; index < arguments.length; index++) { 
      name += "_" + arguments[index]; 
     } 
     return name + ".properties"; 
    } 

    private void populate(URL resourceUrl) { 
     if (resourceUrl != null) { 
      Properties props = new Properties(); 
      InputStream stream = null; 
      try { 
       stream = resourceUrl.openStream(); 
       props.load(stream); 
      } catch (IOException e) { 
       warn("Could not open the resource file " + resourceUrl, e); 
      } finally { 
       try { 
        stream.close(); 
       } catch (IOException e) { 
        warn("Could not close stream for resource file " + resourceUrl, e); 
       } 
      } 
      for (Object key : props.keySet()) { 
       translations.put((String) key, (String) props.get(key)); 
      } 
     } 
    } 

    /** 
    * @param key The key to translate. 
    * @param arguments Array of arguments to format into the translated text. May be empty. 
    * @return The formatted translated string. 
    */ 
    public String getTranslated(String key, Object...arguments) { 
     String translation = translations.get(key); 
     if (translation != null) { 
      if (arguments != null) { 
       translation = MessageFormat.format(translation, arguments); 
      } 
     } else { 
      translation = "!! " + key; 
      if (!knownMissing.contains(key)) { 
       warn("Could not find any translation text for " + key, null); 
       knownMissing.add(key); 
      } 
     } 
     return translation; 
    } 

    private void warn(String string, Throwable cause) { 
     Status status; 
     if (cause == null) { 
      status = new Status(
        IStatus.ERROR, 
        MiddlewareActivator.PLUGIN_ID, 
        string); 
     } else { 
      status = new Status(
       IStatus.ERROR, 
       MiddlewareActivator.PLUGIN_ID, 
       string, 
       cause); 
     } 
     MiddlewareActivator.getDefault().getLog().log(status); 

    } 

    /** 
    * @return The NLS instance. 
    */ 
    public static HackedNLS getInstance() { 
     return instance; 
    } 

    /** 
    * @param key The key to translate. 
    * @param arguments Array of arguments to format into the translated text. May be empty. 
    * @return The formatted translated string. 
    */ 
    public static String getText(String key, Object...arguments) { 
     return getInstance().getTranslated(key, arguments); 
    } 
} 
+0

getLocalizedEntry bundle.getResourceとbundle.getEntryは、getResourceに必要なクラスパス(フラグメント内にあるもの)のファイルとして必要ですが、プラグインのルート(プラグインのローカリゼーション)にはgetEntryが必要です。 また、誰かがより良い回答をお持ちでしたら、お気軽にお問い合わせください。 –

+0

あなたが提供したクラスの使い方がわかりません。たとえば、plugin.xmlファイルで宣言されたパースペクティブ名を、bundle.propertiesファイルを見る方法とは異なる方法で変換するために使用できますか? – Peteter

0

一つの方法は、バンドルリスナーを添付して、バンドルのインストールに聞く(そしておそらく、すでにインストールバンドルを見て)、各バンドルの生成/提供することであり。これがアプリケーションの起動前に行われている場合は、これが有効になります。