All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.grizzly.http.servlet.ServletAdapter Maven / Gradle / Ivy

There is a newer version: 2.0.0-M3
Show newest version
/*
 * 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 */

package com.sun.grizzly.http.servlet;

import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.Request;
import com.sun.grizzly.tcp.Response;
import com.sun.grizzly.tcp.Constants;
import com.sun.grizzly.tcp.http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.GrizzlyResponse;
import com.sun.grizzly.util.IntrospectionUtils;
import com.sun.grizzly.util.http.Cookie;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import javax.servlet.Filter;
import javax.servlet.Servlet;

/**
 * Adapter class that can initiate a {@link FilterChain} and execute its 
 * {@link Filter} and its {@link Servlet}
 * 
 * Configuring a {@link SelectorThread} to use this {@link GrizzlyAdapter} implementation add
 * the ability of servicing Servlet as well as static resource to the Grizzly http extension. 
 * 
 * This class can be used to programatically configure a Servlet, Filters, paths,
 * init parameters, etc. a deployer usually do based on the web.xml content.
 * 
 * As an example:
 * 

        final SelectorThread selectorThread = new SelectorThread(){
                public void listen() throws IOException, InstantiationException{
                    super.listen();
                    System.out.println("Server started in " + (System.currentTimeMillis() - t1)
                            + " milliseconds.");
                }
        };
        selectorThread.setAlgorithmClassName(StaticStreamAlgorithm.class.getName());       
        selectorThread.setPort(port);
        SelectorThread.setWebAppRootPath(folder);
        ServletAdapter adapter = new ServletAdapter();
        adapter.setRootFolder(SelectorThread.getWebAppRootPath());
        st.setAdapter(adapter);
        adapter.setHandleStaticResources(true);        
        Servlet servlet = new MyOwnServlet();
   
        // programatically configure the servlet (like web.xml usually doing)
        adapter.setServletInstance(servlet);
        adapter.addInitParameter("Grizzly","is Really Cool!");
        adapter.setServletPath("/myPath");
         
        selectorThread.setAdapter(adapter);
        selectorThread.setDisplayConfiguration(true);
        selectorThread.listen(); 
 * 
* * @author Jeanfrancois Arcand */ public class ServletAdapter extends GrizzlyAdapter { public static final int REQUEST_RESPONSE_NOTES = 29; public static final int SERVLETCONFIG_NOTES = 30; private Servlet servletInstance = null; private FilterChainImpl filterChain = new FilterChainImpl(); private String servletPath = ""; private String contextPath = ""; private String basePath = ""; private String fullUrlPath = null; /** * The merged context initialization parameters for this Context. */ private HashMap parameters = new HashMap(); /** * Is the Servlet initialized. */ private boolean isInitialized = false; private ReentrantLock initializedLock = new ReentrantLock(); /** * Holder for our configured properties. */ protected HashMap properties = new HashMap(); public ServletAdapter() { super(); } /** * Create a new instance which will look for static pages located * under publicDirectory folder. * @param publicDirectory the folder where the static resource are located. */ public ServletAdapter(String publicDirectory) { super(publicDirectory); } /** * {@inheritDoc} */ @Override public void service(GrizzlyRequest request, GrizzlyResponse response) { try { if (fullUrlPath == null){ fullUrlPath = contextPath + servletPath; } Request req = request.getRequest(); Response res = response.getResponse(); String uri = request.getRequestURI(); // The request is not for us. if (!uri.startsWith(fullUrlPath)){ customizeErrorPage(response,"Resource Not Found", 404); return; } HttpServletRequestImpl httpRequest = (HttpServletRequestImpl) req.getNote(REQUEST_RESPONSE_NOTES); HttpServletResponseImpl httpResponse = (HttpServletResponseImpl) res.getNote(REQUEST_RESPONSE_NOTES); ServletConfigImpl servletConfig = (ServletConfigImpl) req.getNote(SERVLETCONFIG_NOTES); if (httpRequest == null) { httpRequest = new HttpServletRequestImpl(request); httpResponse = new HttpServletResponseImpl(response); ServletContextImpl servletCtx = new ServletContextImpl(); servletCtx.setInitParameter(parameters); servletCtx.setServletPath(servletPath); servletCtx.setContextPath(contextPath); servletCtx.setBasePath(basePath); configureProperties(servletCtx); servletConfig = new ServletConfigImpl(servletCtx); httpRequest.setContextImpl(servletCtx); req.setNote(REQUEST_RESPONSE_NOTES, httpRequest); req.setNote(SERVLETCONFIG_NOTES, servletConfig); res.setNote(REQUEST_RESPONSE_NOTES, httpResponse); } Cookie[] cookies = request.getCookies(); if (cookies != null) for (Cookie c : cookies) { if (Constants.SESSION_COOKIE_NAME.equals(c.getName())) { request.setRequestedSessionId(c.getValue()); request.setRequestedSessionCookie(true); break; } } httpRequest.initSession(); // Try to load the instance using the System.getProperties(); if (!isInitialized){ initializedLock.lock(); try{ if (servletInstance == null) { String servletClassName = System.getProperty("com.sun.grizzly.servletClass"); if (servletClassName != null) { servletInstance = loadServletInstance(servletClassName); } if (servletInstance == null) { throw new RuntimeException("Invalid Servlet defined"); } } if (!isInitialized){ servletInstance.init(servletConfig); isInitialized = true; filterChain.setServlet(servletConfig, servletInstance); } } finally { initializedLock.unlock(); } } //TODO: Make this configurable. httpResponse.addHeader("server", "grizzly/1.8.1"); filterChain.doFilter(httpRequest, httpResponse); } catch (Throwable ex) { getLogger().log(Level.SEVERE, "service exception:", ex); customizeErrorPage(response,"Internal Error", 500); } } /** * Customize the error page returned to the client. * @param response the {@link GrizzlyResponse} * @param message the Http error message * @param erroCode the error code. */ public void customizeErrorPage(GrizzlyResponse response,String message, int errorCode){ response.setStatus(errorCode, "Not Found"); response.setContentType("text/html"); try{ response.getWriter().write("

" + message + "

"); } catch (IOException ex){ // We are in a very bad shape. Ignore. } } /** * {@inheritDoc} */ @Override public void afterService(GrizzlyRequest request, GrizzlyResponse response) throws Exception { filterChain.recycle(); } /** * Add a new servlet initialization parameter for this servlet. * * @param name Name of this initialization parameter to add * @param value Value of this initialization parameter to add */ public void addInitParameter(String name, String value){ parameters.put(name, value); } private final static Servlet loadServletInstance(String servletClass) { Class className = null; try { className = Class.forName(servletClass, true, Thread.currentThread().getContextClassLoader()); return (Servlet) className.newInstance(); } catch (Throwable t) { t.printStackTrace(); } return null; } /** * Add a {@link Filter} to the {@link FilterChain} * @param filter an instance of Filter * @param filterName the Filter's name * @param initParameters the Filter init parameters. */ public void addFilter(Filter filter, String filterName, Map initParameters){ FilterConfigImpl filterConfig = new FilterConfigImpl(); filterConfig.setFilter(filter); filterConfig.setFilterName(filterName); filterConfig.setinitParameters(initParameters); filterChain.addFilter(filterConfig); } /** * Return the {@link Servlet} instance used by this {@link Adapter} * @return */ public Servlet getServletInstance() { return servletInstance; } /** * Set the {@link Servlet} instance used by this {@link Adapter} * @param servletInstance an instance of Servlet. */ public void setServletInstance(Servlet servletInstance) { this.servletInstance = servletInstance; } /** * * Returns the part of this request's URL that calls * the servlet. This path starts with a "/" character * and includes either the servlet name or a path to * the servlet, but does not include any extra path * information or a query string. Same as the value of * the CGI variable SCRIPT_NAME. * *

This method will return an empty string ("") if the * servlet used to process this request was matched using * the "/*" pattern. * * @return a String containing * the name or path of the servlet being * called, as specified in the request URL, * decoded, or an empty string if the servlet * used to process the request is matched * using the "/*" pattern. * */ public String getServletPath() { return servletPath; } /** * Programmatically set the servlet path of the Servlet. * @param servletPath */ public void setServletPath(String servletPath) { this.servletPath = servletPath; } /** * * Returns the portion of the request URI that indicates the context * of the request. The context path always comes first in a request * URI. The path starts with a "/" character but does not end with a "/" * character. For servlets in the default (root) context, this method * returns "". The container does not decode this string. * *

It is possible that a servlet container may match a context by * more than one context path. In such cases this method will return the * actual context path used by the request and it may differ from the * path returned by the * {@link javax.servlet.ServletContext#getContextPath()} method. * The context path returned by * {@link javax.servlet.ServletContext#getContextPath()} * should be considered as the prime or preferred context path of the * application. * * @return a String specifying the * portion of the request URI that indicates the context * of the request * * @see javax.servlet.ServletContext#getContextPath() */ public String getContextPath() { return contextPath; } /** * Programmatically set the context path of the Servlet. * @param contextPath */ public void setContextPath(String contextPath) { this.contextPath = contextPath; } /** * Return the current based path. * @return basePath */ protected String getBasePath() { return basePath; } /** * Set the basePath used by the {@link ServletContext#getRealPath}. * @param basePath */ protected void setBasePath(String basePath) { this.basePath = basePath; } /** * Use reflection to configure Object setter. */ private void configureProperties(Object object){ Iterator keys = properties.keySet().iterator(); while( keys.hasNext() ) { String name = (String)keys.next(); String value = properties.get(name).toString(); IntrospectionUtils.setProperty(object, name, value); } } /** * Return a configured property. */ public Object getProperty(String name) { return properties.get(name); } /** * Set a configured property. */ public void setProperty(String name, Object value) { properties.put(name, value); } /** * remove a configured property. */ public void removeProperty(String name) { properties.remove(name); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy