package foundation.route;
|
|
import java.net.URLDecoder;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Set;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
|
import foundation.util.MapList;
|
import foundation.util.Util;
|
|
|
public class RouteTable {
|
|
protected static Logger logger;
|
private static RouteTable instance;
|
private static String contextPath;
|
private static int contextLength;
|
|
private static HashMap<String, Route> resourceTypeMap;
|
private static URIRouteMap resourceURIMap;
|
private static HashMap<String, Route>virtualPathResourceMap;
|
private static MapList<String, ControllerRoute> controlerMap;
|
private static OperationSet freeCallSet;
|
private static MapList<String, Route> allRouteMap;
|
|
private static AuthorizeURIRoute authorizeURIRoute;
|
private static TimeOutRoute timeOutRoute;
|
private static InvalidUserRightRoute invalidUserRightRoute;
|
private static ServerErrorRoute serverErrorRoute;
|
private static NotExistsRoute notExistsRoute;
|
|
static {
|
logger = LogManager.getLogger(RouteTable.class);
|
}
|
|
|
public static synchronized RouteTable createInstance(String contextPath) {
|
if (instance == null) {
|
instance = new RouteTable(contextPath);
|
}
|
|
return instance;
|
}
|
|
private RouteTable(String context) {
|
init(context);
|
}
|
|
private void init(String context) {
|
//1. context
|
contextPath = context;
|
contextLength = context.length();
|
|
//2.
|
resourceTypeMap = new HashMap<String, Route>();
|
resourceURIMap = new URIRouteMap();
|
virtualPathResourceMap = new HashMap<String, Route>();
|
controlerMap = new MapList<String, ControllerRoute>();
|
freeCallSet = new OperationSet();
|
allRouteMap = new MapList<String, Route>();
|
|
//3.
|
authorizeURIRoute = new AuthorizeURIRoute();
|
timeOutRoute = new TimeOutRoute("root/login.html");
|
invalidUserRightRoute = new InvalidUserRightRoute();
|
serverErrorRoute = new ServerErrorRoute();
|
notExistsRoute = new NotExistsRoute();
|
|
//4.
|
allRouteMap.add("*", authorizeURIRoute);
|
allRouteMap.add("*", timeOutRoute);
|
allRouteMap.add("*", invalidUserRightRoute);
|
allRouteMap.add("*", serverErrorRoute);
|
allRouteMap.add("*", notExistsRoute);
|
}
|
|
public static RouteNavigator matchRoute(HttpServletRequest request) {
|
String uri = request.getRequestURI();
|
|
String path;
|
|
try {
|
path = URLDecoder.decode(uri, "UTF-8");
|
} catch (Exception e) {
|
e.printStackTrace();
|
path = uri;
|
}
|
|
//1. replace root from context path
|
int pos_root = path.lastIndexOf("/root/");
|
path = pos_root >= 0 ? contextPath + path.substring(pos_root + 5) : path;
|
|
//2. delete parameters
|
int pos_end = path.indexOf("?");
|
|
if (pos_end <= 0) {
|
pos_end = path.length();
|
}
|
|
path = path.substring(contextLength, pos_end);
|
|
//3. get suffix
|
int pos_dot = path.lastIndexOf(".");
|
|
String suffix = null;
|
if (pos_dot > 0) {
|
suffix = path.substring(pos_dot);
|
}
|
|
//4. match
|
NavigatorCreator navigatorCreator = new NavigatorCreator(request);
|
doMatchRoute(uri, path, suffix, navigatorCreator);
|
|
return navigatorCreator.getNavigator();
|
}
|
|
private static void doMatchRoute(String uri, String path, String suffix, NavigatorCreator navigatorCreator) {
|
Route route = null;
|
|
//1 resource by suffix
|
if (suffix != null) {
|
suffix = suffix.toLowerCase();
|
route = resourceTypeMap.get(suffix);
|
|
if (route != null) {
|
navigatorCreator.onResourceTypeMatch(uri, path, suffix, route, false);
|
return;
|
}
|
}
|
|
//2 resource by URI
|
String[] segments = createSegements(path);
|
String page = segments[segments.length - 1];
|
route = resourceURIMap.get(page);
|
|
if (route != null) {
|
navigatorCreator.onResourceURIMatch(uri, path, suffix, route, false);
|
return;
|
}
|
|
//3. virtual path resource
|
route = virtualPathResourceMap.get(path);
|
|
if (route != null) {
|
VirtualPathRoute virtualRoute = (VirtualPathRoute) route;
|
navigatorCreator.onVirtualPathMatch(uri, virtualRoute.getTarget(), suffix, route, false);
|
return;
|
}
|
|
//4. controller
|
if (segments.length >= 2) {
|
Operation operation = new Operation(segments);
|
route = controlerMap.get(operation.getObject());
|
|
if (route != null) {
|
boolean authorizeSensitive = !freeCallSet.contains(operation);
|
navigatorCreator.onControllerMatch(uri, path, operation, route, authorizeSensitive);
|
return;
|
}
|
}
|
|
//5. not exists
|
navigatorCreator.onNoMatch(uri, suffix, path);
|
return;
|
}
|
|
private static String[] createSegements(String path) {
|
if (path.charAt(0) == '/') {
|
path = path.substring(1);
|
}
|
|
return path.toLowerCase().split("/");
|
}
|
|
public static void addFreeVisitResourceType(String type) {
|
if (Util.isEmpty(type)) {
|
return;
|
}
|
|
Route route = new FreeTypeRoute(type);
|
String from = route.getFrom();
|
|
resourceTypeMap.put(from, route);
|
allRouteMap.add(type, route);
|
}
|
|
public static void appendFreeVisitResource(String uri) {
|
if (Util.isEmpty(uri)) {
|
return;
|
}
|
|
Route route = new FreeURIRoute(uri);
|
String from = route.getFrom();
|
|
resourceURIMap.add(from, route);
|
allRouteMap.add(uri, route);
|
}
|
|
public static void appendVirtualPath(String from, String target) {
|
VirtualPathRoute route = new VirtualPathRoute(from, target);
|
|
virtualPathResourceMap.put(from, route);
|
allRouteMap.add(from, route);
|
}
|
|
public static void appendFreeVisitCall(String call) {
|
if (Util.isEmpty(call)) {
|
return;
|
}
|
|
call = call.toLowerCase();
|
freeCallSet.add(call);
|
}
|
|
public static void appendCallableClass(String path, String classname) throws Exception {
|
try {
|
ControllerRoute route = new ControllerRoute(path, classname);
|
String from = route.getFrom();
|
|
controlerMap.add(from, route);
|
allRouteMap.add(path, route);
|
|
}
|
catch (ClassNotFoundException e) {
|
e.printStackTrace();
|
}
|
}
|
|
public static List<Route> getRouteList() {
|
return allRouteMap.getItemList();
|
}
|
|
public static List<Route> getFreeResourceTypeRouteList() {
|
List<Route> result = new ArrayList<Route>();
|
|
Set<String> keys = resourceTypeMap.keySet();
|
for (String key: keys) {
|
result.add(resourceTypeMap.get(key));
|
}
|
|
return result;
|
}
|
|
public static List<Route> getFreeResourceURIRouteList() {
|
List<Route> result = new ArrayList<Route>();
|
|
Set<String> keys = resourceURIMap.keySet();
|
for (String key: keys) {
|
result.add(resourceURIMap.get(key));
|
}
|
|
return result;
|
}
|
|
public static List<Route> getAuthorizedControlerRouteList() {
|
List<Route> result = new ArrayList<Route>();
|
|
Set<String> keys = controlerMap.keySet();
|
for (String key: keys) {
|
result.add(controlerMap.get(key));
|
}
|
|
return result;
|
}
|
|
public static List<Route> getSpecializedRouteList() {
|
List<Route> result = new ArrayList<Route>();
|
|
result.add(authorizeURIRoute);
|
result.add(invalidUserRightRoute);
|
result.add(timeOutRoute);
|
result.add(serverErrorRoute);
|
result.add(notExistsRoute);
|
|
return result;
|
}
|
|
public static List<ControllerRoute> getControlerList() {
|
return controlerMap.getItemList();
|
}
|
|
public static ControllerRoute getControler(String name) {
|
return controlerMap.get(name);
|
}
|
|
public static Route getTimeOutRoute() {
|
return timeOutRoute;
|
}
|
|
public static Route getNotExistsRoute() {
|
return notExistsRoute;
|
}
|
|
public static ServerErrorRoute getServerErrorRoute() {
|
return serverErrorRoute;
|
}
|
|
public static InvalidUserRightRoute getInvalidUserRightRoute() {
|
return invalidUserRightRoute;
|
}
|
|
}
|