/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.ext.spring; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.restlet.Application; import org.restlet.Context; import org.restlet.Restlet; import org.restlet.ext.servlet.ServletAdapter; import org.springframework.beans.BeansException; import org.springframework.web.servlet.FrameworkServlet; /** * A Servlet which provides an automatic Restlet integration with an existing * {@link org.springframework.web.context.WebApplicationContext}. The usage is * similar to Spring's {@link org.springframework.web.servlet.DispatcherServlet} * . In the web.xml file, declare the Servlet and map its root URL like this: * * <pre> * <servlet> * <servlet-name>api</servlet-name> * <servlet-class>org.restlet.ext.spring.RestletFrameworkServlet</servlet-class> * <load-on-startup>1</load-on-startup> * </servlet> * * <servlet-mapping> * <servlet-name>api</servlet-name> * <url-pattern>/api/v1/*</url-pattern> * </servlet-mapping> * </pre> * * <p> * Then, create a beans XML file called * <code>/WEB-INF/[servlet-name]-servlet.xml</code> — in this case, * <code>/WEB-INF/api-servlet.xml</code> — and define your restlets and * resources in it. * <p> * All requests to this servlet will be delegated to a single top-level restlet * loaded from the Spring application context. By default, this servlet looks * for a bean named "root". You can override that by passing in the * <code>targetRestletBeanName</code> parameter. For example: * * <pre> * <servlet> * <servlet-name>api</servlet-name> * <servlet-class>org.restlet.ext.spring.RestletFrameworkServlet</servlet-class> * <load-on-startup>1</load-on-startup> * <init-param> * <param-name>targetRestletBeanName</param-name> * <param-value>guard</param-value> * </init-param> * </servlet> * </pre> * <p> * If the target restlet is an {@link org.restlet.Application}, it will be used * directly. Otherwise, it will be wrapped in an instance of {@link Application}. * * @author Rhett Sutphin */ public class RestletFrameworkServlet extends FrameworkServlet { /** The default bean name for the target Restlet. */ private static final String DEFAULT_TARGET_RESTLET_BEAN_NAME = "root"; private static final long serialVersionUID = 1L; /** The adapter of Servlet calls into Restlet equivalents. */ private volatile ServletAdapter adapter; /** The bean name of the target Restlet. */ private volatile String targetRestletBeanName; /** * Creates the Restlet {@link Context} to use if the target application does * not already have a context associated, or if the target restlet is not an * {@link Application} at all. * <p> * Uses a simple {@link Context} by default. * * @return A new instance of {@link Context} */ protected Context createContext() { return new Context(); } @Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getAdapter().service(request, response); } /** * Provides access to the {@link ServletAdapter} used to handle requests. * Exposed so that subclasses may do additional configuration, if necessary, * by overriding {@link #initFrameworkServlet()}. * * @return The adapter of Servlet calls into Restlet equivalents. */ protected ServletAdapter getAdapter() { return this.adapter; } /** * Returns the target Restlet from Spring's Web application context. * * @return The target Restlet. */ protected Restlet getTargetRestlet() { return (Restlet) getWebApplicationContext().getBean( getTargetRestletBeanName()); } /** * Returns the bean name of the target Restlet. Returns "root" by default. * * @return The bean name. */ public String getTargetRestletBeanName() { return (this.targetRestletBeanName == null) ? DEFAULT_TARGET_RESTLET_BEAN_NAME : this.targetRestletBeanName; } @Override protected void initFrameworkServlet() throws ServletException, BeansException { super.initFrameworkServlet(); this.adapter = new ServletAdapter(getServletContext()); org.restlet.Application application; if (getTargetRestlet() instanceof Application) { application = (Application) getTargetRestlet(); } else { application = new Application(); application.setInboundRoot(getTargetRestlet()); } if (application.getContext() == null) { application.setContext(createContext()); } this.adapter.setNext(application); } /** * Sets the bean name of the target Restlet. * * @param targetRestletBeanName * The bean name. */ public void setTargetRestletBeanName(String targetRestletBeanName) { this.targetRestletBeanName = targetRestletBeanName; } }