/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.jooby.internal; import static javaslang.API.$; import static javaslang.API.Case; import static javaslang.API.Match; import static javaslang.Predicates.instanceOf; import java.util.List; import java.util.Map; import org.jooby.Err; import org.jooby.MediaType; import org.jooby.Request; import org.jooby.Response; import org.jooby.Route; import org.jooby.Status; import org.jooby.internal.mvc.MvcHandler; import javaslang.control.Option; public class RouteImpl implements RouteWithFilter { private Definition route; private String path; private Map<Object, String> vars; private Filter filter; private List<MediaType> produces; private String method; private Source source; public static RouteWithFilter notFound(final String method, final String path) { return new FallbackRoute("404", method, path, MediaType.ALL, (req, rsp, chain) -> { if (!rsp.status().isPresent()) { throw new Err(Status.NOT_FOUND, req.path(true)); } }); } public static RouteWithFilter fallback(final Filter filter, final String method, final String path, final String name, final List<MediaType> produces) { return new FallbackRoute(name, method, path, produces, filter); } public RouteImpl(final Filter filter, final Definition route, final String method, final String path, final List<MediaType> produces, final Map<Object, String> vars, final Mapper<?> mapper, final Source source) { this.filter = Option.of(mapper) .map(m -> Match(filter).of( Case(instanceOf(Route.OneArgHandler.class), f -> new MappedHandler((req, rsp) -> f.handle(req), mapper)), Case(instanceOf(Route.ZeroArgHandler.class), f -> new MappedHandler((req, rsp) -> f.handle(), mapper)), Case(instanceOf(MvcHandler.class), f -> { if (f.method().getReturnType() == void.class) { // ignore void results return filter; } return new MappedHandler((req, rsp) -> f.invoke(req, rsp), mapper); }), Case($(), filter))) .getOrElse(filter); this.route = route; this.method = method; this.produces = produces; this.vars = vars; this.source = source; this.path = Route.unerrpath(path); } @Override public void handle(final Request request, final Response response, final Chain chain) throws Throwable { filter.handle(request, response, chain); } @Override public Map<String, Object> attributes() { return route.attributes(); } @Override public String path() { return path; } @Override public String method() { return method; } @Override public String pattern() { return route.pattern().substring(route.pattern().indexOf('/')); } @Override public String name() { return route.name(); } @Override public Map<Object, String> vars() { return vars; } @Override public List<MediaType> consumes() { return route.consumes(); } @Override public List<MediaType> produces() { return produces; } @Override public boolean glob() { return route.glob(); } @Override public String reverse(final Map<String, Object> vars) { return route.reverse(vars); } @Override public String reverse(final Object... values) { return route.reverse(values); } @Override public Source source() { return source; } @Override public String toString() { return print(); } }