From 82bce9837c8308d9132554c738790d84492dbcc0 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 28 Dec 2014 12:58:51 -0700 Subject: [PATCH 01/26] make that a method to allow future hooks into route maps --- hex_action/src/hex/action/RouteManager.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hex_action/src/hex/action/RouteManager.java b/hex_action/src/hex/action/RouteManager.java index d588962..ce67b76 100644 --- a/hex_action/src/hex/action/RouteManager.java +++ b/hex_action/src/hex/action/RouteManager.java @@ -36,23 +36,27 @@ public void defineRoutes() { } public void get(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.GET, path, getHandler(controllerSupplier, action))); + addRoute(new Route(HttpMethod.GET, path, getHandler(controllerSupplier, action))); } public void post(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.POST, path, getHandler(controllerSupplier, action))); + addRoute(new Route(HttpMethod.POST, path, getHandler(controllerSupplier, action))); } public void put(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.PUT, path, getHandler(controllerSupplier, action))); + addRoute(new Route(HttpMethod.PUT, path, getHandler(controllerSupplier, action))); } public void delete(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.DELETE, path, getHandler(controllerSupplier, action))); + addRoute(new Route(HttpMethod.DELETE, path, getHandler(controllerSupplier, action))); } public void matches(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); + addRoute(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); + } + + private void addRoute(Route route) { + definedRoutes.add(route); } private ControllerAction getHandler(Supplier controllerSupplier, String action) { From c7804fdd359df0cccc76ab7976acb21272340048 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 28 Dec 2014 13:47:18 -0700 Subject: [PATCH 02/26] move routemanager to routing package --- example_application/adapters/config/ApplicationRoutes.java | 2 +- hex_action/src/hex/action/Application.java | 1 + hex_action/src/hex/action/{ => routing}/RouteManager.java | 4 +++- hex_action/test/hex/action/RouteManagerTest.java | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) rename hex_action/src/hex/action/{ => routing}/RouteManager.java (95%) diff --git a/example_application/adapters/config/ApplicationRoutes.java b/example_application/adapters/config/ApplicationRoutes.java index 0402cfd..9d60a9e 100644 --- a/example_application/adapters/config/ApplicationRoutes.java +++ b/example_application/adapters/config/ApplicationRoutes.java @@ -1,7 +1,7 @@ package config; import controllers.PeopleController; -import hex.action.RouteManager; +import hex.action.routing.RouteManager; /** * Created by jason on 14-11-16. diff --git a/hex_action/src/hex/action/Application.java b/hex_action/src/hex/action/Application.java index 1a54a32..b31459a 100644 --- a/hex_action/src/hex/action/Application.java +++ b/hex_action/src/hex/action/Application.java @@ -1,5 +1,6 @@ package hex.action; +import hex.action.routing.RouteManager; import hex.routing.RoutingConfig; import hex.routing.RoutingConfigBase; diff --git a/hex_action/src/hex/action/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java similarity index 95% rename from hex_action/src/hex/action/RouteManager.java rename to hex_action/src/hex/action/routing/RouteManager.java index ce67b76..ef45a8d 100644 --- a/hex_action/src/hex/action/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -1,5 +1,7 @@ -package hex.action; +package hex.action.routing; +import hex.action.Controller; +import hex.action.ControllerAction; import hex.routing.HttpMethod; import hex.routing.Route; diff --git a/hex_action/test/hex/action/RouteManagerTest.java b/hex_action/test/hex/action/RouteManagerTest.java index 62a5666..c97e994 100644 --- a/hex_action/test/hex/action/RouteManagerTest.java +++ b/hex_action/test/hex/action/RouteManagerTest.java @@ -1,6 +1,7 @@ package hex.action; import hex.action.examples.PostsController; +import hex.action.routing.RouteManager; import hex.routing.HttpMethod; import hex.routing.Route; import org.junit.Before; From c5249a3117b114f56d6c325ac92e1858d0eb386d Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Thu, 1 Jan 2015 19:21:28 -0700 Subject: [PATCH 03/26] move route manager test to routing package as well --- hex_action/src/hex/action/routing/RouteManager.java | 4 ++++ hex_action/test/hex/action/ActionTests.java | 1 + .../hex/action/{ => routing}/RouteManagerTest.java | 12 +++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) rename hex_action/test/hex/action/{ => routing}/RouteManagerTest.java (83%) diff --git a/hex_action/src/hex/action/routing/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java index ef45a8d..e2cf8b5 100644 --- a/hex_action/src/hex/action/routing/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -57,6 +57,10 @@ public void matches(String path, Supplier controllerSupplier, String addRoute(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); } + Route getRouteNamed(String routeName) { + return null; + } + private void addRoute(Route route) { definedRoutes.add(route); } diff --git a/hex_action/test/hex/action/ActionTests.java b/hex_action/test/hex/action/ActionTests.java index c8b37a4..bcb6ec4 100644 --- a/hex_action/test/hex/action/ActionTests.java +++ b/hex_action/test/hex/action/ActionTests.java @@ -1,6 +1,7 @@ package hex.action; import hex.action.params.ParamsSuite; +import hex.action.routing.RouteManagerTest; import hex.action.views.jsp.TagTests; import org.junit.runner.RunWith; import org.junit.runners.Suite; diff --git a/hex_action/test/hex/action/RouteManagerTest.java b/hex_action/test/hex/action/routing/RouteManagerTest.java similarity index 83% rename from hex_action/test/hex/action/RouteManagerTest.java rename to hex_action/test/hex/action/routing/RouteManagerTest.java index c97e994..b590055 100644 --- a/hex_action/test/hex/action/RouteManagerTest.java +++ b/hex_action/test/hex/action/routing/RouteManagerTest.java @@ -1,15 +1,18 @@ -package hex.action; +package hex.action.routing; import hex.action.examples.PostsController; import hex.action.routing.RouteManager; import hex.routing.HttpMethod; import hex.routing.Route; +import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import java.util.stream.Stream; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** @@ -68,4 +71,11 @@ public void matchesShouldMatchAnyOldMethod() { m -> assertTrue(m.toString(), route.matches(m, path)) ); } + + @Test + public void addingRoutesShouldCreatePathNames() { + routeManager.get("/aliens", PostsController::new, "report_to_the_mother_ship"); + Route route = routeManager.getRouteNamed("report_to_the_mother_ship_aliens"); + assertThat(route, notNullValue()); + } } From 6a7d474f8ff2e5f1eba63a330c0df1a1819fa84c Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 00:32:07 -0700 Subject: [PATCH 04/26] basic path names working --- hex_action/src/hex/action/Controller.java | 4 +++ .../src/hex/action/ControllerAction.java | 4 +++ .../src/hex/action/routing/RouteManager.java | 29 ++++++++++--------- .../hex/action/routing/RouteManagerTest.java | 3 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/hex_action/src/hex/action/Controller.java b/hex_action/src/hex/action/Controller.java index ee678ce..4d720b8 100644 --- a/hex_action/src/hex/action/Controller.java +++ b/hex_action/src/hex/action/Controller.java @@ -37,6 +37,10 @@ public class Controller { * @return Name of the directory in which to find the view template. */ protected String templateDirectory() { + return getName(); + } + + String getName() { Matcher m = CONTROLLER_NAMES.matcher(getClass().getSimpleName()); if(!m.matches()) throw new IllegalArgumentException(String.format(Errors.UNABLE_TO_IMPLY_VIEW_DIRECTORY, getClass().getSimpleName())); return underscore(m.replaceAll(m.group(1))); diff --git a/hex_action/src/hex/action/ControllerAction.java b/hex_action/src/hex/action/ControllerAction.java index 50ea702..3b58780 100644 --- a/hex_action/src/hex/action/ControllerAction.java +++ b/hex_action/src/hex/action/ControllerAction.java @@ -94,6 +94,10 @@ public void prepareController(Controller controller, ServletRequest servletReque } } + public String getName() { + return actionName; + } + private void checkException(ServletRequest request) throws ServletException { InitializationException e = (InitializationException) request.getServletContext().getAttribute(InitializationException.class.getName()); diff --git a/hex_action/src/hex/action/routing/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java index e2cf8b5..9abb0ed 100644 --- a/hex_action/src/hex/action/routing/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -5,16 +5,16 @@ import hex.routing.HttpMethod; import hex.routing.Route; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; +import java.util.*; import java.util.function.Supplier; /** * Created by jason on 14-11-14. */ public class RouteManager { - private List definedRoutes = new ArrayList<>(); + private final Map routeMap = new HashMap<>(); + + private final List definedRoutes = new ArrayList<>(); private Properties hexActionProperties; @@ -38,31 +38,34 @@ public void defineRoutes() { } public void get(String path, Supplier controllerSupplier, String action) { - addRoute(new Route(HttpMethod.GET, path, getHandler(controllerSupplier, action))); + addRoute(HttpMethod.GET, path, getHandler(controllerSupplier, action)); } public void post(String path, Supplier controllerSupplier, String action) { - addRoute(new Route(HttpMethod.POST, path, getHandler(controllerSupplier, action))); + addRoute(HttpMethod.POST, path, getHandler(controllerSupplier, action)); } public void put(String path, Supplier controllerSupplier, String action) { - addRoute(new Route(HttpMethod.PUT, path, getHandler(controllerSupplier, action))); + addRoute(HttpMethod.PUT, path, getHandler(controllerSupplier, action)); } public void delete(String path, Supplier controllerSupplier, String action) { - addRoute(new Route(HttpMethod.DELETE, path, getHandler(controllerSupplier, action))); + addRoute(HttpMethod.DELETE, path, getHandler(controllerSupplier, action)); } public void matches(String path, Supplier controllerSupplier, String action) { - addRoute(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); + definedRoutes.add(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); } - Route getRouteNamed(String routeName) { - return null; + private void addRoute(HttpMethod method, String path, ControllerAction handler) { + Route route = new Route(method, path, handler); + String pathName = path.replaceFirst("/", ""); + definedRoutes.add(route); + routeMap.put(String.format("%s_%s", handler.getName(), pathName), route); } - private void addRoute(Route route) { - definedRoutes.add(route); + Route getRouteNamed(String routeName) { + return routeMap.get(routeName); } private ControllerAction getHandler(Supplier controllerSupplier, String action) { diff --git a/hex_action/test/hex/action/routing/RouteManagerTest.java b/hex_action/test/hex/action/routing/RouteManagerTest.java index b590055..6a88edb 100644 --- a/hex_action/test/hex/action/routing/RouteManagerTest.java +++ b/hex_action/test/hex/action/routing/RouteManagerTest.java @@ -74,7 +74,8 @@ public void matchesShouldMatchAnyOldMethod() { @Test public void addingRoutesShouldCreatePathNames() { - routeManager.get("/aliens", PostsController::new, "report_to_the_mother_ship"); + String path = "/aliens"; + routeManager.get(path, PostsController::new, "report_to_the_mother_ship"); Route route = routeManager.getRouteNamed("report_to_the_mother_ship_aliens"); assertThat(route, notNullValue()); } From 2e849be14e7aee818f3d44a9f1e2b39f51319cf7 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 00:51:13 -0700 Subject: [PATCH 05/26] path names work with params and nested routes --- .../src/hex/action/routing/RouteManager.java | 4 +++- .../test/hex/action/routing/RouteManagerTest.java | 15 +++++++++++++++ hex_routing/src/hex/routing/Route.java | 4 ++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hex_action/src/hex/action/routing/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java index 9abb0ed..bfc9233 100644 --- a/hex_action/src/hex/action/routing/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -59,7 +59,9 @@ public void matches(String path, Supplier controllerSupplier, String private void addRoute(HttpMethod method, String path, ControllerAction handler) { Route route = new Route(method, path, handler); - String pathName = path.replaceFirst("/", ""); + String pathName = Route.PATH_PARAM_PATTERN.matcher(path).replaceAll("") + .replaceFirst("/", "") + .replaceAll("/", "_"); definedRoutes.add(route); routeMap.put(String.format("%s_%s", handler.getName(), pathName), route); } diff --git a/hex_action/test/hex/action/routing/RouteManagerTest.java b/hex_action/test/hex/action/routing/RouteManagerTest.java index 6a88edb..2d6039c 100644 --- a/hex_action/test/hex/action/routing/RouteManagerTest.java +++ b/hex_action/test/hex/action/routing/RouteManagerTest.java @@ -78,5 +78,20 @@ public void addingRoutesShouldCreatePathNames() { routeManager.get(path, PostsController::new, "report_to_the_mother_ship"); Route route = routeManager.getRouteNamed("report_to_the_mother_ship_aliens"); assertThat(route, notNullValue()); + assertTrue(route.matches(HttpMethod.GET, path)); + } + + @Test + public void addingRoutesWithParamsShouldSkipParamsInPathNames() { + routeManager.get("/aliens/:id", PostsController::new, "profile"); + Route route = routeManager.getRouteNamed("profile_aliens"); + assertThat(route, notNullValue()); + } + + @Test + public void addingNestedRoutesShouldNestPathNames() { + routeManager.get("/posts/:postId/comments/:id", PostsController::new, "show"); + Route route = routeManager.getRouteNamed("show_posts_comments"); + assertThat(route, notNullValue()); } } diff --git a/hex_routing/src/hex/routing/Route.java b/hex_routing/src/hex/routing/Route.java index 7d15e6d..4cc33d1 100644 --- a/hex_routing/src/hex/routing/Route.java +++ b/hex_routing/src/hex/routing/Route.java @@ -36,7 +36,7 @@ public class Route { public static final String ROUTE_PARAMS = "hex.hex_routing.Route.ROUTE_PARAMS"; - private static final Pattern PATH_PARAM_DETECTOR = Pattern.compile("/:(\\w+)"); + public static final Pattern PATH_PARAM_PATTERN = Pattern.compile("/:(\\w+)"); private Pattern pathPattern; @@ -76,7 +76,7 @@ private void setPattern(Pattern pathPattern) { } public void setPath(String path) { - Matcher m = PATH_PARAM_DETECTOR.matcher(path); + Matcher m = PATH_PARAM_PATTERN.matcher(path); while(m.find()) { addParam(m.group(1)); } From fa1b9636abc6e314417ded7b7ff50f8c61c84211 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 14:11:13 -0700 Subject: [PATCH 06/26] make package local for great security --- hex_routing/src/hex/routing/Route.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hex_routing/src/hex/routing/Route.java b/hex_routing/src/hex/routing/Route.java index 4cc33d1..eb1fbdd 100644 --- a/hex_routing/src/hex/routing/Route.java +++ b/hex_routing/src/hex/routing/Route.java @@ -75,7 +75,7 @@ private void setPattern(Pattern pathPattern) { this.pathPattern = pathPattern; } - public void setPath(String path) { + void setPath(String path) { Matcher m = PATH_PARAM_PATTERN.matcher(path); while(m.find()) { addParam(m.group(1)); From 1b7794c58fd1817cd8fc465641ce14337ad54389 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 14:12:54 -0700 Subject: [PATCH 07/26] I guess we'll never need these to be public --- hex_action/src/hex/action/routing/RouteManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hex_action/src/hex/action/routing/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java index bfc9233..7e191c9 100644 --- a/hex_action/src/hex/action/routing/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -37,23 +37,23 @@ public void defineRoutes() { } - public void get(String path, Supplier controllerSupplier, String action) { + protected void get(String path, Supplier controllerSupplier, String action) { addRoute(HttpMethod.GET, path, getHandler(controllerSupplier, action)); } - public void post(String path, Supplier controllerSupplier, String action) { + protected void post(String path, Supplier controllerSupplier, String action) { addRoute(HttpMethod.POST, path, getHandler(controllerSupplier, action)); } - public void put(String path, Supplier controllerSupplier, String action) { + protected void put(String path, Supplier controllerSupplier, String action) { addRoute(HttpMethod.PUT, path, getHandler(controllerSupplier, action)); } - public void delete(String path, Supplier controllerSupplier, String action) { + protected void delete(String path, Supplier controllerSupplier, String action) { addRoute(HttpMethod.DELETE, path, getHandler(controllerSupplier, action)); } - public void matches(String path, Supplier controllerSupplier, String action) { + protected void matches(String path, Supplier controllerSupplier, String action) { definedRoutes.add(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); } From 6480133c1a139d8954e82d0415ad99f49b7cab8a Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 15:00:32 -0700 Subject: [PATCH 08/26] optimize imports --- hex_action/test/hex/action/routing/RouteManagerTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hex_action/test/hex/action/routing/RouteManagerTest.java b/hex_action/test/hex/action/routing/RouteManagerTest.java index 2d6039c..4a69095 100644 --- a/hex_action/test/hex/action/routing/RouteManagerTest.java +++ b/hex_action/test/hex/action/routing/RouteManagerTest.java @@ -1,19 +1,15 @@ package hex.action.routing; import hex.action.examples.PostsController; -import hex.action.routing.RouteManager; import hex.routing.HttpMethod; import hex.routing.Route; -import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import java.util.stream.Stream; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * Created by jason on 14-11-15. From b6757401d1d2e9e178ad4f9a8f4bccf335a70915 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 15:30:35 -0700 Subject: [PATCH 09/26] move coercionmap to coercion package since it doesnt extend Map --- hex_action/src/hex/action/ViewContext.java | 4 ++-- hex_action/test/hex/action/params/WebParamsTest.java | 2 +- hex_routing/src/hex/routing/RouteParams.java | 2 +- hex_utils/src/hex/utils/{maps => coercion}/CoercionMap.java | 2 +- hex_utils/src/hex/utils/collections/CoercionArray.java | 2 +- hex_utils/src/hex/utils/maps/PropertyMap.java | 1 + hex_utils/test/hex/utils/maps/CoercionMapTest.java | 1 + 7 files changed, 8 insertions(+), 6 deletions(-) rename hex_utils/src/hex/utils/{maps => coercion}/CoercionMap.java (99%) diff --git a/hex_action/src/hex/action/ViewContext.java b/hex_action/src/hex/action/ViewContext.java index c1d90cd..46dbbf0 100644 --- a/hex_action/src/hex/action/ViewContext.java +++ b/hex_action/src/hex/action/ViewContext.java @@ -1,6 +1,6 @@ package hex.action; -import hex.utils.maps.CoercionMap; +import hex.utils.maps.PropertyMap; import java.util.HashMap; import java.util.Map; @@ -8,7 +8,7 @@ /** * Created by jason on 14-11-15. */ -public class ViewContext extends HashMap implements CoercionMap { +public class ViewContext extends HashMap implements PropertyMap { private static final String BLANK = ""; private String content; diff --git a/hex_action/test/hex/action/params/WebParamsTest.java b/hex_action/test/hex/action/params/WebParamsTest.java index ba5a81b..f696e08 100644 --- a/hex_action/test/hex/action/params/WebParamsTest.java +++ b/hex_action/test/hex/action/params/WebParamsTest.java @@ -6,7 +6,7 @@ import hex.routing.RouteParams; import hex.utils.Memo; import hex.utils.coercion.CoercionException; -import hex.utils.maps.CoercionMap; +import hex.utils.coercion.CoercionMap; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.junit.Test; diff --git a/hex_routing/src/hex/routing/RouteParams.java b/hex_routing/src/hex/routing/RouteParams.java index b2f55cd..588789e 100644 --- a/hex_routing/src/hex/routing/RouteParams.java +++ b/hex_routing/src/hex/routing/RouteParams.java @@ -23,7 +23,7 @@ */ package hex.routing; -import hex.utils.maps.CoercionMap; +import hex.utils.coercion.CoercionMap; import hex.utils.maps.AbstractImmutableMap; import java.math.BigDecimal; diff --git a/hex_utils/src/hex/utils/maps/CoercionMap.java b/hex_utils/src/hex/utils/coercion/CoercionMap.java similarity index 99% rename from hex_utils/src/hex/utils/maps/CoercionMap.java rename to hex_utils/src/hex/utils/coercion/CoercionMap.java index c337e9f..60dc1c4 100644 --- a/hex_utils/src/hex/utils/maps/CoercionMap.java +++ b/hex_utils/src/hex/utils/coercion/CoercionMap.java @@ -1,4 +1,4 @@ -package hex.utils.maps; +package hex.utils.coercion; import hex.utils.coercion.Coercible; import hex.utils.coercion.CoercionException; diff --git a/hex_utils/src/hex/utils/collections/CoercionArray.java b/hex_utils/src/hex/utils/collections/CoercionArray.java index 4b0ecac..209080d 100644 --- a/hex_utils/src/hex/utils/collections/CoercionArray.java +++ b/hex_utils/src/hex/utils/collections/CoercionArray.java @@ -1,6 +1,6 @@ package hex.utils.collections; -import hex.utils.maps.CoercionMap; +import hex.utils.coercion.CoercionMap; import java.lang.reflect.Array; diff --git a/hex_utils/src/hex/utils/maps/PropertyMap.java b/hex_utils/src/hex/utils/maps/PropertyMap.java index a69e0a4..5e1222a 100644 --- a/hex_utils/src/hex/utils/maps/PropertyMap.java +++ b/hex_utils/src/hex/utils/maps/PropertyMap.java @@ -2,6 +2,7 @@ import hex.utils.coercion.Coercible; import hex.utils.coercion.CoercionException; +import hex.utils.coercion.CoercionMap; import hex.utils.generics.TypeVariables; import java.lang.reflect.Field; diff --git a/hex_utils/test/hex/utils/maps/CoercionMapTest.java b/hex_utils/test/hex/utils/maps/CoercionMapTest.java index 3930520..731c56b 100644 --- a/hex_utils/test/hex/utils/maps/CoercionMapTest.java +++ b/hex_utils/test/hex/utils/maps/CoercionMapTest.java @@ -3,6 +3,7 @@ import hex.utils.Memo; import hex.utils.coercion.Coercible; import hex.utils.coercion.CoercionException; +import hex.utils.coercion.CoercionMap; import hex.utils.test.Book; import hex.utils.test.matchers.IntArrayMatcher; import org.junit.Rule; From 20d7d4dd26d5e877954901e53aa059ed68b2d931 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 3 Jan 2015 16:15:12 -0700 Subject: [PATCH 10/26] Generating paths from replacing params in objects --- hex_routing/src/hex/routing/Route.java | 31 +++++++++++++++ hex_routing/test/hex/routing/RouteTest.java | 18 +++++++++ .../hex/utils/coercion/CoercionObject.java | 38 +++++++++++++++++++ hex_utils/src/hex/utils/coercion/Errors.java | 12 ++++++ 4 files changed, 99 insertions(+) create mode 100644 hex_utils/src/hex/utils/coercion/CoercionObject.java create mode 100644 hex_utils/src/hex/utils/coercion/Errors.java diff --git a/hex_routing/src/hex/routing/Route.java b/hex_routing/src/hex/routing/Route.java index eb1fbdd..1ae0f40 100644 --- a/hex_routing/src/hex/routing/Route.java +++ b/hex_routing/src/hex/routing/Route.java @@ -23,8 +23,11 @@ */ package hex.routing; +import hex.utils.coercion.CoercionObject; + import javax.servlet.http.HttpServletRequest; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.function.Predicate; import java.util.regex.Matcher; @@ -38,6 +41,11 @@ public class Route { public static final Pattern PATH_PARAM_PATTERN = Pattern.compile("/:(\\w+)"); + /** + * The original path used to create this {@link Route} + */ + private String path; + private Pattern pathPattern; private RouteHandler handler; @@ -52,6 +60,10 @@ public Route(RouteHandler handler) { this(HttpMethod.ANY, handler); } + public Route(String path, RouteHandler handler) { + this(HttpMethod.ANY, path, handler); + } + public Route(HttpMethod method, RouteHandler handler) { this(m -> m == method, handler); } @@ -76,6 +88,7 @@ private void setPattern(Pattern pathPattern) { } void setPath(String path) { + this.path = path; Matcher m = PATH_PARAM_PATTERN.matcher(path); while(m.find()) { addParam(m.group(1)); @@ -87,6 +100,24 @@ void setPath(String path) { setPattern(Pattern.compile(routePattern + "[/]?")); } + public String createPath() { + return path; + } + + public String createPath(Object params) { + CoercionObject paramValues = new CoercionObject(params); + Matcher m = PATH_PARAM_PATTERN.matcher(path); + StringBuffer path = new StringBuffer(); + + while(m.find()) { + String paramName = m.group(1); + m.appendReplacement(path, "/" + paramValues.getString(paramName)); + } + m.appendTail(path); + + return path.toString(); + } + public RouteHandler getHandler() { return (q, r) -> { HttpServletRequest request = (HttpServletRequest) q; diff --git a/hex_routing/test/hex/routing/RouteTest.java b/hex_routing/test/hex/routing/RouteTest.java index eec056a..c8947b6 100644 --- a/hex_routing/test/hex/routing/RouteTest.java +++ b/hex_routing/test/hex/routing/RouteTest.java @@ -23,10 +23,12 @@ */ package hex.routing; +import hex.routing.test.Post; import org.junit.Test; import java.util.stream.Stream; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; import static servlet_mock.HttpMock.GET; @@ -80,4 +82,20 @@ public void theRootRouteShouldWork() { p -> assertTrue(String.format("%s -> %s", r, p), route.matches(HttpMethod.GET, p))); }); } + + @Test + public void createPathShouldReturnTheDefinedPath() { + Route route = new Route("/aliens", RoutingConfigTest.CALLED); + String path = route.createPath(); + assertThat(path, is("/aliens")); + } + + @Test + public void createPathShouldSubstituteParamsWithPassedInProperties() { + Route route = new Route("/posts/:id", RoutingConfigTest.CALLED); + Post post = new Post(); + post.setId(99); + String path = route.createPath(post); + assertThat(path, is("/posts/99")); + } } diff --git a/hex_utils/src/hex/utils/coercion/CoercionObject.java b/hex_utils/src/hex/utils/coercion/CoercionObject.java new file mode 100644 index 0000000..3a8890b --- /dev/null +++ b/hex_utils/src/hex/utils/coercion/CoercionObject.java @@ -0,0 +1,38 @@ +package hex.utils.coercion; + +import hex.utils.Inflection; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Created by jason on 15-01-03. + */ +public class CoercionObject implements CoercionMap { + + private final Object source; + + public CoercionObject(Object source) { + this.source = source; + } + + @Override + public Object get(Object index) { + String propertyName = (String)index; + try { + Method getter = source.getClass().getMethod(Inflection.toGetter(propertyName)); + return getter.invoke(source); + } catch (NoSuchMethodException e) { + return null; // don't have the property, return null like a proper map would + } catch (InvocationTargetException e) { + Throwable x = e.getCause(); + if(x instanceof RuntimeException) { + throw (RuntimeException)x; + } else { + throw new RuntimeException(String.format(Errors.PROPERTY_GETTER_THREW_EXCEPTION, propertyName), x); + } + } catch (IllegalAccessException e) { + throw new UnsupportedOperationException(String.format(Errors.PROPERTY_GETTER_INSUFFICIENT_ACCESS, propertyName), e); + } + } +} diff --git a/hex_utils/src/hex/utils/coercion/Errors.java b/hex_utils/src/hex/utils/coercion/Errors.java new file mode 100644 index 0000000..b5a79a1 --- /dev/null +++ b/hex_utils/src/hex/utils/coercion/Errors.java @@ -0,0 +1,12 @@ +package hex.utils.coercion; + +/** + * Created by jason on 15-01-03. + */ +public class Errors { + public static final String PROPERTY_GETTER_THREW_EXCEPTION = + "Getter for property [%s] threw exception."; + + public static final String PROPERTY_GETTER_INSUFFICIENT_ACCESS = + "Getter for property[%s] has less than public access."; +} From 771acb66e9e200c624bb0d4a450933baecb5fc04 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 4 Jan 2015 12:11:18 -0700 Subject: [PATCH 11/26] use autoclose block for that class loader --- hex_dev/src/hex/dev/DevRoutingFilter.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hex_dev/src/hex/dev/DevRoutingFilter.java b/hex_dev/src/hex/dev/DevRoutingFilter.java index e3d18e2..375bacc 100644 --- a/hex_dev/src/hex/dev/DevRoutingFilter.java +++ b/hex_dev/src/hex/dev/DevRoutingFilter.java @@ -85,14 +85,11 @@ private void initCompiler(String applicationRootPath) { } private void runApplicationInitializers(FilterConfig filterConfig) throws IOException { - URLClassLoader classLoader = new HexClassLoader(applicationCompiler, this.getClass().getClassLoader()); - InitializerRunner runner = new InitializerRunner(classLoader); - try { + try(URLClassLoader classLoader = new HexClassLoader(applicationCompiler, this.getClass().getClassLoader())) { + InitializerRunner runner = new InitializerRunner(classLoader); runner.run(); } catch (InitializationException e) { filterConfig.getServletContext().setAttribute(InitializationException.class.getName(), e); - } finally { - classLoader.close(); } } From 4473d91c1407317a5a4c3cb6003210aa948647fe Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 4 Jan 2015 13:59:53 -0700 Subject: [PATCH 12/26] register route managers with the servletcontext --- hex_action/src/hex/action/Application.java | 9 +++++++-- hex_dev/src/hex/dev/DevRoutingFilter.java | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hex_action/src/hex/action/Application.java b/hex_action/src/hex/action/Application.java index 1a70fa7..81cde32 100644 --- a/hex_action/src/hex/action/Application.java +++ b/hex_action/src/hex/action/Application.java @@ -26,6 +26,7 @@ public class Application implements ServletContextListener { public static final String ACTION_CONFIG = "hex_action.properties"; public static final String ROUTES = "routes"; public static final String ROOT = "hex.action.Application.ROOT"; + public static final String ROUTING_CONFIG_CLASSES = "hex.action.Application.ROUTING_CONFIG_CLASSES"; @Override public void contextInitialized(ServletContextEvent sce) { @@ -39,7 +40,7 @@ public void contextInitialized(ServletContextEvent sce) { private void initializeApplication(ServletContext application) throws InitializationException { ClassLoader cl = getClass().getClassLoader(); try { - RoutingConfig routingConfig = initializeRoutes(cl); + RoutingConfig routingConfig = initializeRoutes(cl, application); application.setAttribute(Routing.CONFIG, routingConfig); InitializerRunner initializer = new InitializerRunner(); @@ -65,7 +66,7 @@ public void contextDestroyed(ServletContextEvent sce) { } - public static RoutingConfig initializeRoutes(ClassLoader classLoader) throws ServletException { + public static RoutingConfig initializeRoutes(ClassLoader classLoader, ServletContext application) throws ServletException { try { Properties adapterProperties = new Properties(); adapterProperties.load(classLoader.getResourceAsStream(ACTION_CONFIG)); @@ -73,11 +74,15 @@ public static RoutingConfig initializeRoutes(ClassLoader classLoader) throws Ser String[] routingConfigClasses = Stream.of(adapterProperties.getProperty(ROUTES).split(",")) .map(String::trim).toArray(String[]::new); + application.setAttribute(ROUTING_CONFIG_CLASSES, routingConfigClasses); + RoutingConfigBase routingConfig = new RoutingConfigBase(); for (String className : routingConfigClasses) { RouteManager routeManager = (RouteManager) Class.forName(className, false, classLoader).newInstance(); routeManager.setHexActionProperties(adapterProperties); routeManager.defineRoutes(); + application.setAttribute(className, routeManager); + //TODO: This is smelly. Need to decide if supporting multiple RouteManagers in the same routing config is a good idea or not. routeManager.getDefinedRoutes().forEach(routingConfig::addRoute); } return routingConfig; diff --git a/hex_dev/src/hex/dev/DevRoutingFilter.java b/hex_dev/src/hex/dev/DevRoutingFilter.java index 375bacc..a9aaf3d 100644 --- a/hex_dev/src/hex/dev/DevRoutingFilter.java +++ b/hex_dev/src/hex/dev/DevRoutingFilter.java @@ -96,7 +96,7 @@ private void runApplicationInitializers(FilterConfig filterConfig) throws IOExce @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { try (URLClassLoader requestClassLoader = new HexClassLoader(applicationCompiler, this.getClass().getClassLoader())) { - config = Application.initializeRoutes(requestClassLoader); + config = Application.initializeRoutes(requestClassLoader, servletRequest.getServletContext()); filter.doFilter(servletRequest, servletResponse, filterChain); } finally { config = null; From cd7521f4ff3cdcf7a935f58bda5ed3b3fd734be5 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 4 Jan 2015 15:03:39 -0700 Subject: [PATCH 13/26] start of uri building API --- hex_action/src/hex/action/routing/Errors.java | 9 +++ hex_action/src/hex/action/routing/Uri.java | 68 +++++++++++++++++++ .../src/hex/action/routing/UrlUtils.java | 48 +++++++++++++ hex_action/test/hex/action/ActionTests.java | 4 +- .../test/hex/action/routing/RoutingSuite.java | 15 ++++ .../test/hex/action/routing/UriTest.java | 28 ++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 hex_action/src/hex/action/routing/Errors.java create mode 100644 hex_action/src/hex/action/routing/Uri.java create mode 100644 hex_action/src/hex/action/routing/UrlUtils.java create mode 100644 hex_action/test/hex/action/routing/RoutingSuite.java create mode 100644 hex_action/test/hex/action/routing/UriTest.java diff --git a/hex_action/src/hex/action/routing/Errors.java b/hex_action/src/hex/action/routing/Errors.java new file mode 100644 index 0000000..88ba0a5 --- /dev/null +++ b/hex_action/src/hex/action/routing/Errors.java @@ -0,0 +1,9 @@ +package hex.action.routing; + +/** + * Created by jason on 15-01-04. + */ +public class Errors { + static final String ROUTE_NAME_NOT_FOUND = + "Route named (%s) not found in application routes."; +} diff --git a/hex_action/src/hex/action/routing/Uri.java b/hex_action/src/hex/action/routing/Uri.java new file mode 100644 index 0000000..042c90a --- /dev/null +++ b/hex_action/src/hex/action/routing/Uri.java @@ -0,0 +1,68 @@ +package hex.action.routing; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.StringJoiner; +import java.util.function.Consumer; + +/** +* Created by jason on 15-01-04. +*/ +class Uri { + private Optional scheme = Optional.empty(); + + private Optional host = Optional.empty(); + + private int port; + + private Optional context = Optional.empty(); + + private Optional path = Optional.empty(); + + private Map queryParams = new LinkedHashMap<>(); + + public static Uri create(String scheme, String host, int port) { + Uri uri = new Uri(); + uri.scheme = Optional.of(scheme); + uri.host = Optional.of(host); + uri.port = port; + return uri; + } + + public String toString() { + StringBuilder builder = new StringBuilder(); + scheme.ifPresent(s -> builder.append(s).append("://")); + host.ifPresent(builder::append); + if(port != 0 && port != 80) builder.append(':').append(port); + context.ifPresent(builder::append); + path.ifPresent(builder::append); + if(queryParams.size() > 0) { + builder.append('?'); + Consumer> entryAppender = e -> + builder.append(e.getKey()).append('=').append(e.getValue()); + + queryParams.entrySet().stream().findFirst().ifPresent(entryAppender); + queryParams.entrySet().stream().skip(1).peek(e -> builder.append('&')).forEach(entryAppender); + } + return builder.toString(); + } + + public void addQueryParam(String name, String value) { + try { + queryParams.put(name, URLEncoder.encode(value, "UTF-8")); + } catch (UnsupportedEncodingException e) { + // hardcoded UTF-8 + } + } + + public void setContext(String context) { + this.context = Optional.ofNullable(context); + } + + public void setPath(String path) { + this.path = Optional.ofNullable(path); + } +} diff --git a/hex_action/src/hex/action/routing/UrlUtils.java b/hex_action/src/hex/action/routing/UrlUtils.java new file mode 100644 index 0000000..ff498ef --- /dev/null +++ b/hex_action/src/hex/action/routing/UrlUtils.java @@ -0,0 +1,48 @@ +package hex.action.routing; + +import hex.action.Application; +import hex.routing.Route; + +import javax.servlet.ServletRequest; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by jason on 15-01-03. + */ +public class UrlUtils { + private static final Pattern PATH_NAME_PATTERN = Pattern.compile("(.*)_(url|path)$"); + + private static final String URL = "url"; + + public static Uri getUrlFor(String pathRef, ServletRequest request) { + Matcher m = PATH_NAME_PATTERN.matcher(pathRef); + if(!m.matches()) throw new IllegalArgumentException("Path reference did not match format (path_name)_(url|path)"); + String pathName = m.group(1); + String uriType = m.group(2); + Route route = getRouteNamed(pathName, request); + Uri uri = getUri(uriType, request); + uri.setContext(request.getServletContext().getContextPath()); + // TODO: add check for Tomcat mode with it's stupid trailing slash in "directory paths" + uri.setPath(route.createPath()); + return uri; + } + + private static Uri getUri(String uriType, ServletRequest request) { + if(URL.equals(uriType)) { + return Uri.create(request.getScheme(), request.getServerName(), request.getServerPort()); + } + return new Uri(); + } + + private static Route getRouteNamed(String pathName, ServletRequest request) { + String[] routingConfigClasses = (String[]) request.getServletContext().getAttribute(Application.ROUTING_CONFIG_CLASSES); + for(String configClass : routingConfigClasses) { + RouteManager routingConfig = (RouteManager) request.getServletContext().getAttribute(configClass); + Route route = routingConfig.getRouteNamed(pathName); + if(route != null) return route; + } + throw new NoSuchElementException(String.format(Errors.ROUTE_NAME_NOT_FOUND, pathName)); + } +} diff --git a/hex_action/test/hex/action/ActionTests.java b/hex_action/test/hex/action/ActionTests.java index bcb6ec4..3936ae9 100644 --- a/hex_action/test/hex/action/ActionTests.java +++ b/hex_action/test/hex/action/ActionTests.java @@ -1,7 +1,7 @@ package hex.action; import hex.action.params.ParamsSuite; -import hex.action.routing.RouteManagerTest; +import hex.action.routing.RoutingSuite; import hex.action.views.jsp.TagTests; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -12,7 +12,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ ControllerActionTest.class, - RouteManagerTest.class, + RoutingSuite.class, ControllerTest.class, ParamsSuite.class, TagTests.class diff --git a/hex_action/test/hex/action/routing/RoutingSuite.java b/hex_action/test/hex/action/routing/RoutingSuite.java new file mode 100644 index 0000000..51f95d8 --- /dev/null +++ b/hex_action/test/hex/action/routing/RoutingSuite.java @@ -0,0 +1,15 @@ +package hex.action.routing; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Created by jason on 15-01-04. + */ +@RunWith(Suite.class) @Suite.SuiteClasses({ + RouteManagerTest.class, + UriTest.class +}) +public class RoutingSuite { + +} diff --git a/hex_action/test/hex/action/routing/UriTest.java b/hex_action/test/hex/action/routing/UriTest.java new file mode 100644 index 0000000..f750bd3 --- /dev/null +++ b/hex_action/test/hex/action/routing/UriTest.java @@ -0,0 +1,28 @@ +package hex.action.routing; + +import org.junit.Test; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +/** + * Created by jason on 15-01-04. + */ +public class UriTest { + @Test + public void queryParamsShouldBeFormattedCorrectly() { + Uri uri = new Uri(); + uri.setPath("/cowboys"); + uri.addQueryParam("and", "aliens"); + assertThat(uri.toString(), is("/cowboys?and=aliens")); + } + + @Test + public void multipleQueryParamsShouldBeCool() { + Uri uri = new Uri(); + uri.setPath("/posts"); + uri.addQueryParam("tag", "interesting"); + uri.addQueryParam("title", "Atlantis"); + assertThat(uri.toString(), is("/posts?tag=interesting&title=Atlantis")); + } +} From f4b57677d22bb4914ab5b2bf92b8b9b864072c82 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 4 Jan 2015 15:04:23 -0700 Subject: [PATCH 14/26] forgot this class a few commits back --- hex_routing/test/hex/routing/test/Post.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 hex_routing/test/hex/routing/test/Post.java diff --git a/hex_routing/test/hex/routing/test/Post.java b/hex_routing/test/hex/routing/test/Post.java new file mode 100644 index 0000000..500ece9 --- /dev/null +++ b/hex_routing/test/hex/routing/test/Post.java @@ -0,0 +1,16 @@ +package hex.routing.test; + +/** + * Created by jason on 15-01-03. + */ +public class Post { + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} From 3391abd27c4509d577c7b19a67c50ce7c181b493 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 4 Jan 2015 17:15:30 -0700 Subject: [PATCH 15/26] a little less efficient but cleaner code --- hex_action/src/hex/action/routing/Uri.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hex_action/src/hex/action/routing/Uri.java b/hex_action/src/hex/action/routing/Uri.java index 042c90a..d9e28e8 100644 --- a/hex_action/src/hex/action/routing/Uri.java +++ b/hex_action/src/hex/action/routing/Uri.java @@ -5,8 +5,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; -import java.util.StringJoiner; -import java.util.function.Consumer; +import java.util.stream.Collectors; /** * Created by jason on 15-01-04. @@ -41,11 +40,7 @@ public String toString() { path.ifPresent(builder::append); if(queryParams.size() > 0) { builder.append('?'); - Consumer> entryAppender = e -> - builder.append(e.getKey()).append('=').append(e.getValue()); - - queryParams.entrySet().stream().findFirst().ifPresent(entryAppender); - queryParams.entrySet().stream().skip(1).peek(e -> builder.append('&')).forEach(entryAppender); + builder.append(queryParams.entrySet().stream().map(Object::toString).collect(Collectors.joining("&"))); } return builder.toString(); } From d6a3a483f624207d665d3e04b077568ad2e8d5b5 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Wed, 7 Jan 2015 22:47:55 -0700 Subject: [PATCH 16/26] add todo about warning --- hex_action/src/hex/action/routing/Uri.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hex_action/src/hex/action/routing/Uri.java b/hex_action/src/hex/action/routing/Uri.java index d9e28e8..101172b 100644 --- a/hex_action/src/hex/action/routing/Uri.java +++ b/hex_action/src/hex/action/routing/Uri.java @@ -50,6 +50,7 @@ public void addQueryParam(String name, String value) { queryParams.put(name, URLEncoder.encode(value, "UTF-8")); } catch (UnsupportedEncodingException e) { // hardcoded UTF-8 + // TODO: Log a warning here, just in case. } } From d9d9755397b143db75e5e221bd58254eaee31d2f Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Wed, 7 Jan 2015 23:25:17 -0700 Subject: [PATCH 17/26] all the Uri elements --- hex_action/src/hex/action/routing/Uri.java | 7 +++++++ .../test/hex/action/routing/UriTest.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/hex_action/src/hex/action/routing/Uri.java b/hex_action/src/hex/action/routing/Uri.java index 101172b..9e8e057 100644 --- a/hex_action/src/hex/action/routing/Uri.java +++ b/hex_action/src/hex/action/routing/Uri.java @@ -21,6 +21,8 @@ class Uri { private Optional path = Optional.empty(); + private Optional anchor = Optional.empty(); + private Map queryParams = new LinkedHashMap<>(); public static Uri create(String scheme, String host, int port) { @@ -42,6 +44,7 @@ public String toString() { builder.append('?'); builder.append(queryParams.entrySet().stream().map(Object::toString).collect(Collectors.joining("&"))); } + anchor.ifPresent(s -> builder.append('#').append(s)); return builder.toString(); } @@ -61,4 +64,8 @@ public void setContext(String context) { public void setPath(String path) { this.path = Optional.ofNullable(path); } + + public void setAnchor(String anchorValue) { + this.anchor = Optional.ofNullable(anchorValue); + } } diff --git a/hex_action/test/hex/action/routing/UriTest.java b/hex_action/test/hex/action/routing/UriTest.java index f750bd3..22303d2 100644 --- a/hex_action/test/hex/action/routing/UriTest.java +++ b/hex_action/test/hex/action/routing/UriTest.java @@ -25,4 +25,22 @@ public void multipleQueryParamsShouldBeCool() { uri.addQueryParam("title", "Atlantis"); assertThat(uri.toString(), is("/posts?tag=interesting&title=Atlantis")); } + + @Test + public void queryStringAndAnchor() { + Uri uri = new Uri(); + uri.setPath("/aliens"); + uri.addQueryParam("encounterYear", "1947"); + uri.setAnchor("list"); + assertThat(uri.toString(), is("/aliens?encounterYear=1947#list")); + } + + @Test + public void onceMoreWithFeeling() { + Uri uri = Uri.create("https", "example.com", 3000); + uri.setPath("/roswell"); + uri.addQueryParam("recordYear", "1947"); + uri.setAnchor("conspiracies"); + assertThat(uri.toString(), is("https://example.com:3000/roswell?recordYear=1947#conspiracies")); + } } From 7a6f52f2a31e9d6a70ee12ab2c5ff849c246e7bb Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 10 Jan 2015 22:23:15 -0700 Subject: [PATCH 18/26] rename to a factory (this is the beginning of the end) --- hex_action/src/hex/action/routing/Uri.java | 2 +- .../src/hex/action/routing/{UrlUtils.java => UriFactory.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename hex_action/src/hex/action/routing/{UrlUtils.java => UriFactory.java} (98%) diff --git a/hex_action/src/hex/action/routing/Uri.java b/hex_action/src/hex/action/routing/Uri.java index 9e8e057..ac9e036 100644 --- a/hex_action/src/hex/action/routing/Uri.java +++ b/hex_action/src/hex/action/routing/Uri.java @@ -10,7 +10,7 @@ /** * Created by jason on 15-01-04. */ -class Uri { +public class Uri { private Optional scheme = Optional.empty(); private Optional host = Optional.empty(); diff --git a/hex_action/src/hex/action/routing/UrlUtils.java b/hex_action/src/hex/action/routing/UriFactory.java similarity index 98% rename from hex_action/src/hex/action/routing/UrlUtils.java rename to hex_action/src/hex/action/routing/UriFactory.java index ff498ef..d4d8334 100644 --- a/hex_action/src/hex/action/routing/UrlUtils.java +++ b/hex_action/src/hex/action/routing/UriFactory.java @@ -11,7 +11,7 @@ /** * Created by jason on 15-01-03. */ -public class UrlUtils { +public class UriFactory { private static final Pattern PATH_NAME_PATTERN = Pattern.compile("(.*)_(url|path)$"); private static final String URL = "url"; From 45c0bf3b0edd76c547fa4423004ddbea9b6a074c Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 10 Jan 2015 23:58:28 -0700 Subject: [PATCH 19/26] implement link tag to reference path names in route manager --- .../views/layouts/application.html.jsp | 10 ++- .../views/people/index.html.jsp | 3 +- hex_action/resources/META-INF/tld/hex.tld | 26 ++++++ .../src/hex/action/routing/RouteManager.java | 19 ++++- .../hex/action/views/html/HtmlElement.java | 82 +++++++++++++++++++ .../hex/action/views/jsp/tags/LinkTag.java | 64 +++++++++++++++ .../action/views/jsp/tags/QueryParamTag.java | 45 ++++++++++ hex_action/test/hex/action/ActionTests.java | 4 +- .../hex/action/routing/RouteManagerTest.java | 7 ++ .../test/hex/action/views/ViewsSuite.java | 16 ++++ .../action/views/html/HtmlElementTest.java | 57 +++++++++++++ 11 files changed, 322 insertions(+), 11 deletions(-) create mode 100644 hex_action/src/hex/action/views/html/HtmlElement.java create mode 100644 hex_action/src/hex/action/views/jsp/tags/LinkTag.java create mode 100644 hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java create mode 100644 hex_action/test/hex/action/views/ViewsSuite.java create mode 100644 hex_action/test/hex/action/views/html/HtmlElementTest.java diff --git a/example_application/views/layouts/application.html.jsp b/example_application/views/layouts/application.html.jsp index 3d4cf84..7e885d9 100644 --- a/example_application/views/layouts/application.html.jsp +++ b/example_application/views/layouts/application.html.jsp @@ -9,10 +9,12 @@

Hex Example Application

Menu

diff --git a/example_application/views/people/index.html.jsp b/example_application/views/people/index.html.jsp index 211e3bc..dafa112 100644 --- a/example_application/views/people/index.html.jsp +++ b/example_application/views/people/index.html.jsp @@ -29,5 +29,4 @@ - -Create New Person +Create New Person diff --git a/hex_action/resources/META-INF/tld/hex.tld b/hex_action/resources/META-INF/tld/hex.tld index 7572968..1b57d6d 100644 --- a/hex_action/resources/META-INF/tld/hex.tld +++ b/hex_action/resources/META-INF/tld/hex.tld @@ -28,4 +28,30 @@ hex.action.views.jsp.tags.ViewInitTag empty + + link + hex.action.views.jsp.tags.LinkTag + JSP + + action + true + + + anchor + false + + + + query-param + hex.action.views.jsp.tags.QueryParamTag + empty + + name + true + + + value + true + + diff --git a/hex_action/src/hex/action/routing/RouteManager.java b/hex_action/src/hex/action/routing/RouteManager.java index 7e191c9..345f89d 100644 --- a/hex_action/src/hex/action/routing/RouteManager.java +++ b/hex_action/src/hex/action/routing/RouteManager.java @@ -6,6 +6,7 @@ import hex.routing.Route; import java.util.*; +import java.util.function.Predicate; import java.util.function.Supplier; /** @@ -54,16 +55,28 @@ protected void delete(String path, Supplier controllerSupplier, Stri } protected void matches(String path, Supplier controllerSupplier, String action) { - definedRoutes.add(new Route(HttpMethod.ANY, path, getHandler(controllerSupplier, action))); + addRoute(HttpMethod.ANY, path, getHandler(controllerSupplier, action)); + } + + private void addRoute(Predicate any, String path, ControllerAction handler) { + Route route = new Route(any, path, handler); + definedRoutes.add(route); + registerRouteName(handler.getName(), path, route); } private void addRoute(HttpMethod method, String path, ControllerAction handler) { Route route = new Route(method, path, handler); + definedRoutes.add(route); + registerRouteName(handler.getName(), path, route); + } + + private void registerRouteName(String actionName, String path, Route route) { String pathName = Route.PATH_PARAM_PATTERN.matcher(path).replaceAll("") .replaceFirst("/", "") .replaceAll("/", "_"); - definedRoutes.add(route); - routeMap.put(String.format("%s_%s", handler.getName(), pathName), route); + String routeName = actionName; + if(pathName.length() > 0) routeName += "_" + pathName; + routeMap.put(routeName, route); } Route getRouteNamed(String routeName) { diff --git a/hex_action/src/hex/action/views/html/HtmlElement.java b/hex_action/src/hex/action/views/html/HtmlElement.java new file mode 100644 index 0000000..d4668cc --- /dev/null +++ b/hex_action/src/hex/action/views/html/HtmlElement.java @@ -0,0 +1,82 @@ +package hex.action.views.html; + +import javax.servlet.jsp.JspWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.*; + +/** + * Created by jason on 15-01-10. + */ +public class HtmlElement { + private static final char LT = '<'; + private static final char GT = '>'; + private static final char CS = '/'; + private static final char SPACE = ' '; + private static final char EQ = '='; + private static final char QUOTE = '"'; + + private String tagName; + + private String body; + + private final Map attributes = new LinkedHashMap<>(); + + public HtmlElement(String tagName) { + this.tagName = tagName; + } + + public void setBody(String body) { + this.body = body; + } + + public String toString() { + StringWriter out = new StringWriter(); + try { + write(out); + } catch (IOException e) { + // StringWriter won't throw exception + // And if it does.... whatever... + } + return out.toString(); + } + + public HtmlElement setAttribute(String name, String value) { + attributes.put(name, value); + return this; + } + + public void removeAttribute(String name) { + attributes.remove(name); + } + + public String getAttribute(String name) { + return attributes.get(name); + } + + private Writer quote(String value, Writer to) throws IOException { + return to.append(QUOTE).append(value).append(QUOTE); + } + + public void write(Writer out) throws IOException { + List errors = new ArrayList<>(); + out.append(LT).append(tagName); + if(attributes.size() > 0) { + attributes.forEach((k,v) -> { + try { + out.append(SPACE).append(k).append(EQ); + quote(v, out); + } catch (IOException e) { + errors.add(e); + } + }); + if(errors.size() > 0) throw errors.get(0); + } + if(body == null) { + out.append(CS).append(GT); + } else { + out.append(GT).append(body).append(LT).append(CS).append(tagName).append(GT); + } + } +} diff --git a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java new file mode 100644 index 0000000..b8cad4a --- /dev/null +++ b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java @@ -0,0 +1,64 @@ +package hex.action.views.jsp.tags; + +import hex.action.routing.Uri; +import hex.action.routing.UriFactory; +import hex.action.views.html.HtmlElement; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.BodyTagSupport; +import java.io.IOException; + +/** + * Created by jason on 15-01-03. + */ +public class LinkTag extends BodyTagSupport { + private String actionName; + + private String anchor; + + public void setAction(String actionName) { + this.actionName = actionName; + } + + public void setAnchor(String anchor) { + this.anchor = anchor; + } + + private Uri uri; + + public Uri getUri() { + return uri; + } + + /** + * Default processing of the start tag, returning SKIP_BODY. + * + * @return SKIP_BODY + * @throws javax.servlet.jsp.JspException if an error occurs while processing this tag + */ + @Override + public int doStartTag() throws JspException { + uri = UriFactory.getUrlFor(actionName, pageContext.getRequest()); + uri.setAnchor(anchor); + return EVAL_BODY_BUFFERED; + } + + /** + * Default processing of the end tag returning EVAL_PAGE. + * + * @return EVAL_PAGE + * @throws javax.servlet.jsp.JspException if an error occurs while processing this tag + */ + @Override + public int doEndTag() throws JspException { + HtmlElement element = new HtmlElement("a"); + element.setAttribute("href", uri.toString()); + element.setBody(getBodyContent().getString()); + try { + element.write(pageContext.getOut()); + } catch (IOException e) { + throw new JspException("Error while writing html element", e); + } + return EVAL_PAGE; + } +} diff --git a/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java b/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java new file mode 100644 index 0000000..fac99a5 --- /dev/null +++ b/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java @@ -0,0 +1,45 @@ +package hex.action.views.jsp.tags; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; +import java.io.IOException; +import java.util.Objects; + +/** + * Created by jason on 15-01-07. + */ +public class QueryParamTag extends SimpleTagSupport { + private String name; + + private String value; + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * Default processing of the tag does nothing. + * + * @throws javax.servlet.jsp.JspException Subclasses can throw JspException to indicate + * an error occurred while processing this tag. + * @throws javax.servlet.jsp.SkipPageException If the page that + * (either directly or indirectly) invoked this tag is to + * cease evaluation. A Simple Tag Handler generated from a + * tag file must throw this exception if an invoked Classic + * Tag Handler returned SKIP_PAGE or if an invoked Simple + * Tag Handler threw SkipPageException or if an invoked Jsp Fragment + * threw a SkipPageException. + * @throws java.io.IOException Subclasses can throw IOException if there was + * an error writing to the output stream + */ + @Override + public void doTag() throws JspException, IOException { + LinkTag tag = (LinkTag)findAncestorWithClass(this, LinkTag.class); + Objects.requireNonNull(tag); + tag.getUri().addQueryParam(name, value); + } +} diff --git a/hex_action/test/hex/action/ActionTests.java b/hex_action/test/hex/action/ActionTests.java index 3936ae9..398f198 100644 --- a/hex_action/test/hex/action/ActionTests.java +++ b/hex_action/test/hex/action/ActionTests.java @@ -2,7 +2,7 @@ import hex.action.params.ParamsSuite; import hex.action.routing.RoutingSuite; -import hex.action.views.jsp.TagTests; +import hex.action.views.ViewsSuite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -15,7 +15,7 @@ RoutingSuite.class, ControllerTest.class, ParamsSuite.class, - TagTests.class + ViewsSuite.class }) public class ActionTests { } diff --git a/hex_action/test/hex/action/routing/RouteManagerTest.java b/hex_action/test/hex/action/routing/RouteManagerTest.java index 4a69095..b4d72b5 100644 --- a/hex_action/test/hex/action/routing/RouteManagerTest.java +++ b/hex_action/test/hex/action/routing/RouteManagerTest.java @@ -90,4 +90,11 @@ public void addingNestedRoutesShouldNestPathNames() { Route route = routeManager.getRouteNamed("show_posts_comments"); assertThat(route, notNullValue()); } + + @Test + public void routesToRootShouldBeJustTheActionName() { + routeManager.matches("/", PostsController::new, "home"); + Route route = routeManager.getRouteNamed("home"); + assertThat(route, notNullValue()); + } } diff --git a/hex_action/test/hex/action/views/ViewsSuite.java b/hex_action/test/hex/action/views/ViewsSuite.java new file mode 100644 index 0000000..76a9b9c --- /dev/null +++ b/hex_action/test/hex/action/views/ViewsSuite.java @@ -0,0 +1,16 @@ +package hex.action.views; + +import hex.action.views.html.HtmlElementTest; +import hex.action.views.jsp.TagTests; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Created by jason on 15-01-10. + */ +@RunWith(Suite.class) @Suite.SuiteClasses({ + TagTests.class, + HtmlElementTest.class +}) +public class ViewsSuite { +} diff --git a/hex_action/test/hex/action/views/html/HtmlElementTest.java b/hex_action/test/hex/action/views/html/HtmlElementTest.java new file mode 100644 index 0000000..567e2c8 --- /dev/null +++ b/hex_action/test/hex/action/views/html/HtmlElementTest.java @@ -0,0 +1,57 @@ +package hex.action.views.html; + +import org.hamcrest.Matchers; +import org.junit.Test; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +/** + * Created by jason on 15-01-10. + */ +public class HtmlElementTest { + private HtmlElement tag; + + private void setTag(String tagName) { + this.tag = new HtmlElement(tagName); + } + + @Test + public void shouldRenderHtml() { + setTag("a"); + tag.setBody("Home"); + assertThat(tag.toString(), is("Home")); + } + + @Test + public void shouldSelfCloseWhenAppropriate() { + setTag("rara"); + assertThat(tag.toString(), is("")); + } + + @Test + public void shouldIncludeAttributesWithSelfClosing() { + setTag("input"); + tag.setAttribute("type", "text"); + tag.setAttribute("name", "userName"); + String tagHtml = tag.toString(); + assertThat(tagHtml, containsString("")); + } + + @Test + public void shouldIncludeAttributesInBodyTag() { + setTag("form"); + tag.setAttribute("method", "POST"); + tag.setAttribute("action", "/people"); + tag.setBody("some form html"); + String tagHtml = tag.toString(); + assertThat(tagHtml, containsString("some form html<")); + assertThat(tagHtml, containsString("")); + } +} From 806f83c6aea936fdc9104ac33e948ad76eb6e9af Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 11 Jan 2015 00:32:12 -0700 Subject: [PATCH 20/26] add to attribute to link tag to fill in route params --- example_application/views/people/index.html.jsp | 3 +-- hex_action/resources/META-INF/tld/hex.tld | 5 +++++ hex_action/src/hex/action/routing/UriFactory.java | 6 +++++- hex_action/src/hex/action/views/jsp/tags/LinkTag.java | 8 +++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/example_application/views/people/index.html.jsp b/example_application/views/people/index.html.jsp index dafa112..26c6ddc 100644 --- a/example_application/views/people/index.html.jsp +++ b/example_application/views/people/index.html.jsp @@ -22,8 +22,7 @@ ${p.firstName} ${p.lastName} - - View + View diff --git a/hex_action/resources/META-INF/tld/hex.tld b/hex_action/resources/META-INF/tld/hex.tld index 1b57d6d..97cbb77 100644 --- a/hex_action/resources/META-INF/tld/hex.tld +++ b/hex_action/resources/META-INF/tld/hex.tld @@ -40,6 +40,11 @@ anchor false + + to + false + true + query-param diff --git a/hex_action/src/hex/action/routing/UriFactory.java b/hex_action/src/hex/action/routing/UriFactory.java index d4d8334..792efb8 100644 --- a/hex_action/src/hex/action/routing/UriFactory.java +++ b/hex_action/src/hex/action/routing/UriFactory.java @@ -17,6 +17,10 @@ public class UriFactory { private static final String URL = "url"; public static Uri getUrlFor(String pathRef, ServletRequest request) { + return getUrlFor(pathRef, request, null); + } + + public static Uri getUrlFor(String pathRef, ServletRequest request, Object values) { Matcher m = PATH_NAME_PATTERN.matcher(pathRef); if(!m.matches()) throw new IllegalArgumentException("Path reference did not match format (path_name)_(url|path)"); String pathName = m.group(1); @@ -25,7 +29,7 @@ public static Uri getUrlFor(String pathRef, ServletRequest request) { Uri uri = getUri(uriType, request); uri.setContext(request.getServletContext().getContextPath()); // TODO: add check for Tomcat mode with it's stupid trailing slash in "directory paths" - uri.setPath(route.createPath()); + uri.setPath(route.createPath(values)); return uri; } diff --git a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java index b8cad4a..9586c0f 100644 --- a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java @@ -16,6 +16,8 @@ public class LinkTag extends BodyTagSupport { private String anchor; + private Object values; + public void setAction(String actionName) { this.actionName = actionName; } @@ -24,6 +26,10 @@ public void setAnchor(String anchor) { this.anchor = anchor; } + public void setTo(Object values) { + this.values = values; + } + private Uri uri; public Uri getUri() { @@ -38,7 +44,7 @@ public Uri getUri() { */ @Override public int doStartTag() throws JspException { - uri = UriFactory.getUrlFor(actionName, pageContext.getRequest()); + uri = UriFactory.getUrlFor(actionName, pageContext.getRequest(), values); uri.setAnchor(anchor); return EVAL_BODY_BUFFERED; } From ef46851fec47449f6c6d7de8489388e97de5af6d Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 11 Jan 2015 14:16:55 -0700 Subject: [PATCH 21/26] optimize imports --- hex_action/src/hex/action/views/html/HtmlElement.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hex_action/src/hex/action/views/html/HtmlElement.java b/hex_action/src/hex/action/views/html/HtmlElement.java index d4668cc..3d6eaf6 100644 --- a/hex_action/src/hex/action/views/html/HtmlElement.java +++ b/hex_action/src/hex/action/views/html/HtmlElement.java @@ -1,10 +1,12 @@ package hex.action.views.html; -import javax.servlet.jsp.JspWriter; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; /** * Created by jason on 15-01-10. From 1d0f4cc98e48e73bb1469f892e6a0582c176dcd8 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Thu, 22 Jan 2015 23:10:52 -0700 Subject: [PATCH 22/26] params tags working for non-object setting --- hex_action/resources/META-INF/tld/hex.tld | 15 +++++++ .../src/hex/action/routing/UriFactory.java | 6 +-- .../hex/action/views/jsp/tags/LinkTag.java | 23 +++++++--- .../hex/action/views/jsp/tags/ParamTag.java | 44 +++++++++++++++++++ .../action/views/jsp/tags/QueryParamTag.java | 17 ++----- .../src/hex/action/views/jsp/tags/UriTag.java | 14 ++++++ hex_routing/test/hex/routing/RouteTest.java | 11 +++++ .../hex/utils/coercion/CoercionObject.java | 2 + 8 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 hex_action/src/hex/action/views/jsp/tags/ParamTag.java create mode 100644 hex_action/src/hex/action/views/jsp/tags/UriTag.java diff --git a/hex_action/resources/META-INF/tld/hex.tld b/hex_action/resources/META-INF/tld/hex.tld index 97cbb77..f5eab94 100644 --- a/hex_action/resources/META-INF/tld/hex.tld +++ b/hex_action/resources/META-INF/tld/hex.tld @@ -57,6 +57,21 @@ value true + true + + + + param + hex.action.views.jsp.tags.ParamTag + empty + + name + true + + + value + true + true diff --git a/hex_action/src/hex/action/routing/UriFactory.java b/hex_action/src/hex/action/routing/UriFactory.java index 792efb8..9102bac 100644 --- a/hex_action/src/hex/action/routing/UriFactory.java +++ b/hex_action/src/hex/action/routing/UriFactory.java @@ -16,19 +16,15 @@ public class UriFactory { private static final String URL = "url"; - public static Uri getUrlFor(String pathRef, ServletRequest request) { - return getUrlFor(pathRef, request, null); - } - public static Uri getUrlFor(String pathRef, ServletRequest request, Object values) { Matcher m = PATH_NAME_PATTERN.matcher(pathRef); if(!m.matches()) throw new IllegalArgumentException("Path reference did not match format (path_name)_(url|path)"); String pathName = m.group(1); String uriType = m.group(2); - Route route = getRouteNamed(pathName, request); Uri uri = getUri(uriType, request); uri.setContext(request.getServletContext().getContextPath()); // TODO: add check for Tomcat mode with it's stupid trailing slash in "directory paths" + Route route = getRouteNamed(pathName, request); uri.setPath(route.createPath(values)); return uri; } diff --git a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java index 9586c0f..8f68002 100644 --- a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java @@ -7,17 +7,23 @@ import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * Created by jason on 15-01-03. */ -public class LinkTag extends BodyTagSupport { +public class LinkTag extends BodyTagSupport implements UriTag { private String actionName; private String anchor; private Object values; + private Map params; + + private Map queryParams; + public void setAction(String actionName) { this.actionName = actionName; } @@ -30,10 +36,13 @@ public void setTo(Object values) { this.values = values; } - private Uri uri; + @Override + public void setQueryParam(String name, String value) { + queryParams.put(name, value); + } - public Uri getUri() { - return uri; + public void setParam(String name, String value) { + params.put(name, value); } /** @@ -44,8 +53,8 @@ public Uri getUri() { */ @Override public int doStartTag() throws JspException { - uri = UriFactory.getUrlFor(actionName, pageContext.getRequest(), values); - uri.setAnchor(anchor); + params = new HashMap<>(); + queryParams = new HashMap<>(); return EVAL_BODY_BUFFERED; } @@ -57,6 +66,8 @@ public int doStartTag() throws JspException { */ @Override public int doEndTag() throws JspException { + Uri uri = UriFactory.getUrlFor(actionName, pageContext.getRequest(), + params.size() > 0 ? params : values); HtmlElement element = new HtmlElement("a"); element.setAttribute("href", uri.toString()); element.setBody(getBodyContent().getString()); diff --git a/hex_action/src/hex/action/views/jsp/tags/ParamTag.java b/hex_action/src/hex/action/views/jsp/tags/ParamTag.java new file mode 100644 index 0000000..d73bce3 --- /dev/null +++ b/hex_action/src/hex/action/views/jsp/tags/ParamTag.java @@ -0,0 +1,44 @@ +package hex.action.views.jsp.tags; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; +import java.io.IOException; +import java.util.Objects; + +/** + * Created by jason on 15-01-13. + */ +public class ParamTag extends SimpleTagSupport { + protected String name; + + protected String value; + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } + + /** + * Default processing of the tag does nothing. + * + * @throws javax.servlet.jsp.JspException Subclasses can throw JspException to indicate + * an error occurred while processing this tag. + * @throws javax.servlet.jsp.SkipPageException If the page that + * (either directly or indirectly) invoked this tag is to + * cease evaluation. A Simple Tag Handler generated from a + * tag file must throw this exception if an invoked Classic + * Tag Handler returned SKIP_PAGE or if an invoked Simple + * Tag Handler threw SkipPageException or if an invoked Jsp Fragment + * threw a SkipPageException. + * @throws java.io.IOException Subclasses can throw IOException if there was + */ + @Override + public void doTag() throws JspException, IOException { + UriTag tag = (UriTag) findAncestorWithClass(this, UriTag.class); + Objects.requireNonNull(tag); + tag.setParam(name, value); + } +} diff --git a/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java b/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java index fac99a5..1f846e6 100644 --- a/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java @@ -8,18 +8,7 @@ /** * Created by jason on 15-01-07. */ -public class QueryParamTag extends SimpleTagSupport { - private String name; - - private String value; - - public void setName(String name) { - this.name = name; - } - - public void setValue(String value) { - this.value = value; - } +public class QueryParamTag extends ParamTag { /** * Default processing of the tag does nothing. @@ -38,8 +27,8 @@ public void setValue(String value) { */ @Override public void doTag() throws JspException, IOException { - LinkTag tag = (LinkTag)findAncestorWithClass(this, LinkTag.class); + UriTag tag = (UriTag)findAncestorWithClass(this, UriTag.class); Objects.requireNonNull(tag); - tag.getUri().addQueryParam(name, value); + tag.setQueryParam(name, value); } } diff --git a/hex_action/src/hex/action/views/jsp/tags/UriTag.java b/hex_action/src/hex/action/views/jsp/tags/UriTag.java new file mode 100644 index 0000000..b0a7657 --- /dev/null +++ b/hex_action/src/hex/action/views/jsp/tags/UriTag.java @@ -0,0 +1,14 @@ +package hex.action.views.jsp.tags; + +import hex.action.routing.Uri; + +import java.util.Map; + +/** + * Created by jason on 15-01-16. + */ +public interface UriTag { + void setQueryParam(String name, String value); + + void setParam(String name, String value); +} diff --git a/hex_routing/test/hex/routing/RouteTest.java b/hex_routing/test/hex/routing/RouteTest.java index c8947b6..017f8d5 100644 --- a/hex_routing/test/hex/routing/RouteTest.java +++ b/hex_routing/test/hex/routing/RouteTest.java @@ -26,6 +26,8 @@ import hex.routing.test.Post; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; import java.util.stream.Stream; import static org.hamcrest.Matchers.is; @@ -98,4 +100,13 @@ public void createPathShouldSubstituteParamsWithPassedInProperties() { String path = route.createPath(post); assertThat(path, is("/posts/99")); } + + @Test + public void createPathShouldWorkWithMapsAsWell() { + Route route = new Route("/home/:profile", RoutingConfigTest.CALLED); + Map params = new HashMap<>(); + params.put("profile", "a.einstein"); + String path = route.createPath(params); + assertThat(path, is("/home/a.einstein")); + } } diff --git a/hex_utils/src/hex/utils/coercion/CoercionObject.java b/hex_utils/src/hex/utils/coercion/CoercionObject.java index 3a8890b..34cd938 100644 --- a/hex_utils/src/hex/utils/coercion/CoercionObject.java +++ b/hex_utils/src/hex/utils/coercion/CoercionObject.java @@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Map; /** * Created by jason on 15-01-03. @@ -18,6 +19,7 @@ public CoercionObject(Object source) { @Override public Object get(Object index) { + if(source instanceof Map) return ((Map)source).get(index); String propertyName = (String)index; try { Method getter = source.getClass().getMethod(Inflection.toGetter(propertyName)); From cac5dc42e2111bf20f0b44f0f83fedb1dced5ba1 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 24 Jan 2015 17:34:52 -0700 Subject: [PATCH 23/26] separate viewcontext setup for test --- .../test/hex/action/views/jsp/tags/ViewContentTagTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java b/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java index d7483ce..8572129 100644 --- a/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java +++ b/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java @@ -27,8 +27,12 @@ public class ViewContentTagTest { protected MockJspContext jspContext; @Before - public void setUp() { + public void setUpViewContext() { view = new ViewContext(); + } + + @Before + public void setUp() { tag = new ViewContentTag(); view.setContent("This is action view template content"); } From ff99274938535618d80865d1021afae727ceff47 Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Fri, 4 Sep 2015 22:56:19 -0600 Subject: [PATCH 24/26] start refactoring action base tag --- .../views/jsp/tags/HexActionTagBase.java | 49 +++ .../hex/action/views/jsp/tags/LinkTag.java | 37 +- .../action/views/jsp/tags/LinkTagTest.java | 41 +++ .../test/servlet_mock/jsp/MockJspContext.java | 318 +++++++++++++++++- 4 files changed, 409 insertions(+), 36 deletions(-) create mode 100644 hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java create mode 100644 hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java diff --git a/hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java b/hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java new file mode 100644 index 0000000..5cad85e --- /dev/null +++ b/hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java @@ -0,0 +1,49 @@ +package hex.action.views.jsp.tags; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.BodyTagSupport; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by jason on 15-01-24. + */ +public abstract class HexActionTagBase extends BodyTagSupport implements UriTag { + protected String actionName; + + protected Object values; + + protected Map params; + + private Map queryParams; + + public void setAction(String actionName) { + this.actionName = actionName; + } + + public void setValues(Object values) { + this.values = values; + } + + @Override + public void setQueryParam(String name, String value) { + queryParams.put(name, value); + } + + public void setParam(String name, String value) { + params.put(name, value); + } + + /** + * Default processing of the start tag, returning SKIP_BODY. + * + * @return SKIP_BODY + * @throws javax.servlet.jsp.JspException if an error occurs while processing this tag + */ + @Override + public int doStartTag() throws JspException { + params = new HashMap<>(); + queryParams = new HashMap<>(); + return EVAL_BODY_BUFFERED; + } +} diff --git a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java index 8f68002..b8dc4cf 100644 --- a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/LinkTag.java @@ -13,49 +13,16 @@ /** * Created by jason on 15-01-03. */ -public class LinkTag extends BodyTagSupport implements UriTag { - private String actionName; +public class LinkTag extends HexActionTagBase { private String anchor; - private Object values; - - private Map params; - - private Map queryParams; - - public void setAction(String actionName) { - this.actionName = actionName; - } - public void setAnchor(String anchor) { this.anchor = anchor; } public void setTo(Object values) { - this.values = values; - } - - @Override - public void setQueryParam(String name, String value) { - queryParams.put(name, value); - } - - public void setParam(String name, String value) { - params.put(name, value); - } - - /** - * Default processing of the start tag, returning SKIP_BODY. - * - * @return SKIP_BODY - * @throws javax.servlet.jsp.JspException if an error occurs while processing this tag - */ - @Override - public int doStartTag() throws JspException { - params = new HashMap<>(); - queryParams = new HashMap<>(); - return EVAL_BODY_BUFFERED; + setValues(values); } /** diff --git a/hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java b/hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java new file mode 100644 index 0000000..db52f12 --- /dev/null +++ b/hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java @@ -0,0 +1,41 @@ +package hex.action.views.jsp.tags; + +import hex.action.Application; +import hex.action.routing.RouteManager; +import org.junit.Before; +import org.junit.Test; +import servlet_mock.jsp.MockJspContext; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Created by jason on 15-01-24. + */ +public class LinkTagTest { + private RouteManager routes = new RouteManager(); + + private LinkTag tag; + + @Before + public void setUpTag() { + tag = new LinkTag(); + } + + @Test + public void linksShouldRenderQueryParams() { + + } + + private void setUpRequest(HttpServletRequest request, HttpServletResponse response) { + setUpRoutes(request.getServletContext()); + tag.setPageContext(new MockJspContext(request)); + + } + + private void setUpRoutes(ServletContext servletContext) { + servletContext.setAttribute(Application.ROUTING_CONFIG_CLASSES, new String[]{ LinkTagTest.class.getName() }); + servletContext.setAttribute(LinkTagTest.class.getName(), routes); + } +} diff --git a/hex_routing/test/servlet_mock/jsp/MockJspContext.java b/hex_routing/test/servlet_mock/jsp/MockJspContext.java index 696799f..c25b788 100644 --- a/hex_routing/test/servlet_mock/jsp/MockJspContext.java +++ b/hex_routing/test/servlet_mock/jsp/MockJspContext.java @@ -3,12 +3,15 @@ import servlet_mock.MockHttpServletRequest; import javax.el.ELContext; +import javax.servlet.*; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.el.ExpressionEvaluator; import javax.servlet.jsp.el.VariableResolver; +import java.io.IOException; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -18,7 +21,7 @@ /** * Created by jason on 14-12-23. */ -public class MockJspContext extends JspContext { +public class MockJspContext extends PageContext { private final Map attributes = new HashMap<>(); private final HttpServletRequest request; @@ -312,4 +315,317 @@ public ELContext getELContext() { private IntStream scopeStream() { return IntStream.of(PageContext.PAGE_SCOPE, PageContext.REQUEST_SCOPE, PageContext.SESSION_SCOPE, PageContext.APPLICATION_SCOPE); } + + /** + *

+ * The initialize method is called to initialize an uninitialized PageContext + * so that it may be used by a JSP Implementation class to service an + * incoming request and response within it's _jspService() method. + *

+ *

+ * This method is typically called from JspFactory.getPageContext() in + * order to initialize state. + *

+ *

+ * This method is required to create an initial JspWriter, and associate + * the "out" name in page scope with this newly created object. + *

+ *

+ * This method should not be used by page or tag library authors. + * + * @param servlet The Servlet that is associated with this PageContext + * @param request The currently pending request for this Servlet + * @param response The currently pending response for this Servlet + * @param errorPageURL The value of the errorpage attribute from the page + * directive or null + * @param needsSession The value of the session attribute from the + * page directive + * @param bufferSize The value of the buffer attribute from the page + * directive + * @param autoFlush The value of the autoflush attribute from the page + * directive + * @throws java.io.IOException during creation of JspWriter + * @throws IllegalStateException if out not correctly initialized + * @throws IllegalArgumentException If one of the given parameters + * is invalid + */ + @Override + public void initialize(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) throws IOException, IllegalStateException, IllegalArgumentException { + + } + + /** + *

+ * This method shall "reset" the internal state of a PageContext, releasing + * all internal references, and preparing the PageContext for potential + * reuse by a later invocation of initialize(). This method is typically + * called from JspFactory.releasePageContext(). + *

+ *

+ * Subclasses shall envelope this method. + *

+ *

+ * This method should not be used by page or tag library authors. + */ + @Override + public void release() { + + } + + /** + * The current value of the session object (an HttpSession). + * + * @return the HttpSession for this PageContext or null + */ + @Override + public HttpSession getSession() { + return request.getSession(); + } + + /** + * The current value of the page object (In a Servlet environment, + * this is an instance of javax.servlet.Servlet). + * + * @return the Page implementation class instance associated + * with this PageContext + */ + @Override + public Object getPage() { + return null; + } + + /** + * The current value of the request object (a ServletRequest). + * + * @return The ServletRequest for this PageContext + */ + @Override + public ServletRequest getRequest() { + return request; + } + + /** + * The current value of the response object (a ServletResponse). + * + * @return the ServletResponse for this PageContext + */ + @Override + public ServletResponse getResponse() { + return null; + } + + /** + * The current value of the exception object (an Exception). + * + * @return any exception passed to this as an errorpage + */ + @Override + public Exception getException() { + return null; + } + + /** + * The ServletConfig instance. + * + * @return the ServletConfig for this PageContext + */ + @Override + public ServletConfig getServletConfig() { + return null; + } + + /** + * The ServletContext instance. + * + * @return the ServletContext for this PageContext + */ + @Override + public ServletContext getServletContext() { + return null; + } + + /** + *

+ * This method is used to re-direct, or "forward" the current + * ServletRequest and ServletResponse to another active component in + * the application. + *

+ *

+ * If the relativeUrlPath begins with a "/" then the URL specified + * is calculated relative to the DOCROOT of the ServletContext + * for this JSP. If the path does not begin with a "/" then the URL + * specified is calculated relative to the URL of the request that was + * mapped to the calling JSP. + *

+ *

+ * It is only valid to call this method from a Thread + * executing within a _jspService(...) method of a JSP. + *

+ *

+ * Once this method has been called successfully, it is illegal for the + * calling Thread to attempt to modify the + * ServletResponse object. Any such attempt to do so, shall result + * in undefined behavior. Typically, callers immediately return from + * _jspService(...) after calling this method. + *

+ * + * @param relativeUrlPath specifies the relative URL path to the target + * resource as described above + * @throws IllegalStateException if ServletResponse is not + * in a state where a forward can be performed + * @throws javax.servlet.ServletException if the page that was forwarded to throws + * a ServletException + * @throws java.io.IOException if an I/O error occurred while forwarding + */ + @Override + public void forward(String relativeUrlPath) throws ServletException, IOException { + request.getRequestDispatcher(relativeUrlPath).forward(request, getResponse()); + } + + /** + *

+ * Causes the resource specified to be processed as part of the current + * ServletRequest and ServletResponse being processed by the calling Thread. + * The output of the target resources processing of the request is written + * directly to the ServletResponse output stream. + *

+ *

+ * The current JspWriter "out" for this JSP is flushed as a side-effect + * of this call, prior to processing the include. + *

+ *

+ * If the relativeUrlPath begins with a "/" then the URL specified + * is calculated relative to the DOCROOT of the ServletContext + * for this JSP. If the path does not begin with a "/" then the URL + * specified is calculated relative to the URL of the request that was + * mapped to the calling JSP. + *

+ *

+ * It is only valid to call this method from a Thread + * executing within a _jspService(...) method of a JSP. + *

+ * + * @param relativeUrlPath specifies the relative URL path to the target + * resource to be included + * @throws javax.servlet.ServletException if the page that was forwarded to throws + * a ServletException + * @throws java.io.IOException if an I/O error occurred while forwarding + */ + @Override + public void include(String relativeUrlPath) throws ServletException, IOException { + request.getRequestDispatcher(relativeUrlPath).include(request, getResponse()); + } + + /** + *

+ * Causes the resource specified to be processed as part of the current + * ServletRequest and ServletResponse being processed by the calling Thread. + * The output of the target resources processing of the request is written + * directly to the current JspWriter returned by a call to getOut(). + *

+ *

+ * If flush is true, The current JspWriter "out" for this JSP + * is flushed as a side-effect of this call, prior to processing + * the include. Otherwise, the JspWriter "out" is not flushed. + *

+ *

+ * If the relativeUrlPath begins with a "/" then the URL specified + * is calculated relative to the DOCROOT of the ServletContext + * for this JSP. If the path does not begin with a "/" then the URL + * specified is calculated relative to the URL of the request that was + * mapped to the calling JSP. + *

+ *

+ * It is only valid to call this method from a Thread + * executing within a _jspService(...) method of a JSP. + *

+ * + * @param relativeUrlPath specifies the relative URL path to the + * target resource to be included + * @param flush True if the JspWriter is to be flushed before the include, + * or false if not. + * @throws javax.servlet.ServletException if the page that was forwarded to throws + * a ServletException + * @throws java.io.IOException if an I/O error occurred while forwarding + * @since JSP 2.0 + */ + @Override + public void include(String relativeUrlPath, boolean flush) throws ServletException, IOException { + + request.getRequestDispatcher(relativeUrlPath).include(request, getResponse()); + } + + /** + *

+ * This method is intended to process an unhandled 'page' level + * exception by forwarding the exception to the specified + * error page for this JSP. If forwarding is not possible (for + * example because the response has already been committed), an + * implementation dependent mechanism should be used to invoke + * the error page (e.g. "including" the error page instead). + *

+ *

+ * If no error page is defined in the page, the exception should + * be rethrown so that the standard servlet error handling + * takes over. + *

+ *

+ * A JSP implementation class shall typically clean up any local state + * prior to invoking this and will return immediately thereafter. It is + * illegal to generate any output to the client, or to modify any + * ServletResponse state after invoking this call. + *

+ *

+ * This method is kept for backwards compatiblity reasons. Newly + * generated code should use PageContext.handlePageException(Throwable). + * + * @param e the exception to be handled + * @throws javax.servlet.ServletException if an error occurs while invoking the error page + * @throws java.io.IOException if an I/O error occurred while invoking the error + * page + * @throws NullPointerException if the exception is null + * @see #handlePageException(Throwable) + */ + @Override + public void handlePageException(Exception e) throws ServletException, IOException { + + } + + /** + *

+ * This method is intended to process an unhandled 'page' level + * exception by forwarding the exception to the specified + * error page for this JSP. If forwarding is not possible (for + * example because the response has already been committed), an + * implementation dependent mechanism should be used to invoke + * the error page (e.g. "including" the error page instead). + *

+ *

+ * If no error page is defined in the page, the exception should + * be rethrown so that the standard servlet error handling + * takes over. + *

+ *

+ * This method is intended to process an unhandled "page" level exception + * by redirecting the exception to either the specified error page for this + * JSP, or if none was specified, to perform some implementation dependent + * action. + *

+ *

+ * A JSP implementation class shall typically clean up any local state + * prior to invoking this and will return immediately thereafter. It is + * illegal to generate any output to the client, or to modify any + * ServletResponse state after invoking this call. + * + * @param t the throwable to be handled + * @throws javax.servlet.ServletException if an error occurs while invoking the error page + * @throws java.io.IOException if an I/O error occurred while invoking the error + * page + * @throws NullPointerException if the exception is null + * @see #handlePageException(Exception) + */ + @Override + public void handlePageException(Throwable t) throws ServletException, IOException { + + } } From 3e333f97c60cfce5ed6d4f96116b423176f4b23e Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 5 Sep 2015 11:27:51 -0600 Subject: [PATCH 25/26] move ViewSupport to root jsp package --- hex_action/src/hex/action/views/jsp/tags/ContentForTag.java | 2 +- hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java | 2 +- hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java | 2 +- hex_action/src/hex/{action/views => jsp}/ViewSupport.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename hex_action/src/hex/{action/views => jsp}/ViewSupport.java (97%) diff --git a/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java b/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java index 2bfb860..4a22db1 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java @@ -2,7 +2,7 @@ import hex.action.ControllerAction; import hex.action.ViewContext; -import hex.action.views.ViewSupport; +import hex.jsp.ViewSupport; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; diff --git a/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java b/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java index 84cc81d..020eddf 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java @@ -2,7 +2,7 @@ import hex.action.ControllerAction; import hex.action.ViewContext; -import hex.action.views.ViewSupport; +import hex.jsp.ViewSupport; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; diff --git a/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java b/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java index 86a0e75..4d166b3 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java +++ b/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java @@ -1,6 +1,6 @@ package hex.action.views.jsp.tags; -import hex.action.views.ViewSupport; +import hex.jsp.ViewSupport; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; diff --git a/hex_action/src/hex/action/views/ViewSupport.java b/hex_action/src/hex/jsp/ViewSupport.java similarity index 97% rename from hex_action/src/hex/action/views/ViewSupport.java rename to hex_action/src/hex/jsp/ViewSupport.java index c05fc7d..31d0842 100644 --- a/hex_action/src/hex/action/views/ViewSupport.java +++ b/hex_action/src/hex/jsp/ViewSupport.java @@ -1,4 +1,4 @@ -package hex.action.views; +package hex.jsp; import hex.action.ControllerAction; import hex.action.ViewContext; From 425a8b888be18a957239408c47e4a5405ea08cef Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sat, 5 Sep 2015 11:55:28 -0600 Subject: [PATCH 26/26] move tag classes to root jsp package --- hex_action/resources/META-INF/tld/hex.tld | 12 ++++++------ .../{action/views => }/jsp/tags/ContentForTag.java | 2 +- .../views => }/jsp/tags/HexActionTagBase.java | 2 +- .../src/hex/{action/views => }/jsp/tags/LinkTag.java | 5 +---- .../hex/{action/views => }/jsp/tags/ParamTag.java | 2 +- .../{action/views => }/jsp/tags/QueryParamTag.java | 3 +-- .../src/hex/{action/views => }/jsp/tags/UriTag.java | 6 +----- .../{action/views => }/jsp/tags/ViewContentTag.java | 2 +- .../hex/{action/views => }/jsp/tags/ViewInitTag.java | 2 +- hex_action/test/hex/action/views/jsp/TagTests.java | 2 +- .../hex/{action/views => }/jsp/tags/LinkTagTest.java | 2 +- .../views => }/jsp/tags/ViewContentTagTest.java | 2 +- 12 files changed, 17 insertions(+), 25 deletions(-) rename hex_action/src/hex/{action/views => }/jsp/tags/ContentForTag.java (97%) rename hex_action/src/hex/{action/views => }/jsp/tags/HexActionTagBase.java (97%) rename hex_action/src/hex/{action/views => }/jsp/tags/LinkTag.java (90%) rename hex_action/src/hex/{action/views => }/jsp/tags/ParamTag.java (98%) rename hex_action/src/hex/{action/views => }/jsp/tags/QueryParamTag.java (94%) rename hex_action/src/hex/{action/views => }/jsp/tags/UriTag.java (65%) rename hex_action/src/hex/{action/views => }/jsp/tags/ViewContentTag.java (96%) rename hex_action/src/hex/{action/views => }/jsp/tags/ViewInitTag.java (97%) rename hex_action/test/hex/{action/views => }/jsp/tags/LinkTagTest.java (96%) rename hex_action/test/hex/{action/views => }/jsp/tags/ViewContentTagTest.java (98%) diff --git a/hex_action/resources/META-INF/tld/hex.tld b/hex_action/resources/META-INF/tld/hex.tld index f5eab94..a5eb1ba 100644 --- a/hex_action/resources/META-INF/tld/hex.tld +++ b/hex_action/resources/META-INF/tld/hex.tld @@ -7,7 +7,7 @@ http://hex.org/tags view-content - hex.action.views.jsp.tags.ViewContentTag + hex.jsp.tags.ViewContentTag empty name @@ -16,7 +16,7 @@ content-for - hex.action.views.jsp.tags.ContentForTag + hex.jsp.tags.ContentForTag JSP name @@ -25,12 +25,12 @@ view-init - hex.action.views.jsp.tags.ViewInitTag + hex.jsp.tags.ViewInitTag empty link - hex.action.views.jsp.tags.LinkTag + hex.jsp.tags.LinkTag JSP action @@ -48,7 +48,7 @@ query-param - hex.action.views.jsp.tags.QueryParamTag + hex.jsp.tags.QueryParamTag empty name @@ -62,7 +62,7 @@ param - hex.action.views.jsp.tags.ParamTag + hex.jsp.tags.ParamTag empty name diff --git a/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java b/hex_action/src/hex/jsp/tags/ContentForTag.java similarity index 97% rename from hex_action/src/hex/action/views/jsp/tags/ContentForTag.java rename to hex_action/src/hex/jsp/tags/ContentForTag.java index 4a22db1..35c90bd 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ContentForTag.java +++ b/hex_action/src/hex/jsp/tags/ContentForTag.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.action.ControllerAction; import hex.action.ViewContext; diff --git a/hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java b/hex_action/src/hex/jsp/tags/HexActionTagBase.java similarity index 97% rename from hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java rename to hex_action/src/hex/jsp/tags/HexActionTagBase.java index 5cad85e..23acec9 100644 --- a/hex_action/src/hex/action/views/jsp/tags/HexActionTagBase.java +++ b/hex_action/src/hex/jsp/tags/HexActionTagBase.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; diff --git a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java b/hex_action/src/hex/jsp/tags/LinkTag.java similarity index 90% rename from hex_action/src/hex/action/views/jsp/tags/LinkTag.java rename to hex_action/src/hex/jsp/tags/LinkTag.java index b8dc4cf..93e0924 100644 --- a/hex_action/src/hex/action/views/jsp/tags/LinkTag.java +++ b/hex_action/src/hex/jsp/tags/LinkTag.java @@ -1,14 +1,11 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.action.routing.Uri; import hex.action.routing.UriFactory; import hex.action.views.html.HtmlElement; import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.BodyTagSupport; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; /** * Created by jason on 15-01-03. diff --git a/hex_action/src/hex/action/views/jsp/tags/ParamTag.java b/hex_action/src/hex/jsp/tags/ParamTag.java similarity index 98% rename from hex_action/src/hex/action/views/jsp/tags/ParamTag.java rename to hex_action/src/hex/jsp/tags/ParamTag.java index d73bce3..fb21ae1 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ParamTag.java +++ b/hex_action/src/hex/jsp/tags/ParamTag.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; diff --git a/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java b/hex_action/src/hex/jsp/tags/QueryParamTag.java similarity index 94% rename from hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java rename to hex_action/src/hex/jsp/tags/QueryParamTag.java index 1f846e6..25f15ca 100644 --- a/hex_action/src/hex/action/views/jsp/tags/QueryParamTag.java +++ b/hex_action/src/hex/jsp/tags/QueryParamTag.java @@ -1,7 +1,6 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; import java.util.Objects; diff --git a/hex_action/src/hex/action/views/jsp/tags/UriTag.java b/hex_action/src/hex/jsp/tags/UriTag.java similarity index 65% rename from hex_action/src/hex/action/views/jsp/tags/UriTag.java rename to hex_action/src/hex/jsp/tags/UriTag.java index b0a7657..6b95239 100644 --- a/hex_action/src/hex/action/views/jsp/tags/UriTag.java +++ b/hex_action/src/hex/jsp/tags/UriTag.java @@ -1,8 +1,4 @@ -package hex.action.views.jsp.tags; - -import hex.action.routing.Uri; - -import java.util.Map; +package hex.jsp.tags; /** * Created by jason on 15-01-16. diff --git a/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java b/hex_action/src/hex/jsp/tags/ViewContentTag.java similarity index 96% rename from hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java rename to hex_action/src/hex/jsp/tags/ViewContentTag.java index 020eddf..8616c13 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ViewContentTag.java +++ b/hex_action/src/hex/jsp/tags/ViewContentTag.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.action.ControllerAction; import hex.action.ViewContext; diff --git a/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java b/hex_action/src/hex/jsp/tags/ViewInitTag.java similarity index 97% rename from hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java rename to hex_action/src/hex/jsp/tags/ViewInitTag.java index 4d166b3..d2707af 100644 --- a/hex_action/src/hex/action/views/jsp/tags/ViewInitTag.java +++ b/hex_action/src/hex/jsp/tags/ViewInitTag.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.jsp.ViewSupport; diff --git a/hex_action/test/hex/action/views/jsp/TagTests.java b/hex_action/test/hex/action/views/jsp/TagTests.java index 1d77d9f..b30dcf2 100644 --- a/hex_action/test/hex/action/views/jsp/TagTests.java +++ b/hex_action/test/hex/action/views/jsp/TagTests.java @@ -1,6 +1,6 @@ package hex.action.views.jsp; -import hex.action.views.jsp.tags.ViewContentTagTest; +import hex.jsp.tags.ViewContentTagTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; diff --git a/hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java b/hex_action/test/hex/jsp/tags/LinkTagTest.java similarity index 96% rename from hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java rename to hex_action/test/hex/jsp/tags/LinkTagTest.java index db52f12..a8c3471 100644 --- a/hex_action/test/hex/action/views/jsp/tags/LinkTagTest.java +++ b/hex_action/test/hex/jsp/tags/LinkTagTest.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.action.Application; import hex.action.routing.RouteManager; diff --git a/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java b/hex_action/test/hex/jsp/tags/ViewContentTagTest.java similarity index 98% rename from hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java rename to hex_action/test/hex/jsp/tags/ViewContentTagTest.java index 8572129..2871864 100644 --- a/hex_action/test/hex/action/views/jsp/tags/ViewContentTagTest.java +++ b/hex_action/test/hex/jsp/tags/ViewContentTagTest.java @@ -1,4 +1,4 @@ -package hex.action.views.jsp.tags; +package hex.jsp.tags; import hex.action.ControllerAction; import hex.action.ViewContext;