Package org.rendersnake.ext.guice

Source Code of org.rendersnake.ext.guice.GuiceComponentServlet

package org.rendersnake.ext.guice;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.rendersnake.PageContext;
import org.rendersnake.Renderable;
import org.rendersnake.internal.HtmlServletCanvas;
import org.rendersnake.servlet.FormHandler;
import org.rendersnake.servlet.FormResponseAction;

import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Singleton;
/**
* GuiceComponentServlet is used to serve RenderSnake components.
* Each such component must be annotation with @Named in order to pickup here.
*
* Usage
* <pre>
  new ServletModule(){             
       protected void configureServlets() {
           serve("/web/*").with(GuiceComponentServlet.class);
           // list all page classes here
           bind(HomePage.class);
       }
   }
* </pre>        
*
*
* @author emicklei
*/
@Singleton
public class GuiceComponentServlet extends HttpServlet {
    private static final long serialVersionUID = -5260542693799682553L;
    private static final Logger LOG = Logger.getLogger("org.rendersnake.ext.guice");
   
    /**
     * Injector needed for initialization of the mapping.
     */
    @Inject
    private Injector injector;  
   
    /**
     * Cached map of uri paths to Renderable components.
     */
    private Map<String,Renderable> dispatchMap = new HashMap<String,Renderable>();
    /**
     * Cached map of uri paths to FormHandler components.
     */
    private Map<String,FormHandler> handlerMap = new HashMap<String,FormHandler>();
   
    /**
     * Dispatch an incoming request to a Renderable component
     * by looking for a named component that matches the path.
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = "";
        String info = req.getPathInfo();
        if (null != info && info.length() > 0) {
            uri = info.substring(1);           
        }
        Renderable component = this.dispatchMap.get(uri);
        if (component == null) {
            resp.sendError(404);
        } else {
            HtmlServletCanvas canvas = new HtmlServletCanvas(req, resp, resp.getWriter());
            this.copyParametersIntoPageContext(req, canvas);
            canvas.render(component);         
        }
    }

    private void copyParametersIntoPageContext(HttpServletRequest req, HtmlServletCanvas canvas) {
        // copy query parameters into pageContext
        Enumeration<String> names = req.getParameterNames();
        PageContext ctx = canvas.getPageContext();
        while (names.hasMoreElements()) {
            String key = names.nextElement();
            Object value = req.getParameter(key);
            ctx.set(key,value);
        }
    }
   
    /**
     * Dispatch an incoming request to a Renderable component
     * by looking for a named component that matches the path.
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = "";
        String info = req.getPathInfo();
        if (null != info && info.length() > 0) {
            uri = info.substring(1);           
        }
        FormHandler handler = this.handlerMap.get(uri);
        if (handler == null) {
            resp.sendError(404);
        } else {
            FormResponseAction action = handler.handle(req, resp);
            if (action.redirectToUrl != null) {
                resp.sendRedirect(action.redirectToUrl);
                return;
            } else if (action.component != null){
                HtmlServletCanvas html = new HtmlServletCanvas(req, resp, resp.getWriter());
                this.copyParametersIntoPageContext(req, html);
                action.component.renderOn(html);
            } else {
                resp.setStatus(200);
            }
        }
    }
   
    /**
     * Initializes the mapping between path info and Renderable components.
     * It is implemented by inspecting all bindings of the injector.
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        for (Key<?> key : injector.getBindings().keySet()) {
            Type type = key.getTypeLiteral().getType();
            if (type instanceof Class<?>) {
                Class<?> klass = (Class<?>) type;
                if (Renderable.class.isAssignableFrom(klass)) {
                    Renderable p = (Renderable)injector.getInstance(klass);
                    Named annotation = klass.getAnnotation(Named.class);
                    if (annotation != null) {
                        dispatchMap.put(annotation.value(), p);
                        LOG.info("Binding component:"+klass+" to:" + annotation);
                    } else {
                        LOG.severe("Missing @Named annotation in component:"+klass);
                    }
                }
                if (FormHandler.class.isAssignableFrom(klass)) {
                    FormHandler h = (FormHandler)injector.getInstance(klass);
                    Named annotation = klass.getAnnotation(Named.class);
                    if (annotation != null) {
                        handlerMap.put(annotation.value(), h);
                        LOG.info("Binding component:"+klass+" to:" + annotation);
                    } else {
                        LOG.severe("Missing @Named annotation in component:"+klass);
                    }
                }               
            }
        }               
        super.init(config);
    }
}
TOP

Related Classes of org.rendersnake.ext.guice.GuiceComponentServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.