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

spark.route.RouteOverview Maven / Gradle / Ivy

Go to download

A micro framework for creating web applications in Kotlin and Java 8 with minimal effort

There is a newer version: 2.9.4
Show newest version
/*
 * Copyright 2011- Per Wendel
 *
 *  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.
 */
package spark.route;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import spark.Request;
import spark.Response;
import spark.utils.Wrapper;
import sun.reflect.ConstantPool;

import static java.util.Collections.singletonList;
import static spark.Spark.get;

public class RouteOverview {

    /**
     * Enables a route overview (showing all the mapped routes)
     * The overview is made available at "/debug/routeoverview/"
     * Calling this method before any other route mapping
     * bas been performed will initialize the Spark server
     */
    public static void enableRouteOverview() {
        enableRouteOverview("/debug/routeoverview/");
    }

    /**
     * Enables a route overview (showing all the mapped routes)
     * The overview is made available at the provided path
     *
     * @param path the path to the route overview
     *             Calling this method before any other route mapping
     *             bas been performed will initialize the Spark server
     */
    public static void enableRouteOverview(String path) {
        get(path, RouteOverview::createHtmlOverview);
    }

    // Everything below this point is either package private or private

    static List routes = new ArrayList<>();

    static void add(RouteEntry entry, Object wrapped) {

        if (wrapped instanceof Wrapper) {
            entry.target = ((Wrapper) wrapped).delegate();
        }

        routes.add(entry);
    }

    static String createHtmlOverview(Request request, Response response) {
        String head = ""
                + "";

        String rowTemplate = "%s%s%s%s";

        List tableContent = new ArrayList<>(singletonList("MethodAcceptsPathRoute"));

        routes.forEach(r -> {
            tableContent.add(String.format(rowTemplate, r.httpMethod.name(), r.acceptedType.replace("*/*", "any"), r.path, createHtmlForRouteTarget(r.target)));
        });

        return head + "

All mapped routes

" + String.join("", tableContent) + "
"; } static String createHtmlForRouteTarget(Object routeTarget) { String routeStr = routeTarget.toString(); if (routeStr.contains("$$Lambda$")) { // This is a Route or Filter lambda Map fieldNames = fieldNames(routeTarget); String className = routeStr.split("\\$")[0]; if (fieldNames.containsKey(routeTarget)) { // Lambda name has been mapped in fieldNameMap return className + "." + fieldNames.get(routeTarget) + " (field)"; } if (!methodName(routeTarget).contains("lambda$")) { // Method has name (is not anonymous lambda) return className(routeTarget) + "::" + methodName(routeTarget) + " (method reference)"; } return className + "??? (anonymous lambda)"; } if (routeStr.contains("@")) { // This is a Class implementing Route or Filter String packages = routeStr.split("@")[0].substring(0, routeStr.lastIndexOf(".")); String className = routeStr.split("@")[0].substring(routeStr.lastIndexOf(".") + 1); return packages + "." + className + ".class (class)"; } return "Mysterious route handler"; } private static Map fieldNames(Object routeTarget) { Map fieldNames = new HashMap<>(); try { Class clazz = Class.forName(className(routeTarget)); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); fieldNames.put(field.get(field), field.getName()); } } catch (Exception ignored) { // Nothing really matters. } return fieldNames; } private static String className(Object routeTarget) { return methodRefInfo(routeTarget)[0].replace("/", "."); } private static String methodName(Object routeTarget) { return methodRefInfo(routeTarget)[1]; } private static String[] methodRefInfo(Object routeTarget) { try { // This is some robustified shit right here. Method getConstantPool = Class.class.getDeclaredMethod("getConstantPool"); getConstantPool.setAccessible(true); ConstantPool constantPool = (ConstantPool) getConstantPool.invoke(routeTarget.getClass()); return constantPool.getMemberRefInfoAt(constantPool.getSize() - 2); } catch (Exception e) { return new String[] {"", ""}; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy