package name.pehl.taoki;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.restlet.Application;
import org.restlet.Context;
import org.restlet.ext.servlet.ServletAdapter;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
/**
* Abstract base class for a servlet which acts as a dispatcher for all
* resources in a Guice based RESTful webapp. Concrete subclasses have to
* override the method {@link #createRouter(Injector, Context)} and provide a
* concrete implementation of {@link GuiceRouter}.
* <p>
* The following code snippets show a typical setup:
* <p>
* <b>web.xml:</b>
*
* <pre>
* <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
* <filter>
* <filter-name>guiceFilter</filter-name>
* <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
* </filter>
* <filter-mapping>
* <filter-name>guiceFilter</filter-name>
* <url-pattern>/*</url-pattern>
* </filter-mapping>
* <listener>
* <listener-class>name.pehl.tire.server.servlet.ServletConfig</listener-class>
* </listener>
* </web-app>
* </pre>
* <p>
* <b>ServletConfig:</b>
*
* <pre>
* public class ServletConfig extends GuiceServletContextListener
* {
* @Override
* protected Injector getInjector()
* {
* // Further modules are omitted...
* return Guice.createInjector(new ServletModule(), new BookstoreModule());
* }
* }
* </pre>
* <p>
* <b>ServletModule & RestletServlet:</b>
*
* <pre>
* public class ServletModule extends com.google.inject.servlet.ServletModule
* {
* @Override
* protected void configureServlets()
* {
* serve("/rest/v1/*").with(BookstoreRestletServlet.class);
* }
* }
*
* @Singleton
* public class BookstoreRestletServlet extends RestletServlet
* {
* @Override
* protected GuiceRouter createRouter(Injector injector, Context context)
* {
* return new BookstoreRouter(injector, context);
* }
* }
* </pre>
* <p>
* <b>Router:</b>
*
* <pre>
* public class BookstoreRouter extends GuiceRouter
* {
* public BookstoreRouter(Injector injector, Context context)
* {
* super(injector, context);
* }
*
*
* @Override
* protected void attachRoutes()
* {
* attach("/books", BooksResource.class);
* }
* }
* </pre>
* <p>
* <b>Resources:</b>
*
* <pre>
* public class BookstoreModule extends AbstractModule
* {
* @Override
* protected void configure()
* {
* bind(BookstoreService.class).to(BookstoreServiceImpl.class);
* bind(BooksResource.class);
* }
* }
*
* public class BooksResource extends ServerResource
* {
* private final BookstoreService service;
*
*
* @Inject
* public ProjectsResource(BookstoreService service)
* {
* this.service = service;
* }
*
*
* @Get
* public List<Book> represent()
* {
* return service.listBooks();
* }
* }
* </pre>
*
* @author $Author: harald.pehl $
* @version $Revision: 219 $
*/
@Singleton
public abstract class RestletServlet extends HttpServlet
{
@Inject
protected Injector injector;
protected ServletAdapter adapter;
@Override
public void init() throws ServletException
{
adapter = new ServletAdapter(getServletContext());
Context context = adapter.getContext().createChildContext();
Application application = new Application(context);
application.setInboundRoot(createRouter(injector, context));
adapter.setNext(application);
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException
{
adapter.service(request, response);
}
protected abstract GuiceRouter createRouter(final Injector injector, final Context context);
}