You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ts...@apache.org on 2016/07/01 22:25:30 UTC

wicket git commit: WICKET-6193

Repository: wicket
Updated Branches:
  refs/heads/master 739bab408 -> a6673f12b


WICKET-6193

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

Branch: refs/heads/master
Commit: a6673f12be1dd013f3c0d33b372f233946a33ba6
Parents: 739bab4
Author: Tobias Soloschenko <ts...@apache.org>
Authored: Sat Jul 2 00:23:34 2016 +0200
Committer: Tobias Soloschenko <ts...@apache.org>
Committed: Sat Jul 2 00:23:34 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/a6673f12/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/a6673f12/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/a6673f12/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/a6673f12/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/a6673f12/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@: