You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2007/03/01 09:09:21 UTC
svn commit: r513221 - in /incubator/wicket/trunk/wicket/src:
main/java/wicket/ main/java/wicket/markup/html/ main/java/wicket/resource/
main/java/wicket/resource/loader/ main/java/wicket/settings/
main/java/wicket/util/resource/locator/ test/java/wicke...
Author: jdonnerstag
Date: Thu Mar 1 00:09:19 2007
New Revision: 513221
URL: http://svn.apache.org/viewvc?view=rev&rev=513221
Log:
reworked Localizer
Added:
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesChangeListener.java
- copied, changed from r500779, incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesReloadListener.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ComponentStringResourceLoader.java
- copied, changed from r500779, incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/AbstractStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java (with props)
Removed:
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesReloadListener.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/AbstractStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ApplicationStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/WicketBundleStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/IWicketResourceNameIterator.java
Modified:
incubator/wicket/trunk/wicket/src/main/java/wicket/Localizer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/AjaxServerAndClientTimeFilter.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/ServerAndClientTimeFilter.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesFactory.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/Properties.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/PropertiesFactory.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ClassStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/IStringResourceLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ExtensionResourceNameIterator.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/LocaleResourceNameIterator.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceStreamFactory.java
incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/StyleAndVariationResourceNameIterator.java
incubator/wicket/trunk/wicket/src/test/java/wicket/ApplicationSettingsTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/LocalizerTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/WicketMessageAttributeTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/properties/PropertiesTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ApplicationStringResourceLoaderTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ComponentStringResourceLoaderTest.java
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Localizer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Localizer.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Localizer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Localizer.java Thu Mar 1 00:09:19 2007
@@ -16,20 +16,13 @@
*/
package wicket;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import wicket.model.IModel;
import wicket.resource.loader.IStringResourceLoader;
import wicket.settings.IResourceSettings;
import wicket.util.string.AppendingStringBuffer;
-import wicket.util.string.Strings;
import wicket.util.string.interpolator.PropertyVariableInterpolator;
/**
@@ -49,13 +42,10 @@
*
* @author Chris Turner
* @author Juergen Donnerstag
+ * @todo implement properties caching
*/
public class Localizer
{
- /** Log */
- @SuppressWarnings("unused")
- private static final Logger log = LoggerFactory.getLogger(Localizer.class);
-
/**
* Create the utils instance class backed by the configuration information
* contained within the supplied application object.
@@ -79,7 +69,7 @@
public String getString(final String key, final Component component)
throws MissingResourceException
{
- return getString(key, component, null, null, null, null);
+ return getString(key, component, null, null);
}
/**
@@ -100,30 +90,7 @@
public String getString(final String key, final Component component, final IModel model)
throws MissingResourceException
{
- return getString(key, component, model, null, null, null);
- }
-
- /**
- * @see #getString(String, Component, IModel, Locale, String, String)
- *
- * @param key
- * The key to obtain the resource for
- * @param component
- * The component to get the resource for
- * @param model
- * The model to use for property substitutions in the strings
- * (optional)
- * @param defaultValue
- * The default value (optional)
- * @return The string resource
- * @throws MissingResourceException
- * If resource not found and configuration dictates that
- * exception should be thrown
- */
- public String getString(final String key, final Component component, final IModel model,
- final String defaultValue) throws MissingResourceException
- {
- return getString(key, component, model, null, null, defaultValue);
+ return getString(key, component, model, null);
}
/**
@@ -143,7 +110,7 @@
public String getString(final String key, final Component component, final String defaultValue)
throws MissingResourceException
{
- return getString(key, component, null, null, null, defaultValue);
+ return getString(key, component, null, defaultValue);
}
/**
@@ -159,11 +126,6 @@
* The component to get the resource for (optional)
* @param model
* The model to use for substitutions in the strings (optional)
- * @param locale
- * The locale to get the resource for (optional)
- * @param style
- * The style to get the resource for (optional) (see
- * {@link wicket.Session})
* @param defaultValue
* The default value (optional)
* @return The string resource
@@ -172,48 +134,21 @@
* exception should be thrown
*/
public String getString(final String key, final Component component, final IModel model,
- Locale locale, String style, final String defaultValue) throws MissingResourceException
+ final String defaultValue) throws MissingResourceException
{
- final List searchStack;
- final String path;
- if (component != null)
- {
- // The reason why we need to create that stack is because we need to
- // walk it downwards starting with Page down to the Component
- searchStack = getComponentStack(component);
- path = Strings.replaceAll(component.getPageRelativePath(), ":", ".").toString();
-
- if (locale == null)
- {
- locale = component.getLocale();
- }
-
- if (style == null)
- {
- style = component.getStyle();
- }
- }
- else
+ // Iterate over all registered string resource loaders until the
+ // property has been found
+ String string = null;
+ for (IStringResourceLoader loader : Application.get().getResourceSettings()
+ .getStringResourceLoaders())
{
- searchStack = null;
- path = null;
-
- Session session = Session.get();
- if (locale == null)
- {
- locale = session.getLocale();
- }
-
- if (style == null)
+ string = loader.loadStringResource(component, key);
+ if (string != null)
{
- style = session.getStyle();
+ break;
}
}
- // Iterate over all registered string resource loaders until the
- // property has been found
- String string = visitResourceLoaders(key, path, searchStack, locale, style);
-
// If a property value has been found, than replace the placeholder
// and we are done
if (string != null)
@@ -242,73 +177,8 @@
throw new MissingResourceException(message.toString(), (component != null ? component
.getClass().getName() : ""), key);
}
- else
- {
- return "[Warning: String resource for '" + key + "' not found]";
- }
- }
-
- /**
- * Note: This implementation does NOT perform variable substitution
- *
- * @param key
- * The key to obtain the resource for
- * @param searchStack
- * A stack of classes to get the resource for
- * @param path
- * A (file) path to the resource containing the key
- * @param locale
- * The locale to get the resource for (optional)
- * @param style
- * The style to get the resource for (optional) (see
- * {@link wicket.Session})
- * @return The string resource
- * @throws MissingResourceException
- * If resource not found and configuration dictates that
- * exception should be thrown
- */
- private String getString(final String key, final String path, final Locale locale,
- final String style) throws MissingResourceException
- {
- return visitResourceLoaders(key, path, null, locale, style);
- }
-
- /**
- * Traverse the component hierachy up to the Page and add each component
- * class to the list (stack) returned
- *
- * @param component
- * The component to evaluate
- * @return The stack of classes
- */
- public static List<Class> getComponentStack(final Component component)
- {
- // No component, no stack
- if (component == null)
- {
- return null;
- }
-
- // Build the search stack
- final List<Class> searchStack = new ArrayList<Class>();
- searchStack.add(component.getClass());
-
- if (!(component instanceof Page))
- {
- // Add all the component on the way to the Page
- MarkupContainer container = component.getParent();
- while (container != null)
- {
- searchStack.add(container.getClass());
- if (container instanceof Page)
- {
- break;
- }
- container = container.getParent();
- }
- }
- return searchStack;
+ return "[Warning: String resource for '" + key + "' not found]";
}
/**
@@ -329,89 +199,6 @@
{
return PropertyVariableInterpolator.interpolate(string, model.getObject());
}
- return string;
- }
-
- /**
- * For each StringResourceLoader registered with the application, load the
- * properties file associated with the classes in the searchStack, the
- * locale and the style. The searchStack is traversed in reverse order.
- * <p>
- * The property is identified by the 'key' or 'path'+'key'. 'path' is
- * shortened (last element removed) to always represent the page relative
- * path of the original component associate with it.
- *
- * @param key
- * The key to obtain the resource for
- * @param path
- * The component id path relative to the page
- * @param searchStack
- * A stack of classes to get the resource for
- * @param locale
- * The locale to get the resource for (optional)
- * @param style
- * The style to get the resource for (optional) (see
- * {@link wicket.Session})
- * @return The string resource
- */
- private String visitResourceLoaders(final String key, final String path,
- final List searchStack, final Locale locale, final String style)
- {
- // Search each loader in turn and return the string if it is found
- final Iterator<IStringResourceLoader> iterator = Application.get().getResourceSettings()
- .getStringResourceLoaders().iterator();
-
- // The return value
- String string = null;
-
- // Iterate until a property has been found
- while (iterator.hasNext() && (string == null))
- {
- IStringResourceLoader loader = iterator.next();
-
- // The key prefix is equal to the component path relativ to the
- // current component on the top of the stack.
- String prefix = path;
- if ((searchStack != null) && (searchStack.size() > 0))
- {
- // Walk the component hierarchy down from page to the component
- for (int i = searchStack.size() - 1; (i >= 0) && (string == null); i--)
- {
- Class clazz = (Class)searchStack.get(i);
-
- // First check if a property with the 'key' provided by the
- // user is available.
- string = loader.loadStringResource(clazz, key, locale, style);
-
- // If not, prepend the component relativ path to the key
- if ((string == null) && (path != null) && (prefix.length() > 0))
- {
- string = loader
- .loadStringResource(clazz, prefix + '.' + key, locale, style);
-
- // If still not found, adjust the component relativ path
- // for the next component on the path from the page
- // down.
- if (string == null)
- {
- prefix = Strings.afterFirst(prefix, '.');
- }
- }
- }
- }
- else
- {
- // A default string resource loader, e.g. the
- // ApplicationStringResourceLoader,
- // does not necessarily require the component hierachy
- string = loader.loadStringResource(null, key, locale, style);
- if ((string == null) && (prefix != null) && (prefix.length() > 0))
- {
- string = loader.loadStringResource(null, prefix + '.' + key, locale, style);
- }
- }
- }
-
return string;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/AjaxServerAndClientTimeFilter.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/AjaxServerAndClientTimeFilter.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/AjaxServerAndClientTimeFilter.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/AjaxServerAndClientTimeFilter.java Thu Mar 1 00:09:19 2007
@@ -25,18 +25,15 @@
import wicket.Application;
import wicket.IResponseFilter;
import wicket.RequestCycle;
-import wicket.Session;
-import wicket.model.Model;
import wicket.util.string.AppendingStringBuffer;
import wicket.util.string.JavascriptUtils;
/**
* This is a filter that injects javascript code to the top head portion and
* after the body so that the time can me measured what the client parse time
- * was for this page and for ajax calls done on the page.
- * It also reports the total server parse/response time in the client and logs
- * the server response time and response size it took for a specific response
- * in the server log.
+ * was for this page and for ajax calls done on the page. It also reports the
+ * total server parse/response time in the client and logs the server response
+ * time and response size it took for a specific response in the server log.
*
* You can specify what the status text should be like this:
* ServerAndClientTimeFilter.statustext=My Application, Server parsetime:
@@ -100,16 +97,25 @@
*/
private String getStatusString(long timeTaken, String resourceKey)
{
- Map<String,String> map = new HashMap<String,String>(4);
- map.put("clienttime", "' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
- map.put("servertime", ((double)timeTaken) / 1000 + "s");
- AppendingStringBuffer defaultValue = new AppendingStringBuffer(128);
- defaultValue.append("Server parsetime: ");
- defaultValue.append(((double)timeTaken) / 1000);
- defaultValue.append("s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
- String txt = Application.get().getResourceSettings().getLocalizer().getString(resourceKey,
- null, Model.valueOf(map), Session.get().getLocale(), Session.get().getStyle(),
- defaultValue.toString());
+ String txt = Application.get().getResourceSettings().getLocalizer().getString(resourceKey, null);
+ if (txt == null)
+ {
+ Map<String, String> map = new HashMap<String, String>(4);
+ map.put("clienttime", "' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
+ map.put("servertime", ((double)timeTaken) / 1000 + "s");
+
+ txt = map.get(resourceKey);
+ }
+ if (txt == null)
+ {
+ AppendingStringBuffer defaultValue = new AppendingStringBuffer(128);
+ defaultValue.append("Server parsetime: ");
+ defaultValue.append(((double)timeTaken) / 1000);
+ defaultValue.append("s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
+
+ txt = defaultValue.toString();
+ }
+
return txt;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/ServerAndClientTimeFilter.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/ServerAndClientTimeFilter.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/ServerAndClientTimeFilter.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/ServerAndClientTimeFilter.java Thu Mar 1 00:09:19 2007
@@ -26,7 +26,6 @@
import wicket.Application;
import wicket.IResponseFilter;
import wicket.RequestCycle;
-import wicket.Session;
import wicket.model.Model;
import wicket.util.string.AppendingStringBuffer;
import wicket.util.string.JavascriptUtils;
@@ -70,7 +69,7 @@
String txt = Application.get().getResourceSettings().getLocalizer().getString(
"ServerAndClientTimeFilter.statustext", null, Model.valueOf(map),
- Session.get().getLocale(), Session.get().getStyle(), defaultValue.toString());
+ defaultValue.toString());
AppendingStringBuffer endScript = new AppendingStringBuffer(150);
endScript.append("\n").append(JavascriptUtils.SCRIPT_OPEN_TAG);
endScript.append("\nwindow.defaultStatus='");
Copied: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesChangeListener.java (from r500779, incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesReloadListener.java)
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesChangeListener.java?view=diff&rev=513221&p1=incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesReloadListener.java&r1=500779&p2=incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesChangeListener.java&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesReloadListener.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesChangeListener.java Thu Mar 1 00:09:19 2007
@@ -18,16 +18,16 @@
/**
* To be implemented by listeners interested in PropertiesFactory events fired
- * after a new properties files has been loaded
+ * after a change to the properties has been detected
*
* @author Juergen Donnerstag
*/
-public abstract interface IPropertiesReloadListener
+public abstract interface IPropertiesChangeListener
{
/**
- * Fired after a new properties files has been loaded
+ * Fired after a properties file change has been detected
*
* @param key
*/
- void propertiesLoaded(final String key);
+ void propertiesChanged(final String key);
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesFactory.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesFactory.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesFactory.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/IPropertiesFactory.java Thu Mar 1 00:09:19 2007
@@ -16,34 +16,39 @@
*/
package wicket.resource;
-import java.util.Locale;
/**
- * Interface to be implemented by properties loaders
+ * IPropertyiesFactory is not a 100% replacement for java.util.Properties as it
+ * does not provide the same interface. But it serves kind of the same purpose
+ * with Wicket specific features. E.g. besides Locale it take 'styles' and
+ * 'variations' into account as well, it allows to register listeners which get
+ * called when a property resource has changed and it allows to clear the
+ * locally cached properties.
+ *
+ * @see wicket.resource.Properties
*
* @author Juergen Donnerstag
*/
public interface IPropertiesFactory
{
/**
- * Add a listener which will be called after properties have been reloaded
+ * Add a listener which will be called when a change to the underlying
+ * resource stream (e.g. properties file) has been detected
*
* @param listener
*/
- void addListener(final IPropertiesReloadListener listener);
+ void addListener(final IPropertiesChangeListener listener);
/**
- * Get the properties for ...
+ * Load the properties associated with the path
*
* @param clazz
- * The class that resources are bring loaded for
- * @param style
- * The style to load resources for (see {@link wicket.Session})
- * @param locale
- * The locale to load reosurces for
+ * The class requesting the properties
+ * @param path
+ * The path to identify the resource
* @return The properties
*/
- Properties get(final Class clazz, final String style, final Locale locale);
+ Properties load(final Class clazz, final String path);
/**
* Remove all cached properties
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/Properties.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/Properties.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/Properties.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/Properties.java Thu Mar 1 00:09:19 2007
@@ -19,17 +19,18 @@
import wicket.util.value.ValueMap;
/**
- * Reloadable properties. It is not a 100% replacement for java.util.Properties
- * as it does not provide the same interface. But is serves kind of the same
- * purpose with Wicket specific features.
+ * Kind of like java.util.Properties but based on Wicket's ValueMap and thus
+ * benefiting from all its nice build-in type converters and without parent
+ * properties.
*
* @author Juergen Donnerstag
*/
public final class Properties
{
- /** Log. */
- // private static final Logger log = LoggerFactory.getLogger(Properties.class);
- /** The resource key for the properties file */
+ /** Empty Properties */
+ public static final Properties EMPTY_PROPERTIES = new Properties("NULL", ValueMap.EMPTY_MAP);
+
+ /** A unique key for this specific group of properties. */
private final String key;
/** Property values */
@@ -50,7 +51,7 @@
}
/**
- * Get all values from the properties file
+ * Get direct access to all values from the properties file.
*
* @return map
*/
@@ -60,7 +61,7 @@
}
/**
- * Get the property message identified by 'key'
+ * Get the property value identified by its 'key'.
*
* @param key
* @return property message
@@ -71,7 +72,6 @@
}
/**
- *
* @see java.lang.Object#toString()
*/
@Override
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/PropertiesFactory.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/PropertiesFactory.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/PropertiesFactory.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/PropertiesFactory.java Thu Mar 1 00:09:19 2007
@@ -20,23 +20,21 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wicket.Application;
-import wicket.Component;
import wicket.settings.IResourceSettings;
import wicket.util.listener.IChangeListener;
import wicket.util.resource.IFixedLocationResourceStream;
import wicket.util.resource.IResourceStream;
import wicket.util.resource.ResourceStreamNotFoundException;
-import wicket.util.string.AppendingStringBuffer;
+import wicket.util.resource.locator.ResourceStreamFactory;
import wicket.util.string.Strings;
import wicket.util.value.ValueMap;
import wicket.util.watch.ModificationWatcher;
@@ -44,9 +42,11 @@
/**
* Reloadable properties. It is not a 100% replacement for java.util.Properties
* as it does not provide the same interface. But is serves kind of the same
- * purpose with Wicket specific features. PropertiesFactory actually loads and
- * reloads the Properties and maintaines a cache. Hence properties files are
- * loaded just once.
+ * purpose with Wicket specific features as it take Locale, style and variations
+ * into account. PropertiesFactory loads and reloads the Properties and
+ * maintaines a cache. Hence property files are loaded just once, but are
+ * reloaded if a change to a property file has been detected (actually the cache
+ * gets cleared which forces a reload on demand).
*
* @see wicket.settings.IResourceSettings#getPropertiesFactory()
*
@@ -57,29 +57,40 @@
/** Log. */
private static final Logger log = LoggerFactory.getLogger(PropertiesFactory.class);
- /** Cache for all properties files loaded */
- private final Map<String, Properties> propertiesCache = new HashMap<String, Properties>();
+ /** Cache for all property files loaded */
+ private final Map<String, Properties> propertiesCache = new ConcurrentHashMap<String, Properties>();
- /** Listeners will be invoked after properties have been reloaded */
- private final List<IPropertiesReloadListener> afterReloadListeners = new ArrayList<IPropertiesReloadListener>();
+ /**
+ * Listeners will be invoked after changes to property file have been
+ * detected
+ */
+ private final List<IPropertiesChangeListener> afterReloadListeners = new ArrayList<IPropertiesChangeListener>();
/** Resource Settings */
private final IResourceSettings resourceSettings;
/**
* Construct.
+ */
+ public PropertiesFactory()
+ {
+ this.resourceSettings = Application.get().getResourceSettings();
+ }
+
+ /**
+ * Little helper
*
- * @param application
+ * @return The properties factory registered with the application
*/
- public PropertiesFactory(final Application application)
+ public static IPropertiesFactory get()
{
- this.resourceSettings = application.getResourceSettings();
+ return Application.get().getResourceSettings().getPropertiesFactory();
}
/**
- * @see wicket.resource.IPropertiesFactory#addListener(wicket.resource.IPropertiesReloadListener)
+ * @see wicket.resource.IPropertiesFactory#addListener(wicket.resource.IPropertiesChangeListener)
*/
- public void addListener(final IPropertiesReloadListener listener)
+ public void addListener(final IPropertiesChangeListener listener)
{
// Make sure listeners are added only once
if (afterReloadListeners.contains(listener) == false)
@@ -89,31 +100,39 @@
}
/**
- * @see wicket.resource.IPropertiesFactory#get(java.lang.Class,
- * java.lang.String, java.util.Locale)
+ * @see wicket.resource.IPropertiesFactory#load(java.lang.Class,
+ * java.lang.String)
*/
- public Properties get(final Class clazz, final String style, final Locale locale)
+ public Properties load(final Class clazz, final String path)
{
- final String key = createResourceKey(clazz, locale, style);
- Properties props = propertiesCache.get(key);
- if ((props == null) && (propertiesCache.containsKey(key) == false))
+ // Check the cache
+ Properties properties = propertiesCache.get(path);
+ if (properties != null)
{
- final IResourceStream resource = resourceSettings.getResourceStreamFactory().newResourceStream(
- clazz, clazz.getName().replace('.', '/'), style, locale, "properties,xml");
-
- if (resource != null)
+ // Return null, if no resource stream was found
+ if (properties == Properties.EMPTY_PROPERTIES)
{
- props = loadPropertiesFileAndWatchForChanges(key, resource, clazz, style, locale);
+ properties = null;
}
+ return properties;
+ }
- // add the markup to the cache
- synchronized (propertiesCache)
+ // If not in the cache than try to load the resource stream
+ IResourceStream stream = ResourceStreamFactory.get().newResourceStream(clazz, path);
+ if (stream != null)
+ {
+ // Load the properties from the stream
+ properties = loadPropertiesFileAndWatchForChanges(path, stream);
+ if (properties != null)
{
- propertiesCache.put(key, props);
+ this.propertiesCache.put(path, properties);
+ return properties;
}
}
- return props;
+ // Add a placeholder to the cache. Null is not a valid value to add.
+ this.propertiesCache.put(path, Properties.EMPTY_PROPERTIES);
+ return null;
}
/**
@@ -135,69 +154,16 @@
}
/**
- * Create a unique key to identify the properties file in the cache
- *
- * @param componentClass
- * The class that resources are bring loaded for
- * @param locale
- * The locale to load reosurces for
- * @param style
- * The style to load resources for (see {@link wicket.Session})
- * @return The resource key
- */
- public final String createResourceKey(final Class componentClass, final Locale locale,
- final String style)
- {
- final AppendingStringBuffer buffer = new AppendingStringBuffer(80);
- if (componentClass != null)
- {
- buffer.append(componentClass.getName());
- }
- if (style != null)
- {
- buffer.append(Component.PATH_SEPARATOR);
- buffer.append(style);
- }
- if (locale != null)
- {
- buffer.append(Component.PATH_SEPARATOR);
- boolean l = locale.getLanguage().length() != 0;
- boolean c = locale.getCountry().length() != 0;
- boolean v = locale.getVariant().length() != 0;
- buffer.append(locale.getLanguage());
- if (c || (l && v))
- {
- // This may just append '_'
- buffer.append('_').append(locale.getCountry());
- }
- if (v && (l || c))
- {
- buffer.append('_').append(locale.getVariant());
- }
- }
-
- final String id = buffer.toString();
- return id;
- }
-
- /**
* Helper method to do the actual loading of resources if required.
*
* @param key
* The key for the resource
* @param resourceStream
* The properties file stream to load and begin to watch
- * @param componentClass
- * The class that resources are bring loaded for
- * @param style
- * The style to load resources for (see {@link wicket.Session})
- * @param locale
- * The locale to load reosurces for
* @return The map of loaded resources
*/
private synchronized Properties loadPropertiesFile(final String key,
- final IResourceStream resourceStream, final Class componentClass, final String style,
- final Locale locale)
+ final IResourceStream resourceStream)
{
// Make sure someone else didn't load our resources while we were
// waiting for the synchronized lock on the method
@@ -222,8 +188,11 @@
{
try
{
+ // Get the InputStream
BufferedInputStream in = new BufferedInputStream(resourceStream
.getInputStream());
+
+ // Determine if resource is a XML File
boolean loadAsXml = false;
if (resourceStream instanceof IFixedLocationResourceStream)
{
@@ -238,6 +207,8 @@
}
}
}
+
+ // Load the properties
if (loadAsXml)
{
properties.loadFromXML(in);
@@ -246,6 +217,8 @@
{
properties.load(in);
}
+
+ // Copy the properties into the ValueMap
strings = new ValueMap();
Enumeration<?> enumeration = properties.propertyNames();
while (enumeration.hasMoreElements())
@@ -285,17 +258,10 @@
* The key for the resource
* @param resourceStream
* The properties file stream to load and begin to watch
- * @param componentClass
- * The class that resources are bring loaded for
- * @param style
- * The style to load resources for (see {@link wicket.Session})
- * @param locale
- * The locale to load reosurces for
* @return The map of loaded resources
*/
private final Properties loadPropertiesFileAndWatchForChanges(final String key,
- final IResourceStream resourceStream, final Class componentClass, final String style,
- final Locale locale)
+ final IResourceStream resourceStream)
{
// Watch file modifications
final ModificationWatcher watcher = resourceSettings.getResourceWatcher(true);
@@ -309,22 +275,20 @@
+ "from the cache. Resource: " + resourceStream);
// Clear the whole cache as associated localized files may
- // be affected and may need reloading as well. We make it
- // easy. Usually the watcher is activ in dev mode only
- // anyway.
+ // be affected and may need reloading as well.
clearCache();
// Inform all listeners
for (Iterator iter = afterReloadListeners.iterator(); iter.hasNext();)
{
- IPropertiesReloadListener listener = (IPropertiesReloadListener)iter.next();
+ IPropertiesChangeListener listener = (IPropertiesChangeListener)iter.next();
try
{
- listener.propertiesLoaded(key);
+ listener.propertiesChanged(key);
}
catch (Throwable ex)
{
- log.error("PropertiesReloadListener throw an exception: "
+ log.error("PropertiesReloadListener has thrown an exception: "
+ ex.getMessage());
}
}
@@ -333,6 +297,6 @@
}
log.info("Loading properties files from " + resourceStream);
- return loadPropertiesFile(key, resourceStream, componentClass, style, locale);
+ return loadPropertiesFile(key, resourceStream);
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ClassStringResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ClassStringResourceLoader.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ClassStringResourceLoader.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ClassStringResourceLoader.java Thu Mar 1 00:09:19 2007
@@ -18,18 +18,22 @@
import java.util.Locale;
-import wicket.Application;
+import wicket.Component;
+import wicket.Session;
/**
* This string resource loader attempts to find a single resource bundle that
- * has the same name and location as the clazz. If this bundle is found then
- * strings are obtained from here. This implementation is fully aware of both
- * locale and style values when trying to obtain the appropriate bundle.
+ * has the same name and location as the clazz provided in the constructor. If
+ * the bundle is found than strings are obtained from here. This implementation
+ * is fully aware of both locale and style values when trying to obtain the
+ * appropriate bundle.
+ * <p>
+ * An instance of this loader is registered with the Application by default.
*
* @author Chris Turner
* @author Juergen Donnerstag
*/
-public class ClassStringResourceLoader extends AbstractStringResourceLoader
+public class ClassStringResourceLoader extends ComponentStringResourceLoader
{
/** The application we are loading for. */
private final Class clazz;
@@ -37,15 +41,11 @@
/**
* Create and initialise the resource loader.
*
- * @param application
- * Wickets application object
* @param clazz
* The class that this resource loader is associated with
*/
- public ClassStringResourceLoader(final Application application, final Class clazz)
+ public ClassStringResourceLoader(final Class clazz)
{
- super(application);
-
if (clazz == null)
{
throw new IllegalArgumentException("Parameter 'clazz' must not be null");
@@ -54,12 +54,28 @@
}
/**
- * @inheritDoc
+ * @see wicket.resource.loader.ComponentStringResourceLoader#loadStringResource(java.lang.Class,
+ * java.lang.String, java.util.Locale, java.lang.String)
*/
@Override
public String loadStringResource(final Class clazz, final String key, final Locale locale,
final String style)
{
return super.loadStringResource(this.clazz, key, locale, style);
+ }
+
+ /**
+ * @see wicket.resource.loader.ComponentStringResourceLoader#loadStringResource(wicket.Component,
+ * java.lang.String)
+ */
+ @Override
+ public String loadStringResource(Component component, String key)
+ {
+ if (component == null)
+ {
+ return loadStringResource(null, key, Session.get().getLocale(), Session.get()
+ .getStyle());
+ }
+ return super.loadStringResource(component, key);
}
}
Copied: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ComponentStringResourceLoader.java (from r500779, incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/AbstractStringResourceLoader.java)
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ComponentStringResourceLoader.java?view=diff&rev=513221&p1=incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/AbstractStringResourceLoader.java&r1=500779&p2=incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ComponentStringResourceLoader.java&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/AbstractStringResourceLoader.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/ComponentStringResourceLoader.java Thu Mar 1 00:09:19 2007
@@ -16,6 +16,8 @@
*/
package wicket.resource.loader;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
import org.slf4j.Logger;
@@ -29,22 +31,16 @@
import wicket.markup.html.WebMarkupContainer;
import wicket.markup.html.WebPage;
import wicket.resource.Properties;
-import wicket.util.value.ValueMap;
+import wicket.resource.PropertiesFactory;
+import wicket.util.resource.locator.ResourceNameIterator;
+import wicket.util.string.Strings;
/**
- * This abstract string resource loader provides two helper functions to
- * retrieve the message associated with a key, a locale and a style. The simple
- * one uses the <code>Class</code> provided and its parent classes to find the
- * associated message. The more complex one uses in addition the component
- * provided and its parent containers.
+ * This is Wicket's default string resource loader.
* <p>
* The component based string resource loader attempts to find the resource from
* a bundle that corresponds to the supplied component object or one of its
- * parent containers. Generally the component will be an instance of
- * <code>Page</code>, but it may also be an instance of any reusable
- * component that is packaged along with its own resource files. If the
- * component is not an instance of <code>Page</code> then it must be a
- * component that has already been added to a page.
+ * parent containers.
* <p>
* The search order for resources is built around the containers that hold the
* component (if it is not a page). Consider a Page that contains a Panel that
@@ -75,15 +71,18 @@
* property in the following order:
*
* <pre>
- * page1.properties => form1.input1.RequiredValidator
- * page1.properties => RequiredValidator
- * form1.properties => input1.RequiredValidator
- * form1.properties => RequiredValidator
- * input1.properties => RequiredValidator
- * myApplication.properties => page1.form1.input1.RequiredValidator
- * myApplication.properties => RequiredValidator
+ * page1.properties => form1.input1.RequiredValidator
+ * page1.properties => RequiredValidator
+ * form1.properties => input1.RequiredValidator
+ * form1.properties => RequiredValidator
+ * input1.properties => RequiredValidator
+ * myApplication.properties => page1.form1.input1.RequiredValidator
+ * myApplication.properties => RequiredValidator
* </pre>
*
+ * Note that the latter two property files are only checked if the
+ * ClassStringResourceLoader has been registered with Application as well, which
+ * is the default.
* <p>
* In addition to the above search order, each component that is being searched
* for a resource also includes the resources from any parent classes that it
@@ -95,29 +94,26 @@
* resources and then developers implementing subclasses to either override or
* extend these in their own resource bundle.
* <p>
+ * This implementation can be subclassed to implement modified behavior. The new
+ * implementation must be registered with the Application (ResourceSettings)
+ * though.
+ * <p>
* You may enable log debug messages for this class to fully understand the
* search order.
*
* @author Chris Turner
* @author Juergen Donnerstag
*/
-public abstract class AbstractStringResourceLoader implements IStringResourceLoader
+public class ComponentStringResourceLoader implements IStringResourceLoader
{
/** Log. */
- private static final Logger log = LoggerFactory.getLogger(AbstractStringResourceLoader.class);
-
- /** Wickets application object */
- protected final Application application;
+ private static final Logger log = LoggerFactory.getLogger(ComponentStringResourceLoader.class);
/**
* Create and initialise the resource loader.
- *
- * @param application
- * Wickets application object
*/
- public AbstractStringResourceLoader(final Application application)
+ public ComponentStringResourceLoader()
{
- this.application = application;
}
/**
@@ -145,33 +141,37 @@
return null;
}
- String value = null;
while (true)
{
- // Get (or load) the properties associated with clazz, locale and
- // style
- final Properties props = getProperties(clazz, locale, style);
- if (props != null)
+ // Create the base path
+ String path = clazz.getName().replace('.', '/');
+
+ // Iterator over all the combinations
+ ResourceNameIterator iter = new ResourceNameIterator(path, style, locale,
+ "properties,xml");
+ while (iter.hasNext())
{
- ValueMap strings = props.getAll();
+ String newPath = iter.next();
- // Lookup value
- if (log.isDebugEnabled())
+ // Load the properties associated with the path
+ final Properties props = PropertiesFactory.get().load(clazz, newPath);
+ if (props != null)
{
- log.debug("Try to load resource from: " + props + "; key: " + key);
- }
- value = strings.getString(key);
- if (value != null)
- {
- if (log.isDebugEnabled())
+ // Lookup the value
+ String value = props.getString(key);
+ if (value != null)
{
- log.debug("Found resource from: " + props + "; key: " + key);
- }
+ if (log.isDebugEnabled())
+ {
+ log.debug("Found resource from: " + props + "; key: " + key);
+ }
- break;
+ return value;
+ }
}
}
+ // Didn't find the key yet, continue searching if possible
if (isStopResourceSearch(clazz))
{
break;
@@ -181,26 +181,8 @@
clazz = clazz.getSuperclass();
}
- // Return the resource value (may be null if resource was not found)
- return value;
- }
-
- /**
- * Get (or load) the properties associated with clazz, locale and style.
- *
- * @param clazz
- * The class to find resources to be loaded
- * @param locale
- * The locale identifying the resource set to select the strings
- * from
- * @param style
- * The (optional) style identifying the resource set to select
- * the strings from (see {@link wicket.Session})
- * @return The string resource value or null if resource not found
- */
- protected Properties getProperties(final Class clazz, final Locale locale, final String style)
- {
- return application.getResourceSettings().getPropertiesFactory().get(clazz, style, locale);
+ // not found
+ return null;
}
/**
@@ -228,5 +210,89 @@
// Stop at all wicket base classes
return clazz.equals(Page.class) || clazz.equals(MarkupContainer.class)
|| clazz.equals(Component.class);
+ }
+
+ /**
+ *
+ * @see wicket.resource.loader.IStringResourceLoader#loadStringResource(wicket.Component,
+ * java.lang.String)
+ */
+ public String loadStringResource(final Component component, final String key)
+ {
+ if (component == null)
+ {
+ return null;
+ }
+
+ // The return value
+ String string = null;
+ Locale locale = component.getLocale();
+ String style = component.getStyle();
+
+ // The key prefix is equal to the component path relativ to the
+ // current component on the top of the stack.
+ String prefix = Strings.replaceAll(component.getPageRelativePath(), ":", ".").toString();
+
+ // The reason why we need to create that stack is because we need to
+ // walk it downwards starting with Page down to the Component
+ List<Class> searchStack = getComponentStack(component);
+
+ // Walk the component hierarchy down from page to the component
+ for (int i = searchStack.size() - 1; (i >= 0) && (string == null); i--)
+ {
+ Class clazz = (Class)searchStack.get(i);
+
+ // First check if a property with the 'key' provided by the
+ // user is available.
+ string = loadStringResource(clazz, key, locale, style);
+
+ // If not, prepend the component relativ path to the key
+ if ((string == null) && (prefix != null) && (prefix.length() > 0))
+ {
+ string = loadStringResource(clazz, prefix + '.' + key, locale, style);
+
+ // If still not found, adjust the component relativ path
+ // for the next component on the path from the page
+ // down.
+ if (string == null)
+ {
+ prefix = Strings.afterFirst(prefix, '.');
+ }
+ }
+ }
+
+ return string;
+ }
+
+ /**
+ * Traverse the component hierachy up to the Page and add each component
+ * class to the list (stack) returned
+ *
+ * @param component
+ * The component to evaluate
+ * @return The stack of classes
+ */
+ private List<Class> getComponentStack(final Component component)
+ {
+ // Build the search stack
+ final List<Class> searchStack = new ArrayList<Class>();
+ searchStack.add(component.getClass());
+
+ if (!(component instanceof Page))
+ {
+ // Add all the component on the way to the Page
+ MarkupContainer container = component.getParent();
+ while (container != null)
+ {
+ searchStack.add(container.getClass());
+ if (container instanceof Page)
+ {
+ break;
+ }
+
+ container = container.getParent();
+ }
+ }
+ return searchStack;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/IStringResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/IStringResourceLoader.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/IStringResourceLoader.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/resource/loader/IStringResourceLoader.java Thu Mar 1 00:09:19 2007
@@ -18,36 +18,36 @@
import java.util.Locale;
+import wicket.Component;
+
/**
* The string resource loader interface allows a strategy pattern to be applied
* to the loading of resource strings for an application. The loader (or chain
- * of loaders) that are used is configured via the
- * <code>ApplicationSettings</code> class.
+ * of loaders) that are used is configured via the application settings.
* <p>
* Each particular implementation of this interface may define its own mechanism
* for searching for resources. Please see the documents for each particular
- * implementation to determine this behavior and to see how it can be
- * configured.
+ * implementation to determine its behavior and to see how it can be configured.
* <p>
* It is important to note that if a resource is not found by a particular
- * loader then the loader should return <code>null</code> rather than throw an
+ * loader than the loader should return <code>null</code> rather than throw an
* exception. The reason for this is that loaders can be arranged in a chain and
* it would be very inefficient for loaders earlier in the chain to throw
* exceptions that must be caught and handled each time until the correct loader
* in the chain is reached.
*
- * @author Chris Turner
* @see wicket.settings.IResourceSettings
+ *
+ * @author Chris Turner
+ * @author Juergen Donnerstag
*/
public interface IStringResourceLoader
{
/**
* Get the string resource for the given combination of component class,
- * resource key, locale and style. The component is provided used to allow
- * implementation of component specific resource loading (e.g. per page or
- * per reusable component). It also allows the resource loader
- * implementation to get access to the application settings and the root
- * application object if necessary. The key should be a String containing a
+ * resource key, locale and style. The component class provided is used to
+ * allow implementation of component specific resource loading (e.g. per
+ * page or per reusable component). The key should be a String containing a
* lookup key into a resource bundle. The locale should contain the locale
* of the current operation so that the appopriate set of resources can be
* selected. The style allows the set of resources to select to be varied by
@@ -56,15 +56,34 @@
* @param clazz
* The class to get the string resource for
* @param key
- * The key to obtain the string for
+ * The key should be a String containing a lookup key into a
+ * resource bundle
* @param locale
- * The locale identifying the resource set to select the strings
- * from
+ * The locale should contain the locale of the current operation
+ * so that the appopriate set of resources can be selected
* @param style
- * The (optional) style identifying the resource set to select
- * the strings from (see {@link wicket.Session})
+ * The style identifying the resource set to select the strings
+ * from (see {@link wicket.Session})
* @return The string resource value or null if the resource could not be
* loaded by this loader
*/
String loadStringResource(Class clazz, String key, Locale locale, String style);
+
+ /**
+ * Get the string resource for the given combination of component and
+ * resource key. The component provided is used to allow implementation of
+ * component specific resource loading (e.g. per page or per reusable
+ * component). The key should be a String containing a lookup key into a
+ * resource bundle. The Locale and the style will be taken from the
+ * Component provided.
+ *
+ * @param component
+ * The component to get the string resource for
+ * @param key
+ * The key should be a String containing a lookup key into a
+ * resource bundle
+ * @return The string resource value or null if the resource could not be
+ * loaded by this loader
+ */
+ String loadStringResource(Component component, String key);
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java Thu Mar 1 00:09:19 2007
@@ -309,9 +309,8 @@
public Settings(final Application application)
{
this.application = application;
- stringResourceLoaders.add(new ComponentStringResourceLoader(application));
- stringResourceLoaders.add(new ClassStringResourceLoader(application, this.application
- .getClass()));
+ stringResourceLoaders.add(new ComponentStringResourceLoader());
+ stringResourceLoaders.add(new ClassStringResourceLoader(this.application.getClass()));
}
/**
@@ -644,7 +643,7 @@
{
if (propertiesFactory == null)
{
- propertiesFactory = new PropertiesFactory(this.application);
+ propertiesFactory = new PropertiesFactory();
}
return propertiesFactory;
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ExtensionResourceNameIterator.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ExtensionResourceNameIterator.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ExtensionResourceNameIterator.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ExtensionResourceNameIterator.java Thu Mar 1 00:09:19 2007
@@ -16,7 +16,7 @@
*/
package wicket.util.resource.locator;
-import java.util.Locale;
+import java.util.Iterator;
import wicket.util.string.Strings;
@@ -44,7 +44,7 @@
* @author Juergen Donnerstag
* @author Jonathan Locke
*/
-public class ExtensionResourceNameIterator implements IWicketResourceNameIterator
+public class ExtensionResourceNameIterator implements Iterator<String>
{
/** The base path */
private final String path;
@@ -83,14 +83,6 @@
this.path = path;
this.index = 0;
- }
-
- /**
- * @see wicket.util.resource.locator.IWicketResourceNameIterator#getLocale()
- */
- public Locale getLocale()
- {
- return null;
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/LocaleResourceNameIterator.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/LocaleResourceNameIterator.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/LocaleResourceNameIterator.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/LocaleResourceNameIterator.java Thu Mar 1 00:09:19 2007
@@ -16,6 +16,7 @@
*/
package wicket.util.resource.locator;
+import java.util.Iterator;
import java.util.Locale;
import wicket.util.string.Strings;
@@ -44,7 +45,7 @@
* @author Juergen Donnerstag
* @author Jonathan Locke
*/
-public class LocaleResourceNameIterator implements IWicketResourceNameIterator
+public class LocaleResourceNameIterator implements Iterator<String>
{
/** The base path */
private final String path;
@@ -78,7 +79,7 @@
}
/**
- * @see wicket.util.resource.locator.IWicketResourceNameIterator#getLocale()
+ * @return Locale
*/
public Locale getLocale()
{
Added: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java?view=auto&rev=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java (added)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java Thu Mar 1 00:09:19 2007
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 wicket.util.resource.locator;
+
+import java.util.Iterator;
+import java.util.Locale;
+
+import wicket.WicketRuntimeException;
+
+/**
+ * Contains the logic to locate a resource based on a path, a style (see
+ * {@link wicket.Session}), a locale and a extension strings. The full filename
+ * will be built like:
+ * <path>_<style>_<locale>.<extension>.
+ * <p>
+ * Resource matches will be attempted in the following order:
+ * <ol>
+ * <li>1. <path>_<style>_<locale>.<extension></li>
+ * <li>2. <path>_<locale>.<extension></li>
+ * <li>3. <path>_<style>.<extension></li>
+ * <li>4. <path>.<extension></li>
+ * </ol>
+ * <p>
+ * Locales may contain a language, a country and a region or variant.
+ * Combinations of these components will be attempted in the following order:
+ * <ol>
+ * <li>locale.toString() see javadoc for Locale for more details</li>
+ * <li><language>_<country></li>
+ * <li><language></li>
+ * </ol>
+ * <p>
+ * Extensions may be a comma separated list of extensions, e.g. "properties,xml"
+ *
+ * @author Juergen Donnerstag
+ */
+public class ResourceNameIterator implements Iterator<String>
+{
+ // The locale to search for the resource file
+ private final Locale locale;
+
+ // The extensions (comma separated) to search for the resource file
+ private final String extensions;
+
+ // The various iterators used to locate the resource file
+ private Iterator<String> styleIterator;
+ private LocaleResourceNameIterator localeIterator;
+ private Iterator<String> extenstionsIterator;
+
+ // The latest exact Locale used
+ private Locale currentLocale;
+
+ /**
+ * Construct.
+ *
+ * @param path
+ * The path of the resource without extension
+ * @param style
+ * A theme or style (see {@link wicket.Session})
+ * @param locale
+ * The Locale to apply
+ * @param extensions
+ * the filname's extensions (comma separated)
+ */
+ public ResourceNameIterator(String path, final String style, final Locale locale,
+ final String extensions)
+ {
+ this.locale = locale;
+ this.extensions = extensions;
+
+ this.styleIterator = new StyleAndVariationResourceNameIterator(path, style, null);
+ }
+
+ /**
+ * Get the exact Locale which has been used for the latest resource path.
+ *
+ * @return current Locale
+ */
+ public final Locale getLocale()
+ {
+ return this.currentLocale;
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext()
+ {
+ // Most inner loop. Loop through all extensions provided
+ if (this.extenstionsIterator != null)
+ {
+ if (this.extenstionsIterator.hasNext() == true)
+ {
+ return true;
+ }
+
+ // If there are no more extensions, than return to the next outer
+ // loop (locale), get the next value from that loop and start
+ // over again with the first extension in the list.
+ extenstionsIterator = null;
+ }
+
+ // 2nd inner loop: Loop through all Locale combinations
+ if (this.localeIterator != null)
+ {
+ while (this.localeIterator.hasNext())
+ {
+ // Get the next Locale from the iterator and start the next
+ // inner iterator over again.
+ String newPath = this.localeIterator.next();
+ this.currentLocale = this.localeIterator.getLocale();
+ this.extenstionsIterator = new ExtensionResourceNameIterator(newPath,
+ this.extensions);
+ if (this.extenstionsIterator.hasNext() == true)
+ {
+ return true;
+ }
+ }
+ this.localeIterator = null;
+ }
+
+ // Most outer loop: Loop through all combinations of styles and
+ // variations
+ while (this.styleIterator.hasNext())
+ {
+ String newPath = this.styleIterator.next();
+
+ this.localeIterator = new LocaleResourceNameIterator(newPath, this.locale);
+ while (this.localeIterator.hasNext())
+ {
+ newPath = this.localeIterator.next();
+ this.currentLocale = this.localeIterator.getLocale();
+ this.extenstionsIterator = new ExtensionResourceNameIterator(newPath,
+ this.extensions);
+ if (this.extenstionsIterator.hasNext() == true)
+ {
+ return true;
+ }
+ }
+ }
+
+ // No more combinations found. End of iteration.
+ return false;
+ }
+
+ /**
+ * @see java.util.Iterator#next()
+ */
+ public String next()
+ {
+ if (extenstionsIterator != null)
+ {
+ return extenstionsIterator.next();
+ }
+ throw new WicketRuntimeException(
+ "Illegal call of next(). Iterator not properly initialized");
+ }
+
+ /**
+ * @see java.util.Iterator#remove()
+ */
+ public void remove()
+ {
+ // ignore
+ }
+}
Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceNameIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceStreamFactory.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceStreamFactory.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceStreamFactory.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/ResourceStreamFactory.java Thu Mar 1 00:09:19 2007
@@ -17,7 +17,6 @@
package wicket.util.resource.locator;
import java.net.URL;
-import java.util.Iterator;
import java.util.Locale;
import org.slf4j.Logger;
@@ -111,31 +110,16 @@
{
// Try the various combinations of style, locale and extension to find
// the resource.
-
- // Most outer loop are the styles and variations
- Iterator<String> styleIter = new StyleAndVariationResourceNameIterator(path, style, null);
- while (styleIter.hasNext())
+ ResourceNameIterator iter = new ResourceNameIterator(path, style, locale, extension);
+ while (iter.hasNext())
{
- String newPath = styleIter.next();
-
- // next is the Locale
- LocaleResourceNameIterator localeIter = new LocaleResourceNameIterator(newPath, locale);
- while (localeIter.hasNext())
+ String newPath = iter.next();
+
+ IResourceStream stream = newResourceStream(clazz, newPath);
+ if (stream != null)
{
- newPath = localeIter.next();
-
- // and than the possible resource extensions
- Iterator<String> extIter = new ExtensionResourceNameIterator(newPath, extension);
- while (extIter.hasNext())
- {
- newPath = extIter.next();
- IResourceStream stream = newResourceStream(clazz, newPath);
- if (stream != null)
- {
- stream.setLocale(localeIter.getLocale());
- return stream;
- }
- }
+ stream.setLocale(iter.getLocale());
+ return stream;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/StyleAndVariationResourceNameIterator.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/StyleAndVariationResourceNameIterator.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/StyleAndVariationResourceNameIterator.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/util/resource/locator/StyleAndVariationResourceNameIterator.java Thu Mar 1 00:09:19 2007
@@ -16,7 +16,7 @@
*/
package wicket.util.resource.locator;
-import java.util.Locale;
+import java.util.Iterator;
/**
* Contains the logic to build the various combinations of file path, style and
@@ -42,7 +42,7 @@
* @author Juergen Donnerstag
* @author Jonathan Locke
*/
-public class StyleAndVariationResourceNameIterator implements IWicketResourceNameIterator
+public class StyleAndVariationResourceNameIterator implements Iterator<String>
{
/** The base path */
private final String path;
@@ -71,14 +71,6 @@
this.path = path;
this.style = style;
this.variation = variation;
- }
-
- /**
- * @see wicket.util.resource.locator.IWicketResourceNameIterator#getLocale()
- */
- public Locale getLocale()
- {
- return null;
}
/**
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/ApplicationSettingsTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/ApplicationSettingsTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/ApplicationSettingsTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/ApplicationSettingsTest.java Thu Mar 1 00:09:19 2007
@@ -129,7 +129,7 @@
Settings settings = new Settings(dummy);
settings.addStringResourceLoader(new BundleStringResourceLoader(
"wicket.resource.DummyResources"));
- settings.addStringResourceLoader(new ComponentStringResourceLoader(dummy));
+ settings.addStringResourceLoader(new ComponentStringResourceLoader());
List<IStringResourceLoader> loaders = settings.getStringResourceLoaders();
Assert.assertEquals("There should be 2 overridden loaders", 2, loaders.size());
Assert.assertTrue("First loader one should be the bundle one",
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/LocalizerTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/LocalizerTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/LocalizerTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/LocalizerTest.java Thu Mar 1 00:09:19 2007
@@ -70,7 +70,7 @@
public void testGetStringValidString()
{
Assert.assertEquals("Expected string should be returned", "This is a test", localizer
- .getString("test.string", null, null, null, null, "DEFAULT"));
+ .getString("test.string", null, null, "DEFAULT"));
}
/**
@@ -80,7 +80,7 @@
{
settings.setUseDefaultOnMissingResource(true);
Assert.assertEquals("Default string should be returned", "DEFAULT", localizer.getString(
- "unknown.string", null, null, null, null, "DEFAULT"));
+ "unknown.string", null, null, "DEFAULT"));
}
/**
@@ -93,7 +93,7 @@
Assert.assertEquals("Wrapped key should be returned on no default",
"[Warning: String resource for 'unknown.string' not found]", localizer.getString(
- "unknown.string", null, null, null, null, null));
+ "unknown.string", null, null, null));
}
/**
@@ -105,7 +105,7 @@
settings.setThrowExceptionOnMissingResource(false);
Assert.assertEquals("Wrapped key should be returned on not using default and no exception",
"[Warning: String resource for 'unknown.string' not found]", localizer.getString(
- "unknown.string", null, null, null, null, "DEFAULT"));
+ "unknown.string", null, null, "DEFAULT"));
}
/**
@@ -117,7 +117,7 @@
settings.setThrowExceptionOnMissingResource(true);
try
{
- localizer.getString("unknown.string", null, null, null, null, "DEFAULT");
+ localizer.getString("unknown.string", null, null, "DEFAULT");
Assert.fail("MissingResourceException expected");
}
catch (MissingResourceException e)
@@ -135,7 +135,7 @@
vm.put("user", "John Doe");
Model model = new Model<ValueMap>(vm);
Assert.assertEquals("Property substitution should occur", "Welcome, John Doe", localizer
- .getString("test.substitute", null, model, null, null, null));
+ .getString("test.substitute", null, model, null));
}
/**
@@ -154,7 +154,7 @@
Session.get().setLocale(Locale.ENGLISH);
MyMockPage page = new MyMockPage();
Application.get().getResourceSettings().addStringResourceLoader(
- new ComponentStringResourceLoader(Application.get()));
+ new ComponentStringResourceLoader());
Localizer localizer = Application.get().getResourceSettings().getLocalizer();
String drop1 = localizer.getString("null", page.drop1);
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/WicketMessageAttributeTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/WicketMessageAttributeTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/WicketMessageAttributeTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/WicketMessageAttributeTest.java Thu Mar 1 00:09:19 2007
@@ -16,13 +16,11 @@
*/
package wicket;
-import java.util.Locale;
-
import wicket.markup.IMarkupResourceStreamProvider;
import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;
+import wicket.resource.IPropertiesChangeListener;
import wicket.resource.IPropertiesFactory;
-import wicket.resource.IPropertiesReloadListener;
import wicket.resource.Properties;
import wicket.util.resource.IResourceStream;
import wicket.util.resource.StringResourceStream;
@@ -59,11 +57,10 @@
{
return "<span wicket:id='label' wicket:message='title:title-key,style:style-key'></span>";
}
-
};
+
new Label(page, "label", "i am label");
-
tester.startPage(page);
TagTester tagTester = tester.getTagByWicketId("label");
assertTrue("title-value".equals(tagTester.getAttribute("title")));
@@ -86,8 +83,8 @@
{
return "<span wicket:id='label' width='100%' wicket:message='title:title-key,style:style-key,width:width-key'></span>";
}
-
};
+
new Label(page, "label", "i am label");
tester.startPage(page);
@@ -111,8 +108,8 @@
{
return "<span wicket:message='title:title-key,style:style-key'/>";
}
-
};
+
tester.startPage(page);
String response = tester.getServletResponse().getDocument();
assertTrue(response.contains("title=\"title-value\""));
@@ -135,8 +132,8 @@
{
return "<span wicket:message='title:title-key,style:style-key'><span wicket:id='label'></span></span>";
}
-
};
+
new Label(page, "label", "[[SUCCESS]]");
tester.startPage(page);
@@ -153,7 +150,6 @@
*/
private static abstract class TestPage extends WebPage implements IMarkupResourceStreamProvider
{
-
protected abstract String getMarkupString();
public final IResourceStream getMarkupResourceStream(MarkupContainer container,
@@ -161,7 +157,6 @@
{
return new StringResourceStream("<html><body>" + getMarkupString() + "</body></html>");
}
-
}
/**
@@ -178,8 +173,7 @@
private static Properties PAGE = new Properties("key2", new ValueMap(
"title-key=title-value,style-key=style-value"));
-
- public void addListener(IPropertiesReloadListener listener)
+ public void addListener(IPropertiesChangeListener listener)
{
// noop
}
@@ -189,18 +183,14 @@
// noop
}
- public Properties get(Class clazz, String style, Locale locale)
+ public Properties load(Class clazz, String path)
{
if (Page.class.isAssignableFrom(clazz))
{
return PAGE;
}
- else
- {
- return EMPTY;
- }
+ return EMPTY;
}
-
}
}
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/properties/PropertiesTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/properties/PropertiesTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/properties/PropertiesTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/properties/PropertiesTest.java Thu Mar 1 00:09:19 2007
@@ -20,7 +20,6 @@
import wicket.WicketTestCase;
import wicket.protocol.http.WebRequestCycle;
-import wicket.resource.loader.WicketBundleStringResourceLoader;
import wicket.util.tester.WicketTester;
/**
@@ -51,11 +50,6 @@
*/
public void test_1()
{
- // Add the string resource loader with the special Bundle like
- // behavior
- tester.getApplication().getResourceSettings().addStringResourceLoader(
- new WicketBundleStringResourceLoader(tester.getApplication()));
-
tester.setupRequestAndResponse();
WebRequestCycle cycle = tester.createRequestCycle();
TestPage page = new TestPage();
@@ -74,11 +68,6 @@
*/
public void test_2()
{
- // Add the string resource loader with the special Bundle like
- // behavior
- tester.getApplication().getResourceSettings().addStringResourceLoader(
- new WicketBundleStringResourceLoader(tester.getApplication()));
-
tester.setupRequestAndResponse();
WebRequestCycle cycle = tester.createRequestCycle();
cycle.getSession().setLocale(Locale.GERMANY);
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ApplicationStringResourceLoaderTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ApplicationStringResourceLoaderTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ApplicationStringResourceLoaderTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ApplicationStringResourceLoaderTest.java Thu Mar 1 00:09:19 2007
@@ -52,7 +52,7 @@
@Override
protected IStringResourceLoader createLoader()
{
- return new ClassStringResourceLoader(application, application.getClass());
+ return new ClassStringResourceLoader(application.getClass());
}
/**
Modified: incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ComponentStringResourceLoaderTest.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ComponentStringResourceLoaderTest.java?view=diff&rev=513221&r1=513220&r2=513221
==============================================================================
--- incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ComponentStringResourceLoaderTest.java (original)
+++ incubator/wicket/trunk/wicket/src/test/java/wicket/resource/ComponentStringResourceLoaderTest.java Thu Mar 1 00:09:19 2007
@@ -51,7 +51,7 @@
@Override
protected IStringResourceLoader createLoader()
{
- return new ComponentStringResourceLoader(this.application);
+ return new ComponentStringResourceLoader();
}
/**
@@ -65,7 +65,7 @@
{
private static final long serialVersionUID = 1L;
};
- IStringResourceLoader loader = new ComponentStringResourceLoader(this.application);
+ IStringResourceLoader loader = new ComponentStringResourceLoader();
Assert.assertNull("Missing resource should return null", loader.loadStringResource(c
.getClass(), "test.string.bad", Locale.getDefault(), null));
}
@@ -87,7 +87,7 @@
MockComponentStringResourceLoaderTestPage p = new MockComponentStringResourceLoaderTestPage();
WebMarkupContainer panel = new WebMarkupContainer(p, "component");
DummyComponent c = new DummyComponent(panel, "hello", application);
- IStringResourceLoader loader = new ComponentStringResourceLoader(this.application);
+ IStringResourceLoader loader = new ComponentStringResourceLoader();
Assert.assertEquals("Valid resourse string should be found", "Component string", loader
.loadStringResource(c.getClass(), "component.string", Locale.getDefault(), null));
}
@@ -98,7 +98,7 @@
public void testLoadDirectFromPage()
{
DummyPage p = new DummyPage();
- IStringResourceLoader loader = new ComponentStringResourceLoader(this.application);
+ IStringResourceLoader loader = new ComponentStringResourceLoader();
Assert
.assertEquals("Valid resourse string should be found", "Another string", loader
.loadStringResource(p.getClass(), "another.test.string", Locale
@@ -111,7 +111,7 @@
public void testSearchClassHierarchyFromPage()
{
DummySubClassPage p = new DummySubClassPage();
- IStringResourceLoader loader = new ComponentStringResourceLoader(this.application);
+ IStringResourceLoader loader = new ComponentStringResourceLoader();
Assert.assertEquals("Valid resource string should be found", "SubClass Test String",
loader.loadStringResource(p.getClass(), "subclass.test.string",
Locale.getDefault(), null));