/* * Copyright 2015 Petr Bouda * * 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 org.joyrest.routing; import org.joyrest.model.RoutePart; import org.joyrest.model.http.HttpMethod; import org.joyrest.processor.RequestProcessor; import org.joyrest.routing.entity.Type; import org.joyrest.routing.security.Role; import org.joyrest.utils.PathUtils; import java.util.HashSet; import java.util.List; import java.util.Set; import static java.util.Objects.nonNull; import static java.util.Objects.requireNonNull; import static org.joyrest.utils.CollectionUtils.isEmpty; /** * <p> * Class {@link AbstractControllerConfiguration} is abstract implementation of {@link ControllerConfiguration} and makes easier * to create * the given route using predefined protected method. * </p> * <p> * It can be considered as container for routes which are provided to {@link RequestProcessor} because of processing and * handling incoming * requests. * </p> * * @author pbouda */ public abstract class AbstractControllerConfiguration implements ControllerConfiguration { /* Set of routes which are configured in an inherited class */ private final Set<InternalRoute> routes = new HashSet<>(); /* Class validates and customized given path */ private final PathCorrector pathCorrector = new PathCorrector(); /* Resource path that will be added to the beginning of all routes defined in the inherited class */ private String controllerPath = null; /* Global settings roles which protects a given resource */ private String[] roles = null; /* RoutingConfiguration's initialization should be executed only once */ private boolean isInitialized = false; @Override public final void initialize() { if (!this.isInitialized) { configure(); List<RoutePart<String>> globalParts = PathUtils.createRoutePathParts(controllerPath); if (nonNull(controllerPath)) { this.routes.forEach(route -> route.addControllerPath(globalParts)); } if (nonNull(roles)) { this.routes.stream() .filter(route -> isEmpty(route.getRoles())) .forEach(route -> route.roles(this.roles)); } this.isInitialized = true; } } /** * Convenient place where is possible to configure new routes for this instance of {@link ControllerConfiguration} */ abstract protected void configure(); /** * Creates a resource part of the path unified for all routes defined in the inherited class * * @param path resource path of all defined class * @throws NullPointerException whether {@code path} is {@code null} */ protected final void setControllerPath(String path) { requireNonNull(path, "Global path cannot be change to 'null'"); if (!"".equals(path) && !"/".equals(path)) { this.controllerPath = pathCorrector.apply(path); } } /** * Sets roles which are allowed for a given controller * * @param roles allowed roles * @throws NullPointerException whether {@code path} is {@code null} */ protected final void setRoles(String... roles) { requireNonNull(roles, "Roles cannot be change to 'null'"); this.roles = roles; } @Override public Set<InternalRoute> getRoutes() { return routes; } protected InternalRoute createEntityRoute(HttpMethod method, String path, RouteAction action, Type<?> reqClazz, Type<?> respClazz) { requireNonNull(path, "Route path cannot be null."); final String correctPath = pathCorrector.apply(path); final InternalRoute route = new InternalRoute(correctPath, method, action, reqClazz, respClazz); routes.add(route); return route; } }