Most of the time, you should avoid using the regex methods on the String
class (split, matches, replace etc) as these will compile the
java.util.regex.Pattern for every invocation.

Instead, you should Pattern.compile(regex) once and save the result then
use Pattern.matches(value).

On Wednesday, 22 February 2012, Paul Stanton <p...@mapshed.com.au> wrote:
> By the way all,
>
> Here is a solution which does not require any changes to tapestry code.
All code is free to use.
>
> 1. contribute a dispatcher to MasterDispatcher, just before the regular
AssetDispatcher:
>
>    public static void bind(ServiceBinder binder)
>    {
>        binder.bind(Dispatcher.class,
AssetVersionCheckDispatcher.class).withId("AssetVersionCheckDispatcher");
>    }
>
>    public static void
contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
//
>            @InjectService("AssetVersionCheckDispatcher") Dispatcher
assetVersionCheckDispatcher)
>    {
>        configuration.add("AssetVersionCheckDispatcher",
assetVersionCheckDispatcher, "before:AssetDispatcher");
>    }
>
> 2. Implementation of AssetVersionCheckDispatcher:
>
> public class AssetVersionCheckDispatcher implements Dispatcher
> {
>    private final String pathPrefix;
>    private final String pathPrefixPattern;
>
>    public
AssetVersionCheckDispatcher(@Symbol(SymbolConstants.APPLICATION_VERSION)
String appVersion,
>            @Symbol(SymbolConstants.APPLICATION_FOLDER) String appFolder,
>            @Symbol(SymbolConstants.ASSET_PATH_PREFIX) String
assetPathPrefix)
>    {
>        String folder = appFolder.equals("") ? "" : "/" + appFolder;
>        this.pathPrefix = folder + assetPathPrefix + appVersion + "/";
>        this.pathPrefixPattern = "^" + folder + assetPathPrefix +
"[^/]{1,}/(.*)$";
>    }
>
>    @Override
>    public boolean dispatch(Request request, Response response) throws
IOException
>    {
>        String path = request.getPath();
>
>        if (!path.startsWith(pathPrefix))
>        {
>            if (path.matches(pathPrefixPattern))
>            {
>                // send 302 temporary redirect to the current version
>                String newPath = request.getContextPath() +
path.replaceFirst(pathPrefixPattern, pathPrefix + "$1");
>                response.setHeader("Location", newPath);
>
 response.sendError(HttpServletResponse.SC_MOVED_TEMPORARILY, newPath);
>                return true;
>            }
>        }
>
>        return false;
>    }
> }
>
> On 22/02/2012 11:08 AM, Paul Stanton wrote:
>
> Didn't think there was a Jira yet, I'll try to get around to logging it
later this week.
>
> On 22/02/2012 8:38 AM, Howard Lewis Ship wrote:
>
> Patches are best provided on JIRA; there's a checkbox that shows you
> have granted the rights to the patch&  code to the Apache Software
> Foundation.  Thanks!
>
> On Tue, Feb 21, 2012 at 12:28 PM, Paul Stanton<p...@mapshed.com.au>
 wrote:
>
> Here's my implementation:
>
> // Copyright 2006, 2008, 2009, 2010, 2011 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;
>
> 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.ioc.annotations.Symbol;
> import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;
> import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
> import org.apache.tapestry5.services.ClasspathAssetAliasManager;
> import org.apache.tapestry5.services.Dispatcher;
> import org.apache.tapestry5.services.Request;
> import org.apache.tapestry5.services.Response;
> import org.apache.tapestry5.services.assets.AssetRequestHandler;
>
> /**
>  * Recognizes requests where the path begins with "/asset/" and delivers
the
> content therein as a bytestream. Also
>  * handles requests that are simply polling for a change to the file.
>  *
>  * @see ResourceStreamer
>  * @see ClasspathAssetAliasManager
>  * @see AssetRequestHandler
>  */
> // PATCHED incorrect APPLICATION_VERSION 302 temporary redirect to current
> APPLICATION_VERSION
>
> // PATCH +
> @SuppressWarnings("all")
> @UsesMappedConfiguration(AssetRequestHandler.class)
> public class AssetDispatcher implements Dispatcher
> {
>    /**
>     * Keyed on extended path name, which includes the pathPrefix first
and a
> trailing slash.
>     */
>    private final Map<String, AssetRequestHandler>  pathToHandler =
> CollectionFactory.newMap();
>
>    /**
>     * List of path prefixes in the pathToHandler, sorted be descending
> length.
>     */
>    private final List<String>  assetPaths = CollectionFactory.newList();
>
>    private final String pathPrefix;
>
>    // PATCH +
>    private final String pathPrefixPattern;
>
>    public AssetDispatcher(Map<String, AssetRequestHandler>  configuration,
>
>    @Symbol(SymbolConstants.APPLICATION_VERSION) String applicationVersion,
>
>    @Symbol(SymbolConstants.APPLICATION_FOLDER) String applicationFolder,
>
>    @Symbol(SymbolConstants.ASSET_PATH_PREFIX) String assetPathPrefix)
>    {
>        String folder = applicationFolder.equals("") ? "" : "/" +
> applicationFolder;
>
>        this.pathPrefix = folder + assetPathPrefix + applicationVersion +
> "/";
>
>        // PATCH +
>        this.pathPrefixPattern = "^" + folder + assetPathPrefix +
> "[^/]{1,}/(.*)$";
>
>        for (String path : configuration.keySet())
>        {
>            String extendedPath = this.pathPrefix + path + "/";
>
>            pathToHandler.put(extendedPath, configuration.get(path));
>
>            assetPaths.add(extendedPath);
>        }
>
>        // Sort by descending length
>
>        Collections.sort(assetPaths, new Comparator<String>()
>        {
>            public int compare(String o1, String o2)
>            {
>                return o2.length() - o1.length();
>            }
>        });

Reply via email to