You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2013/03/15 00:09:18 UTC
[7/14] git commit: Initial changes to support per-resource checksums
on normal assets
Initial changes to support per-resource checksums on normal assets
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/8fbbd594
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/8fbbd594
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/8fbbd594
Branch: refs/heads/master
Commit: 8fbbd59437c0153ce17f3373e7eaa2ae88bbc6f5
Parents: 2fc96ca
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Wed Mar 6 17:21:02 2013 -0800
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Thu Mar 14 13:41:11 2013 -0700
----------------------------------------------------------------------
54_RELEASE_NOTES.txt | 6 +-
.../internal/services/AssetDispatcher.java | 27 +--
.../services/ClasspathAssetAliasManagerImpl.java | 9 +-
.../internal/services/ClasspathAssetFactory.java | 4 +-
.../internal/services/ContextAssetFactory.java | 4 +-
.../assets/AssetChecksumGeneratorImpl.java | 92 +++++++++
.../services/assets/AssetPathConstructorImpl.java | 67 +++-----
.../internal/services/assets/ChecksumPath.java | 59 ++++++
.../assets/ClasspathAssetRequestHandler.java | 22 +--
.../assets/ContextAssetRequestHandler.java | 14 +-
.../JavaScriptStackPathConstructorImpl.java | 7 +-
.../services/ClasspathAssetAliasManager.java | 29 ++--
.../apache/tapestry5/services/TapestryModule.java | 126 -------------
.../services/assets/AssetChecksumGenerator.java | 37 ++++
.../services/assets/AssetPathConstructor.java | 17 +-
.../services/assets/AssetRequestHandler.java | 26 +--
.../tapestry5/services/assets/AssetsModule.java | 143 ++++++++++++++-
.../apache/tapestry5/test/TapestryTestCase.java | 10 +-
.../assets/AssetPathConstructorImplTest.groovy | 62 +++----
.../ClasspathAssetAliasManagerImplTest.java | 43 ++++-
.../services/ClasspathAssetFactoryTest.java | 8 +-
.../internal/services/ContextAssetFactoryTest.java | 101 +---------
.../assets/ContextAssetRequestHandlerTest.java | 5 +-
23 files changed, 505 insertions(+), 413 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/54_RELEASE_NOTES.txt
----------------------------------------------------------------------
diff --git a/54_RELEASE_NOTES.txt b/54_RELEASE_NOTES.txt
index 13444a3..8c369c6 100644
--- a/54_RELEASE_NOTES.txt
+++ b/54_RELEASE_NOTES.txt
@@ -180,4 +180,8 @@ The OperationTracker interface has had a new method added, for performing an IO
Tapestry now uses a lock on access to the HttpSession; a shared read lock is acquired when reading session attribute
names; an exclusive write lock is acquired when reading or writing session attributes. Locks, once acquired, are kept
until the end of the request. A new configuration symbol can be used to turn this feature off, reverting to Tapestry
-5.3 behavior.
\ No newline at end of file
+5.3 behavior.
+
+## AssetPathConstructor
+
+The interface for AssetPathConstructor was changed incompatibly, to allow for individual asset checksums.
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetDispatcher.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetDispatcher.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetDispatcher.java
index fe33e2b..0f64f73 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetDispatcher.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetDispatcher.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008, 2009, 2010, 2011, 2012 The Apache Software Foundation
+// Copyright 2006-2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,15 +15,11 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.services.AssetRequestDispatcher;
import org.apache.tapestry5.ioc.annotations.Marker;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.services.ClasspathAssetAliasManager;
-import org.apache.tapestry5.services.Dispatcher;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.*;
import org.apache.tapestry5.services.assets.AssetRequestHandler;
import javax.servlet.http.HttpServletResponse;
@@ -59,28 +55,21 @@ public class AssetDispatcher implements Dispatcher
public AssetDispatcher(Map<String, AssetRequestHandler> configuration,
- @Symbol(SymbolConstants.APPLICATION_VERSION)
- String applicationVersion,
-
@Symbol(SymbolConstants.APPLICATION_FOLDER)
String applicationFolder,
+ PathConstructor pathConstructor,
+
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
String assetPathPrefix)
{
- StringBuilder pathPrefix = new StringBuilder("/");
-
- if (! applicationFolder.equals("")) {
- pathPrefix.append(applicationFolder).append("/");
- }
-
- pathPrefix.append(assetPathPrefix).append("/").append(applicationVersion).append("/");
-
- this.pathPrefix = pathPrefix.toString();
+ pathPrefix = pathConstructor.constructDispatchPath(assetPathPrefix, "");
for (String path : configuration.keySet())
{
- String extendedPath = this.pathPrefix + path + "/";
+ String extendedPath = path.length() == 0
+ ? pathPrefix
+ : pathPrefix + path + "/";
pathToHandler.put(extendedPath, configuration.get(path));
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImpl.java
index 3a76ebe..69cb15c 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2009, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2009, 2011, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
package org.apache.tapestry5.internal.services;
+import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.util.AvailableValues;
import org.apache.tapestry5.ioc.util.UnknownValueException;
@@ -90,8 +91,10 @@ public class ClasspathAssetAliasManagerImpl implements ClasspathAssetAliasManage
}
- public String toClientURL(String resourcePath)
+ public String toClientURL(Resource resource)
{
+ String resourcePath = resource.getPath();
+
for (String pathPrefix : sortedPathPrefixes)
{
if (resourcePath.startsWith(pathPrefix))
@@ -100,7 +103,7 @@ public class ClasspathAssetAliasManagerImpl implements ClasspathAssetAliasManage
String virtualPath = resourcePath.substring(pathPrefix.length() + 1);
- return assetPathConstructor.constructAssetPath(virtualFolder, virtualPath);
+ return assetPathConstructor.constructAssetPath(virtualFolder, virtualPath, resource);
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
index 8f298ab..de96d0f 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2011, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@ public class ClasspathAssetFactory implements AssetFactory
path = path.substring(0, lastdotx + 1) + digestManager.getDigest(resource) + path.substring(lastdotx);
}
- return aliasManager.toClientURL(path);
+ return aliasManager.toClientURL(resource);
}
public Asset createAsset(Resource resource)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
index 0a97214..b7e41e2 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public class ContextAssetFactory implements AssetFactory
public Asset createAsset(Resource resource)
{
- String defaultPath = assetPathConstructor.constructAssetPath(RequestConstants.CONTEXT_FOLDER, resource.getPath());
+ String defaultPath = assetPathConstructor.constructAssetPath(RequestConstants.CONTEXT_FOLDER, resource.getPath(), resource);
if (invariant)
{
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
new file mode 100644
index 0000000..0ebbcd7
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetChecksumGeneratorImpl.java
@@ -0,0 +1,92 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.services.assets;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.services.assets.AssetChecksumGenerator;
+import org.apache.tapestry5.services.assets.StreamableResource;
+import org.apache.tapestry5.services.assets.StreamableResourceProcessing;
+import org.apache.tapestry5.services.assets.StreamableResourceSource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+
+public class AssetChecksumGeneratorImpl implements AssetChecksumGenerator
+{
+ private final static int BUFFER_SIZE = 4096;
+
+ private final StreamableResourceSource streamableResourceSource;
+
+ private final ResourceChangeTracker tracker;
+
+ public AssetChecksumGeneratorImpl(StreamableResourceSource streamableResourceSource, ResourceChangeTracker tracker)
+ {
+ this.streamableResourceSource = streamableResourceSource;
+ this.tracker = tracker;
+ }
+
+ public String generateChecksum(Resource resource) throws IOException
+ {
+ // TODO: Caching, and cache invalidation.
+
+ StreamableResource streamable = streamableResourceSource.getStreamableResource(resource, StreamableResourceProcessing.COMPRESSION_DISABLED,
+ tracker);
+
+ return toChecksum(streamable.openStream());
+ }
+
+ private String toChecksum(InputStream is) throws IOException
+ {
+ try
+ {
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+
+ digestStream(digest, is);
+
+ is.close();
+
+ byte[] bytes = digest.digest();
+ char[] encoded = Hex.encodeHex(bytes);
+
+ return new String(encoded);
+ } catch (Exception ex)
+ {
+ throw new RuntimeException(ex);
+ } finally
+ {
+ InternalUtils.close(is);
+ }
+ }
+
+ private void digestStream(MessageDigest digest, InputStream stream) throws IOException
+ {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ while (true)
+ {
+ int length = stream.read(buffer);
+
+ if (length < 0)
+ {
+ return;
+ }
+
+ digest.update(buffer, 0, length);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
index b9fddbd..159c854 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2011, 2012 The Apache Software Foundation
+// Copyright 2010, 2011, 2012, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,12 +15,17 @@
package org.apache.tapestry5.internal.services.assets;
import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.services.BaseURLSource;
+import org.apache.tapestry5.services.PathConstructor;
import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.assets.AssetChecksumGenerator;
import org.apache.tapestry5.services.assets.AssetPathConstructor;
+import java.io.IOException;
+
public class AssetPathConstructorImpl implements AssetPathConstructor
{
private final Request request;
@@ -29,64 +34,33 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
private final BaseURLSource baseURLSource;
+ private final AssetChecksumGenerator assetChecksumGenerator;
+
private final boolean fullyQualified;
public AssetPathConstructorImpl(Request request,
BaseURLSource baseURLSource,
- @Symbol(SymbolConstants.CONTEXT_PATH)
- String contextPath,
-
- @Symbol(SymbolConstants.APPLICATION_VERSION)
- String applicationVersion,
-
- @Symbol(SymbolConstants.APPLICATION_FOLDER)
- String applicationFolder,
-
@Symbol(SymbolConstants.ASSET_URL_FULL_QUALIFIED)
boolean fullyQualified,
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
- String assetPathPrefix)
+ String assetPathPrefix,
+
+ PathConstructor pathConstructor,
+
+ AssetChecksumGenerator assetChecksumGenerator)
{
this.request = request;
this.baseURLSource = baseURLSource;
this.fullyQualified = fullyQualified;
+ this.assetChecksumGenerator = assetChecksumGenerator;
- StringBuilder prefix = new StringBuilder();
-
- boolean needsSlash = false;
-
- if (contextPath.length() == 0) {
- prefix.append("/");
- }
- else {
- prefix.append(contextPath);
- needsSlash = true;
- }
-
- if (!applicationFolder.equals("")) {
-
- if (needsSlash) {
- prefix.append("/");
- }
-
- prefix.append(applicationFolder).append("/");
-
- needsSlash = false;
- }
-
- if (needsSlash) {
- prefix.append("/");
- }
-
- prefix.append(assetPathPrefix).append("/").append(applicationVersion).append("/");
-
- this.prefix = prefix.toString();
+ prefix = pathConstructor.constructClientPath(assetPathPrefix, "");
}
- public String constructAssetPath(String virtualFolder, String path)
+ public String constructAssetPath(String virtualFolder, String path, Resource resource)
{
assert InternalUtils.isNonBlank(virtualFolder);
assert path != null;
@@ -100,6 +74,15 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
builder.append(prefix);
builder.append(virtualFolder);
+ builder.append("/");
+
+ try
+ {
+ builder.append(assetChecksumGenerator.generateChecksum(resource));
+ } catch (IOException ex)
+ {
+ throw new RuntimeException(ex);
+ }
if (InternalUtils.isNonBlank(path))
{
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ChecksumPath.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ChecksumPath.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ChecksumPath.java
new file mode 100644
index 0000000..8155a01
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ChecksumPath.java
@@ -0,0 +1,59 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.services.assets;
+
+import org.apache.tapestry5.internal.services.ResourceStreamer;
+import org.apache.tapestry5.ioc.Resource;
+
+import java.io.IOException;
+
+/**
+ * Utility used by {@link org.apache.tapestry5.services.assets.AssetRequestHandler} implementations
+ * where the first folder in the extra path is actually a computed checksum of the resource's content.
+ *
+ * @since 5.4
+ */
+public class ChecksumPath {
+ public final String checksum;
+
+ public final String resourcePath;
+
+ private final ResourceStreamer streamer;
+
+ public ChecksumPath(ResourceStreamer streamer, String baseFolder, String extraPath) {
+ this.streamer = streamer;
+ int slashx = extraPath.indexOf('/');
+
+ checksum = extraPath.substring(0, slashx);
+
+ String morePath = extraPath.substring(slashx + 1);
+
+ resourcePath = baseFolder == null
+ ? morePath
+ : baseFolder + "/" + morePath;
+ }
+
+ public boolean stream(Resource resource) throws IOException {
+ if (resource == null) {
+ return false;
+ }
+
+ // TODO: Handle incorrect checksum ... maybe with a redirect?
+
+ streamer.streamResource(resource);
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
index 76d4e06..1441010 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,20 +14,19 @@
package org.apache.tapestry5.internal.services.assets;
-import java.io.IOException;
-
import org.apache.tapestry5.internal.services.AssetResourceLocator;
import org.apache.tapestry5.internal.services.ResourceStreamer;
-import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.services.ClasspathAssetAliasManager;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.services.assets.AssetRequestHandler;
+import java.io.IOException;
+
/**
* A handler for asset requests for classpath assets (within a specific folder).
* Each mapping of the {@link ClasspathAssetAliasManager} gets one of these.
- *
+ *
* @since 5.2.0
*/
public class ClasspathAssetRequestHandler implements AssetRequestHandler
@@ -39,7 +38,7 @@ public class ClasspathAssetRequestHandler implements AssetRequestHandler
private final String baseFolder;
public ClasspathAssetRequestHandler(ResourceStreamer streamer, AssetResourceLocator assetResourceLocator,
- String baseFolder)
+ String baseFolder)
{
this.streamer = streamer;
this.assetResourceLocator = assetResourceLocator;
@@ -48,15 +47,8 @@ public class ClasspathAssetRequestHandler implements AssetRequestHandler
public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
{
- String assetPath = baseFolder + "/" + extraPath;
-
- Resource resource = assetResourceLocator.findClasspathResourceForPath(assetPath);
-
- if (resource == null)
- return false;
-
- streamer.streamResource(resource);
+ ChecksumPath path = new ChecksumPath(streamer, baseFolder, extraPath);
- return true;
+ return path.stream(assetResourceLocator.findClasspathResourceForPath(path.resourcePath));
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandler.java
index 3fcadbb..824c824 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandler.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandler.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -45,14 +45,14 @@ public class ContextAssetRequestHandler implements AssetRequestHandler
public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
{
- if (illegal.matcher(extraPath).matches())
- return false;
-
- Resource resource = rootContextResource.forFile(extraPath);
+ ChecksumPath path = new ChecksumPath(resourceStreamer, null, extraPath);
- resourceStreamer.streamResource(resource);
+ if (illegal.matcher(path.resourcePath).matches())
+ {
+ return false;
+ }
- return true;
+ return path.stream(rootContextResource.forFile(path.resourcePath));
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackPathConstructorImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackPathConstructorImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackPathConstructorImpl.java
index 1363e56..02b0822 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackPathConstructorImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackPathConstructorImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -80,7 +80,10 @@ public class JavaScriptStackPathConstructorImpl implements JavaScriptStackPathCo
{
String path = String.format("%s/%s.js", threadLocale.getLocale().toString(), stackName);
- String stackURL = assetPathConstructor.constructAssetPath(RequestConstants.STACK_FOLDER, path);
+ // TODO: Come up with a virtual Resource that represents the actual combined contents. This may involve
+ // looping through the StreamableResourceSource and wrapping the result as a VirtualResource.
+
+ String stackURL = assetPathConstructor.constructAssetPath(RequestConstants.STACK_FOLDER, path, null);
return CollectionFactory.newList(stackURL);
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/ClasspathAssetAliasManager.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ClasspathAssetAliasManager.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ClasspathAssetAliasManager.java
index fbcfaa7..e85234e 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ClasspathAssetAliasManager.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ClasspathAssetAliasManager.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008, 2010, 2011 The Apache Software Foundation
+// Copyright 2006, 2008, 2010, 2011, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,11 +14,13 @@
package org.apache.tapestry5.services;
-import java.util.Map;
-
import org.apache.tapestry5.internal.services.assets.ClasspathAssetRequestHandler;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.annotations.IncompatibleChange;
import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
+import java.util.Map;
+
/**
* Used as part of the support for classpath {@link org.apache.tapestry5.Asset}s, to convert the Asset's
* {@link org.apache.tapestry5.ioc.Resource} to a URL that can be accessed by the client. The asset path, within the
@@ -28,15 +30,15 @@ import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
* Service configuration is a map from folder aliases (short names) to complete paths. Names should not start or end end
* with a slash. Generally, an alias should be a single name (not contain a slash). Paths should also not start or end
* with a slash. An example mapping would be <code>mylib</code> to <code>com/example/mylib</code>.
- * <p>
+ * <p/>
* As originally envisioned, this service would simply <em>optimize</em> classpath assets, allowing the URL path for
* such assets to be shortened (and have a version number added, important for caching); thus the word "alias" makes
* sense ... it was responsible for creating an "alias" URL shorter than the default "classpath" URL.
- * <p>
+ * <p/>
* Starting in Tapestry 5.2, this changed; all classpath assets <strong>must</strong> be "aliased" to a shorter URL
* path. Any URL that can not be shortened is now rejected. This simplifies creating new libraries, but also helps with
* security concerns, as it limits which portions of the classpath can <em>ever</em> be exposed to the user agent.
- * <p>
+ * <p/>
* Tapestry automatically contributes a number of mappings: for the application root package itself (as alias "app") and
* for each library (via {@link ComponentClassResolver#getFolderToPackageMapping()});
*/
@@ -46,20 +48,23 @@ public interface ClasspathAssetAliasManager
/**
* Takes a resource path to a classpath resource and adds the asset path prefix to the path. May also convert part
* of the path to an alias (based on the manager's configuration).
- *
- * @param resourcePath
- * resource path on the classpath (with no leading slash)
+ * <p/>
+ * Note: this method's signature changed incompatibly in Tapestry 5.4.
+ *
+ * @param resource
+ * classpath resource
* @return URL ready to send to the client
*/
- String toClientURL(String resourcePath);
+ @IncompatibleChange(release = "5.4", details = "parameter changed from String to Resource")
+ String toClientURL(Resource resource);
/**
* Returns the mappings used by the service: the keys are the folder aliases (i.e, "corelib")
* and the values are the corresponding paths (i.e., "org/apache/tapestry5/corelib"). This
* exists primarily so that {@link ClasspathAssetRequestHandler}s can be created automatically
* for each mapping.
- *
+ *
* @since 5.2.0
- **/
+ */
Map<String, String> getMappings();
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
index 3eebd3a..786f61d 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
@@ -39,10 +39,6 @@ import org.apache.tapestry5.internal.services.*;
import org.apache.tapestry5.internal.services.ajax.AjaxFormUpdateFilter;
import org.apache.tapestry5.internal.services.ajax.AjaxResponseRendererImpl;
import org.apache.tapestry5.internal.services.ajax.MultiZoneUpdateEventResultProcessor;
-import org.apache.tapestry5.internal.services.assets.AssetPathConstructorImpl;
-import org.apache.tapestry5.internal.services.assets.ClasspathAssetRequestHandler;
-import org.apache.tapestry5.internal.services.assets.ContextAssetRequestHandler;
-import org.apache.tapestry5.internal.services.assets.StackAssetRequestHandler;
import org.apache.tapestry5.internal.services.linktransform.LinkTransformerImpl;
import org.apache.tapestry5.internal.services.linktransform.LinkTransformerInterceptor;
import org.apache.tapestry5.internal.services.messages.ClientLocalizationMessageResource;
@@ -75,14 +71,11 @@ import org.apache.tapestry5.runtime.ComponentResourcesAware;
import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
-import org.apache.tapestry5.services.assets.AssetPathConstructor;
-import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.apache.tapestry5.services.assets.AssetsModule;
import org.apache.tapestry5.services.compatibility.CompatibilityModule;
import org.apache.tapestry5.services.dynamic.DynamicTemplate;
import org.apache.tapestry5.services.dynamic.DynamicTemplateParser;
import org.apache.tapestry5.services.javascript.JavaScriptModule;
-import org.apache.tapestry5.services.javascript.JavaScriptStack;
import org.apache.tapestry5.services.javascript.ModuleManager;
import org.apache.tapestry5.services.linktransform.ComponentEventLinkTransformer;
import org.apache.tapestry5.services.linktransform.LinkTransformer;
@@ -309,7 +302,6 @@ public final class TapestryModule
public static void bind(ServiceBinder binder)
{
- binder.bind(ClasspathAssetAliasManager.class, ClasspathAssetAliasManagerImpl.class);
binder.bind(PersistentLocale.class, PersistentLocaleImpl.class);
binder.bind(ApplicationStateManager.class, ApplicationStateManagerImpl.class);
binder.bind(ApplicationStatePersistenceStrategySource.class,
@@ -317,7 +309,6 @@ public final class TapestryModule
binder.bind(BindingSource.class, BindingSourceImpl.class);
binder.bind(FieldValidatorSource.class, FieldValidatorSourceImpl.class);
binder.bind(ApplicationGlobals.class, ApplicationGlobalsImpl.class);
- binder.bind(AssetSource.class, AssetSourceImpl.class);
binder.bind(Cookies.class, CookiesImpl.class);
binder.bind(FieldValidatorDefaultSource.class, FieldValidatorDefaultSourceImpl.class);
binder.bind(RequestGlobals.class, RequestGlobalsImpl.class);
@@ -354,7 +345,6 @@ public final class TapestryModule
binder.bind(ContextPathEncoder.class, ContextPathEncoderImpl.class);
binder.bind(ApplicationStatePersistenceStrategy.class, SessionApplicationStatePersistenceStrategy.class).withSimpleId();
binder.bind(TapestrySessionFactory.class, TapestrySessionFactoryImpl.class);
- binder.bind(AssetPathConverter.class, IdentityAssetPathConverter.class);
binder.bind(NumericTranslatorSupport.class);
binder.bind(ClientDataEncoder.class, ClientDataEncoderImpl.class);
binder.bind(ComponentEventLinkEncoder.class, ComponentEventLinkEncoderImpl.class);
@@ -363,7 +353,6 @@ public final class TapestryModule
binder.bind(PropertiesFileParser.class, PropertiesFileParserImpl.class);
binder.bind(PageActivator.class, PageActivatorImpl.class);
binder.bind(Dispatcher.class, AssetDispatcher.class).withSimpleId();
- binder.bind(AssetPathConstructor.class, AssetPathConstructorImpl.class);
binder.bind(TranslatorAlternatesSource.class, TranslatorAlternatesSourceImpl.class);
binder.bind(MetaWorker.class, MetaWorkerImpl.class);
binder.bind(LinkTransformer.class, LinkTransformerImpl.class);
@@ -374,7 +363,6 @@ public final class TapestryModule
binder.bind(ValidationDecoratorFactory.class, ValidationDecoratorFactoryImpl.class);
binder.bind(PropertyConduitSource.class, PropertyConduitSourceImpl.class);
binder.bind(ClientWhitelist.class, ClientWhitelistImpl.class);
- binder.bind(AssetFactory.class, ClasspathAssetFactory.class).withSimpleId();
binder.bind(MetaDataLocator.class, MetaDataLocatorImpl.class);
binder.bind(ComponentClassCache.class, ComponentClassCacheImpl.class);
binder.bind(PageActivationContextCollector.class, PageActivationContextCollectorImpl.class);
@@ -441,76 +429,6 @@ public final class TapestryModule
configuration.add(BindingConstants.SYMBOL, symbolBindingFactory);
}
- @Contribute(ClasspathAssetAliasManager.class)
- public static void addMappingsForLibraryVirtualFolders(MappedConfiguration<String, String> configuration,
- ComponentClassResolver resolver)
- {
- // Each library gets a mapping or its folder automatically
-
- Map<String, String> folderToPackageMapping = resolver.getFolderToPackageMapping();
-
- for (String folder : folderToPackageMapping.keySet())
- {
- // This is the 5.3 version, which is still supported:
- configuration.add(folder, toPackagePath(folderToPackageMapping.get(folder)));
-
- // This is the 5.4 version; once 5.3 support is dropped, this can be simplified, and the
- // "meta/" prefix stripped out.
-
- String folderSuffix = folder.equals("") ? folder : "/" + folder;
-
- configuration.add("meta" + folderSuffix, "META-INF/assets" + folderSuffix);
- }
- }
-
- @Contribute(ClasspathAssetAliasManager.class)
- public static void addApplicationAndTapestryMappings(MappedConfiguration<String, String> configuration,
-
- @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
- String appPackage)
- {
- configuration.add("tapestry", "org/apache/tapestry5");
-
- configuration.add("app", toPackagePath(appPackage));
- }
-
- /**
- * Contributes an handler for each mapped classpath alias, as well handlers for context assets
- * and stack assets (combined {@link JavaScriptStack} files).
- */
- @Contribute(Dispatcher.class)
- @AssetRequestDispatcher
- public static void provideBuiltinAssetDispatchers(MappedConfiguration<String, AssetRequestHandler> configuration,
-
- @ContextProvider
- AssetFactory contextAssetFactory,
-
- @Autobuild
- StackAssetRequestHandler stackAssetRequestHandler,
-
- ClasspathAssetAliasManager classpathAssetAliasManager, ResourceStreamer streamer,
- AssetResourceLocator assetResourceLocator)
- {
- Map<String, String> mappings = classpathAssetAliasManager.getMappings();
-
- for (String folder : mappings.keySet())
- {
- String path = mappings.get(folder);
-
- configuration.add(folder, new ClasspathAssetRequestHandler(streamer, assetResourceLocator, path));
- }
-
- configuration.add(RequestConstants.CONTEXT_FOLDER,
- new ContextAssetRequestHandler(streamer, contextAssetFactory.getRootResource()));
-
- configuration.add(RequestConstants.STACK_FOLDER, stackAssetRequestHandler);
-
- }
-
- private static String toPackagePath(String packageName)
- {
- return packageName.replace('.', '/');
- }
@Contribute(ComponentClassResolver.class)
public static void setupCoreAndAppLibraries(Configuration<LibraryMapping> configuration,
@@ -1221,15 +1139,6 @@ public final class TapestryModule
return service;
}
- @Marker(ContextProvider.class)
- public AssetFactory buildContextAssetFactory(ApplicationGlobals globals,
-
- AssetPathConstructor assetPathConstructor,
-
- AssetPathConverter converter)
- {
- return new ContextAssetFactory(assetPathConstructor, globals.getContext(), converter);
- }
/**
* Builds the PropBindingFactory as a chain of command. The terminator of
@@ -1600,16 +1509,6 @@ public final class TapestryModule
configuration.add("session", sessionStategy);
}
- public void contributeAssetSource(MappedConfiguration<String, AssetFactory> configuration, @ContextProvider
- AssetFactory contextAssetFactory,
-
- @ClasspathProvider
- AssetFactory classpathAssetFactory)
- {
- configuration.add(AssetConstants.CONTEXT, contextAssetFactory);
- configuration.add(AssetConstants.CLASSPATH, classpathAssetFactory);
- }
-
/**
* Contributes handlers for the following types:
* <dl>
@@ -2125,8 +2024,6 @@ public final class TapestryModule
configuration.add(SymbolConstants.CLUSTERED_SESSIONS, true);
- configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "assets");
-
configuration.add(SymbolConstants.COMPRESS_WHITESPACE, true);
configuration.add(MetaDataConstants.SECURE_PAGE, false);
@@ -2586,29 +2483,6 @@ public final class TapestryModule
}
/**
- * Contributes:
- * <dl>
- * <dt>ClientLocalization</dt>
- * <dd>A virtual resource of formatting symbols for decimal numbers</dd>
- * <dt>Core</dt>
- * <dd>Built in messages used by Tapestry's default validators and components</dd>
- * <dt>AppCatalog</dt>
- * <dd>The Resource defined by {@link SymbolConstants#APPLICATION_CATALOG}</dd>
- * <dt>
- *
- * @since 5.2.0
- */
- @Contribute(ComponentMessagesSource.class)
- public static void setupGlobalMessageCatalog(AssetSource assetSource,
- @Symbol(SymbolConstants.APPLICATION_CATALOG)
- Resource applicationCatalog, OrderedConfiguration<Resource> configuration)
- {
- configuration.add("ClientLocalization", new ClientLocalizationMessageResource());
- configuration.add("Core", assetSource.resourceForPath("org/apache/tapestry5/core.properties"));
- configuration.add("AppCatalog", applicationCatalog);
- }
-
- /**
* Contributes extractors for {@link Meta}, {@link Secure}, {@link ContentType} and {@link WhitelistAccessOnly} annotations.
*
* @since 5.2.0
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetChecksumGenerator.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetChecksumGenerator.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetChecksumGenerator.java
new file mode 100644
index 0000000..37588ec
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetChecksumGenerator.java
@@ -0,0 +1,37 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services.assets;
+
+import org.apache.tapestry5.ioc.Resource;
+
+import java.io.IOException;
+
+/**
+ * Generates a checksum of an arbitrary {@link org.apache.tapestry5.Resource} which can be incorporated into
+ * the {@linkplain org.apache.tapestry5.Asset#toClientURL() client URL} of an Asset.
+ *
+ * @since 5.4
+ */
+public interface AssetChecksumGenerator
+{
+ /**
+ * Given a raw resource, generates an MD5 checksum of the resource's contents.
+ *
+ * @param resource
+ * @return checksum of contents
+ * @throws IOException
+ */
+ String generateChecksum(Resource resource) throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
index de9f317..1412a7b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2011 The Apache Software Foundation
+// Copyright 2010, 2011, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,10 +14,14 @@
package org.apache.tapestry5.services.assets;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.annotations.IncompatibleChange;
+
/**
* Encapsulates the logic or creating the path portion of an asset URL, including
* the application version.
*
+ * @see org.apache.tapestry5.services.PathConstructor
* @since 5.2.0
*/
public interface AssetPathConstructor
@@ -30,10 +34,11 @@ public interface AssetPathConstructor
* @param path
* within the virtual folder (should <em>not</em> start with a slash). May be the empty string.
* When non-blank, separated from the rest of the path with a slash.
- * @return path portion of asset URL, including the context path, the application folder,
- * the /assets/ virtual folder, the application
- * version number,
- * the virtual folder, and the path extension
+ * @param resource
+ * underlying resource for the asset path, used to compute checksums (since 5.4)
+ * @return path portion of asset URL, which is everything needed by the {@link org.apache.tapestry5.internal.services.AssetDispatcher}
+ * to find and stream the resource
*/
- String constructAssetPath(String virtualFolder, String path);
+ @IncompatibleChange(release = "5.4", details = "resource parameter added")
+ String constructAssetPath(String virtualFolder, String path, Resource resource);
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetRequestHandler.java
index a405ad9..c0acce3 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetRequestHandler.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetRequestHandler.java
@@ -1,4 +1,4 @@
-// Copyright 2010, 2012 The Apache Software Foundation
+// Copyright 2010, 2012, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package org.apache.tapestry5.services.assets;
import org.apache.tapestry5.Asset;
-import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.services.AssetDispatcher;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
@@ -25,20 +24,13 @@ import java.io.IOException;
/**
* Handler for asset requests, which expose some kind of {@link Asset} to
- * the user agent (i.e., the client web browser). Starting in Tapestry 5.2,
- * asset paths are more structured, consisting of four parts:
- * <ul>
- * <li><em>application folder</em> -- optional, based on {@link SymbolConstants#APPLICATION_FOLDER} Symbol </li>
- * <li><code>assets</code> -- the root path for all assets (as defined by {@link SymbolConstants#ASSET_PATH_PREFIX} Symbol)
- * <li><em>application version</em> -- the application version, as defined by the
- * {@link SymbolConstants#APPLICATION_VERSION} symbol
- * <li><em>handler id</em> -- a handler for this part of the asset path (defined by contributions to the
- * <code>AssetDispatcher</code> service)
- * <li><em>extra path</em> -- additional path beyond the handler id, used to identify the specific resource
- * </ul>
+ * the user agent (i.e., the client web browser). When contributed to the {@link AssetDispatcher} service,
+ * the contributed key is a handler id (such as "meta/core").
* <p/>
- * So, an example path might be <code>/assets/1.0.1/corelib/components/select.png</code>. The handler id would be
- * <code>corelib</code>, and the extra path would be <code>components/select.png</code>.
+ * An example request path might be <code>/assets/meta/core/dd8d73ac51dbab28caaec4865d302bf2/deselect.png</code>.
+ * The handler id would be
+ * <code>meta/core</code>, the {@linkplain AssetChecksumGenerator checksum of the resource content} is the
+ * hex string, and the extra path would be <code>select.png</code>.
*
* @see AssetDispatcher
* @see org.apache.tapestry5.services.AssetRequestDispatcher
@@ -57,10 +49,6 @@ public interface AssetRequestHandler
* The handler should return true if it provided a response. If the handler returns false, this indicates that the
* extra path did not identify a known asset (virtual or otherwise) and the AssetDispatcher service should send a
* {@link HttpServletResponse#SC_NOT_FOUND} response.
- * <p/>
- * AssetRequestHandlers are contributed to the {@link AssetDispatcher} service as a mapped configuration; the
- * key is the path used to select the handler. For a request with path "/assets/{appversion}/handler/extra/path" and a key of "handler"
- * the extra path will be "extra/path".
*
* @param request
* incoming asset request
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetsModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetsModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetsModule.java
index aea9cc4..14cd162 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetsModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetsModule.java
@@ -1,4 +1,4 @@
-// Copyright 2011, 2012 The Apache Software Foundation
+// Copyright 2011, 2012, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,15 +15,19 @@
package org.apache.tapestry5.services.assets;
import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.internal.AssetConstants;
+import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.internal.services.*;
import org.apache.tapestry5.internal.services.assets.*;
-import org.apache.tapestry5.ioc.MappedConfiguration;
-import org.apache.tapestry5.ioc.OperationTracker;
-import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.internal.services.messages.ClientLocalizationMessageResource;
+import org.apache.tapestry5.ioc.*;
import org.apache.tapestry5.ioc.annotations.*;
import org.apache.tapestry5.ioc.services.FactoryDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
-import org.apache.tapestry5.services.AssetSource;
-import org.apache.tapestry5.services.Core;
+import org.apache.tapestry5.services.*;
+import org.apache.tapestry5.services.messages.ComponentMessagesSource;
+
+import java.util.Map;
/**
* @since 5.3
@@ -33,21 +37,44 @@ public class AssetsModule
{
public static void bind(ServiceBinder binder)
{
+ binder.bind(AssetFactory.class, ClasspathAssetFactory.class).withSimpleId();
+ binder.bind(AssetPathConverter.class, IdentityAssetPathConverter.class);
+ binder.bind(AssetPathConstructor.class, AssetPathConstructorImpl.class);
+ binder.bind(ClasspathAssetAliasManager.class, ClasspathAssetAliasManagerImpl.class);
+ binder.bind(AssetSource.class, AssetSourceImpl.class);
binder.bind(StreamableResourceSource.class, StreamableResourceSourceImpl.class);
binder.bind(CompressionAnalyzer.class, CompressionAnalyzerImpl.class);
binder.bind(ContentTypeAnalyzer.class, ContentTypeAnalyzerImpl.class);
binder.bind(ResourceChangeTracker.class, ResourceChangeTrackerImpl.class);
binder.bind(ResourceMinimizer.class, MasterResourceMinimizer.class);
+ binder.bind(AssetChecksumGenerator.class, AssetChecksumGeneratorImpl.class);
+ }
+
+ @Contribute(AssetSource.class)
+ public void configureStandardAssetFactories(MappedConfiguration<String, AssetFactory> configuration,
+ @ContextProvider
+ AssetFactory contextAssetFactory,
+
+ @ClasspathProvider
+ AssetFactory classpathAssetFactory)
+ {
+ configuration.add(AssetConstants.CONTEXT, contextAssetFactory);
+ configuration.add(AssetConstants.CLASSPATH, classpathAssetFactory);
}
+
@Contribute(SymbolProvider.class)
@FactoryDefaults
public static void setupSymbols(MappedConfiguration<String, Object> configuration)
{
+ // Minification may be enabled in production mode, but unless a minimizer is provided, nothing
+ // will change.
configuration.add(SymbolConstants.MINIFICATION_ENABLED, SymbolConstants.PRODUCTION_MODE_VALUE);
configuration.add(SymbolConstants.GZIP_COMPRESSION_ENABLED, true);
configuration.add(SymbolConstants.COMBINE_SCRIPTS, SymbolConstants.PRODUCTION_MODE_VALUE);
configuration.add(SymbolConstants.ASSET_URL_FULL_QUALIFIED, false);
+
+ configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "assets");
}
// The use of decorators is to allow third-parties to get their own extensions
@@ -156,4 +183,108 @@ public class AssetsModule
configuration.add("image/png", false);
configuration.add("application/x-shockwave-flash", false);
}
+
+ @Marker(ContextProvider.class)
+ public static AssetFactory buildContextAssetFactory(ApplicationGlobals globals,
+
+ AssetPathConstructor assetPathConstructor,
+
+ AssetPathConverter converter)
+ {
+ return new ContextAssetFactory(assetPathConstructor, globals.getContext(), converter);
+ }
+
+ @Contribute(ClasspathAssetAliasManager.class)
+ public static void addApplicationAndTapestryMappings(MappedConfiguration<String, String> configuration,
+
+ @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
+ String appPackage)
+ {
+ configuration.add("tapestry", "org/apache/tapestry5");
+
+ configuration.add("app", toPackagePath(appPackage));
+ }
+
+ /**
+ * Contributes an handler for each mapped classpath alias, as well handlers for context assets
+ * and stack assets (combined {@link org.apache.tapestry5.services.javascript.JavaScriptStack} files).
+ */
+ @Contribute(Dispatcher.class)
+ @AssetRequestDispatcher
+ public static void provideBuiltinAssetDispatchers(MappedConfiguration<String, AssetRequestHandler> configuration,
+
+ @ContextProvider
+ AssetFactory contextAssetFactory,
+
+ @Autobuild
+ StackAssetRequestHandler stackAssetRequestHandler,
+
+ ClasspathAssetAliasManager classpathAssetAliasManager, ResourceStreamer streamer,
+ AssetResourceLocator assetResourceLocator)
+ {
+ Map<String, String> mappings = classpathAssetAliasManager.getMappings();
+
+ for (String folder : mappings.keySet())
+ {
+ String path = mappings.get(folder);
+
+ configuration.add(folder, new ClasspathAssetRequestHandler(streamer, assetResourceLocator, path));
+ }
+
+ configuration.add(RequestConstants.CONTEXT_FOLDER,
+ new ContextAssetRequestHandler(streamer, contextAssetFactory.getRootResource()));
+
+ configuration.add(RequestConstants.STACK_FOLDER, stackAssetRequestHandler);
+
+ }
+
+ @Contribute(ClasspathAssetAliasManager.class)
+ public static void addMappingsForLibraryVirtualFolders(MappedConfiguration<String, String> configuration,
+ ComponentClassResolver resolver)
+ {
+ // Each library gets a mapping or its folder automatically
+
+ Map<String, String> folderToPackageMapping = resolver.getFolderToPackageMapping();
+
+ for (String folder : folderToPackageMapping.keySet())
+ {
+ // This is the 5.3 version, which is still supported:
+ configuration.add(folder, toPackagePath(folderToPackageMapping.get(folder)));
+
+ // This is the 5.4 version; once 5.3 support is dropped, this can be simplified, and the
+ // "meta/" prefix stripped out.
+
+ String folderSuffix = folder.equals("") ? folder : "/" + folder;
+
+ configuration.add("meta" + folderSuffix, "META-INF/assets" + folderSuffix);
+ }
+ }
+
+ private static String toPackagePath(String packageName)
+ {
+ return packageName.replace('.', '/');
+ }
+
+ /**
+ * Contributes:
+ * <dl>
+ * <dt>ClientLocalization</dt>
+ * <dd>A virtual resource of formatting symbols for decimal numbers</dd>
+ * <dt>Core</dt>
+ * <dd>Built in messages used by Tapestry's default validators and components</dd>
+ * <dt>AppCatalog</dt>
+ * <dd>The Resource defined by {@link SymbolConstants#APPLICATION_CATALOG}</dd>
+ * <dt>
+ *
+ * @since 5.2.0
+ */
+ @Contribute(ComponentMessagesSource.class)
+ public static void setupGlobalMessageCatalog(AssetSource assetSource,
+ @Symbol(SymbolConstants.APPLICATION_CATALOG)
+ Resource applicationCatalog, OrderedConfiguration<Resource> configuration)
+ {
+ configuration.add("ClientLocalization", new ClientLocalizationMessageResource());
+ configuration.add("Core", assetSource.resourceForPath("org/apache/tapestry5/core.properties"));
+ configuration.add("AppCatalog", applicationCatalog);
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java b/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
index 041e812..786b25b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
+// Copyright 2006-2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -644,16 +644,14 @@ public abstract class TapestryTestCase extends IOCTestCase
response.setDateHeader(headerName, date);
}
+ /**
+ * @deprecated Deprecated in 5.4 with no replacement.
+ */
protected final void train_toClientURL(Asset asset, String URL)
{
expect(asset.toClientURL()).andReturn(URL).atLeastOnce();
}
- protected final void train_toClientURL(ClasspathAssetAliasManager manager, String resourcePath, String clientURL)
- {
- expect(manager.toClientURL(resourcePath)).andReturn(clientURL);
- }
-
protected final void train_toRedirectURI(Link link, String URI)
{
expect(link.toRedirectURI()).andReturn(URI).atLeastOnce();
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImplTest.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImplTest.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImplTest.groovy
index f639522..7e41fbf 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImplTest.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImplTest.groovy
@@ -1,9 +1,12 @@
package org.apache.tapestry5.internal.services.assets
+import org.apache.tapestry5.ioc.Resource
import org.apache.tapestry5.ioc.test.TestBase
+import org.apache.tapestry5.services.BaseURLSource
+import org.apache.tapestry5.services.PathConstructor
import org.apache.tapestry5.services.Request
+import org.apache.tapestry5.services.assets.AssetChecksumGenerator
import org.testng.annotations.Test
-import org.apache.tapestry5.services.BaseURLSource
class AssetPathConstructorImplTest extends TestBase {
@@ -12,69 +15,52 @@ class AssetPathConstructorImplTest extends TestBase {
def request = newMock(Request)
- def apc = new AssetPathConstructorImpl(request, null, "", "123", "", false, "assets")
-
- replay()
+ def baseURLSource = newMock(BaseURLSource)
- assert apc.constructAssetPath("virt", "extra") == "/assets/123/virt/extra"
+ def pc = newMock(PathConstructor)
- assert apc.constructAssetPath("virtb", "") == "/assets/123/virtb"
+ def gen = newMock(AssetChecksumGenerator)
- verify()
- }
+ def virtExtra = newMock(Resource)
-@Test
- void "construct an asset path with no extra path"() {
+ def virtb = newMock(Resource)
- def request = newMock(Request)
+ expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
- def apc = new AssetPathConstructorImpl(request, null, "", "123", "", false, "assets")
+ expect(gen.generateChecksum(virtExtra)).andReturn("abc")
replay()
- assert apc.constructAssetPath("virtb", "") == "/assets/123/virtb"
+ def apc = new AssetPathConstructorImpl(request, baseURLSource, false, "assets", pc, gen)
- verify()
- }
- @Test
- void "construct asset path with an application folder"() {
- def request = newMock(Request)
-
- def apc = new AssetPathConstructorImpl(request, null, "", "123", "myapp", false, "assets")
-
- replay()
-
- assert apc.constructAssetPath("virt", "extra") == "/myapp/assets/123/virt/extra"
+ assert apc.constructAssetPath("virt", "extra.png", virtExtra) == "/assets/virt/abc/extra.png"
verify()
}
@Test
- void "construct asset path with a context path"() {
+ void "fully qualified path has base URL prepended"() {
def request = newMock(Request)
+ def baseURLSource = newMock(BaseURLSource)
- def apc = new AssetPathConstructorImpl(request, null, "/ctx", "123", "myapp", false, "assets")
-
- replay()
-
- assert apc.constructAssetPath("virt", "extra") == "/ctx/myapp/assets/123/virt/extra"
+ def pc = newMock(PathConstructor)
- verify()
- }
+ def gen = newMock(AssetChecksumGenerator)
- @Test
- void "fully qualified path has base URL prepended"() {
- def request = newMock(Request)
- def baseURLSource = newMock(BaseURLSource)
+ def r = newMock(Resource)
- def apc = new AssetPathConstructorImpl(request, baseURLSource, "/mycontext", "123", "myapp", true, "assets")
+ expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
expect(request.secure).andReturn(false)
expect(baseURLSource.getBaseURL(false)).andReturn("http://localhost:8080")
+ expect(gen.generateChecksum(r)).andReturn("911")
+
replay()
- assert apc.constructAssetPath("virt", "extra") == "http://localhost:8080/mycontext/myapp/assets/123/virt/extra"
+ def apc = new AssetPathConstructorImpl(request, baseURLSource, true, "assets", pc, gen)
+
+ assert apc.constructAssetPath("virt", "icon.gif", r) == "http://localhost:8080/assets/virt/911/icon.gif"
verify()
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
index 886a156..776ad50 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2009, 2010, 2011, 2012 The Apache Software Foundation
+// Copyright 2006, 2007, 2009, 2010, 2011, 2012, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,14 +16,19 @@ package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.internal.services.assets.AssetPathConstructorImpl;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.util.UnknownValueException;
import org.apache.tapestry5.services.BaseURLSource;
import org.apache.tapestry5.services.ClasspathAssetAliasManager;
+import org.apache.tapestry5.services.PathConstructor;
import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.assets.AssetChecksumGenerator;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import java.io.IOException;
import java.util.Map;
public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
@@ -76,20 +81,28 @@ public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
}
@Test(dataProvider = "to_client_url_data")
- public void to_client_url(String resourcePath, String expectedClientURL)
+ public void to_client_url(String resourcePath, String expectedClientURL) throws IOException
{
Request request = mockRequest();
+ Resource r = mockResource();
+
+ expect(r.getPath()).andReturn(resourcePath);
BaseURLSource baseURLSource = newMock(BaseURLSource.class);
+ PathConstructor pc = newMock(PathConstructor.class);
+ AssetChecksumGenerator acg = newMock(AssetChecksumGenerator.class);
+
+ expect(pc.constructClientPath("assets", "")).andReturn("/ctx/assets/");
+ expect(acg.generateChecksum(r)).andReturn("abcde");
replay();
ClasspathAssetAliasManager manager = new ClasspathAssetAliasManagerImpl(
new AssetPathConstructorImpl(request,
- baseURLSource, "/ctx", APP_VERSION, "", false, "assets"), configuration());
+ baseURLSource, false, "assets", pc, acg), configuration());
- String expectedPath = "/ctx/assets/" + APP_VERSION + "/" + expectedClientURL;
- assertEquals(manager.toClientURL(resourcePath), expectedPath);
+ String expectedPath = "/ctx/assets/" + expectedClientURL.replace("#", "abcde");
+ assertEquals(manager.toClientURL(r), expectedPath);
verify();
}
@@ -97,11 +110,17 @@ public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
@Test
public void failure_if_path_not_in_mapped_alias_folder()
{
- ClasspathAssetAliasManager manager = new ClasspathAssetAliasManagerImpl(null, configuration());
+ AssetPathConstructor pc = newMock(AssetPathConstructor.class);
+ ClasspathAssetAliasManager manager = new ClasspathAssetAliasManagerImpl(pc, configuration());
+ Resource resource = mockResource();
+
+ expect(resource.getPath()).andReturn("org/example/icons/flag.gif").atLeastOnce();
+
+ replay();
try
{
- manager.toClientURL("org/example/icons/flag.gif");
+ manager.toClientURL(resource);
unreachable();
} catch (UnknownValueException ex)
{
@@ -110,6 +129,8 @@ public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
assertListsEquals(ex.getAvailableValues().getValues(), "com/example/mylib", "org/apache/tapestry5",
"org/apache/tapestry5/internal");
}
+
+ verify();
}
@DataProvider
@@ -117,10 +138,10 @@ public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
{
return new Object[][]
{
- {"com/example/mylib/Foo.bar", "mylib/Foo.bar"},
- {"com/example/mylib/nested/Foo.bar", "mylib/nested/Foo.bar"},
- {"org/apache/tapestry5/internal/Foo.bar", "tapestry-internal/Foo.bar"},
- {"org/apache/tapestry5/Foo.bar", "tapestry/Foo.bar"},};
+ {"com/example/mylib/Foo.bar", "mylib/#/Foo.bar"},
+ {"com/example/mylib/nested/Foo.bar", "mylib/#/nested/Foo.bar"},
+ {"org/apache/tapestry5/internal/Foo.bar", "tapestry-internal/#/Foo.bar"},
+ {"org/apache/tapestry5/Foo.bar", "tapestry/#/Foo.bar"},};
}
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
index 2ed2160..4a393a2 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2011, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ public class ClasspathAssetFactoryTest extends InternalBaseTestCase
String expectedClientURL = "/context/asset/foo/Bar.txt";
- train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
+ expect(aliasManager.toClientURL(r)).andReturn(expectedClientURL);
replay();
@@ -68,7 +68,7 @@ public class ClasspathAssetFactoryTest extends InternalBaseTestCase
String expectedClientURL = "/context/asset/foo/Bar.txt";
- train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
+ expect(aliasManager.toClientURL(r)).andReturn(expectedClientURL);
replay();
@@ -97,7 +97,7 @@ public class ClasspathAssetFactoryTest extends InternalBaseTestCase
String expectedClientURL = "/context/asset/foo/Bar.ABC123.txt";
- train_toClientURL(aliasManager, "foo/Bar.ABC123.txt", expectedClientURL);
+ expect(aliasManager.toClientURL(r)).andReturn(expectedClientURL);
replay();
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ContextAssetFactoryTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ContextAssetFactoryTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ContextAssetFactoryTest.java
index ec22315..2f19fe0 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ContextAssetFactoryTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ContextAssetFactoryTest.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2009, 2012 The Apache Software Foundation
+// Copyright 2006, 2007, 2009, 2012, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,13 +15,11 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.Asset;
-import org.apache.tapestry5.internal.services.assets.AssetPathConstructorImpl;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.services.AssetFactory;
-import org.apache.tapestry5.services.BaseURLSource;
import org.apache.tapestry5.services.Context;
-import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.testng.annotations.Test;
public class ContextAssetFactoryTest extends InternalBaseTestCase
@@ -32,11 +30,11 @@ public class ContextAssetFactoryTest extends InternalBaseTestCase
public void root_resource()
{
Context context = mockContext();
- // Request request = mockRequest();
+ AssetPathConstructor apc = newMock(AssetPathConstructor.class);
replay();
- AssetFactory factory = new ContextAssetFactory(null, context, converter);
+ AssetFactory factory = new ContextAssetFactory(apc, context, converter);
assertEquals(factory.getRootResource().toString(), "context:/");
@@ -47,104 +45,27 @@ public class ContextAssetFactoryTest extends InternalBaseTestCase
public void asset_client_URL()
{
Context context = mockContext();
- Request request = mockRequest();
-
- BaseURLSource baseURLSource = newMock(BaseURLSource.class);
-
- Resource r = new ContextResource(context, "foo/Bar.txt");
-
- replay();
-
- AssetFactory factory = new ContextAssetFactory(
- new AssetPathConstructorImpl(request,
- baseURLSource,
- "/context", "4.5.6",
- "",
- false,
- "assets"
- ),
- context,
- new IdentityAssetPathConverter()
- );
-
- Asset asset = factory.createAsset(r);
-
- assertSame(asset.getResource(), r);
- assertEquals(asset.toClientURL(), "/context/assets/4.5.6/ctx/foo/Bar.txt");
-
- // In real life, toString() is the same as toClientURL(), but we're testing
- // that the optimize method is getting called, basically.
-
- assertEquals(asset.toString(), "/context/assets/4.5.6/ctx/foo/Bar.txt");
-
- verify();
- }
-
- @Test
- public void asset_client_URL_with_default_context() {
- Context context = mockContext();
- Request request = mockRequest();
-
- BaseURLSource baseURLSource = newMock(BaseURLSource.class);
+ AssetPathConstructor apc = newMock(AssetPathConstructor.class);
Resource r = new ContextResource(context, "foo/Bar.txt");
- replay();
-
- AssetFactory factory = new ContextAssetFactory(
- new AssetPathConstructorImpl(request,
- baseURLSource,
- "", "4.5.6",
- "",
- false,
- "assets"
- ),
- context,
- new IdentityAssetPathConverter()
- );
-
- Asset asset = factory.createAsset(r);
+ String expectedURL = "/expected-url";
- assertEquals(asset.toClientURL(), "/assets/4.5.6/ctx/foo/Bar.txt");
-
- verify();
- }
-
- @Test
- public void asset_client_URL_fully_qualified()
- {
- Context context = mockContext();
- Request request = mockRequest();
-
- BaseURLSource baseURLSource = newMock(BaseURLSource.class);
-
- Resource r = new ContextResource(context, "foo/Bar.txt");
-
- train_getBaseSource(baseURLSource, request);
+ expect(apc.constructAssetPath("ctx", "foo/Bar.txt", r)).andReturn(expectedURL).atLeastOnce();
replay();
- AssetFactory factory = new ContextAssetFactory(
- new AssetPathConstructorImpl(request,
- baseURLSource,
- "/context", "4.5.6",
- "",
- true,
- "assets"
- ),
- context,
- new IdentityAssetPathConverter()
- );
+ AssetFactory factory = new ContextAssetFactory(apc, context, new IdentityAssetPathConverter());
Asset asset = factory.createAsset(r);
assertSame(asset.getResource(), r);
- assertEquals(asset.toClientURL(), "/context/assets/4.5.6/ctx/foo/Bar.txt");
+
+ assertSame(asset.toClientURL(), expectedURL);
// In real life, toString() is the same as toClientURL(), but we're testing
// that the optimize method is getting called, basically.
-
- assertEquals(asset.toString(), "/context/assets/4.5.6/ctx/foo/Bar.txt");
+ assertSame(asset.toString(), expectedURL);
verify();
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8fbbd594/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandlerTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandlerTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandlerTest.java
index 1629e95..e343b2b 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandlerTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/assets/ContextAssetRequestHandlerTest.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2013 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ public class ContextAssetRequestHandlerTest extends TestBase
{
ContextAssetRequestHandler handler = new ContextAssetRequestHandler(null, null);
- assertFalse(handler.handleAssetRequest(null, null, path), "Handler should return false for invalid path.");
+ assertFalse(handler.handleAssetRequest(null, null, "fake-checksum/" + path),
+ "Handler should return false for invalid path.");
}
}