Package net.sourceforge.javautil.developer.web.unit.mockserver

Source Code of net.sourceforge.javautil.developer.web.unit.mockserver.MockServletContext

package net.sourceforge.javautil.developer.web.unit.mockserver;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSessionListener;

import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.web.server.application.WebApplication;
import net.sourceforge.javautil.web.server.application.WebApplicationDefaultMimeMappings;
import net.sourceforge.javautil.web.server.application.WebApplicationDeploymentContext;
import net.sourceforge.javautil.web.server.application.WebApplicationServletContext;
import net.sourceforge.javautil.web.server.descriptor.IWebXml;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlFilter;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlFilterMapping;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlListener;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlServlet;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlServletMapping;
import net.sourceforge.javautil.web.server.descriptor.WebXmlUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is the main context for actually deploying/undeploying an application.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public abstract class MockServletContext implements ServletContext {
 
  protected Logger log;
 
  protected final MockServerHost host;
  protected final WebApplication application;

  protected final Map<String, MockServletSetup> servlets = new LinkedHashMap<String, MockServletSetup>();
  protected final Map<String, MockFilterSetup> filters = new LinkedHashMap<String, MockFilterSetup>();
 
  protected final List<String> listenerClasses = new CopyOnWriteArrayList<String>();
 
  protected final List<ServletContextListener> contextListeners = new ArrayList<ServletContextListener>();
  protected final List<HttpSessionListener> sessionListeners = new ArrayList<HttpSessionListener>();
 
  protected final Map<String, String> mimeMappings = new LinkedHashMap<String, String>();
  protected final Map<String, String> extMappings = new LinkedHashMap<String, String>();
 
  protected Map<String, Object> attributes = new LinkedHashMap<String, Object>();
  protected WebApplicationServletContext wrapper;
 
  public MockServletContext(MockServerHost host, WebApplication application) {
    this.host = host;
    this.application = application;
    this.wrapper = new WebApplicationServletContext(this, application);
    this.log = LoggerFactory.getLogger("mockserver.context." + application.getContextPath().replaceAll("[\\\\/]", "."));
    this.mimeMappings.putAll(WebApplicationDefaultMimeMappings.getMappings());
    this.extMappings.putAll(WebApplicationDefaultMimeMappings.getDefaultExtensionMapping());
  }
 
  public List<HttpSessionListener> getSessionListenerClasses () { return new ArrayList<HttpSessionListener>(this.sessionListeners); }
 
  /**
   * @param className The name of the class to instantiate, a no-arg constructor is assumed
   * @return The new instance of the class
   */
  protected Object createInstance (String className) {
    return ClassCache.getFor( ReflectionUtil.getClass(className, Thread.currentThread().getContextClassLoader()) )
      .newInstance();
  }
 
  /**
   * This should be called when the context is being deploeyd.
   *
   * @throws ServletException
   */
  protected void initialize () throws ServletException {
    ClassLoader original = null;
    if (this.application.getClassLoader() != null) {
      original = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(this.application.getClassLoader());
    }
   
    this.listenerClasses.clear();
    this.contextListeners.clear();
    this.servlets.clear();
    this.filters.clear();
   
    IWebXml webXml = application.getWebXml();
    for (IWebXmlListener listener : webXml.getListeners()) {
      this.listenerClasses.add(listener.getListenerClass());
    }
   
    for (IWebXmlFilter filter : webXml.getFilters()) {
      MockFilterSetup setup = new MockFilterSetup(wrapper, filter);
      for (IWebXmlFilterMapping mapping : WebXmlUtil.getMappings(webXml, filter)) {
        setup.urlPatterns.addAll(mapping.getPatterns());
      }
      this.filters.put(filter.getFilterName(), setup);
    }
   
    for (IWebXmlServlet servlet : webXml.getServlets()) {
      MockServletSetup setup = new MockServletSetup(wrapper, servlet, WebXmlUtil.getFilterNames(webXml, servlet));
      for (IWebXmlServletMapping mapping : WebXmlUtil.getMappings(webXml, servlet)) {
        setup.urlPatterns.addAll(mapping.getPatterns());
      }
      this.servlets.put(servlet.getServletName(), setup);
    }
   
    try {
      for (String listener : this.listenerClasses) {
        Object linstance = this.createInstance(listener);
        if (linstance instanceof ServletContextListener) this.contextListeners.add( (ServletContextListener) linstance );
        if (linstance instanceof HttpSessionListener) this.sessionListeners.add( (HttpSessionListener) linstance );
      }
     
      ServletContextEvent evt = new ServletContextEvent(wrapper);
      for (int cl=0; cl<contextListeners.size(); cl++) contextListeners.get(cl).contextInitialized(evt);
     
      List<MockServletSetup> sservlets = new ArrayList<MockServletSetup>(this.servlets.values());
      for (int s=0; s<sservlets.size(); s++) sservlets.get(s).getServlet().init(sservlets.get(s));
     
      List<MockFilterSetup> sfilters = new ArrayList<MockFilterSetup>(this.filters.values());
      for (int f=0; f<sfilters.size(); f++) sfilters.get(f).getFilter().init(sfilters.get(f));
    } finally {
      if (original != null) Thread.currentThread().setContextClassLoader(original);
    }
  }
 
  /**
   * This should be called when the servlet context is to be destroyed/undeployed.
   *
   * @throws ServletException
   */
  protected void destroyed () throws ServletException {
    ClassLoader original = null;
    if (this.application.getClassLoader() != null) {
      original = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(this.application.getClassLoader());
    }
   
    try {
      List<MockFilterSetup> sfilters = new ArrayList<MockFilterSetup>(this.filters.values());
      for (int f=0; f<sfilters.size(); f++) sfilters.get(f).getFilter().destroy();
 
      List<MockServletSetup> sservlets = new ArrayList<MockServletSetup>(this.servlets.values());
      for (int s=0; s<sservlets.size(); s++) sservlets.get(s).getServlet().destroy();
 
      ServletContextEvent evt = new ServletContextEvent(this);
      for (int cl=0; cl<contextListeners.size(); cl++) contextListeners.get(cl).contextDestroyed(evt);
    } finally {
      if (original != null) Thread.currentThread().setContextClassLoader(original);
    }
  }
 
  /**
   * @return The wrapper for this for integration
   * @see WebApplicationServletContext
   */
  public WebApplicationServletContext getWrapper() {
    return wrapper;
  }

  /**
   * @param requestPath The requested path
   * @return The first/closest match servlet that is defined to handle the requested path, or null if none could be found
   */
  public MockServletSetup findServlet (String requestPath) {
    List<MockServletSetup> sservlets = new ArrayList<MockServletSetup>(this.servlets.values());
    for (int s=0; s<sservlets.size(); s++) {
      MockServletSetup servlet = sservlets.get(s);
      for (int i=0; i<servlet.getPatterns().size(); i++) {
        if (this.matches(requestPath, servlet.getPatterns().get(i))) return servlet;
      }
    }
    return null;
  }
 
  /**
   * @param servlet The servlet
   * @param requestPath The request path
   * @return A list of filters that should be included in requests for the servlet/path combination
   */
  public List<Filter> getFilters (MockServletSetup servlet, String requestPath) {
    List<Filter> filters = new ArrayList<Filter>();
    List<MockFilterSetup> sfilters = new ArrayList<MockFilterSetup>(this.filters.values());
   
    for (int f=0; f<sfilters.size(); f++) {
      if ( this.isFilterForRequest(sfilters.get(f), servlet, requestPath) )
        filters.add( sfilters.get(f).getFilter() );
    }
   
    return filters;
  }

  /**
   * @param filter The filter setup
   * @param servlet The servlet
   * @param requestPath The request path
   * @return True if the filter should be included in the request, otherwise false
   */
  public boolean isFilterForRequest (MockFilterSetup filter, MockServletSetup servlet, String requestPath) {
    if (servlet != null && servlet.filters.contains(filter.getFilterName())) return true;
    for (int i=0; i<filter.getPatterns().size(); i++) {
      if ( this.matches(requestPath, filter.getPatterns().get(i)) ) return true;
    }
    return false;
  }
 
  /**
   * @param requestPath The requested path
   * @param urlPattern The pattern for checking
   * @return True if the request path matches the pattern, otherwise false
   */
  public boolean matches (String requestPath, String urlPattern) {
    if (!urlPattern.contains("*") && !urlPattern.contains("?")) {
      return requestPath.startsWith(urlPattern);
    } else {
      urlPattern = urlPattern.replaceAll("\\.", "\\\\.");
      if (urlPattern.startsWith("*")) urlPattern = "." + urlPattern;
      else if (urlPattern.startsWith("/*")) urlPattern = "/.*";
      else if (urlPattern.contains("*")) urlPattern = urlPattern.replaceAll("\\*", ".*");
      return Pattern.compile(urlPattern).matcher(requestPath).matches();
    }
  }
 
  /**
   * @return The parent class loader for this context
   */
  public ClassLoader getParentClassLoader() { return this.application.getClassLoader(); }

  public Object getAttribute(String name) { return attributes.get(name); }
 
  public Enumeration getAttributeNames() { return Collections.enumeration( attributes.keySet() ); }
 
  public ServletContext getContext(String path) {
    WebApplicationDeploymentContext deployment = host.getContext(path);
    return deployment == null ? null : deployment.getServletContext();
  }
 
  public String getContextPath() { return this.application.getContextPath(); }
 
  public String getInitParameter(String name) { return this.application.getWebXml().getInitParameters().get(name); }
 
  public Enumeration getInitParameterNames() {
    return Collections.enumeration(this.application.getWebXml().getInitParameters().keySet());
  }
 
  public int getMajorVersion() { return 2; }
 
  public void setMimeTypeMapping (String ext, String mimeType) {
    this.mimeMappings.put(ext, mimeType);
  }
 
  public String getMimeType(String filename) {
    String[] extension = filename.split("\\.");
    return mimeMappings.get( extension[extension.length-1].toLowerCase() );
  }
 
  /**
   * @param mimeType The mime content type
   * @return The first extension related to this type, otherwise null
   */
  public String getDefaultExtension (String mimeType) {
    if (this.extMappings.containsKey(mimeType)) return this.extMappings.get(mimeType);
    for (String ext : mimeMappings.keySet()) {
      if (mimeType.equals(mimeMappings.get(ext))) return ext;
    }
    return null;
  }
 
  public int getMinorVersion() { return 5; }
 
  public RequestDispatcher getNamedDispatcher(String name) {
    return this.servlets.containsKey(name) ? this.createRequestDispatcher(this.servlets.get(name), null) : null;
  }

  public RequestDispatcher getRequestDispatcher(String path) {
    MockServletSetup servlet = this.findServlet(path);
    return servlet == null ? null : this.createRequestDispatcher(servlet, path);
  }
 
  public abstract RequestDispatcher createRequestDispatcher (MockServletSetup servlet, String path);

   public String getRealPath(String path) {
     File file = application.getResourceResolver().getFile(path);
     return file == null ? null : file.getAbsolutePath();
   }

  public URL getResource(String path) throws MalformedURLException { return application.getResourceResolver().getResource(path); }

  public InputStream getResourceAsStream(String path) {
    try {
      return this.getResource(path).openStream();
    } catch (IOException e) {
      return null;
    }
  }

  public Set getResourcePaths(String path) {
    return new HashSet(application.getResourceResolver().getResourcePaths(path));
  }

  public String getServerInfo() { return "Gracelets Tools Mock Server"; }

  public Servlet getServlet(String name) throws ServletException {
    return this.servlets.containsKey(name) ? this.servlets.get(name).getServlet() : null;
  }

  public String getServletContextName() { return this.application.getName(); }

  public Enumeration getServletNames() { return Collections.enumeration( this.servlets.keySet() ); }

  public Enumeration getServlets() {
    List<Servlet> servlets = new ArrayList<Servlet>();
    for (MockServletSetup servlet : this.servlets.values()) servlets.add(servlet.getServlet());
    return Collections.enumeration( servlets );
  }

  public void log(Exception exception, String msg) { log.warn(msg, exception); }

  public void log(String msg, Throwable throwable) { log.error(msg, throwable); }

  public void log(String msg) { log.info(msg); }

  public void removeAttribute(String name) {
    Map<String, Object> newm = new LinkedHashMap<String, Object>(this.attributes);
    newm.remove(name);
    this.attributes = newm;
  }

  public void setAttribute(String name, Object value) {
    Map<String, Object> newm = new LinkedHashMap<String, Object>(this.attributes);
    newm.put(name, value);
    this.attributes = newm;
  }

}
TOP

Related Classes of net.sourceforge.javautil.developer.web.unit.mockserver.MockServletContext

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.