/* * Copyright 2013 Simon Taddiken * * This file is part of Polly HTTP API. * * Polly HTTP API is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * Polly HTTP API is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with Polly HTTP API. If not, see http://www.gnu.org/licenses/. */ package de.skuzzle.polly.http.api; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * <p>Controllers are used in conjunction with * {@link HttpServletServer HttpServletServers}. They provide annotated handler methods * for various {@link HttpEvent HttpEvents}. This is a quick example for a Controller * which may handle a user database:</p> * * <pre> * public class UserController extends Controller { * private Persistence p; // Some abstract persistence manager for this sample * * public UserController(Persistence p) { * this.p = p; * } * * @Override * protected Controller createInstance() { * return new UserController(p); * } * * * @Post("/addUser") * public HttpAnswer addUser(@Param("name) String name) { * User user = new User(name); * this.p.persist(user); * HttpAnswers.createStringAnswer("User added"); * } * * @Post("/deleteUser") * public void deleteUser(@Param("name") String name) { * User user = this.p.find(name); * this.p.delete(user); * HttpAnswers.createStringAnswer("User deleted"); * } * } * </pre> * * When registering this controller with an instance of {@link HttpServletServer} it will * automatically call the annotated methods if a <tt>POST</tt> request to their URL * occurs. * * <p>Controllers report all their registered URLs mapped to a suitable handler name * preceded by a configurable prefix. This prefix can be set using * {@link #setHandlerPrefix(String)}, the map can be obtained by {@link #getMyHandlers()}. * </p> * * @author Simon Taddiken */ public abstract class Controller { private HttpEvent event; private Map<String, String> myHandlers; private String handlerPrefix; private String registeredUrl; public Controller() { this.handlerPrefix = ""; this.myHandlers = new HashMap<>(); } /** * Gets the URL for which the called handler was registered. * * @return The registered URL. */ public String getRegisteredUrl() { return this.registeredUrl; } public void setHandlerPrefix(String handlerPrefix) { this.handlerPrefix = handlerPrefix; } public String getHandlerPrefix() { return this.handlerPrefix; } public void putHandledURL(Map<String, String> target, String handlerName, String url) { target.put(this.handlerPrefix + handlerName, url); this.myHandlers.put(this.handlerPrefix + handlerName, url); } /** * Gets the currently handled HttpEvent. * * @return The HttpEvent. */ protected final HttpEvent getEvent() { return this.event; } /** * Gets the HttpServer from which the current handled event originates. This is just * a call wrapper for <code>getEvent().getSource()</code>. * * @return The HttpServer instance. */ protected final HttpServletServer getServer() { return (HttpServletServer) this.getEvent().getSource(); } protected HttpSession getSession() { return this.getEvent().getSession(); } /** * Gets a map which contains as values all request URLs that are handled by this * controller. The key for each URL will be the name of the method which is annotated * to handle it optionally preceded by a prefix which can be configured in * {@link HttpServletServer}. * @return URL map of this controller. */ public Map<String, String> getMyHandlers() { return Collections.unmodifiableMap(this.myHandlers); } /** * This method is intended to create an exact copy of this controller. It will be * used by {@link #bind(HttpEvent)}. * * @return A new instance of this controller. */ protected abstract Controller createInstance(); /** * Creates a copy of this controller and binds it to the provided {@link HttpEvent}. * * @param The URL with which the handler was registered. * @param e The event. * @return A new instance of this controller. */ public final Controller bind(String registered, HttpEvent e) { final Controller result = this.createInstance(); result.event = e; result.registeredUrl = registered; result.myHandlers = this.myHandlers; return result; } }