Как избежать повторения в строках Java ResourceBundle?
-
25-09-2019 - |
Вопрос
У нас было много строк, которые содержали одну и ту же подкруку, от предложений о проверке журнала или того, как связаться с поддержкой, к брендингу строк, содержащих компанию или название продукта. Повторение вызвало несколько вопросов для себя (в первую очередь опечатки или копирования / вставки), но это также вызывает проблемы, в том, что он увеличивает количество текста нашего переводчика, чтобы перевести.
Решение, которое я придумал, пошел что-то вроде этого:
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
Делегаты на реальный пакет ресурсов, но выполняет преобразование {{it.kind.oft}}, чтобы посмотреть ключ в ресурсах.
Каждый раз, когда вы хотите получить один из них, вам нужно идти:
ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING);
И это работает нормально - на некоторое время.
Что в конечном итоге произойдет, является то, что какой-то новый код (в нашем случае аутогенерационный код, который был выпущен из Matisse), выглядит тот же пакет ресурсов, не указав пользовательский контроль. Это, по-видимому, не воспроизводимо, если вы пишете простую единицу теста, который вызывает его, а затем без, но он возникает, когда приложение будет работать на реальном. Как-то кэш внутри ResourceBundle
Извлеките хорошее значение и заменяет его сломанным. Я еще раз выяснил, почему и файлы BAR SUN были скомпилированы без отладочной информации, поэтому отладка это под русло.
Мои вопросы:
Есть ли у некоторых способов по умолчанию ResourceBundle ResourceBundle.Control, о котором я не могу знать? Это решило бы все довольно элегантно.
Есть ли какой-то другой способ обрабатывать такого рода вещь элегантно, возможно, без подделок с классами ResourceBundle вообще?
Решение
Я думаю, что это фундаментальный недостаток в том, как RescountBunds предназначены для функции: ключей, которые ссылочные другие клавиши автоматически нарушают сухую (не повторяйте себя) принцип. То, как я продвинулся, это было похоже на ваш метод: создать класс отражателей, который позволяет указывать клавиши ресурсов в сообщениях, используя El Notiator.
НЕПРАВИЛЬНЫЙ ПУТЬ:
my.name.first=Bob
my.name.last=Smith
my.name.full=Bob Smith
ПРАВИЛЬНЫЙ ПУТЬ:
my.name.first=Bob
my.name.last=Smith
my.name.full=${my.name.first} ${my.name.last}
У меня есть Загрузил код в GitHub Так вы или кто-то еще можно скачать его. Кроме того, я добавил какой-либо пример код для тех, кто использует Framework Plasses (http://www.stripesfraamework.org/) Чтобы вы быстро и бегаете.
Хитрость, чтобы получить это на работу со стандартным стандартом GSTL FMT Taglibs, было установить перехватчик, который заменил ресурс httpservletrequest с нашим собственным. Код выглядит что-то вроде этого:
ResourceBundle bundle = MyStaticResourceHoldingTheBundle.getBundle();
Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));
Посмотрите на пакет Plasses.interceptor в ссылке выше для более подробной информации.
Другие советы
Если повторения струн локализованы в том смысле, что вы знаете, что определенная строка будет повторяться, но только в том же проекте такой, что обменные распределения ресурсов не являются кошмаром-дизайном, то вы можете рассмотреть возможность разбития строк в несколько частей ключей. Разделите части, которые повторяют из тех, которые не имеют и повторно используют повторные детали. Например, позволяет сказать, что у вас есть следующие две строки, которые вам нужно отобразить:
- «Red-Cheaped Robin - это маленькая береговая птица, родная в Австралии».
- «Red-Cheaped Robin находится в сушильных областях на большую часть континента».
Пакет ресурсов может быть следующим:
robin.name=The Red-capped Robin
robin.native=is a small passerine bird native to Australia.
robin.region=is found in dryer regions across much of the continent.
а затем объединить необходимые части, где это необходимо bundle.getString("robin.name")+bundle.getString(robin.native).
Одна вещь, о которой вы должны быть осторожны, тем не менее, это то, что грамматические правила, такие как порядок предиката субъекта и т. Д., Возможно, не одинаково на всех языках. Таким образом, вам нужно было быть немного осторожным при расщеплении предложений.