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/11/27 20:27:51 UTC
[1/2] git commit: TAP5-2234: Refreshing the browser in Eclipse on
Windows sometimes fails with a locking exception
Updated Branches:
refs/heads/master d34783f05 -> 067916b6c
TAP5-2234: Refreshing the browser in Eclipse on Windows sometimes fails with a locking exception
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/d23f8e06
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/d23f8e06
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/d23f8e06
Branch: refs/heads/master
Commit: d23f8e06687a3ffe5b8d1b0b57e957008cb6e61a
Parents: d34783f
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Wed Nov 27 11:12:42 2013 -0800
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed Nov 27 11:12:42 2013 -0800
----------------------------------------------------------------------
.../internal/webresources/ResourceTransformerFactoryImpl.java | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d23f8e06/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java
index f02d94d..157ffcf 100644
--- a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java
@@ -210,6 +210,8 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor
compiled.store(is);
+ is.close();
+
cache.put(source, compiled);
return compiled.openStream();
@@ -249,6 +251,8 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor
TapestryInternalUtils.copy(compiled, bos);
+ compiled.close();
+
BytestreamCache cache = new BytestreamCache(bos);
writeToCacheFile(cacheFile, cache.openStream());
[2/2] git commit: Simpliy asset & module paths
Posted by hl...@apache.org.
Simpliy asset & module paths
- compressed assets now have a "z" prefix on their checksum in the URL
- assets served from request path "/assets/"
- modules are now top level ("/modules/", not "/assets/modules/")
- compressed asses are now "/modules.gz/"
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/067916b6
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/067916b6
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/067916b6
Branch: refs/heads/master
Commit: 067916b6c95b49195c3f28bebd43f25efe081521
Parents: d23f8e0
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Wed Nov 27 11:27:42 2013 -0800
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed Nov 27 11:27:42 2013 -0800
----------------------------------------------------------------------
.../org/apache/tapestry5/SymbolConstants.java | 51 ++++----
.../org/apache/tapestry5/TapestryConstants.java | 11 --
.../internal/services/AssetDispatcher.java | 57 +++------
.../internal/services/ResourceStreamer.java | 5 +-
.../internal/services/ResourceStreamerImpl.java | 8 +-
.../assets/AssetPathConstructorImpl.java | 51 +++-----
.../assets/StackAssetRequestHandler.java | 14 ++-
.../javascript/ModuleAssetRequestHandler.java | 93 ---------------
.../services/javascript/ModuleDispatcher.java | 117 +++++++++++++++++++
.../services/javascript/ModuleManagerImpl.java | 14 ++-
.../internal/util/VirtualResource.java | 2 +-
.../apache/tapestry5/modules/AssetsModule.java | 17 ++-
.../tapestry5/modules/JavaScriptModule.java | 32 +++--
.../tapestry5/modules/TapestryModule.java | 13 +--
.../services/assets/AssetPathConstructor.java | 15 ---
.../integration/app1/LibraryTests.groovy | 2 +-
.../integration/appfolder/AppFolderTests.groovy | 2 +-
.../assets/AssetPathConstructorImplTest.groovy | 8 +-
.../ModuleAssetRequestHandlerTests.groovy | 43 -------
.../javascript/ModuleDispatcherTests.groovy | 62 ++++++++++
20 files changed, 305 insertions(+), 312 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
index 9414917..c101825 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
@@ -336,20 +336,23 @@ public class SymbolConstants
/**
* Prefix to be used for all resource paths, used to recognize which requests are for assets. This value
* is appended to the context path and the (optional {@linkplain #APPLICATION_FOLDER application folder}.
- * Its default is "asset". It may contain slashes, but should not begin or end with one. This is the prefix
- * for uncompressed assets.
+ * It may contain slashes, but should not begin or end with one.
+ * <p/>
+ * The default is "assets".
*/
public static final String ASSET_PATH_PREFIX = "tapestry.asset-path-prefix";
+
/**
- * As with {@link #ASSET_PATH_PREFIX} but for compressed versions of assets. At render time, it is determined
- * whether each asset is compressable (for example, image file formats are already compressed). A path for
- * either {@link #ASSET_PATH_PREFIX} or this prefix is selected at render time. Defaults to the asset path prefix
- * suffixed with ".gz".
+ * Prefix used for all module resources. This may contain slashes, but should not being or end with one.
+ * Tapestry will create two {@link org.apache.tapestry5.services.Dispatcher}s from this: one for normal
+ * modules, the other for GZip compressed modules (by appending ".gz" to this value).
+ * <p/>
+ * The default is "modules".
*
* @since 5.4
*/
- public static final String COMPRESSED_ASSET_PATH_PREFIX = "tapestry.compressed-asset-path-prefix";
+ public static final String MODULE_PATH_PREFIX = "tapestry.module-path-prefix";
/**
* Identifies the context path of the application, as determined from {@link javax.servlet.ServletContext#getContextPath()}.
@@ -408,36 +411,36 @@ public class SymbolConstants
* @since 5.4
*/
public static final String SESSION_LOCKING_ENABLED = "tapestry.session-locking-enabled";
-
+
/**
* If true (the default), then Tapestry will automatically include the "core" stack in all
* pages.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2169
+ * @since 5.4
*/
public static final String INCLUDE_CORE_STACK = "tapestry.include-core-stack";
-
+
/**
* Defines the CSS class that will be given to HTML element (usually a div) <div> generated by
- * the {@linkplain FormGroup} mixin and the
+ * the {@linkplain FormGroup} mixin and the
* {@linkplain BeanEditForm} and {@linkplain BeanEditor}
* components surrounding the label and the field. The default value is <code>form-group</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_WRAPPER_CSS_CLASS = "tapestry.form-group-wrapper-css-class";
-
+
/**
* Defines the name of the HTML element that will surround the HTML form field generated by
* the {@linkplain FormGroup} mixin and the {@linkplain BeanEditForm} and {@linkplain BeanEditor}.
* If this symbol is null or an empty string, no element will be generated surrouding the
* form field. The default value is the empty string (no wrapping).
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
* @see #FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_CSS_CLASS
+ * @since 5.4
*/
public static final String FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_NAME = "tapestry.form-group-form-field-wrapper-element-name";
@@ -446,29 +449,29 @@ public class SymbolConstants
* the {@linkplain FormGroup} mixin and the {@linkplain BeanEditForm} and {@linkplain BeanEditor}.
* when {@linkplain FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_NAME} is not set to null or the empty string.
* The default value is the empty string (no CSS class added).
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_CSS_CLASS = "tapestry.form-group-form-field-wrapper-element-css-class";
/**
* Defines the CSS class that will be given to <label> element generated by
- * the {@linkplain FormGroup} mixin and the
+ * the {@linkplain FormGroup} mixin and the
* {@linkplain BeanEditForm} and {@linkplain BeanEditor}
* components. The default value is <code>control-label</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_LABEL_CSS_CLASS = "tapestry.form-group-label-css-class";
/**
* Defines the CSS class that will be given to form field components which are
* {@linkplain AbstractField} subclasses. The default value is <code>form-control</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_FIELD_CSS_CLASS = "tapestry.form-field-css-class";
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
index 74adf03..83a6606 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
@@ -46,15 +46,4 @@ public class TapestryConstants
* @since 5.2.0
*/
public static final String PAGE_LOOPBACK_PARAMETER_NAME = "t:lb";
-
- /**
- * {@link org.apache.tapestry5.services.Request} attribute set to true or false before an
- * {@link org.apache.tapestry5.services.assets.AssetRequestHandler} is invoked. This information
- * is used downstream, typically by {@link org.apache.tapestry5.internal.services.ResourceStreamer},
- * to decide whether to obtain a normal, or compressed, {@link org.apache.tapestry5.services.assets.StreamableResource}.
- *
- * @since 5.4
- */
- public static final String COMPRESS_CONTENT = "tapestry.compress-content";
-
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 859680d..760ecb9 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
@@ -14,28 +14,21 @@
package org.apache.tapestry5.internal.services;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.TapestryConstants;
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.AssetRequestDispatcher;
-import org.apache.tapestry5.services.ClasspathAssetAliasManager;
-import org.apache.tapestry5.services.Dispatcher;
-import org.apache.tapestry5.services.PathConstructor;
-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;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
/**
* Recognizes requests where the path begins with "/asset/" (actually, as defined by the
* {@link SymbolConstants#ASSET_PATH_PREFIX} symbol), and delivers the content therein as a bytestream. Also
@@ -60,40 +53,22 @@ public class AssetDispatcher implements Dispatcher
*/
private final List<String> assetPaths = CollectionFactory.newList();
- private final String uncompressedPathPrefix, compressedPathPrefix;
-
- private AssetRequestHandler wrap(final boolean compress, final AssetRequestHandler handler)
- {
- return new AssetRequestHandler()
- {
- public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
- {
- request.setAttribute(TapestryConstants.COMPRESS_CONTENT, compress);
-
- return handler.handleAssetRequest(request, response, extraPath);
- }
- };
- }
+ private final String requestPathPrefix;
public AssetDispatcher(Map<String, AssetRequestHandler> configuration,
PathConstructor pathConstructor,
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
- String uncompressedPrefix,
-
- @Symbol(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX)
- String compressedPrefix)
+ String assetPathPrefix)
{
- uncompressedPathPrefix = pathConstructor.constructDispatchPath(uncompressedPrefix, "");
- compressedPathPrefix = pathConstructor.constructDispatchPath(compressedPrefix, "");
+ requestPathPrefix = pathConstructor.constructDispatchPath(assetPathPrefix, "");
for (String path : configuration.keySet())
{
AssetRequestHandler handler = configuration.get(path);
- addPath(uncompressedPathPrefix, path, wrap(false, handler));
- addPath(compressedPathPrefix, path, wrap(true, handler));
+ addPath(requestPathPrefix, path, handler);
}
// Sort by descending length
@@ -124,12 +99,6 @@ public class AssetDispatcher implements Dispatcher
: prefix + path + "/";
}
- private boolean matchesEitherPrefix(String path)
- {
- return path.startsWith(compressedPathPrefix) ||
- path.startsWith(uncompressedPathPrefix);
- }
-
public boolean dispatch(Request request, Response response) throws IOException
{
String path = request.getPath();
@@ -137,7 +106,7 @@ public class AssetDispatcher implements Dispatcher
// Remember that the request path does not include the context path, so we can simply start
// looking for the asset path prefix right off the bat.
- if (!matchesEitherPrefix(path))
+ if (!path.startsWith(requestPathPrefix))
{
return false;
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
index 81027bf..f28e9b1 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
@@ -25,7 +25,7 @@ import java.util.Set;
/**
* Responsible for streaming the contents of a resource to the client. This is sometimes a simple
- * {@link Resource} (often from the {@link org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler},
+ * {@link Resource} (often from the {@link org.apache.tapestry5.internal.services.javascript.ModuleDispatcher},
* or more frequently an asset represented as a {@link StreamableResource} (via {@link AssetDispatcher}, {@link org.apache.tapestry5.services.assets.AssetRequestHandler},
* and {@link StreamableResourceSource}). As of 5.4, the ResourceStreamer handles ETag support, as well as
* validation of the checksum (provided in the URL).
@@ -66,7 +66,8 @@ public interface ResourceStreamer
boolean streamResource(Resource resource, String providedChecksum, Set<Options> options) throws IOException;
/**
- * Streams a resource that has been assembled elsewhere.
+ * Streams a resource that has been assembled elsewhere. The StreamableResource may reflect either a normal
+ * or a compressed stream, depending on the type of resource and the capabilities of the client.
*
* @param resource
* content to stream
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 9eff1e8..cbfe264 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
@@ -15,7 +15,6 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.TapestryConstants;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
import org.apache.tapestry5.ioc.IOOperation;
@@ -85,8 +84,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
return true;
}
- final boolean compress = (Boolean) request.getAttribute(TapestryConstants.COMPRESS_CONTENT);
-
+ final boolean compress = providedChecksum.startsWith("z");
return tracker.perform(String.format("Streaming %s%s", resource, compress ? " (compressed)" : ""), new IOOperation<Boolean>()
{
@@ -98,7 +96,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
StreamableResource streamable = streamableResourceSource.getStreamableResource(resource, processing, resourceChangeTracker);
- return streamResource(streamable, providedChecksum, options);
+ return streamResource(streamable, compress ? providedChecksum.substring(1) : providedChecksum, options);
}
});
}
@@ -118,7 +116,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
long lastModified = streamable.getLastModified();
- long ifModifiedSince = 0;
+ long ifModifiedSince;
try
{
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 09e434f..e8a3231 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, 2013 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.
@@ -31,7 +31,7 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
{
private final Request request;
- private final String uncompressedPrefix, compressedPrefix;
+ private final String prefix;
private final BaseURLSource baseURLSource;
@@ -48,9 +48,6 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
String uncompressedAssetPrefix,
- @Symbol(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX)
- String compressedAssetPrefix,
-
PathConstructor pathConstructor,
AssetPathConverter pathConverter)
@@ -61,37 +58,13 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
this.fullyQualified = fullyQualified;
this.pathConverter = pathConverter;
- uncompressedPrefix = pathConstructor.constructClientPath(uncompressedAssetPrefix, "");
- compressedPrefix = pathConstructor.constructClientPath(compressedAssetPrefix, "");
+ prefix = pathConstructor.constructClientPath(uncompressedAssetPrefix, "");
}
public String constructAssetPath(String virtualFolder, String path, StreamableResource resource) throws IOException
{
assert InternalUtils.isNonBlank(path);
- StringBuilder builder = create(resource.getCompression() == CompressionStatus.COMPRESSED, virtualFolder);
- builder.append("/");
-
- builder.append(resource.getChecksum());
-
- builder.append('/');
- builder.append(path);
-
- return finish(builder);
- }
-
- public String constructAssetPath(String virtualFolder, boolean compressed)
- {
- return finish(create(compressed, virtualFolder));
- }
-
- private String finish(StringBuilder builder)
- {
- return pathConverter.convertAssetPath(builder.toString());
- }
-
- private StringBuilder create(boolean compress, String virtualFolder)
- {
assert InternalUtils.isNonBlank(virtualFolder);
StringBuilder builder = new StringBuilder();
@@ -101,8 +74,22 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
builder.append(baseURLSource.getBaseURL(request.isSecure()));
}
- builder.append(compress ? compressedPrefix : uncompressedPrefix);
+ builder.append(prefix);
+ builder.append(virtualFolder);
+ builder.append("/");
+
+ // The 'z' prefix indicates a compressed resource.
+
+ if (resource.getCompression() == CompressionStatus.COMPRESSED)
+ {
+ builder.append("z");
+ }
+
+ builder.append(resource.getChecksum());
+ builder.append('/');
+ builder.append(path);
- return builder.append(virtualFolder);
+ return pathConverter.convertAssetPath(builder.toString());
}
+
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
index 487fcf1..c883986 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
@@ -14,7 +14,6 @@
package org.apache.tapestry5.internal.services.assets;
-import org.apache.tapestry5.TapestryConstants;
import org.apache.tapestry5.internal.services.ResourceStreamer;
import org.apache.tapestry5.ioc.IOOperation;
import org.apache.tapestry5.ioc.OperationTracker;
@@ -48,13 +47,12 @@ public class StackAssetRequestHandler implements AssetRequestHandler
private final JavaScriptStackAssembler javaScriptStackAssembler;
private final JavaScriptStackSource stackSource;
- private final Request request;
public StackAssetRequestHandler(Logger logger, LocalizationSetter localizationSetter,
ResourceStreamer resourceStreamer,
OperationTracker tracker,
JavaScriptStackAssembler javaScriptStackAssembler,
- JavaScriptStackSource stackSource, Request request)
+ JavaScriptStackSource stackSource)
{
this.logger = logger;
this.localizationSetter = localizationSetter;
@@ -62,7 +60,6 @@ public class StackAssetRequestHandler implements AssetRequestHandler
this.tracker = tracker;
this.javaScriptStackAssembler = javaScriptStackAssembler;
this.stackSource = stackSource;
- this.request = request;
}
public boolean handleAssetRequest(Request request, Response response, final String extraPath) throws IOException
@@ -92,6 +89,13 @@ public class StackAssetRequestHandler implements AssetRequestHandler
String localeName = matcher.group(2);
final String stackName = matcher.group(3);
+ final boolean compressed = checksum.startsWith("z");
+
+ if (compressed)
+ {
+ checksum = checksum.substring(1);
+ }
+
if (stackSource.findStack(stackName) == null)
{
logger.warn(String.format("JavaScript stack '%s' not found.", stackName));
@@ -111,8 +115,6 @@ public class StackAssetRequestHandler implements AssetRequestHandler
{
public StreamableResource perform() throws IOException
{
- boolean compressed =
- (Boolean) request.getAttribute(TapestryConstants.COMPRESS_CONTENT);
return javaScriptStackAssembler.assembleJavaScriptResourceForStack(stackName, compressed);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
deleted file mode 100644
index 49d366b..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 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.
-// 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.javascript;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.Set;
-
-import org.apache.tapestry5.internal.services.AssetDispatcher;
-import org.apache.tapestry5.internal.services.ResourceStreamer;
-import org.apache.tapestry5.ioc.IOOperation;
-import org.apache.tapestry5.ioc.OperationTracker;
-import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.Response;
-import org.apache.tapestry5.services.assets.AssetRequestHandler;
-import org.apache.tapestry5.services.javascript.ModuleManager;
-
-/**
- * Handler contributed to {@link AssetDispatcher} with key "modules". It interprets the extra path as a module name,
- * and searches for the corresponding JavaScript module. Unlike normal assets, modules do not include any kind of checksum
- * in the URL, and do not set a far-future expires header.
- *
- * @see ModuleManager
- */
-public class ModuleAssetRequestHandler implements AssetRequestHandler
-{
- private final ModuleManager moduleManager;
-
- private final ResourceStreamer streamer;
-
- private final OperationTracker tracker;
-
- private final Set<ResourceStreamer.Options> omitExpiration = EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION);
-
- public ModuleAssetRequestHandler(ModuleManager moduleManager,
- ResourceStreamer streamer,
- OperationTracker tracker)
- {
- this.moduleManager = moduleManager;
- this.streamer = streamer;
- this.tracker = tracker;
- }
-
- public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
- {
- // Ensure request ends with '.js'. That's the extension tacked on by RequireJS because it expects there
- // to be a hierarchy of static JavaScript files here. In reality, we may be cross-compiling CoffeeScript to
- // JavaScript, or generating modules on-the-fly, or exposing arbitrary Resources from somewhere on the classpath
- // as a module.
-
- int dotx = extraPath.lastIndexOf('.');
-
- if (dotx < 0)
- {
- return false;
- }
-
- if (!extraPath.substring(dotx + 1).equals("js"))
- {
- return false;
- }
-
- final String moduleName = extraPath.substring(0, dotx);
-
- return tracker.perform(String.format("Streaming module %s", extraPath), new IOOperation<Boolean>()
- {
- public Boolean perform() throws IOException
- {
- Resource resource = moduleManager.findResourceForModule(moduleName);
-
- if (resource != null)
- {
- return streamer.streamResource(resource, "", omitExpiration);
- }
-
- return false;
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
new file mode 100644
index 0000000..a841578
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
@@ -0,0 +1,117 @@
+// Copyright 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.
+// 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.javascript;
+
+import org.apache.tapestry5.internal.services.AssetDispatcher;
+import org.apache.tapestry5.internal.services.ResourceStreamer;
+import org.apache.tapestry5.ioc.IOOperation;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.services.Dispatcher;
+import org.apache.tapestry5.services.PathConstructor;
+import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.javascript.ModuleManager;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * Handler contributed to {@link AssetDispatcher} with key "modules". It interprets the extra path as a module name,
+ * and searches for the corresponding JavaScript module. Unlike normal assets, modules do not include any kind of checksum
+ * in the URL, and do not set a far-future expires header.
+ *
+ * @see ModuleManager
+ */
+public class ModuleDispatcher implements Dispatcher
+{
+ private final ModuleManager moduleManager;
+
+ private final ResourceStreamer streamer;
+
+ private final OperationTracker tracker;
+
+ private final String requestPrefix;
+
+ private final boolean compress;
+
+ private final Set<ResourceStreamer.Options> omitExpiration = EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION);
+
+ public ModuleDispatcher(ModuleManager moduleManager,
+ ResourceStreamer streamer,
+ OperationTracker tracker,
+ PathConstructor pathConstructor,
+ String prefix,
+ boolean compress)
+ {
+ this.moduleManager = moduleManager;
+ this.streamer = streamer;
+ this.tracker = tracker;
+ this.compress = compress;
+
+ requestPrefix = pathConstructor.constructDispatchPath(compress ? prefix + ".gz" : prefix) + "/";
+ }
+
+ public boolean dispatch(Request request, Response response) throws IOException
+ {
+ String path = request.getPath();
+
+ return path.startsWith(requestPrefix) &&
+ handleModuleRequest(path.substring(requestPrefix.length()));
+
+ }
+
+ private boolean handleModuleRequest(String extraPath) throws IOException
+ {
+ // Ensure request ends with '.js'. That's the extension tacked on by RequireJS because it expects there
+ // to be a hierarchy of static JavaScript files here. In reality, we may be cross-compiling CoffeeScript to
+ // JavaScript, or generating modules on-the-fly, or exposing arbitrary Resources from somewhere on the classpath
+ // as a module.
+
+ int dotx = extraPath.lastIndexOf('.');
+
+ if (dotx < 0)
+ {
+ return false;
+ }
+
+ if (!extraPath.substring(dotx + 1).equals("js"))
+ {
+ return false;
+ }
+
+ final String moduleName = extraPath.substring(0, dotx);
+
+ return tracker.perform(String.format("Streaming %s %s",
+ compress ? "compressed module" : "module",
+ moduleName), new IOOperation<Boolean>()
+ {
+ public Boolean perform() throws IOException
+ {
+ Resource resource = moduleManager.findResourceForModule(moduleName);
+
+ if (resource != null)
+ {
+ // Slightly hacky way of informing the streamer whether to supply the
+ // compressed or default stream. May need to iterate the API on this a bit.
+ return streamer.streamResource(resource, compress ? "z" : "", omitExpiration);
+ }
+
+ return false;
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
index 8e0f3df..26cb24c 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
@@ -26,8 +26,8 @@ import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONLiteral;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.AssetSource;
+import org.apache.tapestry5.services.PathConstructor;
import org.apache.tapestry5.services.ResponseCompressionAnalyzer;
-import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.apache.tapestry5.services.assets.StreamableResourceSource;
import org.apache.tapestry5.services.javascript.JavaScriptModuleConfiguration;
import org.apache.tapestry5.services.javascript.ModuleConfigurationCallback;
@@ -57,7 +57,7 @@ public class ModuleManagerImpl implements ModuleManager
private final JSONObject baseConfig;
- private final AssetPathConstructor assetPathConstructor;
+ private final String basePath, compressedBasePath;
public ModuleManagerImpl(ResponseCompressionAnalyzer compressionAnalyzer,
AssetSource assetSource,
@@ -68,12 +68,16 @@ public class ModuleManagerImpl implements ModuleManager
boolean compactJSON,
@Symbol(SymbolConstants.PRODUCTION_MODE)
boolean productionMode,
- AssetPathConstructor assetPathConstructor)
+ @Symbol(SymbolConstants.MODULE_PATH_PREFIX)
+ String modulePathPrefix,
+ PathConstructor pathConstructor)
{
this.compressionAnalyzer = compressionAnalyzer;
this.globalMessages = globalMessages;
this.compactJSON = compactJSON;
- this.assetPathConstructor = assetPathConstructor;
+
+ basePath = pathConstructor.constructClientPath(modulePathPrefix);
+ compressedBasePath = pathConstructor.constructClientPath(modulePathPrefix + ".gz");
classpathRoot = assetSource.resourceForPath("");
extensions = CollectionFactory.newSet("js");
@@ -129,7 +133,7 @@ public class ModuleManagerImpl implements ModuleManager
private String getBaseURL()
{
- return assetPathConstructor.constructAssetPath("module", compressionAnalyzer.isGZipSupported());
+ return compressionAnalyzer.isGZipSupported() ? compressedBasePath : basePath;
}
private void addModuleToConfig(JSONObject config, String name, JavaScriptModuleConfiguration module)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
index bb1061f..0fc0738 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
@@ -30,7 +30,7 @@ import java.util.Locale;
* the contents of the virtual resource.
*
* @see org.apache.tapestry5.services.javascript.ModuleManager
- * @see org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler
+ * @see org.apache.tapestry5.internal.services.javascript.ModuleDispatcher
* @since 5.4
*/
public abstract class VirtualResource implements Resource
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
index ca928e6..ab2e502 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
@@ -76,8 +76,7 @@ public class AssetsModule
configuration.add(SymbolConstants.COMBINE_SCRIPTS, SymbolConstants.PRODUCTION_MODE_VALUE);
configuration.add(SymbolConstants.ASSET_URL_FULL_QUALIFIED, false);
- configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "asset");
- configuration.add(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX, "${tapestry.asset-path-prefix}.gz");
+ configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "assets");
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "${tapestry.asset.root}/bootstrap-3.0.2");
@@ -309,4 +308,18 @@ public class AssetsModule
configuration.add("Core", assetSource.resourceForPath("org/apache/tapestry5/core.properties"));
configuration.add("AppCatalog", applicationCatalog);
}
+
+ @Contribute(Dispatcher.class)
+ @Primary
+ public static void setupAssetDispatch(OrderedConfiguration<Dispatcher> configuration,
+ @AssetRequestDispatcher
+ Dispatcher assetDispatcher)
+ {
+
+ // This goes first because an asset to be streamed may have an file
+ // extension, such as
+ // ".html", that will confuse the later dispatchers.
+
+ configuration.add("Asset", assetDispatcher, "before:ComponentEvent");
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
index 9475594..fd095a9 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
@@ -19,22 +19,20 @@ import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.services.DocumentLinker;
+import org.apache.tapestry5.internal.services.ResourceStreamer;
import org.apache.tapestry5.internal.services.ajax.JavaScriptSupportImpl;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
import org.apache.tapestry5.internal.services.javascript.*;
import org.apache.tapestry5.internal.util.MessageCatalogResource;
-import org.apache.tapestry5.ioc.MappedConfiguration;
-import org.apache.tapestry5.ioc.OrderedConfiguration;
-import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.*;
import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Primary;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.services.FactoryDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.ioc.util.IdAllocator;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.*;
-import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.apache.tapestry5.services.compatibility.Compatibility;
import org.apache.tapestry5.services.compatibility.Trait;
import org.apache.tapestry5.services.javascript.*;
@@ -138,7 +136,8 @@ public class JavaScriptModule
configuration.add("jquery-library", StackExtension.library(ROOT + "/jquery-1.9.1.js"));
- if (provider.equals("prototype")) {
+ if (provider.equals("prototype"))
+ {
configuration.add("jquery-noconflict", StackExtension.library(ROOT + "/jquery-noconflict.js"));
}
@@ -187,10 +186,22 @@ public class JavaScriptModule
}
@Contribute(Dispatcher.class)
- @AssetRequestDispatcher
- public static void provideModuleHandler(MappedConfiguration<String, AssetRequestHandler> configuration)
+ @Primary
+ public static void setupModuleDispatchers(OrderedConfiguration<Dispatcher> configuration,
+ ModuleManager moduleManager,
+ OperationTracker tracker,
+ ResourceStreamer resourceStreamer,
+ PathConstructor pathConstructor,
+ @Symbol(SymbolConstants.MODULE_PATH_PREFIX)
+ String modulePathPrefix)
{
- configuration.addInstance("module", ModuleAssetRequestHandler.class);
+ configuration.add("Modules",
+ new ModuleDispatcher(moduleManager, resourceStreamer, tracker, pathConstructor, modulePathPrefix, false),
+ "after:Asset", "before:ComponentEvent");
+
+ configuration.add("ComnpressedModules",
+ new ModuleDispatcher(moduleManager, resourceStreamer, tracker, pathConstructor, modulePathPrefix, true),
+ "after:Modules", "before:ComponentEvent");
}
/**
@@ -312,9 +323,10 @@ public class JavaScriptModule
@Contribute(SymbolProvider.class)
@FactoryDefaults
- public static void declareDefaultJavaScriptInfrastructureProvider(MappedConfiguration<String, Object> configuration)
+ public static void setupFactoryDefaults(MappedConfiguration<String, Object> configuration)
{
configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "prototype");
+ configuration.add(SymbolConstants.MODULE_PATH_PREFIX, "modules");
}
@Contribute(ModuleManager.class)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index f4c9209..b9ff2d8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -1627,8 +1627,6 @@ public final class TapestryModule
* <dl>
* <dt>RootPath</dt>
* <dd>Renders the start page for the "/" request (outdated)</dd>
- * <dt>Asset</dt>
- * <dd>Provides access to assets (context, classpath and virtual) via {@link AssetDispatcher}</dd>
* <dt>PageRender</dt>
* <dd>Identifies the {@link org.apache.tapestry5.services.PageRenderRequestParameters} and forwards onto
* {@link PageRenderRequestHandler}</dd>
@@ -1637,10 +1635,7 @@ public final class TapestryModule
* {@link ComponentEventRequestHandler}</dd>
* </dl>
*/
- public static void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
-
- @AssetRequestDispatcher
- Dispatcher assetDispatcher)
+ public static void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration)
{
// Looks for the root path and renders the start page. This is
// maintained for compatibility
@@ -1649,12 +1644,6 @@ public final class TapestryModule
configuration.addInstance("RootPath", RootPathDispatcher.class, "before:Asset");
- // This goes first because an asset to be streamed may have an file
- // extension, such as
- // ".html", that will confuse the later dispatchers.
-
- configuration.add("Asset", assetDispatcher, "before:ComponentEvent");
-
configuration.addInstance("ComponentEvent", ComponentEventDispatcher.class, "before:PageRender");
configuration.addInstance("PageRender", PageRenderDispatcher.class);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 ffb4d2c..db67493 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
@@ -48,19 +48,4 @@ public interface AssetPathConstructor
@IncompatibleChange(release = "5.4", details = "resource parameter added, IOException may now be thrown")
String constructAssetPath(String virtualFolder, String path, StreamableResource resource) throws IOException;
- /**
- * Generates a base URL for a virtual folder (this exists mostly for {@link org.apache.tapestry5.services.javascript.ModuleManager}
- * and {@link org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler}). Uses much of the same logic
- * as {@link #constructAssetPath(String, String, StreamableResource)}, including
- * {@link org.apache.tapestry5.SymbolConstants#ASSET_URL_FULL_QUALIFIED} and the {@link org.apache.tapestry5.services.AssetPathConverter}.
- *
- * @param virtualFolder
- * folder that will be used to select a {@link }
- * @param compressed
- * build a path that indicates GZip compression
- * @return complete path
- * @since 5.4
- */
- String constructAssetPath(String virtualFolder, boolean compressed);
-
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
index 07263c4..67a72d8 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
@@ -19,7 +19,7 @@ class LibraryTests extends GroovyTapestryCoreTestCase
String assetURL = getAttribute("//img[@id='t5logo']/@src")
- def pattern = ~"/asset/lib/alpha/\\w+/pages/tapestry\\.png"
+ def pattern = ~"/assets/lib/alpha/\\w+/pages/tapestry\\.png"
assert pattern.matcher(assetURL).matches()
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
index 3810816..0ee69ba 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
@@ -56,7 +56,7 @@ class AppFolderTests extends GroovyTapestryCoreTestCase
// Ony one image on page
String assetURL = getAttribute("//img/@src")
- assert assetURL.startsWith("/t5app/asset/")
+ assert assetURL.startsWith("/t5app/assets/")
assertDownloadedAsset assetURL, "src/test/appfolder/images/t5-logo.png"
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 02ed33e..b6e4337 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
@@ -24,7 +24,6 @@ class AssetPathConstructorImplTest extends TestBase {
def r = newMock(StreamableResource)
expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
- expect(pc.constructClientPath("assets.gz", "")).andReturn("/assets.gz/")
expect(r.compression).andReturn(CompressionStatus.COMPRESSED)
@@ -32,9 +31,9 @@ class AssetPathConstructorImplTest extends TestBase {
replay()
- def apc = new AssetPathConstructorImpl(null, null, false, "assets", "assets.gz", pc, pathConverter)
+ def apc = new AssetPathConstructorImpl(null, null, false, "assets", pc, pathConverter)
- assert apc.constructAssetPath("virt", "extra.png", r) == "/assets.gz/virt/abc/extra.png"
+ assert apc.constructAssetPath("virt", "extra.png", r) == "/assets/virt/zabc/extra.png"
verify()
}
@@ -50,7 +49,6 @@ class AssetPathConstructorImplTest extends TestBase {
def r = newMock(StreamableResource)
expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
- expect(pc.constructClientPath("assets.gz", "")).andReturn("/assets.gz/")
expect(request.secure).andReturn(false)
expect(baseURLSource.getBaseURL(false)).andReturn("http://localhost:8080")
@@ -61,7 +59,7 @@ class AssetPathConstructorImplTest extends TestBase {
replay()
- def apc = new AssetPathConstructorImpl(request, baseURLSource, true, "assets", "assets.gz", pc, pathConverter)
+ def apc = new AssetPathConstructorImpl(request, baseURLSource, true, "assets", pc, pathConverter)
assert apc.constructAssetPath("virt", "icon.gif", r) == "http://localhost:8080/assets/virt/abc/icon.gif"
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
deleted file mode 100644
index 5b24b1c..0000000
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.apache.tapestry5.services.javascript
-
-import org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler
-import org.apache.tapestry5.ioc.internal.QuietOperationTracker
-import org.apache.tapestry5.ioc.test.TestBase
-import org.testng.annotations.DataProvider
-import org.testng.annotations.Test
-
-class ModuleAssetRequestHandlerTests extends TestBase {
-
- @Test(dataProvider = "unknownPaths")
- void "invalid extension is ignored"(extraPath) {
- def handler = new ModuleAssetRequestHandler(null, null, new QuietOperationTracker())
-
- assert handler.handleAssetRequest(null, null, extraPath) == false
- }
-
- @DataProvider
- Object[][] unknownPaths() {
- [
- "foo/bar.xyz",
- "foo",
- "foo/bar",
- ""
- ].collect({ it -> ["/modules/$it"] as Object[] }) as Object[][]
- }
-
- @Test
- void "returns false if no module is found"() {
-
- def manager = newMock ModuleManager
-
- expect(manager.findResourceForModule("foo/bar")).andReturn null
-
- replay()
-
- def handler = new ModuleAssetRequestHandler(manager, null, new QuietOperationTracker())
-
- assert handler.handleAssetRequest(null, null, "foo/bar.js") == false
-
- verify()
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
new file mode 100644
index 0000000..c239026
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
@@ -0,0 +1,62 @@
+package org.apache.tapestry5.services.javascript
+
+import org.apache.tapestry5.internal.services.javascript.ModuleDispatcher
+import org.apache.tapestry5.ioc.internal.QuietOperationTracker
+import org.apache.tapestry5.ioc.test.TestBase
+import org.apache.tapestry5.services.PathConstructor
+import org.apache.tapestry5.services.Request
+import org.testng.annotations.DataProvider
+import org.testng.annotations.Test
+
+class ModuleDispatcherTests extends TestBase {
+
+ @Test(dataProvider = "unknownPaths")
+ void "invalid extension is ignored"(path) {
+ def request = newMock Request
+ def pc = newMock PathConstructor
+
+ expect(pc.constructDispatchPath("modules")).andReturn("/modules")
+
+ expect(request.path).andReturn(path)
+
+ replay()
+
+ def handler = new ModuleDispatcher(null, null, new QuietOperationTracker(), pc, "modules", false)
+
+ assert handler.dispatch(request, null) == false
+
+ verify()
+ }
+
+ @DataProvider
+ Object[][] unknownPaths() {
+ [
+ "foo/bar.xyz",
+ "foo",
+ "foo/bar",
+ ""
+ ].collect({ it -> ["/modules/$it"] as Object[] }) as Object[][]
+ }
+
+ @Test
+ void "returns false if no module is found"() {
+
+ def manager = newMock ModuleManager
+ def request = newMock Request
+ def pc = newMock PathConstructor
+
+ expect(pc.constructDispatchPath("modules")).andReturn("/modules")
+
+ expect(request.path).andReturn("/modules/foo/bar.js")
+
+ expect(manager.findResourceForModule("foo/bar")).andReturn null
+
+ replay()
+
+ def handler = new ModuleDispatcher(manager, null, new QuietOperationTracker(), pc, "modules", false)
+
+ assert handler.dispatch(request, null) == false
+
+ verify()
+ }
+}
[2/2] git commit: Simpliy asset & module paths
Posted by hl...@apache.org.
Simpliy asset & module paths
- compressed assets now have a "z" prefix on their checksum in the URL
- assets served from request path "/assets/"
- modules are now top level ("/modules/", not "/assets/modules/")
- compressed asses are now "/modules.gz/"
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/067916b6
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/067916b6
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/067916b6
Branch: refs/heads/master
Commit: 067916b6c95b49195c3f28bebd43f25efe081521
Parents: d23f8e0
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Wed Nov 27 11:27:42 2013 -0800
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed Nov 27 11:27:42 2013 -0800
----------------------------------------------------------------------
.../org/apache/tapestry5/SymbolConstants.java | 51 ++++----
.../org/apache/tapestry5/TapestryConstants.java | 11 --
.../internal/services/AssetDispatcher.java | 57 +++------
.../internal/services/ResourceStreamer.java | 5 +-
.../internal/services/ResourceStreamerImpl.java | 8 +-
.../assets/AssetPathConstructorImpl.java | 51 +++-----
.../assets/StackAssetRequestHandler.java | 14 ++-
.../javascript/ModuleAssetRequestHandler.java | 93 ---------------
.../services/javascript/ModuleDispatcher.java | 117 +++++++++++++++++++
.../services/javascript/ModuleManagerImpl.java | 14 ++-
.../internal/util/VirtualResource.java | 2 +-
.../apache/tapestry5/modules/AssetsModule.java | 17 ++-
.../tapestry5/modules/JavaScriptModule.java | 32 +++--
.../tapestry5/modules/TapestryModule.java | 13 +--
.../services/assets/AssetPathConstructor.java | 15 ---
.../integration/app1/LibraryTests.groovy | 2 +-
.../integration/appfolder/AppFolderTests.groovy | 2 +-
.../assets/AssetPathConstructorImplTest.groovy | 8 +-
.../ModuleAssetRequestHandlerTests.groovy | 43 -------
.../javascript/ModuleDispatcherTests.groovy | 62 ++++++++++
20 files changed, 305 insertions(+), 312 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
index 9414917..c101825 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
@@ -336,20 +336,23 @@ public class SymbolConstants
/**
* Prefix to be used for all resource paths, used to recognize which requests are for assets. This value
* is appended to the context path and the (optional {@linkplain #APPLICATION_FOLDER application folder}.
- * Its default is "asset". It may contain slashes, but should not begin or end with one. This is the prefix
- * for uncompressed assets.
+ * It may contain slashes, but should not begin or end with one.
+ * <p/>
+ * The default is "assets".
*/
public static final String ASSET_PATH_PREFIX = "tapestry.asset-path-prefix";
+
/**
- * As with {@link #ASSET_PATH_PREFIX} but for compressed versions of assets. At render time, it is determined
- * whether each asset is compressable (for example, image file formats are already compressed). A path for
- * either {@link #ASSET_PATH_PREFIX} or this prefix is selected at render time. Defaults to the asset path prefix
- * suffixed with ".gz".
+ * Prefix used for all module resources. This may contain slashes, but should not being or end with one.
+ * Tapestry will create two {@link org.apache.tapestry5.services.Dispatcher}s from this: one for normal
+ * modules, the other for GZip compressed modules (by appending ".gz" to this value).
+ * <p/>
+ * The default is "modules".
*
* @since 5.4
*/
- public static final String COMPRESSED_ASSET_PATH_PREFIX = "tapestry.compressed-asset-path-prefix";
+ public static final String MODULE_PATH_PREFIX = "tapestry.module-path-prefix";
/**
* Identifies the context path of the application, as determined from {@link javax.servlet.ServletContext#getContextPath()}.
@@ -408,36 +411,36 @@ public class SymbolConstants
* @since 5.4
*/
public static final String SESSION_LOCKING_ENABLED = "tapestry.session-locking-enabled";
-
+
/**
* If true (the default), then Tapestry will automatically include the "core" stack in all
* pages.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2169
+ * @since 5.4
*/
public static final String INCLUDE_CORE_STACK = "tapestry.include-core-stack";
-
+
/**
* Defines the CSS class that will be given to HTML element (usually a div) <div> generated by
- * the {@linkplain FormGroup} mixin and the
+ * the {@linkplain FormGroup} mixin and the
* {@linkplain BeanEditForm} and {@linkplain BeanEditor}
* components surrounding the label and the field. The default value is <code>form-group</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_WRAPPER_CSS_CLASS = "tapestry.form-group-wrapper-css-class";
-
+
/**
* Defines the name of the HTML element that will surround the HTML form field generated by
* the {@linkplain FormGroup} mixin and the {@linkplain BeanEditForm} and {@linkplain BeanEditor}.
* If this symbol is null or an empty string, no element will be generated surrouding the
* form field. The default value is the empty string (no wrapping).
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
* @see #FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_CSS_CLASS
+ * @since 5.4
*/
public static final String FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_NAME = "tapestry.form-group-form-field-wrapper-element-name";
@@ -446,29 +449,29 @@ public class SymbolConstants
* the {@linkplain FormGroup} mixin and the {@linkplain BeanEditForm} and {@linkplain BeanEditor}.
* when {@linkplain FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_NAME} is not set to null or the empty string.
* The default value is the empty string (no CSS class added).
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_FORM_FIELD_WRAPPER_ELEMENT_CSS_CLASS = "tapestry.form-group-form-field-wrapper-element-css-class";
/**
* Defines the CSS class that will be given to <label> element generated by
- * the {@linkplain FormGroup} mixin and the
+ * the {@linkplain FormGroup} mixin and the
* {@linkplain BeanEditForm} and {@linkplain BeanEditor}
* components. The default value is <code>control-label</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_GROUP_LABEL_CSS_CLASS = "tapestry.form-group-label-css-class";
/**
* Defines the CSS class that will be given to form field components which are
* {@linkplain AbstractField} subclasses. The default value is <code>form-control</code>.
- *
- * @since 5.4
+ *
* @see https://issues.apache.org/jira/browse/TAP5-2182
+ * @since 5.4
*/
public static final String FORM_FIELD_CSS_CLASS = "tapestry.form-field-css-class";
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
index 74adf03..83a6606 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java
@@ -46,15 +46,4 @@ public class TapestryConstants
* @since 5.2.0
*/
public static final String PAGE_LOOPBACK_PARAMETER_NAME = "t:lb";
-
- /**
- * {@link org.apache.tapestry5.services.Request} attribute set to true or false before an
- * {@link org.apache.tapestry5.services.assets.AssetRequestHandler} is invoked. This information
- * is used downstream, typically by {@link org.apache.tapestry5.internal.services.ResourceStreamer},
- * to decide whether to obtain a normal, or compressed, {@link org.apache.tapestry5.services.assets.StreamableResource}.
- *
- * @since 5.4
- */
- public static final String COMPRESS_CONTENT = "tapestry.compress-content";
-
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 859680d..760ecb9 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
@@ -14,28 +14,21 @@
package org.apache.tapestry5.internal.services;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.TapestryConstants;
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.AssetRequestDispatcher;
-import org.apache.tapestry5.services.ClasspathAssetAliasManager;
-import org.apache.tapestry5.services.Dispatcher;
-import org.apache.tapestry5.services.PathConstructor;
-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;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
/**
* Recognizes requests where the path begins with "/asset/" (actually, as defined by the
* {@link SymbolConstants#ASSET_PATH_PREFIX} symbol), and delivers the content therein as a bytestream. Also
@@ -60,40 +53,22 @@ public class AssetDispatcher implements Dispatcher
*/
private final List<String> assetPaths = CollectionFactory.newList();
- private final String uncompressedPathPrefix, compressedPathPrefix;
-
- private AssetRequestHandler wrap(final boolean compress, final AssetRequestHandler handler)
- {
- return new AssetRequestHandler()
- {
- public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
- {
- request.setAttribute(TapestryConstants.COMPRESS_CONTENT, compress);
-
- return handler.handleAssetRequest(request, response, extraPath);
- }
- };
- }
+ private final String requestPathPrefix;
public AssetDispatcher(Map<String, AssetRequestHandler> configuration,
PathConstructor pathConstructor,
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
- String uncompressedPrefix,
-
- @Symbol(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX)
- String compressedPrefix)
+ String assetPathPrefix)
{
- uncompressedPathPrefix = pathConstructor.constructDispatchPath(uncompressedPrefix, "");
- compressedPathPrefix = pathConstructor.constructDispatchPath(compressedPrefix, "");
+ requestPathPrefix = pathConstructor.constructDispatchPath(assetPathPrefix, "");
for (String path : configuration.keySet())
{
AssetRequestHandler handler = configuration.get(path);
- addPath(uncompressedPathPrefix, path, wrap(false, handler));
- addPath(compressedPathPrefix, path, wrap(true, handler));
+ addPath(requestPathPrefix, path, handler);
}
// Sort by descending length
@@ -124,12 +99,6 @@ public class AssetDispatcher implements Dispatcher
: prefix + path + "/";
}
- private boolean matchesEitherPrefix(String path)
- {
- return path.startsWith(compressedPathPrefix) ||
- path.startsWith(uncompressedPathPrefix);
- }
-
public boolean dispatch(Request request, Response response) throws IOException
{
String path = request.getPath();
@@ -137,7 +106,7 @@ public class AssetDispatcher implements Dispatcher
// Remember that the request path does not include the context path, so we can simply start
// looking for the asset path prefix right off the bat.
- if (!matchesEitherPrefix(path))
+ if (!path.startsWith(requestPathPrefix))
{
return false;
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
index 81027bf..f28e9b1 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamer.java
@@ -25,7 +25,7 @@ import java.util.Set;
/**
* Responsible for streaming the contents of a resource to the client. This is sometimes a simple
- * {@link Resource} (often from the {@link org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler},
+ * {@link Resource} (often from the {@link org.apache.tapestry5.internal.services.javascript.ModuleDispatcher},
* or more frequently an asset represented as a {@link StreamableResource} (via {@link AssetDispatcher}, {@link org.apache.tapestry5.services.assets.AssetRequestHandler},
* and {@link StreamableResourceSource}). As of 5.4, the ResourceStreamer handles ETag support, as well as
* validation of the checksum (provided in the URL).
@@ -66,7 +66,8 @@ public interface ResourceStreamer
boolean streamResource(Resource resource, String providedChecksum, Set<Options> options) throws IOException;
/**
- * Streams a resource that has been assembled elsewhere.
+ * Streams a resource that has been assembled elsewhere. The StreamableResource may reflect either a normal
+ * or a compressed stream, depending on the type of resource and the capabilities of the client.
*
* @param resource
* content to stream
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 9eff1e8..cbfe264 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
@@ -15,7 +15,6 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.TapestryConstants;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
import org.apache.tapestry5.ioc.IOOperation;
@@ -85,8 +84,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
return true;
}
- final boolean compress = (Boolean) request.getAttribute(TapestryConstants.COMPRESS_CONTENT);
-
+ final boolean compress = providedChecksum.startsWith("z");
return tracker.perform(String.format("Streaming %s%s", resource, compress ? " (compressed)" : ""), new IOOperation<Boolean>()
{
@@ -98,7 +96,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
StreamableResource streamable = streamableResourceSource.getStreamableResource(resource, processing, resourceChangeTracker);
- return streamResource(streamable, providedChecksum, options);
+ return streamResource(streamable, compress ? providedChecksum.substring(1) : providedChecksum, options);
}
});
}
@@ -118,7 +116,7 @@ public class ResourceStreamerImpl implements ResourceStreamer
long lastModified = streamable.getLastModified();
- long ifModifiedSince = 0;
+ long ifModifiedSince;
try
{
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 09e434f..e8a3231 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, 2013 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.
@@ -31,7 +31,7 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
{
private final Request request;
- private final String uncompressedPrefix, compressedPrefix;
+ private final String prefix;
private final BaseURLSource baseURLSource;
@@ -48,9 +48,6 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
@Symbol(SymbolConstants.ASSET_PATH_PREFIX)
String uncompressedAssetPrefix,
- @Symbol(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX)
- String compressedAssetPrefix,
-
PathConstructor pathConstructor,
AssetPathConverter pathConverter)
@@ -61,37 +58,13 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
this.fullyQualified = fullyQualified;
this.pathConverter = pathConverter;
- uncompressedPrefix = pathConstructor.constructClientPath(uncompressedAssetPrefix, "");
- compressedPrefix = pathConstructor.constructClientPath(compressedAssetPrefix, "");
+ prefix = pathConstructor.constructClientPath(uncompressedAssetPrefix, "");
}
public String constructAssetPath(String virtualFolder, String path, StreamableResource resource) throws IOException
{
assert InternalUtils.isNonBlank(path);
- StringBuilder builder = create(resource.getCompression() == CompressionStatus.COMPRESSED, virtualFolder);
- builder.append("/");
-
- builder.append(resource.getChecksum());
-
- builder.append('/');
- builder.append(path);
-
- return finish(builder);
- }
-
- public String constructAssetPath(String virtualFolder, boolean compressed)
- {
- return finish(create(compressed, virtualFolder));
- }
-
- private String finish(StringBuilder builder)
- {
- return pathConverter.convertAssetPath(builder.toString());
- }
-
- private StringBuilder create(boolean compress, String virtualFolder)
- {
assert InternalUtils.isNonBlank(virtualFolder);
StringBuilder builder = new StringBuilder();
@@ -101,8 +74,22 @@ public class AssetPathConstructorImpl implements AssetPathConstructor
builder.append(baseURLSource.getBaseURL(request.isSecure()));
}
- builder.append(compress ? compressedPrefix : uncompressedPrefix);
+ builder.append(prefix);
+ builder.append(virtualFolder);
+ builder.append("/");
+
+ // The 'z' prefix indicates a compressed resource.
+
+ if (resource.getCompression() == CompressionStatus.COMPRESSED)
+ {
+ builder.append("z");
+ }
+
+ builder.append(resource.getChecksum());
+ builder.append('/');
+ builder.append(path);
- return builder.append(virtualFolder);
+ return pathConverter.convertAssetPath(builder.toString());
}
+
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
index 487fcf1..c883986 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StackAssetRequestHandler.java
@@ -14,7 +14,6 @@
package org.apache.tapestry5.internal.services.assets;
-import org.apache.tapestry5.TapestryConstants;
import org.apache.tapestry5.internal.services.ResourceStreamer;
import org.apache.tapestry5.ioc.IOOperation;
import org.apache.tapestry5.ioc.OperationTracker;
@@ -48,13 +47,12 @@ public class StackAssetRequestHandler implements AssetRequestHandler
private final JavaScriptStackAssembler javaScriptStackAssembler;
private final JavaScriptStackSource stackSource;
- private final Request request;
public StackAssetRequestHandler(Logger logger, LocalizationSetter localizationSetter,
ResourceStreamer resourceStreamer,
OperationTracker tracker,
JavaScriptStackAssembler javaScriptStackAssembler,
- JavaScriptStackSource stackSource, Request request)
+ JavaScriptStackSource stackSource)
{
this.logger = logger;
this.localizationSetter = localizationSetter;
@@ -62,7 +60,6 @@ public class StackAssetRequestHandler implements AssetRequestHandler
this.tracker = tracker;
this.javaScriptStackAssembler = javaScriptStackAssembler;
this.stackSource = stackSource;
- this.request = request;
}
public boolean handleAssetRequest(Request request, Response response, final String extraPath) throws IOException
@@ -92,6 +89,13 @@ public class StackAssetRequestHandler implements AssetRequestHandler
String localeName = matcher.group(2);
final String stackName = matcher.group(3);
+ final boolean compressed = checksum.startsWith("z");
+
+ if (compressed)
+ {
+ checksum = checksum.substring(1);
+ }
+
if (stackSource.findStack(stackName) == null)
{
logger.warn(String.format("JavaScript stack '%s' not found.", stackName));
@@ -111,8 +115,6 @@ public class StackAssetRequestHandler implements AssetRequestHandler
{
public StreamableResource perform() throws IOException
{
- boolean compressed =
- (Boolean) request.getAttribute(TapestryConstants.COMPRESS_CONTENT);
return javaScriptStackAssembler.assembleJavaScriptResourceForStack(stackName, compressed);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
deleted file mode 100644
index 49d366b..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleAssetRequestHandler.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 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.
-// 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.javascript;
-
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.Set;
-
-import org.apache.tapestry5.internal.services.AssetDispatcher;
-import org.apache.tapestry5.internal.services.ResourceStreamer;
-import org.apache.tapestry5.ioc.IOOperation;
-import org.apache.tapestry5.ioc.OperationTracker;
-import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.Response;
-import org.apache.tapestry5.services.assets.AssetRequestHandler;
-import org.apache.tapestry5.services.javascript.ModuleManager;
-
-/**
- * Handler contributed to {@link AssetDispatcher} with key "modules". It interprets the extra path as a module name,
- * and searches for the corresponding JavaScript module. Unlike normal assets, modules do not include any kind of checksum
- * in the URL, and do not set a far-future expires header.
- *
- * @see ModuleManager
- */
-public class ModuleAssetRequestHandler implements AssetRequestHandler
-{
- private final ModuleManager moduleManager;
-
- private final ResourceStreamer streamer;
-
- private final OperationTracker tracker;
-
- private final Set<ResourceStreamer.Options> omitExpiration = EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION);
-
- public ModuleAssetRequestHandler(ModuleManager moduleManager,
- ResourceStreamer streamer,
- OperationTracker tracker)
- {
- this.moduleManager = moduleManager;
- this.streamer = streamer;
- this.tracker = tracker;
- }
-
- public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
- {
- // Ensure request ends with '.js'. That's the extension tacked on by RequireJS because it expects there
- // to be a hierarchy of static JavaScript files here. In reality, we may be cross-compiling CoffeeScript to
- // JavaScript, or generating modules on-the-fly, or exposing arbitrary Resources from somewhere on the classpath
- // as a module.
-
- int dotx = extraPath.lastIndexOf('.');
-
- if (dotx < 0)
- {
- return false;
- }
-
- if (!extraPath.substring(dotx + 1).equals("js"))
- {
- return false;
- }
-
- final String moduleName = extraPath.substring(0, dotx);
-
- return tracker.perform(String.format("Streaming module %s", extraPath), new IOOperation<Boolean>()
- {
- public Boolean perform() throws IOException
- {
- Resource resource = moduleManager.findResourceForModule(moduleName);
-
- if (resource != null)
- {
- return streamer.streamResource(resource, "", omitExpiration);
- }
-
- return false;
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
new file mode 100644
index 0000000..a841578
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleDispatcher.java
@@ -0,0 +1,117 @@
+// Copyright 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.
+// 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.javascript;
+
+import org.apache.tapestry5.internal.services.AssetDispatcher;
+import org.apache.tapestry5.internal.services.ResourceStreamer;
+import org.apache.tapestry5.ioc.IOOperation;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.services.Dispatcher;
+import org.apache.tapestry5.services.PathConstructor;
+import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.javascript.ModuleManager;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * Handler contributed to {@link AssetDispatcher} with key "modules". It interprets the extra path as a module name,
+ * and searches for the corresponding JavaScript module. Unlike normal assets, modules do not include any kind of checksum
+ * in the URL, and do not set a far-future expires header.
+ *
+ * @see ModuleManager
+ */
+public class ModuleDispatcher implements Dispatcher
+{
+ private final ModuleManager moduleManager;
+
+ private final ResourceStreamer streamer;
+
+ private final OperationTracker tracker;
+
+ private final String requestPrefix;
+
+ private final boolean compress;
+
+ private final Set<ResourceStreamer.Options> omitExpiration = EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION);
+
+ public ModuleDispatcher(ModuleManager moduleManager,
+ ResourceStreamer streamer,
+ OperationTracker tracker,
+ PathConstructor pathConstructor,
+ String prefix,
+ boolean compress)
+ {
+ this.moduleManager = moduleManager;
+ this.streamer = streamer;
+ this.tracker = tracker;
+ this.compress = compress;
+
+ requestPrefix = pathConstructor.constructDispatchPath(compress ? prefix + ".gz" : prefix) + "/";
+ }
+
+ public boolean dispatch(Request request, Response response) throws IOException
+ {
+ String path = request.getPath();
+
+ return path.startsWith(requestPrefix) &&
+ handleModuleRequest(path.substring(requestPrefix.length()));
+
+ }
+
+ private boolean handleModuleRequest(String extraPath) throws IOException
+ {
+ // Ensure request ends with '.js'. That's the extension tacked on by RequireJS because it expects there
+ // to be a hierarchy of static JavaScript files here. In reality, we may be cross-compiling CoffeeScript to
+ // JavaScript, or generating modules on-the-fly, or exposing arbitrary Resources from somewhere on the classpath
+ // as a module.
+
+ int dotx = extraPath.lastIndexOf('.');
+
+ if (dotx < 0)
+ {
+ return false;
+ }
+
+ if (!extraPath.substring(dotx + 1).equals("js"))
+ {
+ return false;
+ }
+
+ final String moduleName = extraPath.substring(0, dotx);
+
+ return tracker.perform(String.format("Streaming %s %s",
+ compress ? "compressed module" : "module",
+ moduleName), new IOOperation<Boolean>()
+ {
+ public Boolean perform() throws IOException
+ {
+ Resource resource = moduleManager.findResourceForModule(moduleName);
+
+ if (resource != null)
+ {
+ // Slightly hacky way of informing the streamer whether to supply the
+ // compressed or default stream. May need to iterate the API on this a bit.
+ return streamer.streamResource(resource, compress ? "z" : "", omitExpiration);
+ }
+
+ return false;
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
index 8e0f3df..26cb24c 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java
@@ -26,8 +26,8 @@ import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONLiteral;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.AssetSource;
+import org.apache.tapestry5.services.PathConstructor;
import org.apache.tapestry5.services.ResponseCompressionAnalyzer;
-import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.apache.tapestry5.services.assets.StreamableResourceSource;
import org.apache.tapestry5.services.javascript.JavaScriptModuleConfiguration;
import org.apache.tapestry5.services.javascript.ModuleConfigurationCallback;
@@ -57,7 +57,7 @@ public class ModuleManagerImpl implements ModuleManager
private final JSONObject baseConfig;
- private final AssetPathConstructor assetPathConstructor;
+ private final String basePath, compressedBasePath;
public ModuleManagerImpl(ResponseCompressionAnalyzer compressionAnalyzer,
AssetSource assetSource,
@@ -68,12 +68,16 @@ public class ModuleManagerImpl implements ModuleManager
boolean compactJSON,
@Symbol(SymbolConstants.PRODUCTION_MODE)
boolean productionMode,
- AssetPathConstructor assetPathConstructor)
+ @Symbol(SymbolConstants.MODULE_PATH_PREFIX)
+ String modulePathPrefix,
+ PathConstructor pathConstructor)
{
this.compressionAnalyzer = compressionAnalyzer;
this.globalMessages = globalMessages;
this.compactJSON = compactJSON;
- this.assetPathConstructor = assetPathConstructor;
+
+ basePath = pathConstructor.constructClientPath(modulePathPrefix);
+ compressedBasePath = pathConstructor.constructClientPath(modulePathPrefix + ".gz");
classpathRoot = assetSource.resourceForPath("");
extensions = CollectionFactory.newSet("js");
@@ -129,7 +133,7 @@ public class ModuleManagerImpl implements ModuleManager
private String getBaseURL()
{
- return assetPathConstructor.constructAssetPath("module", compressionAnalyzer.isGZipSupported());
+ return compressionAnalyzer.isGZipSupported() ? compressedBasePath : basePath;
}
private void addModuleToConfig(JSONObject config, String name, JavaScriptModuleConfiguration module)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
index bb1061f..0fc0738 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/VirtualResource.java
@@ -30,7 +30,7 @@ import java.util.Locale;
* the contents of the virtual resource.
*
* @see org.apache.tapestry5.services.javascript.ModuleManager
- * @see org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler
+ * @see org.apache.tapestry5.internal.services.javascript.ModuleDispatcher
* @since 5.4
*/
public abstract class VirtualResource implements Resource
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
index ca928e6..ab2e502 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/AssetsModule.java
@@ -76,8 +76,7 @@ public class AssetsModule
configuration.add(SymbolConstants.COMBINE_SCRIPTS, SymbolConstants.PRODUCTION_MODE_VALUE);
configuration.add(SymbolConstants.ASSET_URL_FULL_QUALIFIED, false);
- configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "asset");
- configuration.add(SymbolConstants.COMPRESSED_ASSET_PATH_PREFIX, "${tapestry.asset-path-prefix}.gz");
+ configuration.add(SymbolConstants.ASSET_PATH_PREFIX, "assets");
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "${tapestry.asset.root}/bootstrap-3.0.2");
@@ -309,4 +308,18 @@ public class AssetsModule
configuration.add("Core", assetSource.resourceForPath("org/apache/tapestry5/core.properties"));
configuration.add("AppCatalog", applicationCatalog);
}
+
+ @Contribute(Dispatcher.class)
+ @Primary
+ public static void setupAssetDispatch(OrderedConfiguration<Dispatcher> configuration,
+ @AssetRequestDispatcher
+ Dispatcher assetDispatcher)
+ {
+
+ // This goes first because an asset to be streamed may have an file
+ // extension, such as
+ // ".html", that will confuse the later dispatchers.
+
+ configuration.add("Asset", assetDispatcher, "before:ComponentEvent");
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
index 9475594..fd095a9 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
@@ -19,22 +19,20 @@ import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.services.DocumentLinker;
+import org.apache.tapestry5.internal.services.ResourceStreamer;
import org.apache.tapestry5.internal.services.ajax.JavaScriptSupportImpl;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
import org.apache.tapestry5.internal.services.javascript.*;
import org.apache.tapestry5.internal.util.MessageCatalogResource;
-import org.apache.tapestry5.ioc.MappedConfiguration;
-import org.apache.tapestry5.ioc.OrderedConfiguration;
-import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.*;
import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Primary;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.services.FactoryDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.ioc.util.IdAllocator;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.*;
-import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.apache.tapestry5.services.compatibility.Compatibility;
import org.apache.tapestry5.services.compatibility.Trait;
import org.apache.tapestry5.services.javascript.*;
@@ -138,7 +136,8 @@ public class JavaScriptModule
configuration.add("jquery-library", StackExtension.library(ROOT + "/jquery-1.9.1.js"));
- if (provider.equals("prototype")) {
+ if (provider.equals("prototype"))
+ {
configuration.add("jquery-noconflict", StackExtension.library(ROOT + "/jquery-noconflict.js"));
}
@@ -187,10 +186,22 @@ public class JavaScriptModule
}
@Contribute(Dispatcher.class)
- @AssetRequestDispatcher
- public static void provideModuleHandler(MappedConfiguration<String, AssetRequestHandler> configuration)
+ @Primary
+ public static void setupModuleDispatchers(OrderedConfiguration<Dispatcher> configuration,
+ ModuleManager moduleManager,
+ OperationTracker tracker,
+ ResourceStreamer resourceStreamer,
+ PathConstructor pathConstructor,
+ @Symbol(SymbolConstants.MODULE_PATH_PREFIX)
+ String modulePathPrefix)
{
- configuration.addInstance("module", ModuleAssetRequestHandler.class);
+ configuration.add("Modules",
+ new ModuleDispatcher(moduleManager, resourceStreamer, tracker, pathConstructor, modulePathPrefix, false),
+ "after:Asset", "before:ComponentEvent");
+
+ configuration.add("ComnpressedModules",
+ new ModuleDispatcher(moduleManager, resourceStreamer, tracker, pathConstructor, modulePathPrefix, true),
+ "after:Modules", "before:ComponentEvent");
}
/**
@@ -312,9 +323,10 @@ public class JavaScriptModule
@Contribute(SymbolProvider.class)
@FactoryDefaults
- public static void declareDefaultJavaScriptInfrastructureProvider(MappedConfiguration<String, Object> configuration)
+ public static void setupFactoryDefaults(MappedConfiguration<String, Object> configuration)
{
configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "prototype");
+ configuration.add(SymbolConstants.MODULE_PATH_PREFIX, "modules");
}
@Contribute(ModuleManager.class)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index f4c9209..b9ff2d8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -1627,8 +1627,6 @@ public final class TapestryModule
* <dl>
* <dt>RootPath</dt>
* <dd>Renders the start page for the "/" request (outdated)</dd>
- * <dt>Asset</dt>
- * <dd>Provides access to assets (context, classpath and virtual) via {@link AssetDispatcher}</dd>
* <dt>PageRender</dt>
* <dd>Identifies the {@link org.apache.tapestry5.services.PageRenderRequestParameters} and forwards onto
* {@link PageRenderRequestHandler}</dd>
@@ -1637,10 +1635,7 @@ public final class TapestryModule
* {@link ComponentEventRequestHandler}</dd>
* </dl>
*/
- public static void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
-
- @AssetRequestDispatcher
- Dispatcher assetDispatcher)
+ public static void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration)
{
// Looks for the root path and renders the start page. This is
// maintained for compatibility
@@ -1649,12 +1644,6 @@ public final class TapestryModule
configuration.addInstance("RootPath", RootPathDispatcher.class, "before:Asset");
- // This goes first because an asset to be streamed may have an file
- // extension, such as
- // ".html", that will confuse the later dispatchers.
-
- configuration.add("Asset", assetDispatcher, "before:ComponentEvent");
-
configuration.addInstance("ComponentEvent", ComponentEventDispatcher.class, "before:PageRender");
configuration.addInstance("PageRender", PageRenderDispatcher.class);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 ffb4d2c..db67493 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
@@ -48,19 +48,4 @@ public interface AssetPathConstructor
@IncompatibleChange(release = "5.4", details = "resource parameter added, IOException may now be thrown")
String constructAssetPath(String virtualFolder, String path, StreamableResource resource) throws IOException;
- /**
- * Generates a base URL for a virtual folder (this exists mostly for {@link org.apache.tapestry5.services.javascript.ModuleManager}
- * and {@link org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler}). Uses much of the same logic
- * as {@link #constructAssetPath(String, String, StreamableResource)}, including
- * {@link org.apache.tapestry5.SymbolConstants#ASSET_URL_FULL_QUALIFIED} and the {@link org.apache.tapestry5.services.AssetPathConverter}.
- *
- * @param virtualFolder
- * folder that will be used to select a {@link }
- * @param compressed
- * build a path that indicates GZip compression
- * @return complete path
- * @since 5.4
- */
- String constructAssetPath(String virtualFolder, boolean compressed);
-
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
index 07263c4..67a72d8 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/LibraryTests.groovy
@@ -19,7 +19,7 @@ class LibraryTests extends GroovyTapestryCoreTestCase
String assetURL = getAttribute("//img[@id='t5logo']/@src")
- def pattern = ~"/asset/lib/alpha/\\w+/pages/tapestry\\.png"
+ def pattern = ~"/assets/lib/alpha/\\w+/pages/tapestry\\.png"
assert pattern.matcher(assetURL).matches()
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
index 3810816..0ee69ba 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/appfolder/AppFolderTests.groovy
@@ -56,7 +56,7 @@ class AppFolderTests extends GroovyTapestryCoreTestCase
// Ony one image on page
String assetURL = getAttribute("//img/@src")
- assert assetURL.startsWith("/t5app/asset/")
+ assert assetURL.startsWith("/t5app/assets/")
assertDownloadedAsset assetURL, "src/test/appfolder/images/t5-logo.png"
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/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 02ed33e..b6e4337 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
@@ -24,7 +24,6 @@ class AssetPathConstructorImplTest extends TestBase {
def r = newMock(StreamableResource)
expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
- expect(pc.constructClientPath("assets.gz", "")).andReturn("/assets.gz/")
expect(r.compression).andReturn(CompressionStatus.COMPRESSED)
@@ -32,9 +31,9 @@ class AssetPathConstructorImplTest extends TestBase {
replay()
- def apc = new AssetPathConstructorImpl(null, null, false, "assets", "assets.gz", pc, pathConverter)
+ def apc = new AssetPathConstructorImpl(null, null, false, "assets", pc, pathConverter)
- assert apc.constructAssetPath("virt", "extra.png", r) == "/assets.gz/virt/abc/extra.png"
+ assert apc.constructAssetPath("virt", "extra.png", r) == "/assets/virt/zabc/extra.png"
verify()
}
@@ -50,7 +49,6 @@ class AssetPathConstructorImplTest extends TestBase {
def r = newMock(StreamableResource)
expect(pc.constructClientPath("assets", "")).andReturn("/assets/")
- expect(pc.constructClientPath("assets.gz", "")).andReturn("/assets.gz/")
expect(request.secure).andReturn(false)
expect(baseURLSource.getBaseURL(false)).andReturn("http://localhost:8080")
@@ -61,7 +59,7 @@ class AssetPathConstructorImplTest extends TestBase {
replay()
- def apc = new AssetPathConstructorImpl(request, baseURLSource, true, "assets", "assets.gz", pc, pathConverter)
+ def apc = new AssetPathConstructorImpl(request, baseURLSource, true, "assets", pc, pathConverter)
assert apc.constructAssetPath("virt", "icon.gif", r) == "http://localhost:8080/assets/virt/abc/icon.gif"
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
deleted file mode 100644
index 5b24b1c..0000000
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleAssetRequestHandlerTests.groovy
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.apache.tapestry5.services.javascript
-
-import org.apache.tapestry5.internal.services.javascript.ModuleAssetRequestHandler
-import org.apache.tapestry5.ioc.internal.QuietOperationTracker
-import org.apache.tapestry5.ioc.test.TestBase
-import org.testng.annotations.DataProvider
-import org.testng.annotations.Test
-
-class ModuleAssetRequestHandlerTests extends TestBase {
-
- @Test(dataProvider = "unknownPaths")
- void "invalid extension is ignored"(extraPath) {
- def handler = new ModuleAssetRequestHandler(null, null, new QuietOperationTracker())
-
- assert handler.handleAssetRequest(null, null, extraPath) == false
- }
-
- @DataProvider
- Object[][] unknownPaths() {
- [
- "foo/bar.xyz",
- "foo",
- "foo/bar",
- ""
- ].collect({ it -> ["/modules/$it"] as Object[] }) as Object[][]
- }
-
- @Test
- void "returns false if no module is found"() {
-
- def manager = newMock ModuleManager
-
- expect(manager.findResourceForModule("foo/bar")).andReturn null
-
- replay()
-
- def handler = new ModuleAssetRequestHandler(manager, null, new QuietOperationTracker())
-
- assert handler.handleAssetRequest(null, null, "foo/bar.js") == false
-
- verify()
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/067916b6/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
new file mode 100644
index 0000000..c239026
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/services/javascript/ModuleDispatcherTests.groovy
@@ -0,0 +1,62 @@
+package org.apache.tapestry5.services.javascript
+
+import org.apache.tapestry5.internal.services.javascript.ModuleDispatcher
+import org.apache.tapestry5.ioc.internal.QuietOperationTracker
+import org.apache.tapestry5.ioc.test.TestBase
+import org.apache.tapestry5.services.PathConstructor
+import org.apache.tapestry5.services.Request
+import org.testng.annotations.DataProvider
+import org.testng.annotations.Test
+
+class ModuleDispatcherTests extends TestBase {
+
+ @Test(dataProvider = "unknownPaths")
+ void "invalid extension is ignored"(path) {
+ def request = newMock Request
+ def pc = newMock PathConstructor
+
+ expect(pc.constructDispatchPath("modules")).andReturn("/modules")
+
+ expect(request.path).andReturn(path)
+
+ replay()
+
+ def handler = new ModuleDispatcher(null, null, new QuietOperationTracker(), pc, "modules", false)
+
+ assert handler.dispatch(request, null) == false
+
+ verify()
+ }
+
+ @DataProvider
+ Object[][] unknownPaths() {
+ [
+ "foo/bar.xyz",
+ "foo",
+ "foo/bar",
+ ""
+ ].collect({ it -> ["/modules/$it"] as Object[] }) as Object[][]
+ }
+
+ @Test
+ void "returns false if no module is found"() {
+
+ def manager = newMock ModuleManager
+ def request = newMock Request
+ def pc = newMock PathConstructor
+
+ expect(pc.constructDispatchPath("modules")).andReturn("/modules")
+
+ expect(request.path).andReturn("/modules/foo/bar.js")
+
+ expect(manager.findResourceForModule("foo/bar")).andReturn null
+
+ replay()
+
+ def handler = new ModuleDispatcher(manager, null, new QuietOperationTracker(), pc, "modules", false)
+
+ assert handler.dispatch(request, null) == false
+
+ verify()
+ }
+}