Repository: wicket
Updated Branches:
  refs/heads/wicket-7.x f71a2d33c -> 2b12b8971


WICKET-6193

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/2b12b897
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/2b12b897
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/2b12b897

Branch: refs/heads/wicket-7.x
Commit: 2b12b897120c66272dabaa3f9093cb05ce981b90
Parents: f71a2d3
Author: Tobias Soloschenko <[email protected]>
Authored: Sat Jul 2 00:23:34 2016 +0200
Committer: Tobias Soloschenko <[email protected]>
Committed: Sat Jul 2 00:26:35 2016 +0200

----------------------------------------------------------------------
 .../loader/NestedStringResourceLoader.java      | 181 +++++++++++++++++++
 ...ingResourceLoaderTest$MyValidator.properties |   4 +
 ...ResourceLoaderTest$MyValidator_nl.properties |   4 +
 .../loader/NestedStringResourceLoaderTest.java  |  33 ++++
 .../src/docs/guide/i18n/i18n_3.gdoc             |   1 +
 5 files changed, 223 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/2b12b897/wicket-core/src/main/java/org/apache/wicket/resource/loader/NestedStringResourceLoader.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/loader/NestedStringResourceLoader.java
 
b/wicket-core/src/main/java/org/apache/wicket/resource/loader/NestedStringResourceLoader.java
new file mode 100644
index 0000000..dab0b92
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/resource/loader/NestedStringResourceLoader.java
@@ -0,0 +1,181 @@
+package org.apache.wicket.resource.loader;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.Component;
+import org.apache.wicket.resource.loader.IStringResourceLoader;
+import org.apache.wicket.settings.ResourceSettings;
+import org.apache.wicket.util.string.AppendingStringBuffer;
+
+/**
+ * Creates a nested string resource loader which resolves nested keys.<br>
+ * <br>
+ * Example:
+ * 
+ * <pre>
+ * <code>
+ * List<IStringResourceLoader> loaders = 
getResourceSettings().getStringResourceLoaders();
+ * // Add more loaders here
+ * NestedStringResourceLoader element = new 
NestedStringResourceLoader(loaders,Pattern.compile("#\\(([^ ]*?)\\)"));
+ * loaders.clear();
+ * loaders.add(element);
+ * </code>
+ * </pre>
+ * 
+ * @author Sven Meier
+ * @author Tobias Soloschenko
+ *
+ */
+public class NestedStringResourceLoader implements IStringResourceLoader
+{
+       private Pattern pattern;
+
+       private List<IStringResourceLoader> loaders;
+
+       private ResourceSettings resourceSettings;
+
+       /**
+        * Creates a nested string resource loader
+        * 
+        * @param loaders
+        *            the loaders to be added in a chain
+        * @param pattern
+        *            the pattern for nested keys. Example for <b>#(key)</b> is 
the pattern:
+        *            <b>Pattern.compile("#\\(([^ ]*?)\\)");</b>
+        */
+       public NestedStringResourceLoader(List<IStringResourceLoader> loaders, 
Pattern pattern)
+       {
+               this.loaders = new ArrayList<>(loaders);
+               this.pattern = pattern;
+               this.resourceSettings = Application.get().getResourceSettings();
+       }
+
+       @Override
+       public String loadStringResource(Component component, String key, 
Locale locale, String style,
+               String variation)
+       {
+               return loadNestedStringResource(component, key, locale, style, 
variation);
+       }
+
+       @Override
+       public String loadStringResource(Class<?> clazz, String key, Locale 
locale, String style,
+               String variation)
+       {
+               return loadNestedStringResource(clazz, key, locale, style, 
variation);
+       }
+
+       /**
+        * loads nested string resources
+        * 
+        * @param scope
+        *            the scope to find the key
+        * @param key
+        *            the actual key
+        * @param locale
+        *            the locale
+        * @param style
+        *            the style
+        * @param variation
+        *            the variation
+        * @return the load string
+        */
+       private String loadNestedStringResource(Object scope, String key, 
Locale locale, String style,
+               String variation)
+       {
+               Class<?> clazz = null;
+               Component component = null;
+               if (scope instanceof Component)
+               {
+                       component = (Component)scope;
+               }
+               else
+               {
+                       clazz = (Class<?>)scope;
+               }
+
+               Iterator<IStringResourceLoader> iter = loaders.iterator();
+               String value = null;
+               while (iter.hasNext() && (value == null))
+               {
+                       IStringResourceLoader loader = iter.next();
+                       value = component != null
+                               ? loader.loadStringResource(component, key, 
locale, style, variation)
+                               : loader.loadStringResource(clazz, key, locale, 
style, variation);
+               }
+
+               if (value == null)
+               {
+                       return handleMissingKey(key, locale, style, component, 
value);
+               }
+               
+               StringBuffer output = new StringBuffer();
+               Matcher matcher = pattern.matcher(value);
+               // Search for other nested keys to replace
+               while (matcher.find())
+               {
+                       String nestedKey = matcher.group(1);
+                       String replacedPlaceHolder = component != null
+                               ? loadNestedStringResource(component, 
nestedKey, locale, style, variation)
+                               : loadNestedStringResource(clazz, nestedKey, 
locale, style, variation);
+
+                       replacedPlaceHolder = handleMissingKey(nestedKey, 
locale, style, component,
+                               replacedPlaceHolder);
+                       matcher.appendReplacement(output, replacedPlaceHolder);
+               }
+               matcher.appendTail(output);
+               return output.toString();
+       }
+
+       /**
+        * Handles a missing key
+        * 
+        * @param nestedKey
+        *            the key which is going to be handled
+        * @param locale
+        *            the actual locale
+        * @param style
+        *            the style
+        * @param component
+        *            the component
+        * 
+        * @param replacedPlaceHolder
+        * @return the replacedPlaceholder
+        */
+       private String handleMissingKey(String nestedKey, Locale locale, String 
style,
+               Component component, String replacedPlaceHolder)
+       {
+               if (replacedPlaceHolder == null)
+               {
+                       if 
(resourceSettings.getThrowExceptionOnMissingResource())
+                       {
+                               AppendingStringBuffer message = new 
AppendingStringBuffer(
+                                       "Unable to find property: '");
+                               message.append(nestedKey);
+                               message.append('\'');
+
+                               if (component != null)
+                               {
+                                       message.append(" for component: ");
+                                       
message.append(component.getPageRelativePath());
+                                       message.append(" 
[class=").append(component.getClass().getName()).append(']');
+                               }
+                               message.append(". Locale: 
").append(locale).append(", style: ").append(style);
+
+                               throw new 
MissingResourceException(message.toString(),
+                                       (component != null ? 
component.getClass().getName() : ""), nestedKey);
+                       }
+                       else
+                       {
+                               replacedPlaceHolder = "[Warning: Property for 
'" + nestedKey + "' not found]";
+                       }
+               }
+               return replacedPlaceHolder;
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/2b12b897/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator.properties
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator.properties
 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator.properties
index 96b9483..4841a02 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator.properties
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator.properties
@@ -1,2 +1,6 @@
 
 error=${label} is invalid
+
+key1=This is an
+key2=assembled nested key.
+nested=#(key1) #(key2)

http://git-wip-us.apache.org/repos/asf/wicket/blob/2b12b897/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator_nl.properties
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator_nl.properties
 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator_nl.properties
index f876ea2..d869396 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator_nl.properties
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/ClassStringResourceLoaderTest$MyValidator_nl.properties
@@ -1,2 +1,6 @@
 
 error=${label} is niet goed
+
+key1=This is an
+key2=assembled nested key.
+nested=#(key1) #(key2)

http://git-wip-us.apache.org/repos/asf/wicket/blob/2b12b897/wicket-core/src/test/java/org/apache/wicket/resource/loader/NestedStringResourceLoaderTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/loader/NestedStringResourceLoaderTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/NestedStringResourceLoaderTest.java
new file mode 100644
index 0000000..3a6b18b
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/loader/NestedStringResourceLoaderTest.java
@@ -0,0 +1,33 @@
+package org.apache.wicket.resource.loader;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.wicket.Component;
+import 
org.apache.wicket.resource.loader.ClassStringResourceLoaderTest.MyValidator;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.Test;
+
+/**
+ * Tests the nested string resource loader
+ */
+public class NestedStringResourceLoaderTest extends WicketTestCase
+{
+
+       /**
+        * Tests the nested string resource loader
+        */
+       @Test
+       public void testNestedStrings(){
+               List<IStringResourceLoader> loaders = 
tester.getApplication().getResourceSettings().getStringResourceLoaders();
+               ClassStringResourceLoader classStringResourceLoader = new 
ClassStringResourceLoader(MyValidator.class);
+               loaders.add(classStringResourceLoader);
+               NestedStringResourceLoader nestedStringResourceLoader = new 
NestedStringResourceLoader(loaders,Pattern.compile("#\\(([^ ]*?)\\)"));
+               loaders.clear();
+               loaders.add(nestedStringResourceLoader);
+               
+               assertEquals("This is an assembled nested key.",
+                       
nestedStringResourceLoader.loadStringResource((Component)null, "nested", null, 
null, null));
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/2b12b897/wicket-user-guide/src/docs/guide/i18n/i18n_3.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/i18n/i18n_3.gdoc 
b/wicket-user-guide/src/docs/guide/i18n/i18n_3.gdoc
index 2d6fc36..04a1453 100644
--- a/wicket-user-guide/src/docs/guide/i18n/i18n_3.gdoc
+++ b/wicket-user-guide/src/docs/guide/i18n/i18n_3.gdoc
@@ -85,6 +85,7 @@ Wicket implements the default lookup algorithm using the 
strategy pattern. The c
 # *ClassStringResourceLoader:* searches into bundles of a given class. By 
default the target class is the application class.
 # *ValidatorStringResourceLoader:* searches for resources into validator's 
bundles. A list of validators is provided by the form component that failed 
validation.
 # *InitializerStringResourceLoader:* this resource allows internationalization 
to interact with the initialization mechanism of the framework that will be 
illustrated in [paragraph 18.3|guide:advanced_3].
+# *NestedStringResourceLoader:* allows to replace nested Strings and can be 
chained up with other resource loader
 
 Developer can customize lookup algorithm removing default resource loaders or 
adding custom implementations to the list of the resource loaders in use. This 
task can be accomplished using method getStringResourceLoaders of setting class 
@org.apache.wicket.settings.ResourceSettings@:
 

Reply via email to