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 2012/04/10 13:45:04 UTC

git commit: WICKET-4487 TextTemplate in RenderHead() on component doesn't Re-Render for every page

Updated Branches:
  refs/heads/wicket-1.5.x b5f330360 -> 4af73c5a9


WICKET-4487 TextTemplate in RenderHead() on component doesn't Re-Render for every page

Make TextTemplateResourceReference more dynamic by:
- re-interpolating the template with the latest state of the variables model
- re-registering the resource reference by key


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

Branch: refs/heads/wicket-1.5.x
Commit: 4af73c5a942fc4596bb29faec54d045a3d60da4c
Parents: b5f3303
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Tue Apr 10 14:43:10 2012 +0300
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Tue Apr 10 14:44:50 2012 +0300

----------------------------------------------------------------------
 .../wicket/request/resource/AbstractResource.java  |    2 +-
 .../wicket/request/resource/ByteArrayResource.java |    5 +-
 .../wicket/request/resource/ResourceReference.java |    2 +-
 .../request/resource/ResourceStreamResource.java   |   46 ++++++++----
 .../resource/TextTemplateResourceReference.java    |   55 ++++++++-------
 .../TextTemplateResourceReferenceTest.java         |   16 ++++-
 .../wicket/util/resource/StringResourceStream.java |    5 +-
 7 files changed, 78 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/resource/AbstractResource.java b/wicket-core/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
index 201e005..79e4d9f 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/resource/AbstractResource.java
@@ -301,7 +301,7 @@ public abstract class AbstractResource implements IResource
 			WebRequest request = (WebRequest)attributes.getRequest();
 			Time ifModifiedSince = request.getIfModifiedSinceHeader();
 
-			if (ifModifiedSince != null && lastModified != null)
+			if (cacheDuration != Duration.NONE && ifModifiedSince != null && lastModified != null)
 			{
 				// [Last-Modified] headers have a maximum precision of one second
 				// so we have to truncate the milliseconds part for a proper compare.

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java b/wicket-core/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
index 544f7ad..fe78ea0 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/resource/ByteArrayResource.java
@@ -18,11 +18,10 @@ package org.apache.wicket.request.resource;
 
 import java.net.URLConnection;
 
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.util.time.Time;
-
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.wicket.util.time.Time;
+
 /**
  * An {@link IResource} for byte arrays. The byte array can be static - passed to the constructor,
  * or dynamic - by overriding

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReference.java b/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
index 4f66ec6..d42ab05 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
@@ -107,7 +107,7 @@ public abstract class ResourceReference implements Serializable
 	 *         ResourceReferenceRegistry to make up the key under which the resource reference gets
 	 *         stored.
 	 */
-	Key getKey()
+	public final Key getKey()
 	{
 		return data;
 	}

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java b/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
index 7600aa8..34e3282 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceStreamResource.java
@@ -22,8 +22,8 @@ import java.io.InputStream;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.wicket.Application;
-import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Bytes;
+import org.apache.wicket.util.lang.Checks;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.IResourceStreamWriter;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
@@ -42,7 +42,7 @@ public class ResourceStreamResource extends AbstractResource
 
 	private static final Logger logger = LoggerFactory.getLogger(ResourceStreamResource.class);
 
-	private final IResourceStream stream;
+	private IResourceStream stream;
 	private String fileName;
 	private ContentDisposition contentDisposition = ContentDisposition.INLINE;
 	private String textEncoding;
@@ -56,7 +56,6 @@ public class ResourceStreamResource extends AbstractResource
 	 */
 	public ResourceStreamResource(IResourceStream stream)
 	{
-		Args.notNull(stream, "stream");
 		this.stream = stream;
 	}
 
@@ -109,16 +108,38 @@ public class ResourceStreamResource extends AbstractResource
 		return this;
 	}
 
