Refactor, document

This commit is contained in:
dotasek 2022-10-27 17:52:38 -04:00
parent 865f41b71f
commit da14683990
2 changed files with 37 additions and 15 deletions

View File

@ -14,6 +14,8 @@ import java.util.ResourceBundle;
*/ */
public abstract class I18nBase { public abstract class I18nBase {
public static final String PLURAL_SUFFIX = "PLURAL";
public static final String KEY_DELIMITER = "_";
private Locale locale; private Locale locale;
private ResourceBundle i18nMessages; private ResourceBundle i18nMessages;
private PluralRules pluralRules; private PluralRules pluralRules;
@ -72,17 +74,17 @@ public abstract class I18nBase {
* @return The formatted, internationalized, {@link String} * @return The formatted, internationalized, {@link String}
*/ */
public String formatMessage(String theMessage, Object... theMessageArguments) { public String formatMessage(String theMessage, Object... theMessageArguments) {
if (theMessage.endsWith("_PLURAL")) { if (isPluralKey(theMessage)) {
throw new Error("I18n error: Plural Message called in non-plural mode"); throw new Error("I18n error: Plural Message called in non-plural mode");
} }
return formatMessageP(theMessage, theMessageArguments); return formatMessagePlural(theMessage, theMessageArguments);
} }
protected String getPluralKey(Integer number, String baseKey) { protected String getPluralKey(Integer number, String baseKey) {
return baseKey + "_" + pluralRules.select(number); return baseKey + KEY_DELIMITER + pluralRules.select(number);
} }
private String formatMessageP(String theMessage, Object... theMessageArguments) { private String formatMessagePlural(String theMessage, Object... theMessageArguments) {
String message = theMessage; String message = theMessage;
if (messageExistsForLocale(theMessage, (theMessageArguments != null && theMessageArguments.length > 0))) { if (messageExistsForLocale(theMessage, (theMessageArguments != null && theMessageArguments.length > 0))) {
if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) {
@ -93,8 +95,24 @@ public abstract class I18nBase {
} }
return message; return message;
} }
public String formatMessagePL(Integer plural, String theMessage, Object... theMessageArguments) {
if (!theMessage.endsWith("_PLURAL")) { /**
* Formats the message with locale correct pluralization using the passed in
* message arguments.
*
* In the message properties files, each plural specific message will have a
* key consisting of a root key and a suffix denoting the plurality rule (_one
* for singular, _other for multiple in English, for example). Suffixes are
* provided by th ICU4J library from unicode.org
*
* @param plural The number that indicates the plurality of the phrase
* @param theMessage the root key of the phrase.
* @param theMessageArguments Placeholder arguments, if needed.
* @return The formatted, internationalized, {@link String}
*/
public String formatMessagePlural(Integer plural, String theMessage, Object... theMessageArguments) {
if (!isPluralKey(theMessage)) {
throw new Error("I18n error: Non-plural Message called in plural mode"); throw new Error("I18n error: Non-plural Message called in plural mode");
} }
Object[] args = new Object[theMessageArguments.length+1]; Object[] args = new Object[theMessageArguments.length+1];
@ -104,7 +122,11 @@ public abstract class I18nBase {
} }
checkPluralRulesAreLoaded(); checkPluralRulesAreLoaded();
String pluralKey = getPluralKey(plural, theMessage); String pluralKey = getPluralKey(plural, theMessage);
return formatMessageP(pluralKey, args); return formatMessagePlural(pluralKey, args);
}
private static boolean isPluralKey(String theMessage) {
return theMessage.endsWith(KEY_DELIMITER + PLURAL_SUFFIX);
} }
/** /**

View File

@ -52,11 +52,11 @@ class I18nBaseTest {
I18nTestClass testClass = new I18nTestClass(); I18nTestClass testClass = new I18nTestClass();
//Answer value must be of the type {1} //Answer value must be of the type {1}
String resultOne = testClass.formatMessagePL(1, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL); String resultOne = testClass.formatMessagePlural(1, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL);
assertThat(resultOne, containsString("be of the type")); assertThat(resultOne, containsString("be of the type"));
//Answer value must be one of the {0} types {1} //Answer value must be one of the {0} types {1}
String resultMany = testClass.formatMessagePL(3, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL); String resultMany = testClass.formatMessagePlural(3, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL);
assertThat(resultMany, containsString("one of the 3 types ")); assertThat(resultMany, containsString("one of the 3 types "));
} }
@ -65,14 +65,14 @@ class I18nBaseTest {
@DisplayName("Test pluralization works with initializing Locale.") @DisplayName("Test pluralization works with initializing Locale.")
void testFormatMessagePluralWithInitLocale() { void testFormatMessagePluralWithInitLocale() {
I18nTestClass testClass = new I18nTestClass(); I18nTestClass testClass = new I18nTestClass();
testClass.setLocale(Locale.GERMAN); testClass.setLocale(Locale.GERMAN);
//Answer value muss vom Typ {0} sein. //Answer value muss vom Typ {0} sein.
String resultOne = testClass.formatMessagePL(1, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL); String resultOne = testClass.formatMessagePlural(1, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL);
assertThat(resultOne, containsString("muss vom Typ")); assertThat(resultOne, containsString("muss vom Typ"));
//Answer value muss einer der Typen {1} sein //Answer value muss einer der Typen {1} sein
String resultMany = testClass.formatMessagePL(3, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL); String resultMany = testClass.formatMessagePlural(3, I18nConstants.QUESTIONNAIRE_QR_ITEM_WRONGTYPE_PLURAL);
assertThat(resultMany, containsString("einer der Typen ")); assertThat(resultMany, containsString("einer der Typen "));
} }
@ -123,11 +123,11 @@ class I18nBaseTest {
ResourceBundle loadedBundle = ResourceBundle.getBundle("Messages", Locale.GERMAN); ResourceBundle loadedBundle = ResourceBundle.getBundle("Messages", Locale.GERMAN);
PluralRules pluralRules = PluralRules.forLocale(Locale.GERMANY); PluralRules pluralRules = PluralRules.forLocale(Locale.GERMANY);
for (String key : loadedBundle.keySet()) { for (String key : loadedBundle.keySet()) {
String[] keyComponent = key.split("_"); String[] keyComponent = key.split(I18nBase.KEY_DELIMITER);
assertFalse(keyComponent[keyComponent.length - 1].equalsIgnoreCase("PLURAL"), "Invalid use of PLURAL keyword for key: " + key); assertFalse(keyComponent[keyComponent.length - 1].equalsIgnoreCase(I18nBase.PLURAL_SUFFIX), "Invalid use of PLURAL keyword for key: " + key);
if (keyComponent.length > 2 if (keyComponent.length > 2
&& keyComponent[keyComponent.length - 2].equalsIgnoreCase("PLURAL")) { && keyComponent[keyComponent.length - 2].equalsIgnoreCase(I18nBase.PLURAL_SUFFIX)) {
assertTrue(pluralRules.getKeywords().contains(keyComponent[keyComponent.length - 1])); assertTrue(pluralRules.getKeywords().contains(keyComponent[keyComponent.length - 1]));
} }
} }