All Downloads are FREE. Search and download functionalities are using the official Maven repository.

act.route.RouteTableRouterBuilder Maven / Gradle / Ivy

package act.route;

/*-
 * #%L
 * ACT Framework
 * %%
 * Copyright (C) 2014 - 2017 ActFramework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import act.Act;
import act.app.App;
import act.app.event.SysEventId;
import org.osgl.http.H;
import org.osgl.http.util.Path;
import org.osgl.util.*;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * {@code RouteTableRouterBuilder} take a list of route map definition line and
 * build the router. The line of a route map definition should look like:
 * 

*

 * [http-method] [url-path] [action-definition]
 * 
*

* Where http-method could be one of the following: *

    *
  • GET
  • *
  • POST
  • *
  • PUT
  • *
  • DELETE
  • *
*

* url-path defines the incoming URL path, and it could * be either static or dynamic. For example, *

*

 * # home
 * /
 *
 * # order list
 * /order
 *
 * # (dynamic) access to a certain order by ID
 * /order/{id}
 *
 * # (dynamic) access to a user by ID with regex spec
 * /user/{<[1-9]{5}>id}
 * 
*

* action-definition could be in either built-in action * or controller action method. *

*

Built-in action definition should be in a format of * [directive]: [payload], for example *

*

*

    *
  • * Echo - write back a text message directly *
     * echo: hello world!
     * 
    *
  • *
  • * Redirect - send permanent redirect in the response *
     * redirect: http://www.google.com
     * 
    *
  • *
  • * Static file directory handler - fetch files in a local directory *
     * staticDir: /public
     * 
    *
  • *
  • * Static file locator - fetch specified file on request *
     * staticFile: /public/js/jquery.js
     * 
    *
  • *
*/ public class RouteTableRouterBuilder implements RouterBuilder { private static AtomicInteger jobIdCounter = new AtomicInteger(0); public static final String ROUTES_FILE = "routes.conf"; public static final String ROUTES_FILE2 = "route.conf"; private List lines; public RouteTableRouterBuilder(List lines) { E.NPE(lines); this.lines = lines; } public RouteTableRouterBuilder(String... lines) { E.illegalArgumentIf(lines.length == 0, "Empty route configuration file lines"); this.lines = C.listOf(lines); } @Override public void build(Router router) { int lineNo = lines.size(); for (int i = 0; i < lineNo; ++i) { String line = lines.get(i).trim(); if (line.startsWith("#")) continue; if (S.blank(line)) continue; try { process(line, router); } catch (final RuntimeException e) { if (Act.isDev()) { final App app = router.app(); app.jobManager().on(SysEventId.PRE_START, "RouteTableRouterBuilder:setAppBlockIssue-" + jobIdCounter.getAndIncrement(), new Runnable() { @Override public void run() { app.handleBlockIssue(e); } }); } else { throw e; } } } } private void process(String line, Router router) { Iterator itr = Path.tokenizer(Unsafe.bufOf(line), 0, ' ', '\u0000'); final String UNKNOWN = S.fmt("route configuration not recognized: %s", line); String method = null, path = null; S.Buffer action = S.newBuffer(); if (itr.hasNext()) { method = itr.next(); } else { E.illegalArgumentIf(true, UNKNOWN); } if (itr.hasNext()) { path = itr.next(); if (path.contains("%")) { path = Codec.decodeUrl(path); } } else { E.illegalArgumentIf(true, UNKNOWN); } E.illegalArgumentIf(!itr.hasNext(), UNKNOWN); action.append(itr.next()); while (itr.hasNext()) { action.append(" ").append(itr.next()); } if ("*".contentEquals(method)) { for (H.Method m : Router.supportedHttpMethods()) { router.addMapping(m, path, action.toString(), RouteSource.ROUTE_TABLE); } } else { if ("context".equalsIgnoreCase(method) || "ctx".equalsIgnoreCase(method)) { router.addContext(action.toString(), path); } else { H.Method m = H.Method.valueOfIgnoreCase(method); router.addMapping(m, path, action.toString(), RouteSource.ROUTE_TABLE); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy