KEYCLOAK-12926 Improve Locale based message lookup

We now consider intermediate Locales when performing a Locale based
ResourceBundle lookup, before using an Locale.ENGLISH fallback.

Co-authored-by: stianst <stianst@gmail.com>
This commit is contained in:
Thomas Darimont 2020-02-07 01:14:16 +01:00 committed by Stian Thorgersen
parent d352d3fa8e
commit 67ddd3b0eb
8 changed files with 68 additions and 3 deletions

View file

@ -255,8 +255,10 @@ public class ExtendingThemeManager implements ThemeProvider {
if (messages.get(baseBundlename) == null || messages.get(baseBundlename).get(locale) == null) {
Properties messages = new Properties();
if (!Locale.ENGLISH.equals(locale)) {
messages.putAll(getMessages(baseBundlename, Locale.ENGLISH));
Locale parent = getParent(locale);
if (parent != null) {
messages.putAll(getMessages(baseBundlename, parent));
}
for (ThemeResourceProvider t : themeResourceProviders ){
@ -309,4 +311,21 @@ public class ExtendingThemeManager implements ThemeProvider {
}
}
}
private static Locale getParent(Locale locale) {
if (Locale.ENGLISH.equals(locale)) {
return null;
}
if (locale.getVariant() != null && !locale.getVariant().isEmpty()) {
return new Locale(locale.getLanguage(), locale.getCountry());
}
if (locale.getCountry() != null && !locale.getCountry().isEmpty()) {
return new Locale(locale.getLanguage());
}
return Locale.ENGLISH;
}
}

View file

@ -1,2 +1,4 @@
test.keycloak-8818= Hello from theme-resources
fullName=Full name (Theme-resources)
fullName=Full name (Theme-resources)
test.keycloak-12926=Test en
test.keycloak-12926-resolving3=fallback en

View file

@ -0,0 +1,3 @@
test.keycloak-8818= Hello from theme-resources
fullName=Full name (Theme-resources)
test.keycloak-12926=Test en_US

View file

@ -0,0 +1,3 @@
test.keycloak-8818= Hello from theme-resources
fullName=Full name (Theme-resources)
test.keycloak-12926=Test en_US_variant

View file

@ -60,4 +60,39 @@ public class ThemeResourceProviderTest extends AbstractTestRealmKeycloakTest {
}
});
}
/**
* See KEYCLOAK-12926
*/
@Test
public void getMessagesLocaleResolving() {
testingClient.server().run(session -> {
try {
ThemeProvider extending = session.getProvider(ThemeProvider.class, "extending");
Theme theme = extending.getTheme("base", Theme.Type.LOGIN);
Assert.assertEquals("Test en_US_variant", theme.getMessages("messages", new Locale("en", "US", "variant")).get("test.keycloak-12926"));
Assert.assertEquals("Test en_US", theme.getMessages("messages", new Locale("en", "US")).get("test.keycloak-12926"));
Assert.assertEquals("Test en", theme.getMessages("messages", Locale.ENGLISH).get("test.keycloak-12926"));
Assert.assertEquals("Test en_US", theme.getMessages("messages", new Locale("en", "US")).get("test.keycloak-12926"));
Assert.assertEquals("Test en", theme.getMessages("messages", Locale.ENGLISH).get("test.keycloak-12926"));
Assert.assertEquals("only de_AT_variant", theme.getMessages("messages", new Locale("de", "AT", "variant")).get("test.keycloak-12926-resolving1"));
Assert.assertNull(theme.getMessages("messages", new Locale("de", "AT")).get("test.keycloak-12926-resolving1"));
Assert.assertEquals("only de_AT", theme.getMessages("messages", new Locale("de", "AT", "variant")).get("test.keycloak-12926-resolving2"));
Assert.assertNull(theme.getMessages("messages", new Locale("de")).get("test.keycloak-12926-resolving2"));
Assert.assertEquals("only de", theme.getMessages("messages", new Locale("de", "AT", "variant")).get("test.keycloak-12926-only_de"));
Assert.assertNull(theme.getMessages("messages", Locale.ENGLISH).get("test.keycloak-12926-only_de"));
Assert.assertEquals("fallback en", theme.getMessages("messages", new Locale("de", "AT", "variant")).get("test.keycloak-12926-resolving3"));
Assert.assertEquals("fallback en", theme.getMessages("messages", new Locale("de", "AT")).get("test.keycloak-12926-resolving3"));
Assert.assertEquals("fallback en", theme.getMessages("messages", new Locale("de")).get("test.keycloak-12926-resolving3"));
Assert.assertNull(theme.getMessages("messages", Locale.ENGLISH).get("fallback en"));
} catch (IOException e) {
Assert.fail(e.getMessage());
}
});
}
}