Author: jdonnerstag Date: Sun Aug 12 03:24:50 2007 New Revision: 565035 URL: http://svn.apache.org/viewvc?view=rev&rev=565035 Log: Cache localized property values early to avoid traversing the serch stack.
Modified: wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Localizer.java wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/resource/PropertiesFactory.java wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java Modified: wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Localizer.java URL: http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Localizer.java?view=diff&rev=565035&r1=565034&r2=565035 ============================================================================== --- wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Localizer.java (original) +++ wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/Localizer.java Sun Aug 12 03:24:50 2007 @@ -16,8 +16,10 @@ */ package org.apache.wicket; +import java.util.HashMap; import java.util.Iterator; import java.util.Locale; +import java.util.Map; import java.util.MissingResourceException; import org.apache.wicket.model.IModel; @@ -44,10 +46,12 @@ * * @author Chris Turner * @author Juergen Donnerstag - * @todo implement properties caching */ public class Localizer { + /** Cache properties */ + private Map cache = new HashMap(); + /** * Create the utils instance class backed by the configuration information * contained within the supplied application object. @@ -57,6 +61,14 @@ } /** + * Clear all cache entries + */ + public final void clearCache() + { + cache = new HashMap(); + } + + /** * @see #getString(String, Component, IModel, Locale, String, String) * * @param key @@ -160,20 +172,35 @@ public String getString(final String key, final Component component, final IModel model, final String defaultValue) throws MissingResourceException { - // Iterate over all registered string resource loaders until the - // property has been found + final IResourceSettings resourceSettings = Application.get().getResourceSettings(); + + // Check the cache first + String cacheKey = getCacheKey(key, component); String string = null; - final IResourceSettings resourceSettings = Application.get().getResourceSettings(); - Iterator iter = resourceSettings.getStringResourceLoaders().iterator(); - while (iter.hasNext()) + // Value not found are cached as well (value = null) + if (cache.containsKey(cacheKey)) + { + string = getFromCache(cacheKey); + } + else { - IStringResourceLoader loader = (IStringResourceLoader)iter.next(); - string = loader.loadStringResource(component, key); - if (string != null) + // Iterate over all registered string resource loaders until the + // property has been found + + Iterator iter = resourceSettings.getStringResourceLoaders().iterator(); + while (iter.hasNext()) { - break; + IStringResourceLoader loader = (IStringResourceLoader)iter.next(); + string = loader.loadStringResource(component, key); + if (string != null) + { + break; + } } + + // Cache the result incl null if not found + putIntoCache(cacheKey, string); } if ((string == null) && (defaultValue != null)) @@ -208,6 +235,54 @@ } return "[Warning: String resource for '" + key + "' not found]"; + } + + /** + * Put the value into the cache and associate it with the cache key + * + * @param cacheKey + * @param string + */ + protected void putIntoCache(final String cacheKey, final String string) + { + if (cacheKey != null) + { + cache.put(cacheKey, string); + } + } + + /** + * Get the value associated with the key from the cache. + * + * @param cacheKey + * @return + */ + protected String getFromCache(final String cacheKey) + { + return (String)cache.get(cacheKey); + } + + /** + * Gets the cache key + * + * @param key + * @param component + * @return + */ + protected String getCacheKey(final String key, final Component component) + { + String cacheKey = key; + if (component != null) + { + cacheKey += '-' + component.getPageRelativePath(); + + Page page = component.findPage(); + if (page != null) + { + cacheKey += '-' + page.getClass().getName(); + } + } + return cacheKey; } /** Modified: wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/resource/PropertiesFactory.java URL: http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/resource/PropertiesFactory.java?view=diff&rev=565035&r1=565034&r2=565035 ============================================================================== --- wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/resource/PropertiesFactory.java (original) +++ wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/resource/PropertiesFactory.java Sun Aug 12 03:24:50 2007 @@ -73,7 +73,7 @@ */ public PropertiesFactory() { - this.resourceSettings = Application.get().getResourceSettings(); + resourceSettings = Application.get().getResourceSettings(); } /** @@ -124,13 +124,13 @@ properties = loadPropertiesFileAndWatchForChanges(path, stream); if (properties != null) { - this.propertiesCache.put(path, properties); + propertiesCache.put(path, properties); return properties; } } // Add a placeholder to the cache. Null is not a valid value to add. - this.propertiesCache.put(path, Properties.EMPTY_PROPERTIES); + propertiesCache.put(path, Properties.EMPTY_PROPERTIES); return null; } @@ -250,13 +250,16 @@ { public void onChange() { - log.info("A properties files has changed. Remove all entries " - + "from the cache. Resource: " + resourceStream); + log.info("A properties files has changed. Remove all entries " + + "from the cache. Resource: " + resourceStream); // Clear the whole cache as associated localized files may // be affected and may need reloading as well. clearCache(); + // clear the localizer cache as well + Application.get().getResourceSettings().getLocalizer().clearCache(); + // Inform all listeners Iterator iter = afterReloadListeners.iterator(); while (iter.hasNext()) @@ -268,8 +271,8 @@ } catch (Throwable ex) { - log.error("PropertiesReloadListener has thrown an exception: " - + ex.getMessage()); + log.error("PropertiesReloadListener has thrown an exception: " + + ex.getMessage()); } } } @@ -287,6 +290,6 @@ */ protected final Map getCache() { - return this.propertiesCache; + return propertiesCache; } } Modified: wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java URL: http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java?view=diff&rev=565035&r1=565034&r2=565035 ============================================================================== --- wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java (original) +++ wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java Sun Aug 12 03:24:50 2007 @@ -112,13 +112,14 @@ void addStringResourceLoader(final IStringResourceLoader loader); /** - * Whether to disable gzip compression for resources. You need this on SAP, which gzips things twice. + * Whether to disable gzip compression for resources. You need this on SAP, + * which gzips things twice. * * @return True if we should disable gzip compression * @since 1.3.0 */ boolean getDisableGZipCompression(); - + /** * Get the application's localizer. * @@ -199,14 +200,22 @@ boolean getUseDefaultOnMissingResource(); /** - * Sets whether to disable gzip compression for resources. - * You need to set this on some SAP versions, which gzip things twice. + * Sets whether to disable gzip compression for resources. You need to set + * this on some SAP versions, which gzip things twice. * * @param disableGZipCompression * @since 1.3.0 */ void setDisableGZipCompression(final boolean disableGZipCompression); - + + /** + * Sets the localizer which will be used to find property values. + * + * @param localizer + * @since 1.3.0 + */ + void setLocalizer(Localizer localizer); + /** * Sets the [EMAIL PROTECTED] PackageResourceGuard package resource guard}. * @@ -267,15 +276,16 @@ void setUseDefaultOnMissingResource(final boolean useDefaultOnMissingResource); /** - * Sets whether the whitespace characters and comments should be stripped for - * resources served through [EMAIL PROTECTED] JavascriptPackageResource} + * Sets whether the whitespace characters and comments should be stripped + * for resources served through [EMAIL PROTECTED] JavascriptPackageResource} + * * @param value */ void setStripJavascriptCommentsAndWhitespace(boolean value); - + /** * @return whether the comments and whitespace characters will be stripped - * from resources served through [EMAIL PROTECTED] JavascriptPackageResource} + * from resources served through [EMAIL PROTECTED] JavascriptPackageResource} */ boolean getStripJavascriptCommentsAndWhitespace(); } Modified: wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java URL: http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java?view=diff&rev=565035&r1=565034&r2=565035 ============================================================================== --- wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java (original) +++ wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/settings/Settings.java Sun Aug 12 03:24:50 2007 @@ -92,7 +92,7 @@ IRequestLoggerSettings { /** Class of access denied page. */ - private WeakReference/*<Class<? extends Page>*/ accessDeniedPage; + private WeakReference/* <Class<? extends Page> */accessDeniedPage; /** ajax debug mode status */ private boolean ajaxDebugModeEnabled = false; @@ -146,7 +146,7 @@ * Whether we should disable gzip compression for resources. */ private boolean disableGZipCompression = false; - + /** * Whether mounts should be enforced. If true, requests for mounted targets * have to done through the mounted paths. If, for instance, a bookmarkable @@ -165,7 +165,7 @@ private boolean gatherExtendedBrowserInfo = false; /** Class of internal error page. */ - private WeakReference/*<Class<? extends Page>*/ internalErrorPage; + private WeakReference/* <Class<? extends Page> */internalErrorPage; /** I18N support */ private Localizer localizer; @@ -175,7 +175,7 @@ /** A markup cache which will load the markup if required. */ private IMarkupCache markupCache; - + /** To help prevent denial of service attacks */ private int maxPageMaps = 5; @@ -189,7 +189,7 @@ private IPackageResourceGuard packageResourceGuard = new PackageResourceGuard(); /** The error page displayed when an expired page is accessed. */ - private WeakReference/*<Class<? extends Page>*/ pageExpiredErrorPage; + private WeakReference/* <Class<? extends Page> */pageExpiredErrorPage; /** factory to create new Page objects */ private IPageFactory pageFactory = new DefaultPageFactory(); @@ -295,10 +295,11 @@ private boolean stripJavascriptCommentsAndWhitespace; /** - * Whether the container's class name should be printed to response (in a html comment). + * Whether the container's class name should be printed to response (in a + * html comment). */ private boolean outputMarkupContainerClassName = false; - + /** * Create the application settings, carrying out any necessary * initialisations. @@ -439,7 +440,7 @@ */ public boolean getComponentUseCheck() { - return this.componentUseCheck; + return componentUseCheck; } /** @@ -501,7 +502,7 @@ { return disableGZipCompression; } - + /** * @see wicket.settings.ISecuritySettings#getEnforceMounts() */ @@ -533,19 +534,27 @@ { if (localizer == null) { - this.localizer = new Localizer(); + localizer = new Localizer(); } return localizer; } /** + * @see org.apache.wicket.settings.IResourceSettings#setLocalizer(org.apache.wicket.Localizer) + */ + public void setLocalizer(final Localizer localizer) + { + this.localizer = localizer; + } + + /** * @see org.apache.wicket.settings.IMarkupSettings#getMarkupParserFactory() */ public IMarkupParserFactory getMarkupParserFactory() { - if (this.markupParserFactory == null) + if (markupParserFactory == null) { - this.markupParserFactory = new MarkupParserFactory(); + markupParserFactory = new MarkupParserFactory(); } return markupParserFactory; } @@ -708,7 +717,7 @@ */ public boolean getStripWicketTags() { - return this.stripWicketTags; + return stripWicketTags; } /** @@ -716,7 +725,7 @@ */ public boolean getStripXmlDeclarationFromOutput() { - return this.stripXmlDeclarationFromOutput; + return stripXmlDeclarationFromOutput; } /** @@ -766,7 +775,7 @@ public String getVersion() { String implVersion = null; - Package pkg = this.getClass().getPackage(); + Package pkg = getClass().getPackage(); if (pkg != null) { implVersion = pkg.getImplementationVersion(); @@ -821,7 +830,7 @@ { throw new IllegalArgumentException("authorization strategy cannot be set to null"); } - this.authorizationStrategy = strategy; + authorizationStrategy = strategy; } /** @@ -853,7 +862,7 @@ */ public void setClassResolver(final IClassResolver defaultClassResolver) { - this.classResolver = defaultClassResolver; + classResolver = defaultClassResolver; } /** @@ -914,7 +923,7 @@ */ public void setDefaultMarkupEncoding(final String encoding) { - this.defaultMarkupEncoding = encoding; + defaultMarkupEncoding = encoding; } /** @@ -924,13 +933,13 @@ { this.disableGZipCompression = disableGZipCompression; } - + /** * @see wicket.settings.ISecuritySettings#setEnforceMounts(boolean) */ public void setEnforceMounts(boolean enforce) { - this.enforceMounts = enforce; + enforceMounts = enforce; } /** @@ -965,7 +974,7 @@ throw new IllegalArgumentException("markup parser factory cannot be null"); } - this.markupParserFactory = factory; + markupParserFactory = factory; } /** @@ -1007,7 +1016,7 @@ */ public void setPageFactory(final IPageFactory defaultPageFactory) { - this.pageFactory = defaultPageFactory; + pageFactory = defaultPageFactory; } /** @@ -1023,7 +1032,7 @@ */ public void setPropertiesFactory(org.apache.wicket.resource.IPropertiesFactory factory) { - this.propertiesFactory = factory; + propertiesFactory = factory; } /** @@ -1042,7 +1051,7 @@ this.resourceFinder = resourceFinder; // Cause resource locator to get recreated - this.resourceStreamLocator = null; + resourceStreamLocator = null; } /** @@ -1090,7 +1099,7 @@ */ public void setStripXmlDeclarationFromOutput(final boolean strip) { - this.stripXmlDeclarationFromOutput = strip; + stripXmlDeclarationFromOutput = strip; } /** @@ -1144,7 +1153,7 @@ */ public void setVersionPagesByDefault(boolean pagesVersionedByDefault) { - this.versionPagesByDefault = pagesVersionedByDefault; + versionPagesByDefault = pagesVersionedByDefault; } /** @@ -1163,8 +1172,8 @@ // IPageFactory implementation if (!Page.class.isAssignableFrom(pageClass)) { - throw new IllegalArgumentException("argument " + pageClass - + " must be a subclass of Page"); + throw new IllegalArgumentException("argument " + pageClass + + " must be a subclass of Page"); } } @@ -1231,7 +1240,7 @@ { stripJavascriptCommentsAndWhitespace = value; } - + /** * @see org.apache.wicket.settings.IDebugSettings#setOutputMarkupContainerClassName(boolean) */ @@ -1253,13 +1262,13 @@ */ public IMarkupCache getMarkupCache() { - if (this.markupCache == null) + if (markupCache == null) { // Construct markup cache for this application - this.markupCache = new MarkupCache(application); + markupCache = new MarkupCache(application); } - return this.markupCache; + return markupCache; } /** @@ -1274,7 +1283,7 @@ public Bytes getDefaultMaximumUploadSize() { - return this.defaultMaximumUploadSize; + return defaultMaximumUploadSize; } public void setDefaultMaximumUploadSize(Bytes defaultMaximumUploadSize)