You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by th...@apache.org on 2014/07/02 17:43:05 UTC

git commit: TAP5-2185

Repository: tapestry-5
Updated Branches:
  refs/heads/master 23f491d55 -> 2e11d5dd3


TAP5-2185


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/2e11d5dd
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/2e11d5dd
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/2e11d5dd

Branch: refs/heads/master
Commit: 2e11d5dd3d9fdb48d47ed3ba8559b506e32c4486
Parents: 23f491d
Author: Thiago H. de Paula Figueiredo <th...@apache.org>
Authored: Wed Jul 2 12:42:38 2014 -0300
Committer: Thiago H. de Paula Figueiredo <th...@apache.org>
Committed: Wed Jul 2 12:42:38 2014 -0300

----------------------------------------------------------------------
 .../internal/services/ResourceStreamerImpl.java | 79 +++++++++++++++++++-
 .../tapestry5/integration/app1/AssetTests.java  | 12 +++
 .../app1/pages/nested/AssetDemo.java            | 19 +++++
 .../integration/app1/pages/nested/AssetDemo.tml |  6 +-
 .../app1/pages/nested/AssetWithWrongChecksum.js |  1 +
 5 files changed, 113 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/2e11d5dd/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java
index d5e6024..ce3d1ae 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java
@@ -12,13 +12,16 @@
 
 package org.apache.tapestry5.internal.services;
 
+import org.apache.tapestry5.Asset;
 import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.internal.InternalConstants;
 import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
 import org.apache.tapestry5.ioc.IOOperation;
 import org.apache.tapestry5.ioc.OperationTracker;
 import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.annotations.InjectService;
 import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.services.AssetFactory;
 import org.apache.tapestry5.services.Request;
 import org.apache.tapestry5.services.Response;
 import org.apache.tapestry5.services.assets.*;
@@ -47,6 +50,10 @@ public class ResourceStreamerImpl implements ResourceStreamer
     private final ResourceChangeTracker resourceChangeTracker;
 
     private final String omitExpirationCacheControlHeader;
+    
+    private final AssetFactory classpathAssetFactory;
+    
+    private final AssetFactory contextAssetFactory;
 
     public ResourceStreamerImpl(Request request,
 
@@ -62,7 +69,13 @@ public class ResourceStreamerImpl implements ResourceStreamer
                                 ResourceChangeTracker resourceChangeTracker,
 
                                 @Symbol(SymbolConstants.OMIT_EXPIRATION_CACHE_CONTROL_HEADER)
-                                String omitExpirationCacheControlHeader)
+                                String omitExpirationCacheControlHeader,
+                                
+                                @InjectService("ClasspathAssetFactory")
+                                AssetFactory classpathAssetFactory,
+                                
+                                @InjectService("ContextAssetFactory")
+                                AssetFactory contextAssetFactory)
     {
         this.request = request;
         this.response = response;
@@ -72,6 +85,9 @@ public class ResourceStreamerImpl implements ResourceStreamer
         this.productionMode = productionMode;
         this.resourceChangeTracker = resourceChangeTracker;
         this.omitExpirationCacheControlHeader = omitExpirationCacheControlHeader;
+        
+        this.classpathAssetFactory = classpathAssetFactory;
+        this.contextAssetFactory = contextAssetFactory;
     }
 
     public boolean streamResource(final Resource resource, final String providedChecksum, final Set<Options> options) throws IOException
@@ -87,7 +103,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
 
         final boolean compress = providedChecksum.startsWith("z");
 
-        return tracker.perform(String.format("Streaming %s%s", resource, compress ? " (compressed)" : ""), new IOOperation<Boolean>()
+        return tracker.perform("Streaming " + resource + (compress ? " (compressed)" : ""), new IOOperation<Boolean>()
         {
             public Boolean perform() throws IOException
             {
@@ -97,13 +113,18 @@ public class ResourceStreamerImpl implements ResourceStreamer
 
                 StreamableResource streamable = streamableResourceSource.getStreamableResource(resource, processing, resourceChangeTracker);
 
-                return streamResource(streamable, compress ? providedChecksum.substring(1) : providedChecksum, options);
+                return streamResource(resource, streamable, compress ? providedChecksum.substring(1) : providedChecksum, options);
             }
         });
     }
 
     public boolean streamResource(StreamableResource streamable, String providedChecksum, Set<Options> options) throws IOException
     {
+        return streamResource(null, streamable, providedChecksum, options);
+    }
+    
+    public boolean streamResource(Resource resource, StreamableResource streamable, String providedChecksum, Set<Options> options) throws IOException
+    {
         assert streamable != null;
         assert providedChecksum != null;
         assert options != null;
@@ -112,6 +133,19 @@ public class ResourceStreamerImpl implements ResourceStreamer
 
         if (providedChecksum.length() > 0 && !providedChecksum.equals(actualChecksum))
         {
+            
+            // TAP5-2185: Trying to find the wrongly-checksummed resource in the classpath and context,
+            // so we can create an Asset with the correct checksum and redirect to it.
+            Asset asset = null;
+            if (resource != null)
+            {
+                asset = findAssetInsideWebapp(resource);
+            }
+            if (asset != null)
+            {
+                response.sendRedirect(asset.toClientURL());
+                return true;
+            }
             return false;
         }
 
@@ -198,4 +232,43 @@ public class ResourceStreamerImpl implements ResourceStreamer
         return true;
     }
 
