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;
}
}