public ActionRuntime lookup(final String method, final String[] actionPath) { return routes.lookup(method, actionPath); }
public ActionsManager() { this.routes = new Routes(this); this.pathAliases = new HashMap<>(); this.runtimes = new HashMap<>(); this.asyncMode = false; }
protected RouteChunk(final Routes routes, final RouteChunk parent, final String value) { this.routes = routes; this.parent = parent; this.value = value; this.pathMacros = routes.buildActionPathMacros(value); if (pathMacros != null) { this.hasMacros = true; } else { this.hasMacros = parent != null && parent.hasMacros; } }
private ActionRuntime lookupFrom(final RouteChunk chunk, final String[] path) { // matched, scan children RouteChunk[] children = chunk.children(); if (children == null) { return null; } for (RouteChunk child : children) { ActionRuntime matched = match(child, path, 0); if (matched != null) { return matched; } } return null; }
private ActionRuntime _lookup(String method, final String[] pathChunks) { // 1 - match method if (method != null) { method = method.toUpperCase(); RouteChunk methodChunk = root.findOrCreateChild(method); ActionRuntime actionRuntime = lookupFrom(methodChunk, pathChunks); if (actionRuntime != null) { return actionRuntime; } } // 2 - match all methods if (anyMethodChunk != null) { ActionRuntime actionRuntime = lookupFrom(anyMethodChunk, pathChunks); if (actionRuntime != null) { return actionRuntime; } } // nothing found return null; }
/** * Builds {@link PathMacros action path macros} from given action * path chunks. Returns either <code>null</code>, if * no action path contains no macros, or instance of the <code>PathMacro</code> * implementations. */ public PathMacros buildActionPathMacros(final String actionPath) { if (actionPath.isEmpty()) { return null; } PathMacros pathMacros = createPathMacroInstance(); if (!pathMacros.init(actionPath, actionsManager.getPathMacroSeparators())) { return null; } return pathMacros; }
public ActionRuntime lookup(final String method, final String[] pathChunks) { while (true) { final ActionRuntime actionRuntime = _lookup(method, pathChunks); if (actionRuntime != null) { return actionRuntime; } if (actionsManager.isStrictRoutePaths()) { return null; } // special case final String lastPath = pathChunks[pathChunks.length - 1]; final int lastNdx = lastPath.lastIndexOf('.'); if (lastNdx == -1) { return null; } final String pathExtension = lastPath.substring(lastNdx + 1); if (StringUtil.equalsOne(pathExtension, actionsManager.getPathExtensionsToStrip()) == -1) { return null; } pathChunks[pathChunks.length - 1] = lastPath.substring(0, lastNdx); } }
/** * Registers manually created {@link ActionRuntime action runtime configurations}. * Optionally, if action path with the same name already exist, * exception will be thrown. */ public ActionRuntime registerActionRuntime(final ActionRuntime actionRuntime) { final String actionPath = actionRuntime.getActionPath(); final String method = actionRuntime.getActionMethod(); log.debug(() -> "Madvoc action: " + ifNotNull(method, m -> m + " ") + actionRuntime.getActionPath() + " => " + actionRuntime.createActionString()); final RouteChunk routeChunk = routes.registerPath(method, actionPath); if (routeChunk.value() != null) { // existing chunk if (detectDuplicatePathsEnabled) { throw new MadvocException("Duplicate action path for [" + actionRuntime + "] occupied by: [" + routeChunk.value() + "]"); } } else { actionsCount++; } routeChunk.bind(actionRuntime); // finally runtimes.put(actionRuntime.createActionString(), actionRuntime); // async check if (actionRuntime.isAsync()) { asyncMode = true; } return actionRuntime; }
private ActionRuntime match(final RouteChunk chunk, final String[] path, final int ndx) { final int maxDeep = path.length - 1; if (ndx > maxDeep) { // too deep, don't go any further return null; } if (!chunk.match(path[ndx])) { // no match, continue return null; } if (ndx == maxDeep) { // end of the path if (chunk.isEndpoint()) { return chunk.value(); } return null; } // matched, scan children RouteChunk[] children = chunk.children(); if (children == null) { return null; } for (RouteChunk child : children) { ActionRuntime matched = match(child, path, ndx + 1); if (matched != null) { return matched; } } return null; }
@Test void testActionPathMacros1() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/{one}")); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo")); assertNotNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo/boo")); assertNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo/boo/zoo")); assertNull(actionRuntime); }
@Test void testActionPathMacros2() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.registerAction(FooAction.class, "two", new ActionDefinition("/xxx-{two}")); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/{one}")); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo")); assertEquals("one", actionRuntime.getActionClassMethod().getName()); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo/boo")); assertNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/xxx-foo")); assertEquals("two", actionRuntime.getActionClassMethod().getName()); // best match! }
@Test void testActionPathMacros4() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/dummy")); // no macro actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/{one}")); actionsManager.registerAction(FooAction.class, "three", new ActionDefinition("/life/{three}")); actionsManager.registerAction(FooAction.class, "two", new ActionDefinition("/{two}/{three}")); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo")); assertEquals("one", actionRuntime.getActionClassMethod().getName()); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/scott/ramonna")); assertEquals("two", actionRuntime.getActionClassMethod().getName()); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/life/universe")); assertEquals("three", actionRuntime.getActionClassMethod().getName()); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/scott/ramonna/envy")); assertNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/life/universe/else")); assertNull(actionRuntime); }
@Test void testActionPathMacrosRegexp() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.setPathMacroClass(RegExpPathMacros.class); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/{one:[ab]+}")); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/a")); assertNotNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/ac")); assertNull(actionRuntime); }
@Test void testActionPathMacrosWildcard() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.setPathMacroClass(WildcardPathMacros.class); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/{one:a?a}")); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/aaa")); assertNotNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/aab")); assertNull(actionRuntime); } }
@Test void testActionPathMacros3() { WebApp webapp = new WebApp(); webapp.start(); ActionsManager actionsManager = webapp.madvocContainer().lookupComponent(ActionsManager.class); actionsManager.registerAction(FooAction.class, "one", new ActionDefinition("/yyy-{one}")); actionsManager.registerAction(FooAction.class, "two", new ActionDefinition("/xxx-{two}")); assertEquals(2, actionsManager.getActionsCount()); ActionRuntime actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/foo")); assertNull(actionRuntime); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/yyy-111")); assertEquals("one", actionRuntime.getActionClassMethod().getName()); actionRuntime = actionsManager.routes.lookup(null, MadvocUtil.splitPathToChunks("/xxx-222")); assertEquals("two", actionRuntime.getActionClassMethod().getName()); try { actionsManager.registerAction(FooAction.class, "two", new ActionDefinition("/xxx-{two}")); fail("error"); } catch (Exception ex) { // ignore } }