You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2011/03/13 20:13:38 UTC

svn commit: r1081200 - in /wicket/trunk/wicket-core/src: main/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocator.java test/java/org/apache/wicket/util/resource/locator/CachingResourceStreamLocatorTest.java

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);
+	}
 }