keycloak-aplcache

Changes

forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_de.properties 6(+0 -6)

forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_en.properties 6(+0 -6)

Details

diff --git a/docbook/reference/en/en-US/modules/themes.xml b/docbook/reference/en/en-US/modules/themes.xml
index cd59f38..10b2417 100755
--- a/docbook/reference/en/en-US/modules/themes.xml
+++ b/docbook/reference/en/en-US/modules/themes.xml
@@ -181,6 +181,12 @@ import=common/keycloak
                 <literal>messages/messages.properties</literal> inside your theme folder and add the following content:
             </para>
             <programlisting>username=Your Username</programlisting>
+            <para>
+                For the admin console, there is a second resource bundle named <literal>admin-messages.properties</literal>.
+                This resource bundle is converted to JSON and shipped to the console to be processed by
+                angular-translate.  It is found in the same directory as messages.properties and can be overridden
+                in the same way as described above.
+            </para>
         </section>
         <section>
             <title>Modifying HTML</title>
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
index 31b1d22..2f845e0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
@@ -285,8 +285,7 @@ public class AdminConsole {
             map.put("resourceUrl", Urls.themeRoot(baseUri) + "/admin/" + adminTheme);
             map.put("resourceVersion", Version.RESOURCES_VERSION);
 
-            ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
-            Theme theme = themeProvider.getTheme(realm.getAdminTheme(), Theme.Type.ADMIN);
+            Theme theme = getTheme();
 
             map.put("properties", theme.getProperties());
 
@@ -298,6 +297,11 @@ public class AdminConsole {
         }
     }
 
+    private Theme getTheme() throws IOException {
+        ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
+        return themeProvider.getTheme(realm.getAdminTheme(), Theme.Type.ADMIN);
+    }
+
     @GET
     @Path("{indexhtml: index.html}") // this expression is a hack to get around jaxdoclet generation bug.  Doesn't like index.html
     public Response getIndexHtmlRedirect() {
@@ -314,14 +318,14 @@ public class AdminConsole {
         }
 
         try {
-            Properties msgs = AdminMessagesLoader.getMessages(lang);
+            Properties msgs = AdminMessagesLoader.getMessages(getTheme(), lang);
             if (msgs.isEmpty()) {
                 logger.warn("Message bundle not found for language code '" + lang + "'");
-                msgs = AdminMessagesLoader.getMessages("en"); // fall back to en
+                msgs = AdminMessagesLoader.getMessages(getTheme(), "en"); // fall back to en
             }
 
             if (msgs.isEmpty()) logger.fatal("Message bundle not found for language code 'en'");
-            
+
             return msgs;
         } catch (IOException e) {
             throw new RuntimeException(e);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
index 709cb12..df0ce27 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
@@ -22,11 +22,13 @@ import java.io.FileInputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
+import org.keycloak.freemarker.Theme;
 
 /**
- * Simple loader for message bundles consumed by angular-translate.
+ * Simple loader and cache for message bundles consumed by angular-translate.
  *
  * Note that these bundles are converted to JSON before being shipped to the UI.
  * Also, the content should be formatted such that it can be interpolated by
@@ -35,59 +37,18 @@ import java.util.Properties;
  * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
  */
 public class AdminMessagesLoader {
-    private static final String CONFIG_DIR = System.getProperty("jboss.server.config.dir");
-    private static final String BUNDLE_DIR = CONFIG_DIR + "/themes/base/admin/angular-messages/";
-
     private static final Map<String, Properties> allMessages = new HashMap<String, Properties>();
 
-    static Properties getMessages(String locale) throws IOException {
-        Properties messages = allMessages.get(locale);
+    static Properties getMessages(Theme theme, String strLocale) throws IOException {
+        String allMessagesKey = theme.getName() + "_" + strLocale;
+        Properties messages = allMessages.get(allMessagesKey);
         if (messages != null) return messages;
 
-        return loadMessages(locale);
-    }
-
-    private static Properties loadMessages(String locale) throws IOException {
-        Properties masterMsgs = new Properties();
-
-        for (File file : getBundlesForLocale(locale)) {
-            try (FileInputStream msgStream = new FileInputStream(file)){
-                Properties propsFromFile = new Properties();
-                propsFromFile.load(msgStream);
-                checkForDups(masterMsgs, propsFromFile, file, locale);
-                masterMsgs.putAll(propsFromFile);
-            }
-        }
-
-        allMessages.put(locale, masterMsgs);
-        return masterMsgs;
-    }
-
-    private static void checkForDups(Properties masterMsgs, Properties propsFromFile, File file, String locale) {
-        for (String prop : propsFromFile.stringPropertyNames()) {
-            if (masterMsgs.getProperty(prop) != null) {
-                String errorMsg = "Message bundle " + file.getName() + " contains key '" + prop;
-                errorMsg += "', which already exists in another bundle for " + locale + " locale.";
-                throw new RuntimeException(errorMsg);
-            }
-        }
-    }
-
-    private static File[] getBundlesForLocale(String locale) {
-        File bundleDir = new File(BUNDLE_DIR);
-        return bundleDir.listFiles(new LocaleFilter(locale));
-    }
-
-    private static class LocaleFilter implements FilenameFilter {
-        private final String locale;
-
-        public LocaleFilter(String locale) {
-            this.locale = locale;
-        }
+        Locale locale = new Locale(strLocale);
+        messages = theme.getMessages("admin-messages", locale);
+        if (messages == null) return new Properties();
 
-        @Override
-        public boolean accept(File dir, String name) {
-            return name.endsWith("_" + locale + ".properties");
-        }
+        allMessages.put(allMessagesKey, messages);
+        return messages;
     }
 }