KEYCLOAK-8818 Support message bundle in theme resources
This commit is contained in:
parent
c2f3350f8a
commit
9c37da0ee9
5 changed files with 66 additions and 10 deletions
|
@ -17,12 +17,13 @@
|
|||
|
||||
package org.keycloak.theme;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* A theme resource provider can be used to load additional templates and resources. An example use of this would be
|
||||
|
@ -53,4 +54,17 @@ public interface ThemeResourceProvider extends Provider {
|
|||
*/
|
||||
InputStream getResourceAsStream(String path) throws IOException;
|
||||
|
||||
/**
|
||||
* Load the message bundle for the specific name and locale
|
||||
*
|
||||
* @param baseBundlename The base name of the bundle, such as "messages" in
|
||||
* messages_en.properties.
|
||||
* @param locale The locale of the desired message bundle.
|
||||
* @return The localized messages from the bundle.
|
||||
* @throws IOException If bundle can not be read.
|
||||
*/
|
||||
default Properties getMessages(String baseBundlename, Locale locale) throws IOException{
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
package org.keycloak.theme;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
public class ClasspathThemeResourceProviderFactory implements ThemeResourceProviderFactory, ThemeResourceProvider {
|
||||
|
||||
public static final String THEME_RESOURCES_TEMPLATES = "theme-resources/templates/";
|
||||
public static final String THEME_RESOURCES_RESOURCES = "theme-resources/resources/";
|
||||
public static final String THEME_RESOURCES_MESSAGES = "theme-resources/messages/";
|
||||
|
||||
private final String id;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
|
@ -35,6 +42,21 @@ public class ClasspathThemeResourceProviderFactory implements ThemeResourceProvi
|
|||
return classLoader.getResourceAsStream(THEME_RESOURCES_RESOURCES + path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getMessages(String baseBundlename, Locale locale) throws IOException {
|
||||
Properties m = new Properties();
|
||||
InputStream in = classLoader.getResourceAsStream(THEME_RESOURCES_MESSAGES + baseBundlename + "_" + locale.toString() + ".properties");
|
||||
if(in != null){
|
||||
Charset encoding = PropertiesUtil.detectEncoding(in);
|
||||
// detectEncoding closes the stream
|
||||
try (Reader reader = new InputStreamReader(
|
||||
classLoader.getResourceAsStream(THEME_RESOURCES_MESSAGES + baseBundlename + "_" + locale.toString() + ".properties"), encoding)) {
|
||||
m.load(reader);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
|
|
|
@ -257,6 +257,10 @@ public class ExtendingThemeManager implements ThemeProvider {
|
|||
messages.putAll(getMessages(baseBundlename, Locale.ENGLISH));
|
||||
}
|
||||
|
||||
for (ThemeResourceProvider t : themeResourceProviders ){
|
||||
messages.putAll(t.getMessages(baseBundlename, locale));
|
||||
}
|
||||
|
||||
ListIterator<Theme> itr = themes.listIterator(themes.size());
|
||||
while (itr.hasPrevious()) {
|
||||
Properties m = itr.previous().getMessages(baseBundlename, locale);
|
||||
|
@ -264,7 +268,7 @@ public class ExtendingThemeManager implements ThemeProvider {
|
|||
messages.putAll(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.messages.putIfAbsent(baseBundlename, new ConcurrentHashMap<Locale, Properties>());
|
||||
this.messages.get(baseBundlename).putIfAbsent(locale, messages);
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
test.keycloak-8818= Hello from theme-resources
|
||||
fullName=Full name (Theme-resources)
|
|
@ -1,5 +1,8 @@
|
|||
package org.keycloak.testsuite.theme;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
|
@ -10,8 +13,6 @@ import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
|||
import org.keycloak.theme.Theme;
|
||||
import org.keycloak.theme.ThemeProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ThemeResourceProviderTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
|
@ -50,4 +51,17 @@ public class ThemeResourceProviderTest extends AbstractTestRealmKeycloakTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMessages() {
|
||||
testingClient.server().run(session -> {
|
||||
try {
|
||||
ThemeProvider extending = session.getProvider(ThemeProvider.class, "extending");
|
||||
Theme theme = extending.getTheme("base", Theme.Type.LOGIN);
|
||||
Assert.assertNotNull(theme.getMessages("messages", Locale.ENGLISH).get("test.keycloak-8818"));
|
||||
Assert.assertNotEquals("Full name (Theme-resources)", theme.getMessages("messages", Locale.ENGLISH).get("fullName"));
|
||||
} catch (IOException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue