Frage

Ihr Projekt umfasst mehrere Plugins und jedes Plugin enthält die plugin.properties bis 20 Übersetzungen mit in der Nähe von Datei. Die MANIFEST.MF Datei definiert den Namen der Eigenschaften Dateien, in denen die externen Plugin Strings gespeichert werden.

Bundle-Localization: plugin

Der Name des Plug-in i wie

definieren
%plugin.name

Eclipse das "% plugin.name" in der plugin.properties Datei zur Laufzeit suchen.

Welche Klasse des MANIFEST.MF Bundle-Lokalisierung Eintrag ausgelesen und an welcher Stelle die Zeichenfolge mit dem Start ‚%‘ Suffix wird in der „plugin.properties“ Datei gesucht?

Ich möchte finden und diese Klasse auf diese Weise patchen, dass ich zum ersten Mal in einige andere Verzeichnisse / Dateien für die „% plugin.name“ identifier aussehen kann. Mit diesem neuen Mechanismus kann ich Fragmente zu meinem Produkt hinzufügen und einzelne Zeilen in einer „plugin.properties“ Datei überschreiben, ohne die Original-Plugin zu ändern. Mit diesem Mechanismus, indem verschiedene Fragmenten einen Build-Prozess für mehrere Kunden erstellen, ich könnte. Die Fragmente, einschließlich der Kundennamen und spezielle Zeichenfolge sie ändern möchten.

Ich mag es so tun, weil nur das Fragment Mechanismus Dateien in der ursprünglichen Plugin hinzufügen. Wenn die „plugin.properties“ Datei wird im Plugin vorhanden, werden die Fragment „plugin.properties“ Dateien ignoriert.

UPDATE 1:

Die Methode

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

gibt die Resource der Eigenschaften für die angegebene locale String-Datei. Wenn jemand nows wie kann ich jetzt zuerst das Fragment schauen Sie in den Ressourcenpfad erhalten bitte posten.

UPDATE 2:

Die Methode in der Klasse ManifestLocalization

    private URL findInResolved(String filePath, AbstractBundle bundleHost) {

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

Suchen für die Eigenschaftendatei und Cache es. Die Übersetzungen können als von der Cache-Datei erhalten. Das Problem ist, dass die vollständige Datei zwischengespeichert wird und nicht einzelne Übersetzungen.

Eine Lösung wäre, zuerst die Fragment-Datei zu lesen, als die Bundle-Datei lesen. Wenn beide Dateien vorhanden sind, werden kombinieren sie in eine Datei schreiben Datei die neuen Eigenschaften auf die Platte. Die URL der neuen Eigenschaftsdatei zurückkehrt, so dass die neue propetries Datei zwischengespeichert werden.

War es hilfreich?

Lösung

Auch wenn ich die Informationen falsch verstanden ... Ich hatte genau das gleiche Problem. Das Plugin ist nicht zweimal aktiviert und ich kann nicht an die Fragmente Bundle-Lokalisierungsschlüssel erhalten.

ich meine Sprachübersetzungen alle will in dem plugin.properties (Ich weiß, das ist verpönt, aber es ist viel einfacher, eine einzelne Datei zu verwalten).

I (halb) löste das Problem, indem sie mit

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())));
}

und einfach mein Fragment Lokalisierungsdateinamen 'fragment.properties' nennen.

Das ist nicht besonders elegant, aber es funktioniert.

Durch die Art und Weise zu bekommen, Dateien aus dem Fragmente Sie das getResource benötigen, scheint es, dass Fragment-Dateien auf dem Classpath sind, oder werden nur durchsucht, wenn getResource verwendet wird.

Wenn jemand eine bessere Lösung hat, bitte korrigieren Sie mich.

Alles Gute,

Mark.

Andere Tipps

/**
 * 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);
    }
}

Ändern Sie den Namen Ihres Fragment plugin.properties auf etwas anderes zB. fragment.properties

in Ihrem Fragmente die ändern manifest Bundle-Lokalisierung: Plugin zu Bundle-Lokalisierung: Fragment

Ihr Plugin zweimal aktiviert wird, zum ersten Mal die plugin.properties verwendet wird, der zweite die fragment.properties verwendet wird.

Plugin-Aktivierung wird durch die OSGi Runtime Equinox behandelt. Allerdings würde ich dringend abraten alle Dateien versuchen, es zu patchen bestimmtes Verhalten zu erstellen. Der vorgeschlagene Weg von Mark scheint ein viel vernünftiger Ansatz für Ihr Problem.

Eine Möglichkeit ist, ein Bündel Hörer zu befestigen und hört für Installationen von Bündeln (und vielleicht auch bei bereits installierten Paketen suchen) und für jedes Bündel erzeugen / liefern - und installieren - ein Fragment mit den gewünschten Eigenschaftsdateien. Wenn dies geschehen ist, bevor die Anwendung gestartet wird, sollte dies Auswirkungen haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top