package servletunit; // StrutsTestCase - a JUnit extension for testing Struts actions // within the context of the ActionServlet. // Copyright (C) 2002 Deryl Seale // // This library is free software; you can redistribute it and/or // modify it under the terms of the Apache Software License as // published by the Apache Software Foundation; either version 1.1 // of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Apache Software Foundation Licens for more details. // // You may view the full text here: http://www.apache.org/LICENSE.txt import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import java.io.InputStream; import java.io.File; import java.io.FileInputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Hashtable; import java.util.Set; /** * This class simulates a ServletContext. */ public class ServletContextSimulator implements ServletContext { private Hashtable initParameters; private Hashtable attributes; private RequestDispatcherSimulator dispatcher = null; private static Log logger = LogFactory.getLog( ServletContextSimulator.class ); private File contextDirectory; public ServletContextSimulator() { this.initParameters = new Hashtable(); this.attributes = new Hashtable(); } /** * Returns the servlet container attribute with the given name, * or null if there is no attribute by that name. * An attribute allows a servlet container to give the * servlet additional information not * already provided by this interface. See your * server documentation for information about its attributes. * A list of supported attributes can be retrieved using * getAttributeNames. * *

The attribute is returned as a java.lang.Object * or some subclass. * Attribute names should follow the same convention as package * names. The Java Servlet API specification reserves names * matching java.*, javax.*, * and sun.*. * * * @param name a String specifying the name * of the attribute * * @return an Object containing the value * of the attribute, or null * if no attribute exists matching the given * name * * @see ServletContext#getAttributeNames * */ public Object getAttribute(String name) { return attributes.get(name); } /** * Returns an Enumeration containing the * attribute names available * within this servlet context. Use the * {@link #getAttribute} method with an attribute name * to get the value of an attribute. * * @return an Enumeration of attribute * names * * @see #getAttribute * */ public Enumeration getAttributeNames() { return attributes.keys(); } /** * Unsupported in this version. */ public ServletContext getContext(String uripath) { throw new UnsupportedOperationException("getContext operation is not supported!"); } /** * Returns a String containing the value of the named * context-wide initialization parameter, or null if the * parameter does not exist. * *

This method can make available configuration information useful * to an entire "web application". For example, it can provide a * webmaster's email address or the name of a system that holds * critical data. * * @param s a String containing the name of the * parameter whose value is requested * * @return a String containing at least the * servlet container name and version number * * @see javax.servlet.ServletConfig#getInitParameter */ public String getInitParameter(String s) { return (String) initParameters.get(s); } /** * Returns the names of the context's initialization parameters as an * Enumeration of String objects, or an * empty Enumeration if the context has no initialization * parameters. * * @return an Enumeration of String * objects containing the names of the context's * initialization parameters * * @see javax.servlet.ServletConfig#getInitParameter */ public Enumeration getInitParameterNames() { return initParameters.keys(); } /** * Sets a named initialization parameter with the supplied * String value. * * @param key a String specifying the name * of the initialization parameter * * @param value a String value for this initialization * parameter * */ public void setInitParameter(String key,String value) { initParameters.put(key,value); } /** * Returns the major version of the Java Servlet API that this * Web server supports. All implementations that comply * with Version 2.3 must have this method * return the integer 2. * * @return 2 * */ public int getMajorVersion() { return 2; } /** * Unsupported in this version. */ public String getMimeType(String file) { throw new UnsupportedOperationException("getMimeType operation is not supported!"); } /** * Returns the minor version of the Servlet API that this * Web server supports. All implementations that comply * with Version 2.3 must have this method * return the integer 1. * * @return 3 * */ public int getMinorVersion() { return 3; } public RequestDispatcher getNamedDispatcher(String s) { throw new UnsupportedOperationException("getNamedDispatcher operation is not supported!"); } public String getRealPath(String path) { if ((contextDirectory == null) || (path == null)) return null; else return (new File(contextDirectory, path)).getAbsolutePath(); } /** * * Returns a {@link RequestDispatcher} object that acts * as a wrapper for the resource located at the given path. * A RequestDispatcher object can be used to forward * a request to the resource or to include the resource in a response. * The resource can be dynamic or static. * *

The pathname must begin with a "/" and is interpreted as relative * to the current context root. Use getContext to obtain * a RequestDispatcher for resources in foreign contexts. * This method returns null if the ServletContext * cannot return a RequestDispatcher. * * @param urlpath a String specifying the pathname * to the resource * * @return a RequestDispatcher object * that acts as a wrapper for the resource * at the specified path * * @see RequestDispatcher * @see ServletContext#getContext * */ public RequestDispatcher getRequestDispatcher(String urlpath) { dispatcher = new RequestDispatcherSimulator(urlpath); return dispatcher; } /** * Returns the mock RequestDispatcher object used in this test. * The RequestDispatcherSimulator contains forwarding information * that can be used in test validation. */ public RequestDispatcherSimulator getRequestDispatcherSimulator() { return dispatcher; } /** * TODO: add appropriate comments */ public URL getResource(String path) throws MalformedURLException { try { File file = getResourceAsFile(path); if (file.exists()) { return file.toURL(); } else { if(!path.startsWith("/")){ path = "/" + path; } return this.getClass().getResource(path); } } catch (Exception e) { return null; } } /** * Returns the resource located at the named path as * an InputStream object. * *

The data in the InputStream can be * of any type or length. The path must be specified according * to the rules given in getResource. * This method returns null if no resource exists at * the specified path. * *

Meta-information such as content length and content type * that is available via getResource * method is lost when using this method. * *

The servlet container must implement the URL handlers * and URLConnection objects necessary to access * the resource. * *

In this mock implementation, this method first looks for * the supplied pathname in the underlying filesystem; if it * does not exist there, the default Java classloader is used. * * * @param path a String specifying the path * to the resource * * @return the InputStream returned to the * servlet, or null if no resource * exists at the specified path * * */ public InputStream getResourceAsStream(String path) { try { File file = getResourceAsFile(path); if (file.exists()) { return new FileInputStream(file); } else { if(!path.startsWith("/")){ path = "/" + path; } return this.getClass().getResourceAsStream(path); } } catch (Exception e) { System.out.println("caught error: " + e); e.printStackTrace(); return null; } } /** * Attempts to load a resource from the underlying file system * and return a file handle to it. * It first treats the path as an absolute path. If no file is found, * it attempts to treat the path as relative to the context directory. * If no file is found, it attempts to treat the path as relative to * the current directory. * If all these options fail, the returned file will return false() * to calls to File.exists(). * @param path the relative or context-relative path to the file * @return the refernce to the file (which may or may not exist) */ public File getResourceAsFile(String path){ File file = new File(path); // If the path is relative then apply the contextDirectory path if it exists. if (!file.exists()) { if(!path.startsWith("/")){ path = "/" + path; } if((getContextDirectory() != null)) { file = new File(getContextDirectory().getAbsolutePath() + path); }else{ //try using current directory file = new File(new File(".").getAbsolutePath() + path); } } return file; } /** * Unsupported in this version. */ public Set getResourcePaths() { throw new UnsupportedOperationException("getResourcePaths operation is not supported!"); } /** * Returns the name and version of the servlet container on which * the servlet is running. * *

The form of the returned string is * servername/versionnumber. * For example, the JavaServer Web Development Kit may return the string * JavaServer Web Dev Kit/1.0. * *

The servlet container may return other optional information * after the primary string in parentheses, for example, * JavaServer Web Dev Kit/1.0 (JDK 1.1.6; Windows NT 4.0 x86). * * * @return a String containing at least the * servlet container name and version number * */ public String getServerInfo() { return "MockServletEngine/1.9.5"; } /** * Unsupported in this version. */ public Servlet getServlet(String name) throws ServletException { throw new UnsupportedOperationException("getServlet operation is not supported!"); } /** * Unsupported in this version. */ public String getServletContextName() { throw new UnsupportedOperationException("getServletContextName operation is not supported!"); } /** * Unsupported in this version. */ public Enumeration getServletNames() { throw new UnsupportedOperationException("getServletNames operation is not supported!"); } /** * Unsupported in this version. */ public Enumeration getServlets() { throw new UnsupportedOperationException("getServlets operation is not supported!"); } /** * @deprecated As of Java Servlet API 2.1, use * @link ServletContext.log(String message, Throwable throwable) * instead. * *

This method was originally defined to write an * exception's stack trace and an explanatory error message * to the servlet log file. * */ public void log(Exception exception, String msg) { logger.info(msg + "\n" + exception.getClass() + " - " + exception.getMessage()); } /** * * Writes the specified message to a servlet log file, which is usually * an event log. The message provides explanatory information about * an exception or error or an action the servlet engine takes. The name * and type of the servlet log file is specific to the servlet engine. * * * @param msg a String specifying the explanatory * message to be written to the log file * */ public void log(String msg) { logger.info(msg); } /** * Writes the stack trace and an explanatory message * for a given Throwable exception * to the servlet log file. The name and type of the servlet log * file is specific to the servlet engine, but it is usually an event log. * * * @param message a String that * describes the error or exception * * @param throwable the Throwable error * or exception * */ public void log(String message, Throwable throwable) { logger.info(message + "\n" + throwable.getClass() + " - " + throwable.getMessage()); } /** * Removes the attribute with the given name from * the servlet context. After removal, subsequent calls to * {@link #getAttribute} to retrieve the attribute's value * will return null. *

If listeners are configured on the ServletContext the * container notifies them accordingly. * * * @param name a String specifying the name * of the attribute to be removed * */ public void removeAttribute(String name) { attributes.remove(name); } /** * * Binds an object to a given attribute name in this servlet context. If * the name specified is already used for an attribute, this * method will replace the attribute with the new to the new attribute. *

If listeners are configured on the ServletContext the * container notifies them accordingly. *

* If a null value is passed, the effect is the same as calling * removeAttribute(). * *

Attribute names should follow the same convention as package * names. The Java Servlet API specification reserves names * matching java.*, javax.*, and * sun.*. * * * @param name a String specifying the name * of the attribute * * @param object an Object representing the * attribute to be bound * * * */ public void setAttribute(String name, Object object) { attributes.put(name,object); } /** * Unsupported in this version. */ public Set getResourcePaths(String path) { throw new UnsupportedOperationException("getResourcePaths operation is not supported!"); } /** * Sets the absolute context directory to be used in the getRealPath() method. * @param contextDirectory the absolute path of the root context directory for this application. */ public void setContextDirectory(File contextDirectory) { this.contextDirectory = contextDirectory; } public File getContextDirectory() { return contextDirectory; } }