Вопрос

Мой проект включает в себя несколько плагинов, и каждый плагин включает файл плагина.properties, содержащий около 20 переводов.Файл MANIFEST.MF определяет имена файлов свойств, в которых хранятся строки внешнего плагина.

Bundle-Localization: plugin

Имя плагина я определяю как

%plugin.name

Eclipse будет искать «%plugin.name» в файле плагина.properties во время выполнения.

Какой класс считывает запись MANIFEST.MF Bundle-Localization и в какой момент в файле «plugin.properties» выполняется поиск строки с начальным суффиксом «%»?

Я хочу найти и исправить этот класс таким образом, чтобы сначала просмотреть некоторые другие каталоги/файлы на предмет идентификатора «%plugin.name».С помощью этого нового механизма я могу добавлять фрагменты в свой продукт и перезаписывать отдельные строки в файле «plugin.properties», не меняя исходный плагин.С помощью этого механизма я мог бы создать процесс сборки для нескольких клиентов, просто добавляя разные фрагменты.Фрагменты, включающие имена клиентов и специальную строку, которую они хотят изменить.

Я хочу сделать именно так, потому что механизм фрагментирования только добавляет файлы в исходный плагин.Если в плагине существует файл «plugin.properties», файлы фрагмента «plugin.properties» игнорируются.

ОБНОВЛЕНИЕ 1:

Метод

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

возвращает ResourceBundle файла свойств для данной строки языкового стандарта.Когда кто-нибудь узнает, как я могу сначала просмотреть фрагмент, чтобы получить путь к ресурсу, опубликуйте его.

ОБНОВЛЕНИЕ 2:

Метод в классе ManifestLocalization

    private URL findInResolved(String filePath, AbstractBundle bundleHost) {

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

Ищет файл свойств и кэширует его.Переводы можно получить из кэшированного файла.Проблема в том, что кэшируется весь файл, а не отдельные переводы.

Решением было бы сначала прочитать файл фрагмента, а затем прочитать файл пакета.Когда оба файла существуют, объедините их в один файл и запишите новый файл свойств на диск.Возвращается URL-адрес нового файла свойств, чтобы новый файл свойств можно было кэшировать.

Это было полезно?

Решение

Хотя я неправильно понял информацию...У меня была точно такая же проблема.Плагин дважды не активируется и я не могу добраться до фрагментов Bundle-Key Localization.

Я хочу, чтобы все мои языковые переводы были в плагине.properties (я знаю, что это не одобряется, но гораздо проще управлять одним файлом).

Я (половину) решил проблему, используя

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.

Если у кого-то есть лучший подход, пожалуйста, поправьте меня.

Всего наилучшего,

Отметка.

Другие советы

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

Измените имя вашего фрагмента плагин.свойства на что-нибудь другое, например.фрагмент.свойства

В вашем фрагменте Manifest Измените локализацию пакета:плагин на пакет-локализацию:фрагмент

Ваш плагин будет активирован дважды: первый раз с помощью плагина.properties, второй с помощью фрагмента.свойств.

Активация плагина осуществляется средой выполнения OSGi Equinox.Однако я бы настоятельно не рекомендовал исправлять какие-либо файлы для создания определенного поведения.Предложенный способ Марка кажется гораздо более разумным подходом к вашей проблеме.

Один из способов — подключить прослушиватель пакетов и прослушивать установки пакетов (и, возможно, также просматривать уже установленные пакеты), а также для каждого пакета генерировать/предоставлять — и устанавливать — фрагмент с нужными файлами свойств.Если это сделать до запуска приложения, это должно иметь эффект.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top