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

io.mangoo.routing.Router Maven / Gradle / Ivy

The newest version!
package io.mangoo.routing;

import com.google.common.base.Preconditions;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.mangoo.constants.NotNull;
import io.mangoo.interfaces.MangooRoute;
import io.mangoo.routing.routes.FileRoute;
import io.mangoo.routing.routes.PathRoute;
import io.mangoo.routing.routes.RequestRoute;
import io.mangoo.routing.routes.ServerSentEventRoute;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@SuppressFBWarnings(value = "PMB_POSSIBLE_MEMORY_BLOAT", justification = "Route size is limited")
public final class Router {
    private static final Logger LOG = LogManager.getLogger(Router.class);
    private static final int MAX_ROUTES = 100000;
    private static final List urls = new ArrayList<>();
    private static Set routes = ConcurrentHashMap.newKeySet();
    private static Map reverseRoutes = new ConcurrentHashMap<>();

    private Router(){
    }

    /**
     * Adds a new route to the router
     *
     * @param route The route to add
     */
    public static void addRoute(MangooRoute route, String type) {
        Objects.requireNonNull(route, NotNull.ROUTE);
        Objects.requireNonNull(type, NotNull.TYPE);
        Preconditions.checkArgument(routes.size() <= MAX_ROUTES, "Maximum of " + MAX_ROUTES + " routes reached");

        urls.add(type.toUpperCase() + " " + route.getUrl());
        routes.add(route);

        if (route instanceof RequestRoute requestRoute && requestRoute.getControllerClass() != null && StringUtils.isNotBlank(requestRoute.getControllerMethod())) {
            reverseRoutes.put((requestRoute.getControllerClass().getSimpleName().toLowerCase(Locale.ENGLISH) + ":" + requestRoute.getControllerMethod()).toLowerCase(Locale.ENGLISH), requestRoute);
        }
    }

    public static boolean validUrls() {
        HashSet uniqueUrls = new HashSet<>();
        List duplicates = urls.stream()
                .filter(url -> !uniqueUrls.add(url))
                .toList();

        if (!duplicates.isEmpty()) {
            duplicates.forEach(duplicate -> LOG.error("Found multiple mappings of URL mapping '{}'", duplicate));
            return false;
        }

        return true;
    }

    /**
     * @return An unmodifiable set of all configured routes
     */
    public static Set getRoutes() {
        return Collections.unmodifiableSet(routes);
    }
    
    /**
     * @return An unmodifiable set of all configured RequestRoutes
     */
    public static Stream getRequestRoutes() {
        return routes.stream()
                .filter(RequestRoute.class::isInstance)
                .map(RequestRoute.class::cast)
                .collect(Collectors.toUnmodifiableSet())
                .stream();
    }
    
    /**
     * @return An unmodifiable set of all configured FileRoutes
     */
    public static Stream getFileRoutes() {
        return routes.stream()
                .filter(FileRoute.class::isInstance)
                .map(FileRoute.class::cast)
                .collect(Collectors.toUnmodifiableSet())
                .stream();
    }
    
    /**
     * @return An unmodifiable set of all configured PathRouts
     */
    public static Stream getPathRoutes() {
        return routes.stream()
                .filter(PathRoute.class::isInstance)
                .map(PathRoute.class::cast)
                .collect(Collectors.toUnmodifiableSet())
                .stream();
    }
    
    /**
     * @return An unmodifiable set of all configured ServerSentEventRoutes
     */
    public static Stream getServerSentEventRoutes() {
        return routes.stream()
                .filter(ServerSentEventRoute.class::isInstance)
                .map(ServerSentEventRoute.class::cast)
                .collect(Collectors.toUnmodifiableSet())
                .stream();
    }
    
    /**
     * Retrieves a reverse route by its controller class and controller method
     * 
     * @param key The controller class and method in the form ControllerClass:ControllerMethod
     * @return A route object based on the given controller and method or null if none found
     */
    public static RequestRoute getReverseRoute(String key) {
        Objects.requireNonNull(key, NotNull.KEY);
        return reverseRoutes.get(key.toLowerCase(Locale.ENGLISH));
    }
    
    /**
     * Removes all routes from the router
     */
    public static void reset() {
        routes = ConcurrentHashMap.newKeySet();
        reverseRoutes = new ConcurrentHashMap<>();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy