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 2010/04/19 15:48:23 UTC
svn commit: r935566 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/internal/services/assets/
main/java/org/apache/tapestry5/ser...
Author: hlship
Date: Mon Apr 19 13:48:23 2010
New Revision: 935566
URL: http://svn.apache.org/viewvc?rev=935566&view=rev
Log:
Temporarily cobble back together the virtual assets.
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java (with props)
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetDispatcher.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocator.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocatorImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetStreamerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java?rev=935566&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java Mon Apr 19 13:48:23 2010
@@ -0,0 +1,29 @@
+// Copyright 2010 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;
+
+/**
+ * Defines constants for the two basic asset prefixes.
+ *
+ * @since 5.2.0
+ */
+public class AssetConstants
+{
+ /** For assets that are stored in the web application context. */
+ public static final String CONTEXT = "context";
+
+ /** For assets that are stored in the classpath (i.e., inside 3rd party component library JARs). */
+ public static final String CLASSPATH = "classpath";
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/AssetConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocator.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocator.java Mon Apr 19 13:48:23 2010
@@ -15,6 +15,7 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
import java.io.IOException;
@@ -29,13 +30,25 @@ import java.io.IOException;
public interface AssetResourceLocator
{
/**
- * Analyzes the path and identifies the underying Asset Resource for that path. Handles context resources and
- * checking for a digest.
+ * Analyzes the path and identifies the underlying Asset Resource for that path. Handles both context resources and
+ * classpath resources,
+ * as well as checking for a digest (for protected classpath resources).
*
* @param path
- * classpath path, possibly including a checksum in the file name
- * @return resource corresponding to path (may be for a non-existent resource), or null if path is invalid (i.e.,
+ * path for Asset URL, as per {@link AssetPathConstructor#constructAssetPath(String, String)}
+ * @return
+ * resource corresponding to path (may be for a non-existent resource), or null if path is invalid (i.e.,
* incorrect digest)
*/
- Resource findResourceForPath(String path) throws IOException;
+ Resource findResourceForAssetPath(String path) throws IOException;
+
+ /**
+ * For a complete classpath path, returns the Resource for the path. This include checking for a
+ * digest for protected files.
+ *
+ * @return
+ * resource corresponding to path (may be for a non-existent resource), or null if path is invalid (i.e.,
+ * incorrect digest)
+ */
+ Resource findClasspathResourceForPath(String path) throws IOException;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocatorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocatorImpl.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocatorImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetResourceLocatorImpl.java Mon Apr 19 13:48:23 2010
@@ -1,4 +1,4 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,12 +15,16 @@
package org.apache.tapestry5.internal.services;
import java.io.IOException;
+import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import org.apache.tapestry5.internal.AssetConstants;
import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry5.services.AssetSource;
+import org.apache.tapestry5.services.ClasspathAssetAliasManager;
import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
public class AssetResourceLocatorImpl implements AssetResourceLocator
{
@@ -28,21 +32,79 @@ public class AssetResourceLocatorImpl im
private final Response response;
+ private final AssetSource assetSource;
+
+ private final String contextAssetPathPrefix;
+
+ private final String assetPathPrefix;
+
+ private final Map<String, String> classpathMappings;
+
public AssetResourceLocatorImpl(ResourceCache resourceCache,
- Response response)
+ Response response,
+
+ AssetSource assetSource, ClasspathAssetAliasManager aliasManager,
+
+ AssetPathConstructor assetPathConstructor)
{
this.resourceCache = resourceCache;
this.response = response;
+ this.assetSource = assetSource;
+
+ classpathMappings = aliasManager.getMappings();
+
+ contextAssetPathPrefix = assetPathConstructor.constructAssetPath(RequestConstants.CONTEXT_FOLDER, "");
+
+ assetPathPrefix = assetPathConstructor.getAssetPathPrefix();
+
+ }
+
+ public Resource findResourceForAssetPath(String path) throws IOException
+ {
+ if (path.startsWith(contextAssetPathPrefix))
+ {
+ String assetPath = String.format("%s:%s", AssetConstants.CONTEXT, path.substring(contextAssetPathPrefix
+ .length() + 1));
+
+ return assetSource.resourceForPath(assetPath);
+ }
+
+ // TODO: We need some work in this area to support more than just classpath and context assets
+ // but any asset.
+
+ // The path provided has been mangled into an asset URL for a classpath asset. Let's unmangle it.
+
+ // Strip off the asset path prefix, leaving just the virtual folder and path below it.
+
+ String virtualPath = path.substring(assetPathPrefix.length());
+
+ int slashx = virtualPath.indexOf('/');
+ String virtualFolder = virtualPath.substring(0, slashx);
+ String extraPath = virtualPath.substring(slashx + 1);
+
+ String assetPath = classpathMappings.get(virtualFolder) + "/" + extraPath;
+
+ return findClasspathResourceForPath(assetPath);
}
- public Resource findResourceForPath(String path) throws IOException
+ public Resource findClasspathResourceForPath(String path) throws IOException
{
- Resource resource = new ClasspathResource(path);
+
+ Resource resource = assetSource.resourceForPath(path);
if (!resourceCache.requiresDigest(resource))
return resource;
+ return validateChecksumOfClasspathResource(resource);
+ }
+
+ /**
+ * Validates the checksome encoded into the resource, and returns the true resource (with the checksum
+ * portion removed from the file name).
+ */
+ private Resource validateChecksumOfClasspathResource(Resource resource) throws IOException
+ {
String file = resource.getFile();
// Somehow this code got real ugly, but it's all about preventing NPEs when a resource
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java Mon Apr 19 13:48:23 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.Asset;
+import org.apache.tapestry5.internal.AssetConstants;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.Defense;
@@ -28,10 +29,6 @@ import java.util.Map;
public class AssetSourceImpl implements AssetSource
{
- private static final String CLASSPATH = "classpath";
-
- private static final String CONTEXT = "context";
-
private final StrategyRegistry<AssetFactory> registry;
private final ThreadLocale threadLocale;
@@ -75,7 +72,7 @@ public class AssetSourceImpl implements
public Asset getContextAsset(String path, Locale locale)
{
- return getAsset(prefixToRootResource.get(CONTEXT), path, locale);
+ return getAsset(prefixToRootResource.get(AssetConstants.CONTEXT), path, locale);
}
public Asset getAsset(Resource baseResource, String path, Locale locale)
@@ -101,7 +98,7 @@ public class AssetSourceImpl implements
if (colonx < 0)
{
- Resource root = baseResource != null ? baseResource : prefixToRootResource.get(CLASSPATH);
+ Resource root = baseResource != null ? baseResource : prefixToRootResource.get(AssetConstants.CLASSPATH);
return root.forFile(path);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java Mon Apr 19 13:48:23 2010
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2007, 2008, 2009, 2010 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.
@@ -21,6 +21,7 @@ import org.apache.tapestry5.ioc.internal
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.services.ClientDataEncoder;
import org.apache.tapestry5.services.ClientDataSink;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
import java.io.IOException;
import java.io.ObjectOutputStream;
@@ -54,6 +55,8 @@ public class DocumentLinkerImpl implemen
private final int contextPathLength;
+ private final AssetPathConstructor assetPathConstructor;
+
/**
* @param productionMode
* via symbol configuration
@@ -67,12 +70,16 @@ public class DocumentLinkerImpl implemen
* {@link org.apache.tapestry5.services.Request#getContextPath()}
* @param clientDataEncoder
* used to encode data for the combined virtual asset
+ * @param assetPathConstructor
+ * TODO
*/
public DocumentLinkerImpl(boolean productionMode, boolean omitGeneratorMetaTag, String tapestryVersion,
- boolean combineScripts, String contextPath, ClientDataEncoder clientDataEncoder)
+ boolean combineScripts, String contextPath, ClientDataEncoder clientDataEncoder,
+ AssetPathConstructor assetPathConstructor)
{
this.combineScripts = combineScripts;
this.clientDataEncoder = clientDataEncoder;
+ this.assetPathConstructor = assetPathConstructor;
developmentMode = !productionMode;
this.omitGeneratorMetaTag = omitGeneratorMetaTag;
@@ -248,8 +255,9 @@ public class DocumentLinkerImpl implemen
stream.writeUTF(scriptURL.substring(contextPathLength));
}
- String virtualURL = fullAssetPrefix + RequestConstants.VIRTUAL_FOLDER + dataSink.getEncodedClientData()
- + ".js";
+ String virtualURL = assetPathConstructor.constructAssetPath(RequestConstants.VIRTUAL_FOLDER, dataSink
+ .getEncodedClientData()
+ + ".js");
container.element("script", "type", "text/javascript", "src", virtualURL);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestConstants.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestConstants.java Mon Apr 19 13:48:23 2010
@@ -42,7 +42,7 @@ public final class RequestConstants
*
* @since 5.1.0.2
*/
- public static final String VIRTUAL_FOLDER = "virtual/";
+ public static final String VIRTUAL_FOLDER = "virtual";
/**
* Name of parameter, in an Ajax update, that identifies the client-side id of the {@link Form} being extended. Used
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetStreamerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetStreamerImpl.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetStreamerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/VirtualAssetStreamerImpl.java Mon Apr 19 13:48:23 2010
@@ -114,8 +114,7 @@ public class VirtualAssetStreamerImpl im
request.setAttribute(InternalConstants.SUPPRESS_COMPRESSION, true);
// CSS support is problematic, because of relative URLs inside the CSS files. For the
- // moment, only
- // JavaScript is supported.
+ // moment, only JavaScript is supported.
OutputStream output = response.getOutputStream("text/javascript");
@@ -221,7 +220,7 @@ public class VirtualAssetStreamerImpl im
private void streamPath(String path, ByteArrayOutputStream output) throws IOException
{
- Resource resource = resourceLocator.findResourceForPath(path);
+ Resource resource = resourceLocator.findResourceForAssetPath(request.getContextPath() + path);
StreamableResource streamable = resourceCache.getStreamableResource(resource);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/AssetPathConstructorImpl.java Mon Apr 19 13:48:23 2010
@@ -37,6 +37,11 @@ public class AssetPathConstructorImpl im
this.prefix = RequestConstants.ASSET_PATH_PREFIX + applicationVersion + "/";
}
+ public String getAssetPathPrefix()
+ {
+ return request.getContextPath() + prefix;
+ }
+
public String constructAssetPath(String virtualFolder, String path)
{
StringBuilder builder = new StringBuilder(request.getContextPath());
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/ClasspathAssetRequestHandler.java Mon Apr 19 13:48:23 2010
@@ -48,9 +48,9 @@ public class ClasspathAssetRequestHandle
public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
{
- String path = baseFolder + "/" + extraPath;
+ String assetPath = baseFolder + "/" + extraPath;
- Resource resource = assetResourceLocator.findResourceForPath(path);
+ Resource resource = assetResourceLocator.findClasspathResourceForPath(assetPath);
if (resource == null)
return false;
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java?rev=935566&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java Mon Apr 19 13:48:23 2010
@@ -0,0 +1,52 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.services.assets;
+
+import java.io.IOException;
+
+import org.apache.tapestry5.internal.services.VirtualAssetStreamer;
+import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.assets.AssetRequestHandler;
+
+/**
+ * Processes requests for virtual assets, passing off such requests to the {@link VirtualAssetStreamer} service.
+ *
+ * @since 5.2.0
+ */
+public class VirtualAssetRequestHandler implements AssetRequestHandler
+{
+ private final VirtualAssetStreamer streamer;
+
+ public VirtualAssetRequestHandler(VirtualAssetStreamer streamer)
+ {
+ this.streamer = streamer;
+ }
+
+ public boolean handleAssetRequest(Request request, Response response, String extraPath) throws IOException
+ {
+ // To make the virtual asset look like an ordinary file, a fake ".js" suffix is added, which is
+ // stripped off here.
+
+ int dotx = extraPath.lastIndexOf('.');
+
+ String clientData = extraPath.substring(0, dotx);
+
+ streamer.streamVirtualAsset(clientData);
+
+ return true;
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/VirtualAssetRequestHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Mon Apr 19 13:48:23 2010
@@ -51,6 +51,7 @@ import org.apache.tapestry5.corelib.data
import org.apache.tapestry5.corelib.data.GridPagerPosition;
import org.apache.tapestry5.corelib.data.InsertPosition;
import org.apache.tapestry5.grid.GridDataSource;
+import org.apache.tapestry5.internal.AssetConstants;
import org.apache.tapestry5.internal.DefaultNullFieldStrategy;
import org.apache.tapestry5.internal.DefaultValidationDecorator;
import org.apache.tapestry5.internal.InternalConstants;
@@ -79,6 +80,7 @@ import org.apache.tapestry5.internal.ser
import org.apache.tapestry5.internal.services.assets.AssetPathConstructorImpl;
import org.apache.tapestry5.internal.services.assets.ClasspathAssetRequestHandler;
import org.apache.tapestry5.internal.services.assets.ContextAssetRequestHandler;
+import org.apache.tapestry5.internal.services.assets.VirtualAssetRequestHandler;
import org.apache.tapestry5.internal.services.messages.PropertiesFileParserImpl;
import org.apache.tapestry5.internal.transform.*;
import org.apache.tapestry5.internal.translator.NumericTranslator;
@@ -116,6 +118,7 @@ import org.apache.tapestry5.validator.Mi
import org.apache.tapestry5.validator.Regexp;
import org.apache.tapestry5.validator.Required;
import org.apache.tapestry5.validator.ValidatorMacro;
+import org.apache.tools.ant.taskdefs.condition.ResourceContains;
import org.slf4j.Logger;
/**
@@ -461,7 +464,8 @@ public final class TapestryModule
}
/**
- * Contributes an handler for each mapped classpath alias, as well as one for context assets.
+ * Contributes an handler for each mapped classpath alias, as well handlers for context assets
+ * and virtual assets (combined Javascript files).
*/
public static void contributeAssetDispatcher(MappedConfiguration<String, AssetRequestHandler> configuration,
@@ -482,6 +486,8 @@ public final class TapestryModule
configuration.add(RequestConstants.CONTEXT_FOLDER, new ContextAssetRequestHandler(streamer, contextAssetFactory
.getRootResource()));
+
+ configuration.addInstance(RequestConstants.VIRTUAL_FOLDER, VirtualAssetRequestHandler.class);
}
private static String toPackagePath(String packageName)
@@ -1688,8 +1694,8 @@ public final class TapestryModule
@ClasspathProvider
AssetFactory classpathAssetFactory)
{
- configuration.add("context", contextAssetFactory);
- configuration.add("classpath", classpathAssetFactory);
+ configuration.add(AssetConstants.CONTEXT, contextAssetFactory);
+ configuration.add(AssetConstants.CLASSPATH, classpathAssetFactory);
}
/**
@@ -1789,9 +1795,7 @@ public final class TapestryModule
* <dt>RootPath</dt>
* <dd>Renders the start page for the "/" request (outdated)</dd>
* <dt>Asset</dt>
- * <dd>Provides access to assets</dd>
- * <dt>VirtualAsset</dt>
- * <dd>Provides access to combined scripts</dd>
+ * <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>
@@ -1818,8 +1822,6 @@ public final class TapestryModule
configuration.add("Asset", assetDispatcher, "before:ComponentEvent");
- configuration.addInstance("VirtualAsset", VirtualAssetDispatcher.class, "before:Asset");
-
configuration.addInstance("ComponentEvent", ComponentEventDispatcher.class, "before:PageRender");
configuration.addInstance("PageRender", PageRenderDispatcher.class);
@@ -1912,14 +1914,16 @@ public final class TapestryModule
final ClientDataEncoder clientDataEncoder,
- final ClientInfrastructure clientInfrastructure)
+ final ClientInfrastructure clientInfrastructure,
+
+ final AssetPathConstructor assetPathConstructor)
{
MarkupRendererFilter documentLinker = new MarkupRendererFilter()
{
public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
{
DocumentLinkerImpl linker = new DocumentLinkerImpl(productionMode, omitGeneratorMeta, tapestryVersion,
- combineScripts, request.getContextPath(), clientDataEncoder);
+ combineScripts, request.getContextPath(), clientDataEncoder, assetPathConstructor);
environment.push(DocumentLinker.class, linker);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/AssetPathConstructor.java Mon Apr 19 13:48:23 2010
@@ -29,7 +29,15 @@ public interface AssetPathConstructor
* corresponds to a {@link AssetRequestHandler} contributed to the AssetDispatcher service
* @param path
* within the virtual folder (should <em>not</em> start with a slash)
- * @return path portion of asset URL
+ * @return path portion of asset URL, including the context path, the /assets/ virtual folder, the application
+ * version number,
+ * the virtual folder, and the path extension
*/
String constructAssetPath(String virtualFolder, String path);
+
+ /**
+ * Returns the prefix portion of the asset URL, the portion including the context path, the /assets/ virtual folder,
+ * and the version number, and the trailing slash.
+ */
+ String getAssetPathPrefix();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java?rev=935566&r1=935565&r2=935566&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java Mon Apr 19 13:48:23 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2007, 2008, 2009, 2010 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
+// 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,
@@ -19,6 +19,9 @@ import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.dom.XMLMarkupModel;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.services.URLEncoder;
+import org.apache.tapestry5.services.assets.AssetPathConstructor;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -47,7 +50,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("not-html").text("not an HTML document");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
// Only checked if there's something to link.
@@ -61,8 +64,9 @@ public class DocumentLinkerImplTest exte
}
catch (RuntimeException ex)
{
- assertEquals(ex.getMessage(),
- "The root element of the rendered document was <not-html>, not <html>. A root element of <html> is needed when linking JavaScript and stylesheet resources.");
+ assertEquals(
+ ex.getMessage(),
+ "The root element of the rendered document was <not-html>, not <html>. A root element of <html> is needed when linking JavaScript and stylesheet resources.");
}
}
@@ -73,7 +77,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("not-html").text("not an HTML document");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
// Only checked if there's something to link.
@@ -95,7 +99,7 @@ public class DocumentLinkerImplTest exte
{
Document document = new Document();
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScript("foo.js");
linker.addScript("doSomething();");
@@ -112,7 +116,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScriptLink("foo.js");
linker.addScriptLink("bar/baz.js");
@@ -133,11 +137,10 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be marked with generator meta.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false, "1.2.3", false, "", null, null);
linker.updateDocument(document);
-
check(document, "include_generator_meta.txt");
}
@@ -151,11 +154,10 @@ public class DocumentLinkerImplTest exte
document.newRootElement("no_html").text("Generator meta only added if root is html tag.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false, "1.2.3", false, "", null, null);
linker.updateDocument(document);
-
check(document, "omit_generator_meta_on_no_html_root.txt");
}
@@ -166,7 +168,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addStylesheetLink("style.css", "print");
linker.addScriptLink("foo.js");
@@ -185,7 +187,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts at top.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScriptLink("foo.js");
linker.addScriptLink("bar/baz.js");
@@ -203,7 +205,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with styles.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addStylesheetLink("foo.css", null);
linker.addStylesheetLink("bar/baz.css", "print");
@@ -220,7 +222,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with styles.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addStylesheetLink("foo.css", null);
linker.addStylesheetLink("bar/baz.css", "print");
@@ -238,10 +240,10 @@ public class DocumentLinkerImplTest exte
{
Document document = new Document(new XMLMarkupModel());
- document.newRootElement("html").element("head").comment("existing head").getParent()
- .element("body").text("body content");
+ document.newRootElement("html").element("head").comment("existing head").getParent().element("body").text(
+ "body content");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addStylesheetLink("foo.css", null);
@@ -257,7 +259,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
for (int i = 0; i < 3; i++)
{
@@ -278,7 +280,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScript("doSomething();");
linker.addScript("doSomethingElse();");
@@ -295,7 +297,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(false, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(false, true, "1.2.3", false, "", null, null);
linker.addScriptLink("foo.js");
@@ -314,7 +316,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("notbody").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScriptLink("foo.js");
@@ -323,7 +325,6 @@ public class DocumentLinkerImplTest exte
check(document, "no_body_element.txt");
}
-
@Test
public void script_written_raw() throws Exception
{
@@ -331,7 +332,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", false, "", null, null);
linker.addScript("for (var i = 0; i < 5; i++) { doIt(i); }");
@@ -343,13 +344,37 @@ public class DocumentLinkerImplTest exte
@Test
public void aggregated_script_link() throws Exception
{
+ final ClientDataEncoderImpl encoder = new ClientDataEncoderImpl(urlEncoder);
+
+ AssetPathConstructor apc = newMock(AssetPathConstructor.class);
+
+ expect(apc.constructAssetPath(EasyMock.eq(RequestConstants.VIRTUAL_FOLDER), EasyMock.isA(String.class)))
+ .andAnswer(new IAnswer<String>()
+ {
+ public String answer() throws Throwable
+ {
+ String path = (String) EasyMock.getCurrentArguments()[1];
+
+ String clientData = path.substring(0, path.length() - 3);
+
+ ObjectInputStream stream = encoder.decodeEncodedClientData(clientData);
+
+ assertEquals(stream.readInt(), 2);
+ assertEquals(stream.readUTF(), "/assets/foo.js");
+ assertEquals(stream.readUTF(), "/assets/xyz/bar.js");
+
+ return "{virtual}";
+ }
+
+ });
+
+ replay();
+
Document document = new Document();
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- ClientDataEncoderImpl encoder = new ClientDataEncoderImpl(urlEncoder);
-
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", encoder);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", encoder, apc);
linker.addScriptLink("/context/assets/foo.js");
linker.addScriptLink("/context/assets/xyz/bar.js");
@@ -358,17 +383,9 @@ public class DocumentLinkerImplTest exte
Element script = document.getRootElement().find("head/script");
- String assetURL = script.getAttribute("src");
-
- String fileName = assetURL.substring("/context/assets/virtual/".length());
-
- String clientData = fileName.substring(0, fileName.length() - 3);
-
- ObjectInputStream stream = encoder.decodeEncodedClientData(clientData);
+ assertEquals(script.getAttribute("src"), "{virtual}");
- assertEquals(stream.readInt(), 2);
- assertEquals(stream.readUTF(), "/assets/foo.js");
- assertEquals(stream.readUTF(), "/assets/xyz/bar.js");
+ verify();
}
@Test
@@ -378,7 +395,7 @@ public class DocumentLinkerImplTest exte
document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", null, null);
linker.addScriptLink("/context/foo.js");
@@ -401,7 +418,7 @@ public class DocumentLinkerImplTest exte
head.element("meta");
head.element("script");
- DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", null);
+ DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true, "1.2.3", true, "/context", null, null);
linker.addScriptLink("/foo.js");
@@ -409,6 +426,5 @@ public class DocumentLinkerImplTest exte
assertEquals(document.toString(), readFile("added_scripts_go_before_existing_script.txt"));
-
}
}