diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/application-context.xml b/openid-connect-server-webapp/src/main/webapp/WEB-INF/application-context.xml
index 02131cf71..864470e15 100644
--- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/application-context.xml
+++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/application-context.xml
@@ -205,18 +205,23 @@
-
-
-
- classpath:custom_messages
- classpath:messages
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/config/JsonMessageSource.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/config/JsonMessageSource.java
new file mode 100644
index 000000000..6194a433f
--- /dev/null
+++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/config/JsonMessageSource.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright 2015 The MITRE Corporation
+ * and the MIT Kerberos and Internet Trust Consortium
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+package org.mitre.openid.connect.config;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.support.AbstractMessageSource;
+import org.springframework.core.io.Resource;
+
+import com.google.common.base.Splitter;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * @author jricher
+ *
+ */
+public class JsonMessageSource extends AbstractMessageSource {
+ // Logger for this class
+ private static final Logger logger = LoggerFactory.getLogger(JsonMessageSource.class);
+
+ private Resource baseDirectory;
+
+ private Map languageMaps = new HashMap<>();
+
+ @Override
+ protected MessageFormat resolveCode(String code, Locale locale) {
+
+ JsonObject lang = getLanguageMap(locale);
+
+ MessageFormat mf = getMessageFormat(code, locale, lang);
+
+ // TODO Auto-generated method stub
+ return mf;
+ }
+
+ /**
+ * @param code
+ * @param locale
+ * @param lang
+ * @return
+ */
+ private MessageFormat getMessageFormat(String code, Locale locale, JsonObject lang) {
+
+ JsonElement e = lang;
+
+ Iterable parts = Splitter.on('.').split(code);
+ Iterator it = parts.iterator();
+
+ String value = code;
+
+ while (it.hasNext()) {
+ String p = it.next();
+ if (e.isJsonObject()) {
+ JsonObject o = e.getAsJsonObject();
+ if (o.has(p)) {
+ e = o.get(p); // found the next level
+ if (!it.hasNext()) {
+ // we've reached a leaf, grab it
+ if (e.isJsonPrimitive()) {
+ value = e.getAsString();
+ }
+ }
+ } else {
+ // didn't find it, stop processing
+ break;
+ }
+ } else {
+ // didn't find it, stop processing
+ break;
+ }
+ }
+
+
+ MessageFormat mf = new MessageFormat(value, locale);
+
+ return mf;
+ }
+
+ /**
+ * @param locale
+ * @return
+ */
+ private JsonObject getLanguageMap(Locale locale) {
+
+ if (!languageMaps.containsKey(locale)) {
+ try {
+ String filename = locale.getLanguage() + File.separator + "messages.json";
+
+ Resource r = getBaseDirectory().createRelative(filename);
+
+ logger.info("No locale loaded, trying to load from " + r);
+
+ JsonParser parser = new JsonParser();
+ JsonObject obj = (JsonObject) parser.parse(new InputStreamReader(r.getInputStream()));
+
+ languageMaps.put(locale, obj);
+ } catch (JsonIOException | JsonSyntaxException | IOException e) {
+ logger.error("Unable to load locale", e);
+ }
+ }
+
+ return languageMaps.get(locale);
+
+
+
+ }
+
+ /**
+ * @return the baseDirectory
+ */
+ public Resource getBaseDirectory() {
+ return baseDirectory;
+ }
+
+ /**
+ * @param baseDirectory the baseDirectory to set
+ */
+ public void setBaseDirectory(Resource baseDirectory) {
+ this.baseDirectory = baseDirectory;
+ }
+
+}