+	/**
+	 * Lazy or dynamic initialization of the wrapped IResourceStream(Writer)
+	 * @return the underlying IResourceStream
+	 */
+	protected IResourceStream getResourceStream()
+	{
+		return stream;
+	}
+
+	private IResourceStream internalGetResourceStream()
+	{
+		final IResourceStream resourceStream = getResourceStream();
+		Checks.notNull(resourceStream, "%s#getResourceStream() should not return null!", ResourceStreamResource.class.getName());
+		return resourceStream;
+	}
+
 	@Override
 	protected ResourceResponse newResourceResponse(Attributes attributes)
 	{
+		final IResourceStream resourceStream = internalGetResourceStream();
 		ResourceResponse data = new ResourceResponse();
-		Time lastModifiedTime = stream.lastModifiedTime();
+		Time lastModifiedTime = resourceStream.lastModifiedTime();
 		if (lastModifiedTime != null)
 		{
 			data.setLastModified(lastModifiedTime);
 		}
 
+		if (cacheDuration != null)
+		{
+			data.setCacheDuration(cacheDuration);
+		}
+
 		// performance check; don't bother to do anything if the resource is still cached by client
 		if (data.dataNeedsToBeWritten(attributes))
 		{
@@ -127,7 +148,7 @@ public class ResourceStreamResource extends AbstractResource
 			{
 				try
 				{
-					inputStream = stream.getInputStream();
+					inputStream = resourceStream.getInputStream();
 				}
 				catch (ResourceStreamNotFoundException e)
 				{
@@ -137,14 +158,14 @@ public class ResourceStreamResource extends AbstractResource
 			}
 
 			data.setContentDisposition(contentDisposition);
-			Bytes length = stream.length();
+			Bytes length = resourceStream.length();
 			if (length != null)
 			{
 				data.setContentLength(length.bytes());
 			}
 			data.setFileName(fileName);
 
-			String contentType = stream.getContentType();
+			String contentType = resourceStream.getContentType();
 			if (contentType == null && fileName != null && Application.exists())
 			{
 				contentType = Application.get().getMimeType(fileName);
@@ -152,19 +173,14 @@ public class ResourceStreamResource extends AbstractResource
 			data.setContentType(contentType);
 			data.setTextEncoding(textEncoding);
 
-			if (cacheDuration != null)
-			{
-				data.setCacheDuration(cacheDuration);
-			}
-
-			if (stream instanceof IResourceStreamWriter)
+			if (resourceStream instanceof IResourceStreamWriter)
 			{
 				data.setWriteCallback(new WriteCallback()
 				{
 					@Override
 					public void writeData(Attributes attributes)
 					{
-						((IResourceStreamWriter)stream).write(attributes.getResponse());
+						((IResourceStreamWriter)resourceStream).write(attributes.getResponse());
 						close();
 					}
 				});
@@ -197,7 +213,7 @@ public class ResourceStreamResource extends AbstractResource
 	{
 		try
 		{
-			stream.close();
+			internalGetResourceStream().close();
 		}
 		catch (IOException e)
 		{

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/main/java/org/apache/wicket/resource/TextTemplateResourceReference.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/resource/TextTemplateResourceReference.java b/wicket-core/src/main/java/org/apache/wicket/resource/TextTemplateResourceReference.java
index 7e85b92..16ed5cb 100644
--- a/wicket-core/src/main/java/org/apache/wicket/resource/TextTemplateResourceReference.java
+++ b/wicket-core/src/main/java/org/apache/wicket/resource/TextTemplateResourceReference.java
@@ -24,10 +24,14 @@ import org.apache.wicket.IClusterable;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.request.resource.ResourceReferenceRegistry;
 import org.apache.wicket.request.resource.ResourceStreamResource;
+import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.apache.wicket.util.template.PackageTextTemplate;
 import org.apache.wicket.util.template.TextTemplate;
+import org.apache.wicket.util.time.Duration;
+import org.apache.wicket.util.time.Time;
 
 /**
  * A class which adapts a {@link PackageTextTemplate} to a {@link ResourceReference}.
@@ -38,18 +42,12 @@ import org.apache.wicket.util.template.TextTemplate;
  */
 public class TextTemplateResourceReference extends ResourceReference implements IClusterable
 {
-// **********************************************************************************************************************
-// Fields
-// **********************************************************************************************************************
 
 	private static final long serialVersionUID = 1L;
+
 	private final TextTemplate textTemplate;
 	private final IModel<Map<String, Object>> variablesModel;
-	private IResource resource;
-
-// **********************************************************************************************************************
-// Constructors
-// **********************************************************************************************************************
+	private final ResourceStreamResource resource;
 
 	/**
 	 * Creates a resource reference to a {@link PackageTextTemplate}.
@@ -142,16 +140,34 @@ public class TextTemplateResourceReference extends ResourceReference implements
 		textTemplate = new PackageTextTemplate(scope, fileName, contentType, encoding);
 		this.variablesModel = variablesModel;
 
+		resource = new ResourceStreamResource(null)
+		{
+			@Override
+			protected IResourceStream getResourceStream()
+			{
+				IModel<Map<String, Object>> variables = TextTemplateResourceReference.this.variablesModel;
+				String stringValue = textTemplate.asString(variables.getObject());
+				variables.detach(); // We're done with the model so detach it!
+
+				StringResourceStream resourceStream = new StringResourceStream(stringValue,
+						textTemplate.getContentType());
+				resourceStream.setLastModified(Time.now());
+
+				return resourceStream;
+			}
+		};
+		resource.setCacheDuration(Duration.NONE);
+
 		if (Application.exists())
 		{
-			Application.get().getResourceReferenceRegistry().registerResourceReference(this);
+			// TextTemplateResourceReference should not be cached due to its dynamic nature
+			// Old entry in the registry would keep wrong 'variablesModel'
+			ResourceReferenceRegistry resourceReferenceRegistry = Application.get().getResourceReferenceRegistry();
+			resourceReferenceRegistry.unregisterResourceReference(getKey());
+			resourceReferenceRegistry.registerResourceReference(this);
 		}
 	}
 
-// **********************************************************************************************************************
-// Other Methods
-// **********************************************************************************************************************
-
 	/**
 	 * Creates a new resource which returns the interpolated value of the text template.
 	 * 
@@ -160,19 +176,6 @@ public class TextTemplateResourceReference extends ResourceReference implements
 	@Override
 	public IResource getResource()
 	{
-		if (resource != null)
-		{
-			return resource;
-		}
-
-		String stringValue = textTemplate.asString(variablesModel.getObject());
-		variablesModel.detach(); // We're done with the model so detach it!
-
-		StringResourceStream resourceStream = new StringResourceStream(stringValue,
-			textTemplate.getContentType());
-		resourceStream.setLastModified(textTemplate.lastModifiedTime());
-
-		resource = new ResourceStreamResource(resourceStream);
 		return resource;
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-core/src/test/java/org/apache/wicket/resource/TextTemplateResourceReferenceTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/resource/TextTemplateResourceReferenceTest.java b/wicket-core/src/test/java/org/apache/wicket/resource/TextTemplateResourceReferenceTest.java
index 2a85401..dedee2e 100644
--- a/wicket-core/src/test/java/org/apache/wicket/resource/TextTemplateResourceReferenceTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/resource/TextTemplateResourceReferenceTest.java
@@ -40,6 +40,8 @@ public class TextTemplateResourceReferenceTest extends WicketTestCase
 	private static final String TEMPLATE_NAME = "textTemplateResRef.tmpl";
 
 	private static final String EXPECTED_VALUE = "value";
+	private static final String SECOND_EXPECTED_VALUE = "second-value";
+	private static final String VARIABLE_NAME = "variable";
 
 	/**
 	 * https://issues.apache.org/jira/browse/WICKET-3971
@@ -49,13 +51,20 @@ public class TextTemplateResourceReferenceTest extends WicketTestCase
 	{
 		// the page will render just <script> element with url to the template
 		// this will register it in the application's ResourceReferenceRegistry
-		Page page = tester.startPage(new TemplateResourceReferencePage());
+		TemplateResourceReferencePage page = new TemplateResourceReferencePage();
+		tester.startPage(page);
 
 		// make a separate request to the template resource
 		CharSequence urlForTemplate = page.urlFor(new PackageResourceReference(
 			TextTemplateResourceReferenceTest.class, TEMPLATE_NAME), null);
 		tester.executeUrl(urlForTemplate.toString());
 		tester.assertContains("TMPL_START\\|" + EXPECTED_VALUE + "\\|TMPL_END");
+
+		// update the model and re-render (WICKET-4487)
+		page.variables.put(VARIABLE_NAME, SECOND_EXPECTED_VALUE);
+		tester.executeUrl(urlForTemplate.toString());
+		tester.assertContains("TMPL_START\\|"+SECOND_EXPECTED_VALUE+"\\|TMPL_END");
+
 	}
 
 	private static class TemplateResourceReferencePage extends WebPage
@@ -64,13 +73,14 @@ public class TextTemplateResourceReferenceTest extends WicketTestCase
 	{
 		private static final long serialVersionUID = 1L;
 
+		private final Map<String, Object> variables = new HashMap<String, Object>();
+
 		@Override
 		public void renderHead(IHeaderResponse response)
 		{
 			super.renderHead(response);
 
-			Map<String, Object> variables = new HashMap<String, Object>();
-			variables.put("variable", EXPECTED_VALUE);
+			variables.put(VARIABLE_NAME, EXPECTED_VALUE);
 
 			final TextTemplateResourceReference reference = new TextTemplateResourceReference(
 				TextTemplateResourceReferenceTest.class, TEMPLATE_NAME, Model.ofMap(variables));

http://git-wip-us.apache.org/repos/asf/wicket/blob/4af73c5a/wicket-util/src/main/java/org/apache/wicket/util/resource/StringResourceStream.java
----------------------------------------------------------------------
diff --git a/wicket-util/src/main/java/org/apache/wicket/util/resource/StringResourceStream.java b/wicket-util/src/main/java/org/apache/wicket/util/resource/StringResourceStream.java
index a7d12ed..c8720ea 100644
--- a/wicket-util/src/main/java/org/apache/wicket/util/resource/StringResourceStream.java
+++ b/wicket-util/src/main/java/org/apache/wicket/util/resource/StringResourceStream.java
@@ -39,7 +39,7 @@ public final class StringResourceStream extends AbstractStringResourceStream
 	 */
 	public StringResourceStream(final CharSequence string)
 	{
-		this.string = string;
+		this(string, null);
 	}
 
 	/**
@@ -74,9 +74,6 @@ public final class StringResourceStream extends AbstractStringResourceStream
 		return string.toString();
 	}
 
-	/**
-	 * @see org.apache.wicket.util.resource.AbstractResourceStream#asString()
-	 */
 	@Override
 	public String asString()
 	{