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

restx.RestxRouting Maven / Gradle / Ivy

There is a newer version: 1.2.0-rc2
Show newest version
package restx;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import restx.factory.Factory;
import restx.factory.NamedComponent;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import static com.google.common.collect.Iterables.transform;

/**
 * User: xavierhanin
 * Date: 4/1/13
 * Time: 11:28 PM
 */
public class RestxRouting {
    private final ImmutableList> filters;
    private final ImmutableMultimap> routeFilters;
    private final ImmutableList routes;

    public RestxRouting(ImmutableList> filters,
                        ImmutableList> routeFilters,
                        ImmutableList routes) {
        this.filters = filters;
        Builder> builder = ImmutableListMultimap.builder();
        for (RestxRoute route : routes) {
            for (NamedComponent routeFilter : routeFilters) {
                Optional m = routeFilter.getComponent().match(route);
                if (m.isPresent()) {
                    RestxHandlerMatch restxHandlerMatch = m.get();
                    builder.put(route, NamedComponent.of(
                            RestxHandlerMatch.class, routeFilter.getName().getName(),
                            routeFilter.getPriority(), restxHandlerMatch));
                }
            }
        }
        this.routeFilters = builder.build();
        this.routes = routes;
    }

    public ImmutableList getFilters() {
        return ImmutableList.copyOf(transform(filters, NamedComponent.toComponent()));
    }

    public ImmutableCollection getRouteFilters(RestxRoute route) {
        return ImmutableList.copyOf(transform(
                routeFilters.get(route), NamedComponent.toComponent()));
    }

    public ImmutableList getRoutes() {
        return routes;
    }

    public Optional match(RestxRequest restxRequest) {
        for (RestxRoute route : routes) {
            Optional match = route.match(restxRequest);
            if (match.isPresent()) {
                // here we need to:
                // - check which filters apply
                // - order all filters (route filters and regular filters) by priority
                // so we put all matches as NamedComponents (to preserve the filter priority) in a list,
                // and finally sort the list by priority before returning it as a Match
                ImmutableCollection> routeFilters = this.routeFilters.get(route);

                List> matches = Lists.newArrayListWithCapacity(
                        filters.size() + routeFilters.size() + 1);
                matches.addAll(routeFilters);

                for (NamedComponent filter : filters) {
                    Optional filterMatch = filter.getComponent().match(restxRequest);
                    if (filterMatch.isPresent()) {
                        matches.add(NamedComponent.of(
                                RestxHandlerMatch.class, filter.getName().getName(),
                                filter.getPriority(), filterMatch.get()));
                    }
                }

                return Optional.of(new Match(
                        ImmutableList.builder()
                                .addAll(
                                        transform(Ordering.from(Factory.NAMED_COMPONENT_COMPARATOR).sortedCopy(matches),
                                                NamedComponent.toComponent()))
                                .add(match.get())
                                .build(),
                        match));
            }
        }
        return Optional.absent();
    }

    public static class Match {
        private final ImmutableList matches;
        private final Optional match;

        private Match(ImmutableList matches, Optional match) {
            this.matches = matches;
            this.match = match;
        }

        public ImmutableList getMatches() {
            return matches;
        }

        public Optional getMatch() {
            return match;
        }

        @Override
        public String toString() {
            return "Match{" +
                    "matches=" + matches +
                    ", match=" + match +
                    '}';
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy