Создать объект Properties из ResourceBundle? - PullRequest
0 голосов
/ 07 июля 2011

У меня есть "нормальная" Java PropertyResourceBundle, которая основана на стеке .properties файлов.В некоторых местах было бы гораздо удобнее работать с объектом Properties на основе правильного переведенного файла .properties вместо ResourceBundle.Есть ли удобный способ "привести" ResourceBundle к Properties?

Что бы я хотел, это примерно так:

Locale currentLocale = MagicLocaleFactory.getLocale();
ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);

Properties myProperties = myResources.magicallyProduceAPropertiesObject();

Итак, после слов,myProperties объект ведет себя так, как если бы он был создан из того же файла .properties, который был найден ResourceBundle.getBundle().

Есть несколько способов сделать это "вручную";например, перебирая набор пар ключ-значение ResourceBundle и устанавливая их в новый объект Properties, но я надеялся, что есть лучший или, по крайней мере, более короткий способ сделать это.

Редактировать:

Чтобы ответить на очевидное "но, ПОЧЕМУ?"вопрос, дело в том, что мы модернизируем давно существующую настольную Java-программу для i18n.Программа уже извлекает строки из объекта Properties, поддерживаемого одним файлом .properties.Мы заменяем один файл несколькими файлами и «продвигаем» объект Properties в пакет ресурсов.Проблема, такая как есть, состоит в том, что метод получения ключа для Properties - это getProperty, тогда как для ResourceBundle это getString или getObject.Изменить источник Properties до того, как он обойдёт программу и вытащить строки, очень легко.Изменение фактического вызова метода ... менее просто.Конечно, вы можете в значительной степени искать и заменять это, но затем вместо того, чтобы просто изменить один класс, который загружает свойства, мы должны коснуться, по сути, каждого исходного файла.(Да, в этой статье много текста.) Мы надеялись, что упустили способ использования кратного .properties ResourceBundle с резервным механизмом без необходимости перемонтировать все приложение.(Благодарная цитата Гэндальфа: «Надежды никогда не было. Просто надежда дурака».)

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

Там нет ни по одной и по уважительной причине: ResourceBundle должен содержать свойства на разных языках, чтобы он загружал * и резервный соответствующий файл - когда вы запрашиваете, скажем, сообщения с де -AT locale (немецкий, Австрия), в противном случае он обратится к немецкому, если сможет найти один или ваш базовый файл свойств (messages.properties) в другом случае.

Я действительно не знаю, какой у вас здесь вариант использования (может, это просто достижимо другим способом?), Но, похоже, единственный способ - это читать напрямую из файла свойств и, к сожалению, имитировать механизм, который я упомянул выше ( самая сложная часть - это португальский, бразильский и традиционный китайский, которые не должны возвращаться к своим языкам «по умолчанию» («pt» и «zh» соответственно)).

3 голосов
/ 07 июля 2011

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

Однако есть одна оговорка.Хотя интерфейс похож, реализация не такова: пакет ресурсов имеет модель наследования, которая позволяет возвращать значение в foo.properties, если оно не определено в foo_fr_FR.properties и foo_fr.properties.Таким образом, при копировании всех записей вы не получите те же свойства, которые были загружены из файла свойств.Он получит записи файла свойств и свойства всех его родителей.Но я думаю, вы знали, что, поскольку вы говорите о стеке файлов свойств.

Вы не указали почему вы бы предпочли Properties вместо ResourceBundle, поэтому трудно датьВы лучше ответите.

Другое решение - просто загрузить свойства самостоятельно:

Properties props = new Properties();
properties.load(MyClass.class.getResourceAsStream("MyResources_" + locale + ".properties")

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

0 голосов
/ 18 мая 2017

Другим решением является итерация по ключам и помещение всей пары в объект свойств. Вы можете использовать convertBundleToProperties:

static Properties convertBundleToProperties(ResourceBundle resource) {
    Properties properties = new Properties();

    Enumeration<String> keys = resource.getKeys();
    while (keys.hasMoreElements()) {
      String key = keys.nextElement();
      properties.put(key, resource.getString(key));
    }

    return properties;
 }
...