У нас было много строк, содержащих одну и ту же подстроку, от предложений о проверке журнала или о том, как связаться со службой поддержки, до строк, похожих на брендинг, содержащих название компании или продукта. Повторение вызывало у нас несколько проблем (в первую очередь опечатки или ошибки копирования/вставки), но оно также вызывает проблемы, поскольку увеличивает объем текста, который наш переводчик должен перевести.
Решение, которое я придумал, выглядело примерно так:
public class ExpandingResourceBundleControl extends ResourceBundle.Control {
public static final ResourceBundle.Control EXPANDING =
new ExpandingResourceBundleControl();
private ExpandingResourceBundleControl() { }
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
ResourceBundle inner = super.newBundle(baseName, locale, format, loader, reload);
return inner == null ? null : new ExpandingResourceBundle(inner, loader);
}
}
ExpandingResourceBundle
делегирует реальный пакет ресурсов, но выполняет преобразование {{this.kind.of.thing}} для поиска ключа в ресурсах.
Каждый раз, когда вы хотите получить один из них, вы должны пойти:
ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING);
И это прекрасно работает - какое-то время.
Что в конечном итоге происходит, так это то, что какой-то новый код (в нашем случае автоматически сгенерированный код, который был выброшен из Matisse) ищет тот же пакет ресурсов без указания пользовательского элемента управления. Это кажется невоспроизводимым, если вы пишете простой модульный тест, который вызывает его с и без, но это происходит, когда приложение запускается по-настоящему. Каким-то образом кеш внутри ResourceBundle
извлекает хорошее значение и заменяет его неработающим. Мне еще предстоит выяснить, почему, и файлы jar Sun были скомпилированы без отладочной информации, поэтому отладка - это рутинная работа.
Мои вопросы:
Есть ли способ глобально установить ResourceBundle.Control по умолчанию, о котором я мог не знать? Это решило бы все довольно элегантно.
Есть ли какой-то другой способ элегантно справиться с такими вещами, возможно, вообще не вмешиваясь в классы ResourceBundle?