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/78d39365
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/78d39365
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/78d39365

Branch: refs/heads/sandbox/atmosphere
Commit: 78d39365726790a42087ed0d77c917fb93f0082f
Parents: 925cae5
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Tue Apr 10 14:43:10 2012 +0300
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Tue Apr 10 14:47:11 2012 +0300

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


http://git-wip-us.apache.org/repos/asf/wicket/blob/78d39365/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 d0f58b1..2033a72 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/78d39365/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 04521a8..b936115 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
@@ -110,7 +110,7 @@ public abstract class ResourceReference implements 
IClusterable
         *         ResourceReferenceRegistry to make up the key under which the 
resource reference gets
         *         stored.
         */
-       public Key getKey()
+       public final Key getKey()
        {
                return data;
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/78d39365/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 53dd6cd..08b8a8e 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.core.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/78d39365/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 8bb050e..dbaa81a 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
@@ -23,11 +23,15 @@ import org.apache.wicket.Application;
 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.io.IClusterable;
+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/78d39365/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 4520c8f..e16450b 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
@@ -41,6 +41,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
@@ -50,13 +52,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
@@ -65,13 +74,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/78d39365/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()
        {

Reply via email to