Author: mgrigorov
Date: Sun Mar 13 19:13:37 2011
New Revision: 1081200

URL: http://svn.apache.org/viewvc?rev=1081200&view=rev
Log:
WICKET-3511 Mapping ResourceReferences to Urls is slow

Fix the broken caching for missing resources.
Add a test that lightweight (all but file and url resource streams) should not 
be cached.


Modified:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java?rev=1081200&r1=1081199&r2=1081200&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java
 Sun Mar 13 19:13:37 2011
@@ -22,6 +22,7 @@ import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.request.resource.ResourceReference.Key;
 import org.apache.wicket.util.file.File;
 import org.apache.wicket.util.lang.Args;
@@ -49,7 +50,7 @@ public class CachingResourceStreamLocato
         */
        private static interface IResourceStreamReference
        {
-               String getReference();
+               IResourceStream getReference();
        }
 
        /**
@@ -61,7 +62,7 @@ public class CachingResourceStreamLocato
        {
                private final static NullResourceStreamReference INSTANCE = new 
NullResourceStreamReference();
 
-               public String getReference()
+               public IResourceStream getReference()
                {
                        return null;
                }
@@ -79,9 +80,9 @@ public class CachingResourceStreamLocato
                        this.fileName = fileName;
                }
 
-               public String getReference()
+               public FileResourceStream getReference()
                {
-                       return fileName;
+                       return new FileResourceStream(new File(fileName));
                }
        }
 
@@ -97,9 +98,18 @@ public class CachingResourceStreamLocato
                        this.url = url;
                }
 
-               public String getReference()
+               public UrlResourceStream getReference()
                {
-                       return url;
+                       try
+                       {
+                               return new UrlResourceStream(new URL(url));
+                       }
+                       catch (MalformedURLException e)
+                       {
+                               // should not ever happen. The cached url is 
created by previously existing URL
+                               // instance
+                               throw new WicketRuntimeException(e);
+                       }
                }
        }
 
@@ -133,16 +143,21 @@ public class CachingResourceStreamLocato
        public IResourceStream locate(Class<?> clazz, String path)
        {
                Key key = new Key(clazz.getName(), path, null, null, null);
-               IResourceStream resourceStream = getCopyFromCache(key);
+               IResourceStreamReference resourceStreamReference = 
cache.get(key);
 
-               if (resourceStream == null)
+               final IResourceStream result;
+               if (resourceStreamReference == null)
                {
-                       resourceStream = delegate.locate(clazz, path);
+                       result = delegate.locate(clazz, path);
 
-                       updateCache(key, resourceStream);
+                       updateCache(key, result);
+               }
+               else
+               {
+                       result = resourceStreamReference.getReference();
                }
 
-               return resourceStream;
+               return result;
        }
 
        private void updateCache(Key key, IResourceStream stream)
@@ -165,60 +180,25 @@ public class CachingResourceStreamLocato
                }
        }
 
-       /**
-        * Make a copy before returning an item from the cache as resource 
streams are not thread-safe.
-        * 
-        * @param key
-        *            the cache key
-        * @return the cached File or Url resource stream
-        */
-       private IResourceStream getCopyFromCache(Key key)
-       {
-               final IResourceStreamReference orig = cache.get(key);
-               if (NullResourceStreamReference.INSTANCE == orig)
-               {
-                       return null;
-               }
-
-               if (orig instanceof UrlResourceStreamReference)
-               {
-                       UrlResourceStreamReference resourceStreamReference = 
(UrlResourceStreamReference)orig;
-                       String url = resourceStreamReference.getReference();
-                       try
-                       {
-                               return new UrlResourceStream(new URL(url));
-                       }
-                       catch (MalformedURLException e)
-                       {
-                               return null;
-                       }
-               }
-
-               if (orig instanceof FileResourceStreamReference)
-               {
-                       FileResourceStreamReference resourceStreamReference = 
(FileResourceStreamReference)orig;
-                       String absolutePath = 
resourceStreamReference.getReference();
-                       return new FileResourceStream(new File(absolutePath));
-               }
-
-               return null;
-       }
-
        public IResourceStream locate(Class<?> scope, String path, String 
style, String variation,
                Locale locale, String extension, boolean strict)
        {
                Key key = new Key(scope.getName(), path, locale, style, 
variation);
-               IResourceStream resourceStream = getCopyFromCache(key);
+               IResourceStreamReference resourceStreamReference = 
cache.get(key);
 
-               if (resourceStream == null)
+               final IResourceStream result;
+               if (resourceStreamReference == null)
                {
-                       resourceStream = delegate.locate(scope, path, style, 
variation, locale, extension,
-                               strict);
+                       result = delegate.locate(scope, path, style, variation, 
locale, extension, strict);
 
-                       updateCache(key, resourceStream);
+                       updateCache(key, result);
+               }
+               else
+               {
+                       result = resourceStreamReference.getReference();
                }
 
-               return resourceStream;
+               return result;
        }
 
        public ResourceNameIterator newResourceNameIterator(String path, Locale 
locale, String style,

Modified: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java?rev=1081200&r1=1081199&r2=1081200&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java
 (original)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java
 Sun Mar 13 19:13:37 2011
@@ -25,6 +25,7 @@ import java.io.File;
 import java.net.URL;
 
 import org.apache.wicket.util.resource.FileResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
 import org.apache.wicket.util.resource.UrlResourceStream;
 import org.junit.Test;
 
@@ -51,8 +52,9 @@ public class CachingResourceStreamLocato
                cachingLocator.locate(String.class, "path");
                cachingLocator.locate(String.class, "path");
 
-               // there is no resource with that Key so expect two calls to 
the delegate
-               verify(resourceStreamLocator, times(2)).locate(String.class, 
"path");
+               // there is no resource with that Key so a "miss" will be 
cached and expect 1 call to the
+               // delegate
+               verify(resourceStreamLocator, times(1)).locate(String.class, 
"path");
        }
 
        /**
@@ -103,4 +105,31 @@ public class CachingResourceStreamLocato
                // there is a url resource with that Key so expect just one 
call to the delegate
                verify(resourceStreamLocator, times(1)).locate(String.class, 
"path");
        }
+
+       /**
+        * Tests light weight resource streams (everything but 
FileResourceStream and
+        * UrlResourceStream). These should <strong>not</strong> be cached.
+        */
+       @Test
+       public void testLightweightResource()
+       {
+               IResourceStreamLocator resourceStreamLocator = 
mock(IResourceStreamLocator.class);
+
+               StringResourceStream srs = new StringResourceStream("anything");
+
+               when(
+                       resourceStreamLocator.locate(String.class, "path", 
"style", "variation", null,
+                               "extension", true)).thenReturn(srs);
+
+               CachingResourceStreamLocator cachingLocator = new 
CachingResourceStreamLocator(
+                       resourceStreamLocator);
+
+               cachingLocator.locate(String.class, "path", "style", 
"variation", null, "extension", true);
+               cachingLocator.locate(String.class, "path", "style", 
"variation", null, "extension", true);
+
+               // lightweight resource streams should not be cached so expect 
just a call to the delegate
+               // for each call to the caching locator
+               verify(resourceStreamLocator, times(2)).locate(String.class, 
"path", "style", "variation",
+                       null, "extension", true);
+       }
 }


Reply via email to