+    private Asset findAssetInsideWebapp(Resource resource)
+    {
+        Asset asset;
+        asset = findAssetFromClasspath(resource);
+        if (asset == null)
+        {
+            asset = findAssetFromContext(resource);
+        }
+        return asset;
+    }
+
+    private Asset findAssetFromContext(Resource resource)
+    {
+        Asset asset = null;
+        try
+        {
+            asset = contextAssetFactory.createAsset(resource);
+        }
+        catch (RuntimeException e)
+        {
+            // not an existing context asset. go ahead.
+        }
+        return asset;
+    }
+
+    private Asset findAssetFromClasspath(Resource resource)
+    {
+        Asset asset = null;
+        try
+        {
+            asset = classpathAssetFactory.createAsset(resource);
+        }
+        catch (RuntimeException e)
+        {
+            // not an existing classpath asset. go ahead.
+        }
+        return asset;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/2e11d5dd/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/AssetTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/AssetTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/AssetTests.java
index 6e69fad..40f148c 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/AssetTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/AssetTests.java
@@ -68,6 +68,18 @@ public class AssetTests extends App1TestCase
         // check whether externaly @Import'ed d3 works
         assertTrue(isElementPresent("css=svg"));
     }
+    
+    // TAP5-2185
+    @Test
+    public void redirection_of_requests_to_assets_with_wrong_checksums()
+    {
+        openLinks("AssetDemo");
+        // paragraph is rendered with display="none" and the javascript asset changes it to display="block"
+        // without the fix, selenium timesout because the javascript code that sets the condition
+        // used by tapestry testing code to know when the page is finished loading is never invoked.
+        assertTrue(isVisible("assetWithWrongChecksum"));
+    }
+
 
     private void compareDownloadedAsset(String assetURL, String localPath) throws Exception
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/2e11d5dd/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.java
index ca77f76..8a0a669 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.java
@@ -15,11 +15,13 @@
 package org.apache.tapestry5.integration.app1.pages.nested;
 
 import org.apache.tapestry5.Asset;
+import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.annotations.Environmental;
 import org.apache.tapestry5.annotations.Import;
 import org.apache.tapestry5.annotations.Path;
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.AssetSource;
 import org.apache.tapestry5.services.javascript.JavaScriptSupport;
 import org.apache.tapestry5.services.javascript.StylesheetLink;
 import org.apache.tapestry5.services.javascript.StylesheetOptions;
@@ -77,10 +79,27 @@ public class AssetDemo
     @Inject
     @Path("tapestry.png")
     private Asset logo;
+    
+    @Inject
+    private ComponentResources resources;
+    
+    @Inject
+    private AssetSource assetSource;
 
     @Import(stylesheet = "context:css/via-import.css")
     void afterRender()
     {
         javascriptSupport.importStylesheet(new StylesheetLink(ieOnly, new StylesheetOptions(null, "IE")));
+        javascriptSupport.importJavaScriptLibrary(getAssetWithWrongChecksumUrl());
+    }
+    
+    public String getAssetWithWrongChecksumUrl() {
+        final Asset asset = getAssetWithCorrectChecksum();
+        return asset.toClientURL().replaceAll("[0-9a-f]{8}", "00000000");
+    }
+
+    public Asset getAssetWithCorrectChecksum()
+    {
+        return assetSource.getComponentAsset(resources, "AssetWithWrongChecksum.js", "");
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/2e11d5dd/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.tml
index 68bc425..695a825 100644
--- a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.tml
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetDemo.tml
@@ -83,6 +83,10 @@
 	Using d3, loaded directly from a CDN using external asset support (example from http://christopheviau.com/d3_tutorial/): 
 </p>
 
-<div id="viz"/>
+<div id="viz"></div>
+
+<p>Asset with good checksum: ${assetWithCorrectChecksum}</p>
+<p>Asset with bad checksum: ${assetWithWrongChecksumUrl}</p>
+<p id="assetWithWrongChecksum" style="display: none">Asset with wrong checksum handled correctly.</p>
 
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/2e11d5dd/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetWithWrongChecksum.js
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetWithWrongChecksum.js b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetWithWrongChecksum.js
new file mode 100644
index 0000000..652950f
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/nested/AssetWithWrongChecksum.js
@@ -0,0 +1 @@
+document.getElementById('assetWithWrongChecksum').style.display = 'block';
\ No newline at end of file