Create a PathConstructor service, to encapsulate configuration logic about context path and application folder
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/b67b961c Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/b67b961c Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/b67b961c Branch: refs/heads/master Commit: b67b961c95881dfa81d3174bf98e71a40046055f Parents: 1dd33e1 Author: Howard M. Lewis Ship <[email protected]> Authored: Mon Jan 21 16:01:10 2013 -0800 Committer: Howard M. Lewis Ship <[email protected]> Committed: Tue Jan 22 10:30:54 2013 -0800 ---------------------------------------------------------------------- .../internal/services/PathConstructorImpl.java | 54 +++++++++++++++ .../javascript/ModuleAssetRequestHandler.java | 9 ++- .../apache/tapestry5/services/PathConstructor.java | 48 +++++++++++++ .../services/PathConstructorImplSpec.groovy | 27 +++++++ 4 files changed, 136 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b67b961c/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PathConstructorImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PathConstructorImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PathConstructorImpl.java new file mode 100644 index 0000000..d1e4f1b --- /dev/null +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PathConstructorImpl.java @@ -0,0 +1,54 @@ +package org.apache.tapestry5.internal.services; + +import org.apache.tapestry5.SymbolConstants; +import org.apache.tapestry5.ioc.annotations.Symbol; +import org.apache.tapestry5.services.PathConstructor; + +public class PathConstructorImpl implements PathConstructor +{ + private final String clientPrefix, dispatchPrefix; + + public PathConstructorImpl( + @Symbol(SymbolConstants.CONTEXT_PATH) String contextPath, + @Symbol(SymbolConstants.APPLICATION_FOLDER) String applicationFolder) + { + StringBuilder b = new StringBuilder("/"); + + if (applicationFolder.length() > 0) + { + b.append(applicationFolder); + b.append("/"); + } + + dispatchPrefix = b.toString(); + + clientPrefix = contextPath + dispatchPrefix; + } + + public String constructClientPath(String... terms) + { + return build(clientPrefix, terms); + } + + public String constructDispatchPath(String... terms) + { + return build(dispatchPrefix, terms); + } + + private String build(String prefix, String... terms) + { + StringBuilder b = new StringBuilder(prefix); + String sep = ""; + + for (String term : terms) + { + b.append(sep); + b.append(term); + + sep = "/"; + } + + + return b.toString(); + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b67b961c/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 index 7506ec5..1d6a1b7 100644 --- 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 @@ -16,10 +16,10 @@ 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.internal.util.Holder; 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.Request; import org.apache.tapestry5.services.Response; import org.apache.tapestry5.services.assets.AssetRequestHandler; @@ -31,7 +31,7 @@ import java.io.IOException; * Handler contributed to {@link AssetDispatcher} with key "modules". It interprets the extra path as a module name, * and searches for the corresponding JavaScript module. */ -public class ModuleAssetRequestHandler implements AssetRequestHandler +public class ModuleAssetRequestHandler implements AssetRequestHandler, Dispatcher { private final ModuleManager moduleManager; @@ -46,6 +46,11 @@ public class ModuleAssetRequestHandler implements AssetRequestHandler this.tracker = tracker; } + public boolean dispatch(Request request, Response response) throws IOException + { + return false; + } + 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 http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b67b961c/tapestry-core/src/main/java/org/apache/tapestry5/services/PathConstructor.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/PathConstructor.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/PathConstructor.java new file mode 100644 index 0000000..b6ccb3e --- /dev/null +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/PathConstructor.java @@ -0,0 +1,48 @@ +// Copyright 2013 The Apache Software Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.apache.tapestry5.services; + +/** + * Central location for logic related to building client-side paths, taking into account + * the context path (if any), and the {@link org.apache.tapestry5.SymbolConstants#APPLICATION_FOLDER} + * (if any). + * + * @since 5.4 + */ +public interface PathConstructor +{ + /** + * Constructs a client path, the path portion of an absolute URL. The result consists of the + * the context path (if any), the application folder (if any), then the series of terms. + * + * @param terms + * additional terms (folder names, or a file name) following the context path and application folder. + * @return the full path, starting with a leading slash, and including the context path, application folder, and the terms, + * all seperated with slashes + */ + String constructClientPath(String... terms); + + /** + * Constructs the dispatch path, which is like the client path, but omits the context path; this aligns + * the result with the value returned from {@link org.apache.tapestry5.services.Request#getPath()}, and is used + * in code, typically {@link Dispatcher} implementations, that are attempting to route based on the incoming request path. + * + * @param terms + * additional terms (folder names, or a file name) following the context path and application folder. + * @return path string starting with a leading slash, and including the application folder (if any) and the individual terms, + * seperated by slashes + */ + String constructDispatchPath(String... terms); +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b67b961c/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/PathConstructorImplSpec.groovy ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/PathConstructorImplSpec.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/PathConstructorImplSpec.groovy new file mode 100644 index 0000000..53166cc --- /dev/null +++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/PathConstructorImplSpec.groovy @@ -0,0 +1,27 @@ +package org.apache.tapestry5.internal.services + +import org.testng.Assert +import org.testng.annotations.DataProvider +import org.testng.annotations.Test + +class PathConstructorImplSpec extends Assert { + + @DataProvider + Object[][] data() { + return [ + ["", "", "/foo/bar", "/foo/bar"], + ["", "myapp", "/myapp/foo/bar", "/myapp/foo/bar"], + ["/ctx", "", "/ctx/foo/bar", "/foo/bar"], + ["/ctx", "myapp", "/ctx/myapp/foo/bar", "/myapp/foo/bar"] + ] as Object[][] + } + + + @Test(dataProvider = "data") + void doTest(String contextPath, String appFolder, String expectedClientPath, String expectedDispatchPath) { + def pc = new PathConstructorImpl(contextPath, appFolder) + + assert pc.constructClientPath("foo", "bar") == expectedClientPath + assert pc.constructDispatchPath("foo", "bar") == expectedDispatchPath + } +}
