From d6ce5b79c453da63e392f4ccfeed6dfc7a4c578f Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sat, 2 Mar 2019 17:41:18 +0100 Subject: [PATCH 1/6] Add routing behavior DEFAULT, NOT_FOUND, REDIRECT --- .../java/org/tynamo/routing/Behavior.java | 6 +++++ src/main/java/org/tynamo/routing/Route.java | 13 ++++++---- .../org/tynamo/routing/annotations/At.java | 3 +++ .../org/tynamo/routing/annotations/Route.java | 3 +++ .../tynamo/routing/services/RouteFactory.java | 5 ++-- .../routing/services/RouteFactoryImpl.java | 9 ++++--- .../tynamo/routing/services/RouteWorker.java | 6 ++++- .../routing/services/RouterDispatcher.java | 25 +++++++++++++++++-- .../services/RouterLinkTransformer.java | 12 +++------ .../routing/services/RoutingModule.java | 2 +- 10 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 src/main/java/org/tynamo/routing/Behavior.java diff --git a/src/main/java/org/tynamo/routing/Behavior.java b/src/main/java/org/tynamo/routing/Behavior.java new file mode 100644 index 0000000..929fdc7 --- /dev/null +++ b/src/main/java/org/tynamo/routing/Behavior.java @@ -0,0 +1,6 @@ + +package org.tynamo.routing; + +public enum Behavior { + DEFAULT, REDIRECT, NOT_FOUND +} \ No newline at end of file diff --git a/src/main/java/org/tynamo/routing/Route.java b/src/main/java/org/tynamo/routing/Route.java index 6b98112..935bff2 100644 --- a/src/main/java/org/tynamo/routing/Route.java +++ b/src/main/java/org/tynamo/routing/Route.java @@ -12,13 +12,14 @@ public class Route { private static final String URI_PARAM_REGEX = "\\{\\s*(" + URI_PARAM_NAME_REGEX + ")\\s*(:\\s*(" + URI_PARAM_REGEX_REGEX + "))?\\}"; private static final Pattern URI_PARAM_PATTERN = Pattern.compile(URI_PARAM_REGEX); - private final String canonicalizedPageName; private final String pathExpression; + private final String canonicalizedPageName; + private final Behavior behavior; private final Pattern pattern; - public Route(final String pathExpression, final String canonicalizedPageName) { - + public Route(final String pathExpression, final String canonicalizedPageName, final Behavior behavior) { this.canonicalizedPageName = canonicalizedPageName; + this.behavior = behavior; // remove ending slash unless it's the root path this.pathExpression = pathExpression.length() > 1 && pathExpression.charAt(pathExpression.length() - 1) == SLASH ? pathExpression.substring(0, pathExpression.length() - 1) : pathExpression; @@ -31,11 +32,9 @@ public Route(final String pathExpression, final String canonicalizedPageName) { String regex = buildExpression(this.pathExpression); pattern = Pattern.compile(regex); - } static String buildExpression(String expression) { - String[] split = URI_PARAM_PATTERN.split(expression); Matcher withPathParam = URI_PARAM_PATTERN.matcher(expression); int i = 0; @@ -66,6 +65,10 @@ public String getCanonicalizedPageName() { return canonicalizedPageName; } + public Behavior getBehavior() { + return behavior; + } + public Pattern getPattern() { return pattern; } diff --git a/src/main/java/org/tynamo/routing/annotations/At.java b/src/main/java/org/tynamo/routing/annotations/At.java index 9721367..b469c2c 100644 --- a/src/main/java/org/tynamo/routing/annotations/At.java +++ b/src/main/java/org/tynamo/routing/annotations/At.java @@ -5,6 +5,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.tynamo.routing.Behavior; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @@ -12,6 +13,8 @@ String value(); + Behavior behavior() default Behavior.DEFAULT; + String[] order() default {}; } diff --git a/src/main/java/org/tynamo/routing/annotations/Route.java b/src/main/java/org/tynamo/routing/annotations/Route.java index 7392b05..47a2b0f 100644 --- a/src/main/java/org/tynamo/routing/annotations/Route.java +++ b/src/main/java/org/tynamo/routing/annotations/Route.java @@ -5,6 +5,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.tynamo.routing.Behavior; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @@ -12,6 +13,8 @@ String value(); + Behavior behavior() default Behavior.DEFAULT; + String[] order() default {}; } diff --git a/src/main/java/org/tynamo/routing/services/RouteFactory.java b/src/main/java/org/tynamo/routing/services/RouteFactory.java index cd3f231..8461e8c 100644 --- a/src/main/java/org/tynamo/routing/services/RouteFactory.java +++ b/src/main/java/org/tynamo/routing/services/RouteFactory.java @@ -1,12 +1,13 @@ package org.tynamo.routing.services; import org.tynamo.routing.Route; +import org.tynamo.routing.Behavior; public interface RouteFactory { - Route create(String pathExpression, String canonicalized); + Route create(String pathExpression, String canonicalized, Behavior behavior); @Deprecated - Route create(String pathExpression, Class page); + Route create(String pathExpression, Class page, Behavior behavior); } diff --git a/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java b/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java index c2c00d4..54c7f93 100644 --- a/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java +++ b/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java @@ -2,6 +2,7 @@ import org.apache.tapestry5.services.ComponentClassResolver; import org.tynamo.routing.Route; +import org.tynamo.routing.Behavior; public class RouteFactoryImpl implements RouteFactory { @@ -12,14 +13,14 @@ public RouteFactoryImpl(ComponentClassResolver componentClassResolver) { } @Override - public Route create(String pathExpression, String canonicalized) { - return new Route(pathExpression, canonicalized); + public Route create(String pathExpression, String canonicalized, Behavior behavior) { + return new Route(pathExpression, canonicalized, behavior); } @Override - public Route create(String pathExpression, Class page) { + public Route create(String pathExpression, Class page, Behavior behavior) { String pageName = componentClassResolver.resolvePageClassNameToPageName(page.getName()); String canonicalized = componentClassResolver.canonicalizePageName(pageName); - return create(pathExpression, canonicalized); + return create(pathExpression, canonicalized, behavior); } } diff --git a/src/main/java/org/tynamo/routing/services/RouteWorker.java b/src/main/java/org/tynamo/routing/services/RouteWorker.java index 82c41e2..9280fbc 100644 --- a/src/main/java/org/tynamo/routing/services/RouteWorker.java +++ b/src/main/java/org/tynamo/routing/services/RouteWorker.java @@ -7,6 +7,7 @@ import org.apache.tapestry5.services.transform.TransformationSupport; import org.tynamo.routing.annotations.At; import org.tynamo.routing.annotations.Route; +import org.tynamo.routing.Behavior; public class RouteWorker implements ComponentClassTransformWorker2 { @@ -25,14 +26,17 @@ public void transform(PlasticClass plasticClass, TransformationSupport support, String pathExpression = null; String[] order = {}; + Behavior behavior = Behavior.DEFAULT; if (plasticClass.hasAnnotation(At.class)) { At ann = plasticClass.getAnnotation(At.class); pathExpression = ann.value(); + behavior = ann.behavior(); order = ann.order(); } else if (plasticClass.hasAnnotation(Route.class)) { Route ann = plasticClass.getAnnotation(Route.class); pathExpression = ann.value(); + behavior = ann.behavior(); order = ann.order(); } @@ -40,7 +44,7 @@ public void transform(PlasticClass plasticClass, TransformationSupport support, String pageName = componentClassResolver.resolvePageClassNameToPageName(plasticClass.getClassName()); String canonicalized = componentClassResolver.canonicalizePageName(pageName); - org.tynamo.routing.Route route = routeFactory.create(pathExpression, canonicalized); + org.tynamo.routing.Route route = routeFactory.create(pathExpression, canonicalized, behavior); annotatedPagesManager.add(route, order); } diff --git a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java index 25c8748..dc09657 100644 --- a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java +++ b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java @@ -6,16 +6,20 @@ import java.io.IOException; +import org.tynamo.routing.Route; + /** * The router dispatcher recognizes incoming requests and transforms them into page render requests. */ public class RouterDispatcher implements Dispatcher { private final ComponentRequestHandler componentRequestHandler; + private final ComponentEventLinkEncoder linkEncoder; private final RouteSource routeSource; - public RouterDispatcher(ComponentRequestHandler componentRequestHandler, RouteSource routeSource) { + public RouterDispatcher(ComponentRequestHandler componentRequestHandler, ComponentEventLinkEncoder linkEncoder, RouteSource routeSource) { this.componentRequestHandler = componentRequestHandler; + this.linkEncoder = linkEncoder; this.routeSource = routeSource; } @@ -26,6 +30,23 @@ public boolean dispatch(Request request, final Response response) throws IOExcep componentRequestHandler.handlePageRender(parameters); return true; } - return false; + + parameters = linkEncoder.decodePageRenderRequest(request); + if (parameters == null) return false; + + Route route = routeSource.getRoute(parameters.getLogicalPageName()); + if (route == null) return false; + + switch (route.getBehavior()) { + case REDIRECT: + response.sendRedirect(linkEncoder.createPageRenderLink(parameters).toAbsoluteURI()); + return true; + case NOT_FOUND: + response.sendError(404, "Not Found"); + return true; + case DEFAULT: + default: + return false; + } } } \ No newline at end of file diff --git a/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java b/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java index 9c0c678..cd395a5 100644 --- a/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java +++ b/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java @@ -17,6 +17,7 @@ public class RouterLinkTransformer implements PageRenderLinkTransformer { private static final char SLASH = '/'; + private static final int BUFFER_SIZE = 100; private final RouteSource routeSource; private final Request request; @@ -24,12 +25,10 @@ public class RouterLinkTransformer implements PageRenderLinkTransformer { private final Response response; private final ContextPathEncoder contextPathEncoder; private final BaseURLSource baseURLSource; + private final PersistentLocale persistentLocale; + private final boolean encodeLocaleIntoPath; private final String applicationFolder; - private static final int BUFFER_SIZE = 100; - private PersistentLocale persistentLocale; - private boolean encodeLocaleIntoPath; - public RouterLinkTransformer(RouteSource routeSource, Request request, RequestSecurityManager requestSecurityManager, Response response, @@ -54,7 +53,6 @@ public PageRenderRequestParameters decodePageRenderRequest(Request request) { } public Link transformPageRenderLink(Link defaultLink, PageRenderRequestParameters parameters) { - String activePageName = parameters.getLogicalPageName(); Route route = routeSource.getRoute(activePageName); @@ -86,8 +84,7 @@ public Link transformPageRenderLink(Link defaultLink, PageRenderRequestParameter return null; } - private void encodeAppFolderAndLocale(StringBuilder builder) - { + private void encodeAppFolderAndLocale(StringBuilder builder) { if (!applicationFolder.equals("")) { builder.append(SLASH).append(applicationFolder); @@ -106,7 +103,6 @@ private void encodeAppFolderAndLocale(StringBuilder builder) } private String[] encode(EventContext context) { - assert context != null; int count = context.getCount(); diff --git a/src/main/java/org/tynamo/routing/services/RoutingModule.java b/src/main/java/org/tynamo/routing/services/RoutingModule.java index 4b898bc..2c4aece 100644 --- a/src/main/java/org/tynamo/routing/services/RoutingModule.java +++ b/src/main/java/org/tynamo/routing/services/RoutingModule.java @@ -33,7 +33,7 @@ public static void provideURLRewriting(OrderedConfiguration configuration, @Autobuild RouterDispatcher dispatcher) { - configuration.add(RouterDispatcher.class.getSimpleName(), dispatcher, "after:PageRender"); + configuration.add(RouterDispatcher.class.getSimpleName(), dispatcher, "after:ComponentEvent", "before:PageRender"); } @Contribute(SymbolProvider.class) From f7c6423e61921f25d982c759020a866ec201df9f Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sun, 3 Mar 2019 03:23:39 +0100 Subject: [PATCH 2/6] Add tests and fix routing logic --- .../routing/services/RouterDispatcher.java | 39 ++-- .../java/org/tynamo/routing/RouteTest.java | 183 ++++++++++++++++-- .../tynamo/routing/modules/TestsModule.java | 6 +- .../routing/pages/NotFoundBehavior.java | 9 + .../routing/pages/RedirectBehavior.java | 9 + .../pages/subpackage/SubPageFirst.java | 1 - .../pages/subpackageWithIndex/Index.java | 9 + .../subpackageWithIndex/SubPackageMain.java | 9 + ...RouterDispatcherWithAutoDiscoveryTest.java | 2 +- .../SubPage.tml => NotFoundBehavior.tml} | 0 .../tynamo/routing/pages/RedirectBehavior.tml | 1 + .../routing/pages/subpackage/SubPage1.tml | 1 + .../pages/subpackageWithIndex/Index.tml | 1 + .../subpackageWithIndex/SubPackageMain.tml | 1 + 14 files changed, 239 insertions(+), 32 deletions(-) create mode 100644 src/test/java/org/tynamo/routing/pages/NotFoundBehavior.java create mode 100644 src/test/java/org/tynamo/routing/pages/RedirectBehavior.java create mode 100644 src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java create mode 100644 src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java rename src/test/resources/org/tynamo/routing/pages/{subpackage/SubPage.tml => NotFoundBehavior.tml} (100%) create mode 100644 src/test/resources/org/tynamo/routing/pages/RedirectBehavior.tml create mode 100644 src/test/resources/org/tynamo/routing/pages/subpackage/SubPage1.tml create mode 100644 src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml create mode 100644 src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml diff --git a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java index dc09657..8abe99f 100644 --- a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java +++ b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java @@ -7,6 +7,7 @@ import java.io.IOException; import org.tynamo.routing.Route; +import org.tynamo.routing.Behavior; /** * The router dispatcher recognizes incoming requests and transforms them into page render requests. @@ -17,26 +18,42 @@ public class RouterDispatcher implements Dispatcher { private final ComponentEventLinkEncoder linkEncoder; private final RouteSource routeSource; - public RouterDispatcher(ComponentRequestHandler componentRequestHandler, ComponentEventLinkEncoder linkEncoder, RouteSource routeSource) { + public RouterDispatcher(final ComponentRequestHandler componentRequestHandler, final ComponentEventLinkEncoder linkEncoder, final RouteSource routeSource) { this.componentRequestHandler = componentRequestHandler; this.linkEncoder = linkEncoder; this.routeSource = routeSource; } @Log - public boolean dispatch(Request request, final Response response) throws IOException { - PageRenderRequestParameters parameters = routeSource.decodePageRenderRequest(request); - if (parameters != null) { - componentRequestHandler.handlePageRender(parameters); - return true; - } + public boolean dispatch(final Request request, final Response response) throws IOException { + PageRenderRequestParameters pageParameters = linkEncoder.decodePageRenderRequest(request); + PageRenderRequestParameters routeParameters = routeSource.decodePageRenderRequest(request); + Route pageParametersRoute = pageParameters == null ? null : routeSource.getRoute(pageParameters.getLogicalPageName()); + Route routeParametersRoute = routeParameters == null ? null : routeSource.getRoute(routeParameters.getLogicalPageName()); - parameters = linkEncoder.decodePageRenderRequest(request); - if (parameters == null) return false; + if (pageParameters != null && pageParametersRoute == null) { + return false; + } + if (pageParameters != null && pageParametersRoute != null && !pageParameters.getLogicalPageName().endsWith("Index")) { + return handleRoute(pageParametersRoute, pageParameters, request, response); + } + if (routeParametersRoute != null) { + boolean handled = handleRoute(routeParametersRoute, routeParameters, request, response); + if (handled) return true; + } + if (pageParametersRoute != null) { + boolean handled = handleRoute(pageParametersRoute, pageParameters, request, response); + if (handled) return true; + } - Route route = routeSource.getRoute(parameters.getLogicalPageName()); - if (route == null) return false; + return false; + } + private boolean handleRoute(Route route, PageRenderRequestParameters parameters, Request request, Response response) throws IOException { + if (route.getPattern().matcher(request.getPath()).matches()) { + componentRequestHandler.handlePageRender(parameters); + return true; + } switch (route.getBehavior()) { case REDIRECT: response.sendRedirect(linkEncoder.createPageRenderLink(parameters).toAbsoluteURI()); diff --git a/src/test/java/org/tynamo/routing/RouteTest.java b/src/test/java/org/tynamo/routing/RouteTest.java index e254d46..5d80a1e 100644 --- a/src/test/java/org/tynamo/routing/RouteTest.java +++ b/src/test/java/org/tynamo/routing/RouteTest.java @@ -5,6 +5,7 @@ import org.apache.tapestry5.internal.services.PageRenderDispatcher; import org.apache.tapestry5.ioc.RegistryBuilder; import org.apache.tapestry5.services.*; +import org.apache.tapestry5.Link; import org.easymock.Capture; import org.easymock.EasyMock; import org.testng.Assert; @@ -27,6 +28,8 @@ public class RouteTest extends RoutingTestCase { + private static final String SERVER_NAME = "test"; + private static final int SERVER_PORT = 8080; private static final String EMPTY_PATH = ""; private static final int NO_CONTEXT = 0; private static final String APPLICATION_FOLDER = ""; @@ -39,7 +42,6 @@ protected void addAdditionalModules(RegistryBuilder builder) { @Test public void regular_expressions() { - String path = "/foo/52"; String routeExpression = Route.buildExpression("/foo/{0}"); @@ -62,7 +64,7 @@ public void regular_expressions() { @Test public void decode_page_render_request() { - Route route = routeFactory.create(SimplePage.class.getAnnotation(At.class).value(), SimplePage.class.getSimpleName()); + Route route = routeFactory.create(SimplePage.class.getAnnotation(At.class).value(), SimplePage.class.getSimpleName(), Behavior.DEFAULT); Request request = mockRequest(); expect(request.getPath()).andReturn("/foo/45/bar/24").atLeastOnce(); @@ -75,7 +77,6 @@ public void decode_page_render_request() { Assert.assertEquals(parameters.getActivationContext().getCount(), 2); Assert.assertEquals(parameters.getActivationContext().get(Integer.class, 0).intValue(), 45); Assert.assertEquals(parameters.getActivationContext().get(Integer.class, 1).intValue(), 24); - } @Test @@ -165,30 +166,61 @@ public void link_to_unannotatedpage() { @Test public void order() throws IOException { + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); - Request request = mockRequest(); - expect(request.getPath()).andReturn("/subpackage/inventedpath").atLeastOnce(); + RouterDispatcher routerDispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + Request request = mockRequest(); + Response response = null; PageRenderRequestParameters expectedParameters = new PageRenderRequestParameters("subpackage/SubPageFirst", new EmptyEventContext(), false); - ComponentRequestHandler requestHandler = mockComponentRequestHandler(); - requestHandler.handlePageRender(expectedParameters); - RouterDispatcher routerDispatcher = new RouterDispatcher(requestHandler, routeSource); + expect(request.getPath()).andReturn("/subpackage/inventedpath").atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); + requestHandler.handlePageRender(expectedParameters); replay(); + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + routerDispatcher.dispatch(request, null); verify(); } @Test - public void PageRender_precedence_over_RouterDispatcher() throws IOException { + public void page_without_route_is_not_dispatched() throws IOException { + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + + Request request = mockRequest(); + Response response = null; + + expect(request.getPath()).andReturn("/subpackage/unannotated").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); + + EasyMock.expectLastCall(); + + replay(); + + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + Assert.assertFalse(dispatcher.dispatch(request, response), "Unannotated page should not be dispatched"); + + verify(); + } + + @Test + public void page_precede_over_route() throws IOException { ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); - ComponentRequestHandler handler = mockComponentRequestHandler(); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); - Dispatcher dispatcher = new PageRenderDispatcher(handler, linkEncoder); + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); Request request = mockRequest(); Response response = null; @@ -196,11 +228,133 @@ public void PageRender_precedence_over_RouterDispatcher() throws IOException { expect(request.getPath()).andReturn("/home").atLeastOnce(); expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); - expect(request.getAttribute(InternalConstants.REFERENCED_COMPONENT_NOT_FOUND)).andReturn(null).once(); + + EasyMock.expectLastCall(); + + replay(); + + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + + Assert.assertFalse(dispatcher.dispatch(request, response), "Home page should take precedence over the '/home' route in the Inaccessible page"); + + verify(); + } + + @Test + public void route_precede_over_index() throws IOException { + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + + Request request = mockRequest(); + Response response = null; + + expect(request.getPath()).andReturn("/subpackageWithIndex/SubPackageMain").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); Capture parameters = newCapture(); - handler.handlePageRender(EasyMock.capture(parameters)); EasyMock.expectLastCall(); + requestHandler.handlePageRender(EasyMock.capture(parameters)); + EasyMock.expectLastCall(); + + replay(); + + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + + Assert.assertTrue(dispatcher.dispatch(request, response), "SubPackageMain should take precedence over the subpackageWithIndex/Index page"); + Assert.assertEquals(parameters.getValue().getLogicalPageName(), "subpackageWithIndex/SubPackageMain", "SubPackageMain should take precedence over the subpackageWithIndex/Index page"); + + verify(); + } + + @Test + public void route_path_is_dispatched() throws IOException { + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + + Request request = mockRequest(); + Response response = null; + + expect(request.getPath()).andReturn("/foo/0/bar/1").atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); + + Capture parameters = newCapture(); + + requestHandler.handlePageRender(EasyMock.capture(parameters)); + EasyMock.expectLastCall(); + + replay(); + + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + + Assert.assertTrue(dispatcher.dispatch(request, response), "SimplePage route should be dispatched"); + Assert.assertEquals(parameters.getValue().getLogicalPageName(), "Simple", "SimplePage route should be dispatched"); + + verify(); + } + + @Test + public void redirect_behavior() throws IOException { + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + + Request request = mockRequest(); + Response response = mockResponse(); + String expectedURL = String.format("https://%s:%d/redirect-behavior", SERVER_NAME, SERVER_PORT); + + expect(request.getPath()).andReturn("/redirectbehavior").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); + expect(request.isSecure()).andReturn(true).atLeastOnce(); + expect(request.getContextPath()).andReturn(EMPTY_PATH).atLeastOnce(); + expect(request.getServerName()).andReturn(SERVER_NAME).atLeastOnce(); + expect(request.getServerPort()).andReturn(SERVER_PORT).atLeastOnce(); + expect(response.encodeURL(expectedURL)).andReturn(expectedURL).atLeastOnce(); + + Capture url = newCapture(); + + response.sendRedirect(EasyMock.capture(url)); + EasyMock.expectLastCall(); + + replay(); + + RequestGlobals globals = registry.getService(RequestGlobals.class); + globals.storeRequestResponse(request, response); + + Assert.assertTrue(dispatcher.dispatch(request, response)); + Assert.assertEquals(url.getValue(), expectedURL, "Redirect behavior is applied when page default convention path is provided"); + + verify(); + } + + @Test + public void not_found_behavior() throws IOException { + ComponentEventLinkEncoder linkEncoder = getService(ComponentEventLinkEncoder.class); + ComponentRequestHandler requestHandler = mockComponentRequestHandler(); + + Dispatcher dispatcher = new RouterDispatcher(requestHandler, linkEncoder, routeSource); + + Request request = mockRequest(); + Response response = mockResponse(); + + expect(request.getPath()).andReturn("/notfoundbehavior").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); + expect(request.getLocale()).andReturn(FI).atLeastOnce(); + + Capture errorCode = newCapture(); + Capture message = newCapture(); + + response.sendError(EasyMock.captureInt(errorCode), EasyMock.capture(message)); + EasyMock.expectLastCall(); replay(); @@ -208,8 +362,7 @@ public void PageRender_precedence_over_RouterDispatcher() throws IOException { globals.storeRequestResponse(request, response); Assert.assertTrue(dispatcher.dispatch(request, response)); - Assert.assertEquals(parameters.getValue().getLogicalPageName(), "Home", "Home page should take precedence over the '/home' route in the Inaccessible page"); - Assert.assertEquals(parameters.getValue().getActivationContext().getCount(), 0); + Assert.assertEquals((int) errorCode.getValue(), 404, "Not found behavior is applied when page default convention path is provided"); verify(); } diff --git a/src/test/java/org/tynamo/routing/modules/TestsModule.java b/src/test/java/org/tynamo/routing/modules/TestsModule.java index 808685c..2ed8bf6 100644 --- a/src/test/java/org/tynamo/routing/modules/TestsModule.java +++ b/src/test/java/org/tynamo/routing/modules/TestsModule.java @@ -11,6 +11,7 @@ import org.apache.tapestry5.ioc.services.ApplicationDefaults; import org.apache.tapestry5.ioc.services.SymbolProvider; import org.tynamo.routing.Route; +import org.tynamo.routing.Behavior; import org.tynamo.routing.services.RouteFactory; import org.tynamo.routing.services.RouteProvider; @@ -28,10 +29,7 @@ public static void provideApplicationDefaults(MappedConfiguration configuration, RouteFactory routeFactory) { - String canonicalized = "subpackage/Unannotated"; - configuration.add(canonicalized.toLowerCase(), routeFactory.create("/not/annotated/{0}", canonicalized)); - + configuration.add(canonicalized.toLowerCase(), routeFactory.create("/not/annotated/{0}", canonicalized, Behavior.DEFAULT)); } - } \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/pages/NotFoundBehavior.java b/src/test/java/org/tynamo/routing/pages/NotFoundBehavior.java new file mode 100644 index 0000000..8eb4414 --- /dev/null +++ b/src/test/java/org/tynamo/routing/pages/NotFoundBehavior.java @@ -0,0 +1,9 @@ +package org.tynamo.routing.pages; + +import org.tynamo.routing.annotations.At; +import org.tynamo.routing.Behavior; + +@At(value = "/not-found-behavior/", behavior = Behavior.NOT_FOUND) +public class NotFoundBehavior { + protected void onActivate() {} +} \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/pages/RedirectBehavior.java b/src/test/java/org/tynamo/routing/pages/RedirectBehavior.java new file mode 100644 index 0000000..9508ce7 --- /dev/null +++ b/src/test/java/org/tynamo/routing/pages/RedirectBehavior.java @@ -0,0 +1,9 @@ +package org.tynamo.routing.pages; + +import org.tynamo.routing.annotations.At; +import org.tynamo.routing.Behavior; + +@At(value = "/redirect-behavior", behavior = Behavior.REDIRECT) +public class RedirectBehavior { + protected void onActivate() {} +} \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/pages/subpackage/SubPageFirst.java b/src/test/java/org/tynamo/routing/pages/subpackage/SubPageFirst.java index a87c348..5b7c8d7 100644 --- a/src/test/java/org/tynamo/routing/pages/subpackage/SubPageFirst.java +++ b/src/test/java/org/tynamo/routing/pages/subpackage/SubPageFirst.java @@ -1,6 +1,5 @@ package org.tynamo.routing.pages.subpackage; - import org.tynamo.routing.annotations.At; @At(value = "/subpackage/inventedpath", order = "before:subpackage/SubPage1") diff --git a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java b/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java new file mode 100644 index 0000000..cde5311 --- /dev/null +++ b/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java @@ -0,0 +1,9 @@ +package org.tynamo.routing.pages.subpackageWithIndex; + +import org.tynamo.routing.annotations.At; + +@At("/subpackageWithIndex") +public class Index { + protected void onActivate() { + } +} \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java b/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java new file mode 100644 index 0000000..ea800fa --- /dev/null +++ b/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java @@ -0,0 +1,9 @@ +package org.tynamo.routing.pages.subpackageWithIndex; + +import org.tynamo.routing.annotations.At; + +@At("/subpackageWithIndex/SubPackageMain") +public class SubPackageMain { + protected void onActivate() { + } +} \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java b/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java index fa04a6a..2524b02 100644 --- a/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java +++ b/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java @@ -20,7 +20,7 @@ public void auto_discovery_enabled() { Registry registry = getRegistry(TapestryModule.class, RoutingModule.class, TestsModule.class); AnnotatedPagesManager provider = registry.getService(AnnotatedPagesManager.class); - Assert.assertEquals(provider.getRoutes().size(), 7, "there are seven pages with Routes in org/tynamo/routing"); + Assert.assertEquals(provider.getRoutes().size(), 11, "there are eleven pages with Routes in org/tynamo/routing"); registry.cleanupThread(); registry.shutdown(); diff --git a/src/test/resources/org/tynamo/routing/pages/subpackage/SubPage.tml b/src/test/resources/org/tynamo/routing/pages/NotFoundBehavior.tml similarity index 100% rename from src/test/resources/org/tynamo/routing/pages/subpackage/SubPage.tml rename to src/test/resources/org/tynamo/routing/pages/NotFoundBehavior.tml diff --git a/src/test/resources/org/tynamo/routing/pages/RedirectBehavior.tml b/src/test/resources/org/tynamo/routing/pages/RedirectBehavior.tml new file mode 100644 index 0000000..1f551ea --- /dev/null +++ b/src/test/resources/org/tynamo/routing/pages/RedirectBehavior.tml @@ -0,0 +1 @@ + diff --git a/src/test/resources/org/tynamo/routing/pages/subpackage/SubPage1.tml b/src/test/resources/org/tynamo/routing/pages/subpackage/SubPage1.tml new file mode 100644 index 0000000..1f551ea --- /dev/null +++ b/src/test/resources/org/tynamo/routing/pages/subpackage/SubPage1.tml @@ -0,0 +1 @@ + diff --git a/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml b/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml new file mode 100644 index 0000000..1f551ea --- /dev/null +++ b/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml @@ -0,0 +1 @@ + diff --git a/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml b/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml new file mode 100644 index 0000000..1f551ea --- /dev/null +++ b/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml @@ -0,0 +1 @@ + From d0b7af7d22887051475aa3eb66c52c94634869dd Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sun, 3 Mar 2019 03:52:06 +0100 Subject: [PATCH 3/6] Test changes --- src/test/java/org/tynamo/routing/RouteTest.java | 14 ++++++++------ .../pages/{subpackageWithIndex => }/Index.java | 4 ++-- .../pages/subpackageWithIndex/SubPackageMain.java | 9 --------- .../RouterDispatcherWithAutoDiscoveryTest.java | 2 +- .../Index.tml => Inaccessible.tml} | 0 .../SubPackageMain.tml => Index.tml} | 0 6 files changed, 11 insertions(+), 18 deletions(-) rename src/test/java/org/tynamo/routing/pages/{subpackageWithIndex => }/Index.java (54%) delete mode 100644 src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java rename src/test/resources/org/tynamo/routing/pages/{subpackageWithIndex/Index.tml => Inaccessible.tml} (100%) rename src/test/resources/org/tynamo/routing/pages/{subpackageWithIndex/SubPackageMain.tml => Index.tml} (100%) diff --git a/src/test/java/org/tynamo/routing/RouteTest.java b/src/test/java/org/tynamo/routing/RouteTest.java index 5d80a1e..1b07772 100644 --- a/src/test/java/org/tynamo/routing/RouteTest.java +++ b/src/test/java/org/tynamo/routing/RouteTest.java @@ -176,6 +176,7 @@ public void order() throws IOException { PageRenderRequestParameters expectedParameters = new PageRenderRequestParameters("subpackage/SubPageFirst", new EmptyEventContext(), false); expect(request.getPath()).andReturn("/subpackage/inventedpath").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); requestHandler.handlePageRender(expectedParameters); @@ -251,7 +252,7 @@ public void route_precede_over_index() throws IOException { Request request = mockRequest(); Response response = null; - expect(request.getPath()).andReturn("/subpackageWithIndex/SubPackageMain").atLeastOnce(); + expect(request.getPath()).andReturn("/foo/0/bar/1").atLeastOnce(); expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); @@ -265,8 +266,8 @@ public void route_precede_over_index() throws IOException { RequestGlobals globals = registry.getService(RequestGlobals.class); globals.storeRequestResponse(request, response); - Assert.assertTrue(dispatcher.dispatch(request, response), "SubPackageMain should take precedence over the subpackageWithIndex/Index page"); - Assert.assertEquals(parameters.getValue().getLogicalPageName(), "subpackageWithIndex/SubPackageMain", "SubPackageMain should take precedence over the subpackageWithIndex/Index page"); + Assert.assertTrue(dispatcher.dispatch(request, response), "Simple should take precedence over the Index page"); + Assert.assertEquals(parameters.getValue().getLogicalPageName(), "Simple", "Simple should take precedence over the Index page"); verify(); } @@ -281,7 +282,8 @@ public void route_path_is_dispatched() throws IOException { Request request = mockRequest(); Response response = null; - expect(request.getPath()).andReturn("/foo/0/bar/1").atLeastOnce(); + expect(request.getPath()).andReturn("/subpackage").atLeastOnce(); + expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); Capture parameters = newCapture(); @@ -294,8 +296,8 @@ public void route_path_is_dispatched() throws IOException { RequestGlobals globals = registry.getService(RequestGlobals.class); globals.storeRequestResponse(request, response); - Assert.assertTrue(dispatcher.dispatch(request, response), "SimplePage route should be dispatched"); - Assert.assertEquals(parameters.getValue().getLogicalPageName(), "Simple", "SimplePage route should be dispatched"); + Assert.assertTrue(dispatcher.dispatch(request, response), "SubPackageMain route should be dispatched"); + Assert.assertEquals(parameters.getValue().getLogicalPageName(), "subpackage/Main", "SubPackageMain route should be dispatched"); verify(); } diff --git a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java b/src/test/java/org/tynamo/routing/pages/Index.java similarity index 54% rename from src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java rename to src/test/java/org/tynamo/routing/pages/Index.java index cde5311..a400608 100644 --- a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/Index.java +++ b/src/test/java/org/tynamo/routing/pages/Index.java @@ -1,8 +1,8 @@ -package org.tynamo.routing.pages.subpackageWithIndex; +package org.tynamo.routing.pages; import org.tynamo.routing.annotations.At; -@At("/subpackageWithIndex") +@At("/root-index") public class Index { protected void onActivate() { } diff --git a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java b/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java deleted file mode 100644 index ea800fa..0000000 --- a/src/test/java/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.tynamo.routing.pages.subpackageWithIndex; - -import org.tynamo.routing.annotations.At; - -@At("/subpackageWithIndex/SubPackageMain") -public class SubPackageMain { - protected void onActivate() { - } -} \ No newline at end of file diff --git a/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java b/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java index 2524b02..58192cc 100644 --- a/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java +++ b/src/test/java/org/tynamo/routing/services/RouterDispatcherWithAutoDiscoveryTest.java @@ -20,7 +20,7 @@ public void auto_discovery_enabled() { Registry registry = getRegistry(TapestryModule.class, RoutingModule.class, TestsModule.class); AnnotatedPagesManager provider = registry.getService(AnnotatedPagesManager.class); - Assert.assertEquals(provider.getRoutes().size(), 11, "there are eleven pages with Routes in org/tynamo/routing"); + Assert.assertEquals(provider.getRoutes().size(), 10, "there are ten pages with Routes in org/tynamo/routing"); registry.cleanupThread(); registry.shutdown(); diff --git a/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml b/src/test/resources/org/tynamo/routing/pages/Inaccessible.tml similarity index 100% rename from src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/Index.tml rename to src/test/resources/org/tynamo/routing/pages/Inaccessible.tml diff --git a/src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml b/src/test/resources/org/tynamo/routing/pages/Index.tml similarity index 100% rename from src/test/resources/org/tynamo/routing/pages/subpackageWithIndex/SubPackageMain.tml rename to src/test/resources/org/tynamo/routing/pages/Index.tml From 2e14eb4fee8510eb1eb8b2f87a1ae1af72705794 Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sun, 3 Mar 2019 10:47:49 +0100 Subject: [PATCH 4/6] Imports refactor and use SymbolConstants.CONTEXT_PATH intead request.getContextPath() --- .../java/org/tynamo/routing/Behavior.java | 7 +++---- src/main/java/org/tynamo/routing/Route.java | 2 ++ .../routing/services/RouteDecoderImpl.java | 3 --- .../routing/services/RouterDispatcher.java | 20 +++++++++---------- .../services/RouterLinkTransformer.java | 14 ++++++++++--- .../java/org/tynamo/routing/RouteTest.java | 1 - .../org/tynamo/routing/RoutingTestCase.java | 3 +-- 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/tynamo/routing/Behavior.java b/src/main/java/org/tynamo/routing/Behavior.java index 929fdc7..58c0fce 100644 --- a/src/main/java/org/tynamo/routing/Behavior.java +++ b/src/main/java/org/tynamo/routing/Behavior.java @@ -1,6 +1,5 @@ - package org.tynamo.routing; - + public enum Behavior { - DEFAULT, REDIRECT, NOT_FOUND -} \ No newline at end of file + DEFAULT, REDIRECT, NOT_FOUND +} diff --git a/src/main/java/org/tynamo/routing/Route.java b/src/main/java/org/tynamo/routing/Route.java index 935bff2..749927c 100644 --- a/src/main/java/org/tynamo/routing/Route.java +++ b/src/main/java/org/tynamo/routing/Route.java @@ -1,5 +1,7 @@ package org.tynamo.routing; +import org.apache.tapestry5.services.LocalizationSetter; + import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/main/java/org/tynamo/routing/services/RouteDecoderImpl.java b/src/main/java/org/tynamo/routing/services/RouteDecoderImpl.java index 3bd7580..d3a414d 100644 --- a/src/main/java/org/tynamo/routing/services/RouteDecoderImpl.java +++ b/src/main/java/org/tynamo/routing/services/RouteDecoderImpl.java @@ -30,7 +30,6 @@ public RouteDecoderImpl(LocalizationSetter localizationSetter, ContextValueEncoder valueEncoder, Logger logger) { - this.localizationSetter = localizationSetter; this.encodeLocaleIntoPath = encodeLocaleIntoPath; @@ -56,7 +55,6 @@ private String getLocaleFromPath(String path) { } private String removeAppFolderAndLocaleFromPath(final Request request) { - String path = request.getPath(); if (this.applicationFolder.length() > 0) { @@ -74,7 +72,6 @@ private String removeAppFolderAndLocaleFromPath(final Request request) { @Override public PageRenderRequestParameters decodePageRenderRequest(final Route route, final Request request) { - Matcher matcher = route.getPattern().matcher(removeAppFolderAndLocaleFromPath(request)); if (!matcher.matches()) return null; diff --git a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java index 8abe99f..c3a7f36 100644 --- a/src/main/java/org/tynamo/routing/services/RouterDispatcher.java +++ b/src/main/java/org/tynamo/routing/services/RouterDispatcher.java @@ -1,14 +1,16 @@ package org.tynamo.routing.services; import org.apache.tapestry5.annotations.Log; -import org.apache.tapestry5.ioc.annotations.Primary; -import org.apache.tapestry5.services.*; +import org.apache.tapestry5.services.ComponentEventLinkEncoder; +import org.apache.tapestry5.services.ComponentRequestHandler; +import org.apache.tapestry5.services.Dispatcher; +import org.apache.tapestry5.services.PageRenderRequestParameters; +import org.apache.tapestry5.services.Request; +import org.apache.tapestry5.services.Response; +import org.tynamo.routing.Route; import java.io.IOException; -import org.tynamo.routing.Route; -import org.tynamo.routing.Behavior; - /** * The router dispatcher recognizes incoming requests and transforms them into page render requests. */ @@ -38,8 +40,8 @@ public boolean dispatch(final Request request, final Response response) throws I return handleRoute(pageParametersRoute, pageParameters, request, response); } if (routeParametersRoute != null) { - boolean handled = handleRoute(routeParametersRoute, routeParameters, request, response); - if (handled) return true; + componentRequestHandler.handlePageRender(routeParameters); + return true; } if (pageParametersRoute != null) { boolean handled = handleRoute(pageParametersRoute, pageParameters, request, response); @@ -50,10 +52,6 @@ public boolean dispatch(final Request request, final Response response) throws I } private boolean handleRoute(Route route, PageRenderRequestParameters parameters, Request request, Response response) throws IOException { - if (route.getPattern().matcher(request.getPath()).matches()) { - componentRequestHandler.handlePageRender(parameters); - return true; - } switch (route.getBehavior()) { case REDIRECT: response.sendRedirect(linkEncoder.createPageRenderLink(parameters).toAbsoluteURI()); diff --git a/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java b/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java index cd395a5..f56e11e 100644 --- a/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java +++ b/src/main/java/org/tynamo/routing/services/RouterLinkTransformer.java @@ -7,7 +7,12 @@ import org.apache.tapestry5.internal.services.LinkImpl; import org.apache.tapestry5.internal.services.RequestSecurityManager; import org.apache.tapestry5.ioc.annotations.Symbol; -import org.apache.tapestry5.services.*; +import org.apache.tapestry5.services.BaseURLSource; +import org.apache.tapestry5.services.ContextPathEncoder; +import org.apache.tapestry5.services.PageRenderRequestParameters; +import org.apache.tapestry5.services.PersistentLocale; +import org.apache.tapestry5.services.Request; +import org.apache.tapestry5.services.Response; import org.apache.tapestry5.services.linktransform.PageRenderLinkTransformer; import org.tynamo.routing.Route; @@ -26,6 +31,7 @@ public class RouterLinkTransformer implements PageRenderLinkTransformer { private final ContextPathEncoder contextPathEncoder; private final BaseURLSource baseURLSource; private final PersistentLocale persistentLocale; + private final String contextPath; private final boolean encodeLocaleIntoPath; private final String applicationFolder; @@ -34,6 +40,7 @@ public RouterLinkTransformer(RouteSource routeSource, RequestSecurityManager requestSecurityManager, Response response, ContextPathEncoder contextPathEncoder, BaseURLSource baseURLSource, PersistentLocale persistentLocale, + @Symbol(SymbolConstants.CONTEXT_PATH) final String contextPath, @Symbol(SymbolConstants.ENCODE_LOCALE_INTO_PATH) boolean encodeLocaleIntoPath, @Symbol(SymbolConstants.APPLICATION_FOLDER) final String applicationFolder) { this.routeSource = routeSource; @@ -43,6 +50,7 @@ public RouterLinkTransformer(RouteSource routeSource, this.contextPathEncoder = contextPathEncoder; this.baseURLSource = baseURLSource; this.persistentLocale = persistentLocale; + this.contextPath = contextPath; this.encodeLocaleIntoPath = encodeLocaleIntoPath; this.applicationFolder = applicationFolder; } @@ -60,9 +68,9 @@ public Link transformPageRenderLink(Link defaultLink, PageRenderRequestParameter if (route != null) { StringBuilder builder = new StringBuilder(BUFFER_SIZE); - if (!"".equals(request.getContextPath())) { + if (!"".equals(contextPath)) { // Build up the absolute URI. - builder.append(request.getContextPath()); + builder.append(contextPath); } encodeAppFolderAndLocale(builder); diff --git a/src/test/java/org/tynamo/routing/RouteTest.java b/src/test/java/org/tynamo/routing/RouteTest.java index 1b07772..ad46acb 100644 --- a/src/test/java/org/tynamo/routing/RouteTest.java +++ b/src/test/java/org/tynamo/routing/RouteTest.java @@ -317,7 +317,6 @@ public void redirect_behavior() throws IOException { expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); expect(request.isSecure()).andReturn(true).atLeastOnce(); - expect(request.getContextPath()).andReturn(EMPTY_PATH).atLeastOnce(); expect(request.getServerName()).andReturn(SERVER_NAME).atLeastOnce(); expect(request.getServerPort()).andReturn(SERVER_PORT).atLeastOnce(); expect(response.encodeURL(expectedURL)).andReturn(expectedURL).atLeastOnce(); diff --git a/src/test/java/org/tynamo/routing/RoutingTestCase.java b/src/test/java/org/tynamo/routing/RoutingTestCase.java index 7534df3..fdde0fd 100644 --- a/src/test/java/org/tynamo/routing/RoutingTestCase.java +++ b/src/test/java/org/tynamo/routing/RoutingTestCase.java @@ -114,7 +114,6 @@ public void testPageRenderLinkGeneration(String expectedURI, Request request = mockRequest(); expect(request.getPath()).andReturn(requestPath).atLeastOnce(); - expect(request.getContextPath()).andReturn(contextPath).atLeastOnce(); Response response = mockResponse(); train_encodeURL(response, expectedURI, expectedURI); @@ -132,7 +131,7 @@ public void testPageRenderLinkGeneration(String expectedURI, Assert.assertEquals(parameters.getActivationContext().getCount(), activationContextCount); RouterLinkTransformer linkTransformer = new RouterLinkTransformer(routeSource, request, securityManager, - response, contextPathEncoder, null, persistentLocale, encodeLocaleIntoPath, applicationFolder); + response, contextPathEncoder, null, persistentLocale, contextPath, encodeLocaleIntoPath, applicationFolder); Assert.assertEquals(linkTransformer.transformPageRenderLink(null, parameters).toURI(), expectedURI); } From 0460087575abeddde73bd78f0e965756489d8a6e Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sun, 3 Mar 2019 12:02:41 +0100 Subject: [PATCH 5/6] Test route activation context --- src/test/java/org/tynamo/routing/RouteTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/tynamo/routing/RouteTest.java b/src/test/java/org/tynamo/routing/RouteTest.java index ad46acb..0278833 100644 --- a/src/test/java/org/tynamo/routing/RouteTest.java +++ b/src/test/java/org/tynamo/routing/RouteTest.java @@ -252,7 +252,7 @@ public void route_precede_over_index() throws IOException { Request request = mockRequest(); Response response = null; - expect(request.getPath()).andReturn("/foo/0/bar/1").atLeastOnce(); + expect(request.getPath()).andReturn("/foo/45/bar/24").atLeastOnce(); expect(request.getParameter("t:lb")).andReturn(null).atLeastOnce(); expect(request.getLocale()).andReturn(FI).atLeastOnce(); @@ -268,6 +268,9 @@ public void route_precede_over_index() throws IOException { Assert.assertTrue(dispatcher.dispatch(request, response), "Simple should take precedence over the Index page"); Assert.assertEquals(parameters.getValue().getLogicalPageName(), "Simple", "Simple should take precedence over the Index page"); + Assert.assertEquals(parameters.getValue().getActivationContext().getCount(), 2, "Simple should receive activation context parameters"); + Assert.assertEquals((int) parameters.getValue().getActivationContext().get(Integer.class, 0), 45, "Simple should receive activation context parameters"); + Assert.assertEquals((int) parameters.getValue().getActivationContext().get(Integer.class, 1), 24, "Simple should receive activation context parameters"); verify(); } From c8f651de1aa970508073eeeb06b206ca24cb8389 Mon Sep 17 00:00:00 2001 From: "pico.dev" Date: Sun, 3 Mar 2019 13:05:47 +0100 Subject: [PATCH 6/6] Backward compatibility changes --- .../org/tynamo/routing/services/RouteFactory.java | 5 +++++ .../tynamo/routing/services/RouteFactoryImpl.java | 12 +++++++++++- src/test/java/org/tynamo/routing/RouteTest.java | 2 +- .../java/org/tynamo/routing/modules/TestsModule.java | 3 +-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/tynamo/routing/services/RouteFactory.java b/src/main/java/org/tynamo/routing/services/RouteFactory.java index 8461e8c..80a09e0 100644 --- a/src/main/java/org/tynamo/routing/services/RouteFactory.java +++ b/src/main/java/org/tynamo/routing/services/RouteFactory.java @@ -5,8 +5,13 @@ public interface RouteFactory { + Route create(String pathExpression, String canonicalized); + Route create(String pathExpression, String canonicalized, Behavior behavior); + @Deprecated + Route create(String pathExpression, Class page); + @Deprecated Route create(String pathExpression, Class page, Behavior behavior); diff --git a/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java b/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java index 54c7f93..92cd2f2 100644 --- a/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java +++ b/src/main/java/org/tynamo/routing/services/RouteFactoryImpl.java @@ -12,15 +12,25 @@ public RouteFactoryImpl(ComponentClassResolver componentClassResolver) { this.componentClassResolver = componentClassResolver; } + @Override + public Route create(String pathExpression, String canonicalized) { + return create(pathExpression, canonicalized, Behavior.DEFAULT); + } + @Override public Route create(String pathExpression, String canonicalized, Behavior behavior) { return new Route(pathExpression, canonicalized, behavior); } + @Override + public Route create(String pathExpression, Class page) { + return create(pathExpression, page, Behavior.DEFAULT); + } + @Override public Route create(String pathExpression, Class page, Behavior behavior) { String pageName = componentClassResolver.resolvePageClassNameToPageName(page.getName()); String canonicalized = componentClassResolver.canonicalizePageName(pageName); - return create(pathExpression, canonicalized, behavior); + return create(pathExpression, canonicalized); } } diff --git a/src/test/java/org/tynamo/routing/RouteTest.java b/src/test/java/org/tynamo/routing/RouteTest.java index 0278833..1fb8bf5 100644 --- a/src/test/java/org/tynamo/routing/RouteTest.java +++ b/src/test/java/org/tynamo/routing/RouteTest.java @@ -64,7 +64,7 @@ public void regular_expressions() { @Test public void decode_page_render_request() { - Route route = routeFactory.create(SimplePage.class.getAnnotation(At.class).value(), SimplePage.class.getSimpleName(), Behavior.DEFAULT); + Route route = routeFactory.create(SimplePage.class.getAnnotation(At.class).value(), SimplePage.class.getSimpleName()); Request request = mockRequest(); expect(request.getPath()).andReturn("/foo/45/bar/24").atLeastOnce(); diff --git a/src/test/java/org/tynamo/routing/modules/TestsModule.java b/src/test/java/org/tynamo/routing/modules/TestsModule.java index 2ed8bf6..4d7030d 100644 --- a/src/test/java/org/tynamo/routing/modules/TestsModule.java +++ b/src/test/java/org/tynamo/routing/modules/TestsModule.java @@ -11,7 +11,6 @@ import org.apache.tapestry5.ioc.services.ApplicationDefaults; import org.apache.tapestry5.ioc.services.SymbolProvider; import org.tynamo.routing.Route; -import org.tynamo.routing.Behavior; import org.tynamo.routing.services.RouteFactory; import org.tynamo.routing.services.RouteProvider; @@ -30,6 +29,6 @@ public static void provideApplicationDefaults(MappedConfiguration configuration, RouteFactory routeFactory) { String canonicalized = "subpackage/Unannotated"; - configuration.add(canonicalized.toLowerCase(), routeFactory.create("/not/annotated/{0}", canonicalized, Behavior.DEFAULT)); + configuration.add(canonicalized.toLowerCase(), routeFactory.create("/not/annotated/{0}", canonicalized)); } } \ No newline at end of file