org.apache.cactus.server.AbstractHttpServletRequestWrapper.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.cactus.server.AbstractHttpServletRequestWrapper.java

Source

/* 
 * ========================================================================
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ========================================================================
 */
package org.apache.cactus.server;

import org.apache.cactus.ServletURL;
import org.apache.cactus.util.ChainedRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Locale;

/**
 * Abstract wrapper around {@link HttpServletRequest}. This class provides
 * a common implementation of the wrapper for the different Servlet APIs.
 * This is an implementation that delegates all the call to the
 * {@link HttpServletRequest} object passed in the constructor except for
 * some overidden methods which are use to simulate a URL. This is to be able 
 * to simulate any URL that would have been used to call the test method : if 
 * this was not done, the URL that would be returned (by calling the
 * {@link HttpServletRequest#getRequestURI()} method or others alike) would be 
 * the URL of the Cactus redirector servlet and not a URL that the test case 
 * want to simulate.
 *
 * @version $Id: AbstractHttpServletRequestWrapper.java 292559 2005-09-29 21:36:43Z kenney $
 */
public abstract class AbstractHttpServletRequestWrapper implements HttpServletRequest {
    /**
     * The logger.
     */
    private static final Log LOGGER = LogFactory.getLog(AbstractHttpServletRequestWrapper.class);

    /**
     * The real HTTP request.
     */
    protected HttpServletRequest request;

    /**
     * The URL to simulate.
     */
    protected ServletURL url;

    /**
     * Remote IP address to simulate (if any).
     * @see #setRemoteIPAddress(String)
     */
    protected String remoteIPAddress;

    /**
     * Remote Host name to simulate (if any).
     * @see #setRemoteHostName(String)
     */
    protected String remoteHostName;

    /**
     * Remote user to simulate (if any).
     * @see #setRemoteUser(String)
     */
    protected String remoteUser;

    // New methods not in the interface --------------------------------------

    /**
     * Construct an <code>HttpServletRequest</code> instance that delegates
     * it's method calls to the request object passed as parameter and that
     * uses the URL passed as parameter to simulate a URL from which the request
     * would come from.
     *
     * @param theRequest the real HTTP request
     * @param theURL     the URL to simulate or <code>null</code> if none
     */
    public AbstractHttpServletRequestWrapper(HttpServletRequest theRequest, ServletURL theURL) {
        this.request = theRequest;
        this.url = theURL;
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#newInstance()
     */
    public static AbstractHttpServletRequestWrapper newInstance(HttpServletRequest theOriginalRequest,
            ServletURL theURL) {
        try {
            Class clazz = Class.forName("org.apache.cactus.server.HttpServletRequestWrapper");
            Object[] args = new Object[] { theOriginalRequest, theURL };

            Constructor constructor = clazz
                    .getConstructor(new Class[] { HttpServletRequest.class, ServletURL.class });

            return (AbstractHttpServletRequestWrapper) constructor.newInstance(args);
        } catch (Throwable t) {
            throw new ChainedRuntimeException("Failed to create HttpServletRequestWrapper", t);
        }
    }

    /**
     * @return the original request object
     */
    public HttpServletRequest getOriginalRequest() {
        return this.request;
    }

    /**
     * Simulates the remote IP address (ie the client IP address).
     *
     * @param theRemoteIPAddress the simulated IP address in string format.
     *        Exemple : "127.0.0.1"
     */
    public void setRemoteIPAddress(String theRemoteIPAddress) {
        this.remoteIPAddress = theRemoteIPAddress;
    }

    /**
     * Simulates the remote host name(ie the client host name).
     *
     * @param theRemoteHostName the simulated host name in string format.
     *        Exemple : "atlantis"
     */
    public void setRemoteHostName(String theRemoteHostName) {
        this.remoteHostName = theRemoteHostName;
    }

    /**
     * Sets the remote user name to simulate.
     *
     * @param theRemoteUser the simulated remote user name
     */
    public void setRemoteUser(String theRemoteUser) {
        this.remoteUser = theRemoteUser;
    }

    // Modified methods ------------------------------------------------------

    /**
     * @return the context path from the simulated URL or the real context path
     *         if a simulation URL has not been defined. The real context path
     *         will be returned if the context path defined in the simulated 
     *         URL has a null value.
     */
    public String getContextPath() {
        String result = this.request.getContextPath();

        if ((this.url != null) && (this.url.getContextPath() != null)) {
            result = this.url.getContextPath();
            LOGGER.debug("Using simulated context : [" + result + "]");
        }

        return result;
    }

    /**
     * @return the path info from the simulated URL or the real path info
     *         if a simulation URL has not been defined.
     */
    public String getPathInfo() {
        String result;

        if (this.url != null) {
            result = this.url.getPathInfo();
            LOGGER.debug("Using simulated PathInfo : [" + result + "]");
        } else {
            result = this.request.getPathInfo();
        }

        return result;
    }

    /**
     * @return the server name from the simulated URL or the real server name
     *         if a simulation URL has not been defined. If the server name
     *         defined in the simulation URL is null, return the real server
     *         name.
     */
    public String getServerName() {
        String result = this.request.getServerName();

        if ((this.url != null) && (this.url.getHost() != null)) {
            result = this.url.getHost();
            LOGGER.debug("Using simulated server name : [" + result + "]");
        }

        return result;
    }

    /**
     * @return the server port number from the simulated URL or the real server
     *         port number if a simulation URL has not been defined. If no
     *         port is defined in the simulation URL, then port 80 is returned.
     *         If the server name has been defined with a null value in
     *         in the simulation URL, return the real server port. 
     */
    public int getServerPort() {
        int result = this.request.getServerPort();

        if ((this.url != null) && (this.url.getServerName() != null)) {
            result = (this.url.getPort() == -1) ? 80 : this.url.getPort();
            LOGGER.debug("Using simulated server port : [" + result + "]");
        }

        return result;
    }

    /**
     * @return the URI from the simulated URL or the real URI
     *         if a simulation URL has not been defined.
     */
    public String getRequestURI() {
        String result;

        if (this.url != null) {
            result = getContextPath() + ((getServletPath() == null) ? "" : getServletPath())
                    + ((getPathInfo() == null) ? "" : getPathInfo());

            LOGGER.debug("Using simulated request URI : [" + result + "]");
        } else {
            result = this.request.getRequestURI();
        }

        return result;
    }

    /**
     * @return the servlet path from the simulated URL or the real servlet path
     *         if a simulation URL has not been defined. The real servlet path
     *         will be returned if the servlet path defined in the simulated 
     *         URL has a null value.
     */
    public String getServletPath() {
        String result = this.request.getServletPath();

        if ((this.url != null) && (this.url.getServletPath() != null)) {
            result = this.url.getServletPath();
            LOGGER.debug("Using simulated servlet path : [" + result + "]");
        }

        return result;
    }

    /**
     * @return any extra path information after the servlet name but
     *         before the query string, and translates it to a real path.
     *         Takes into account the simulated URL (if any).
     */
    public String getPathTranslated() {
        String pathTranslated;

        if ((this.url != null) && (this.url.getPathInfo() != null)) {
            String pathInfo = this.url.getPathInfo();

            // If getRealPath returns null then getPathTranslated should also
            // return null (see section SRV.4.5 of the Servlet 2.3 spec).
            if (this.request.getRealPath("/") == null) {
                pathTranslated = null;
            } else {
                // Compute the translated path using the root real path
                String newPathInfo = (pathInfo.startsWith("/") ? pathInfo.substring(1) : pathInfo);

                if (this.request.getRealPath("/").endsWith("/")) {
                    pathTranslated = this.request.getRealPath("/") + newPathInfo.replace('/', File.separatorChar);
                } else {
                    pathTranslated = this.request.getRealPath("/") + File.separatorChar
                            + newPathInfo.replace('/', File.separatorChar);
                }
            }
        } else {
            pathTranslated = this.request.getPathTranslated();
        }

        return pathTranslated;
    }

    /**
     * @return the query string from the simulated URL or the real query
     *         string if a simulation URL has not been defined.
     */
    public String getQueryString() {
        String result;

        if (this.url != null) {
            result = this.url.getQueryString();
            LOGGER.debug("Using simulated query string : [" + result + "]");
        } else {
            result = this.request.getQueryString();
        }

        return result;
    }

    /**
     * @param thePath the path to the resource
     * @return a wrapped request dispatcher instead of the real one, so that
     *         forward() and include() calls will use the wrapped dispatcher
     *         passing it the *original* request [this is needed for some
     *         servlet engine like Tomcat 3.x which do not support the new
     *         mechanism introduced by Servlet 2.3 Filters].
     * @see HttpServletRequest#getRequestDispatcher(String)
     */
    public RequestDispatcher getRequestDispatcher(String thePath) {
        // I hate it, but we have to write some logic here ! Ideally we
        // shouldn't have to do this as it is supposed to be done by the servlet
        // engine. However as we are simulating the request URL, we have to
        // provide it ... This is where we can see the limitation of Cactus
        // (it has to mock some parts of the servlet engine) !
        if (thePath == null) {
            return null;
        }

        RequestDispatcher dispatcher = null;
        String fullPath;

        // The spec says that the path can be relative, in which case it will
        // be relative to the request. So for relative paths, we need to take
        // into account the simulated URL (ServletURL).
        if (thePath.startsWith("/")) {
            fullPath = thePath;
        } else {
            String pI = getPathInfo();

            if (pI == null) {
                fullPath = catPath(getServletPath(), thePath);
            } else {
                fullPath = catPath(getServletPath() + pI, thePath);
            }

            if (fullPath == null) {
                return null;
            }
        }

        LOGGER.debug("Computed full path : [" + fullPath + "]");

        dispatcher = new RequestDispatcherWrapper(this.request.getRequestDispatcher(fullPath));

        return dispatcher;
    }

    /**
     * Will concatenate 2 paths, normalising it. For example :
     * ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d ). Code borrowed from
     * Tomcat 3.2.2 !
     *
     * @param theLookupPath the first part of the path
     * @param thePath the part to add to the lookup path
     * @return the concatenated thePath or null if an error occurs
     */
    private String catPath(String theLookupPath, String thePath) {
        // Cut off the last slash and everything beyond
        int index = theLookupPath.lastIndexOf("/");

        theLookupPath = theLookupPath.substring(0, index);

        // Deal with .. by chopping dirs off the lookup thePath
        while (thePath.startsWith("../")) {
            if (theLookupPath.length() > 0) {
                index = theLookupPath.lastIndexOf("/");
                theLookupPath = theLookupPath.substring(0, index);
            } else {
                // More ..'s than dirs, return null
                return null;
            }

            index = thePath.indexOf("../") + 3;
            thePath = thePath.substring(index);
        }

        return theLookupPath + "/" + thePath;
    }

    /**
     * @return the simulated remote IP address if any or the real one.
     *
     * @see HttpServletRequest#getRemoteAddr()
     */
    public String getRemoteAddr() {
        String remoteIPAddress;

        if (this.remoteIPAddress != null) {
            remoteIPAddress = this.remoteIPAddress;
        } else {
            remoteIPAddress = this.request.getRemoteAddr();
        }

        return remoteIPAddress;
    }

    /**
     * @return the simulated remote host name if any or the real one.
     *
     * @see HttpServletRequest#getRemoteHost()
     */
    public String getRemoteHost() {
        String remoteHostName;

        if (this.remoteHostName != null) {
            remoteHostName = this.remoteHostName;
        } else {
            remoteHostName = this.request.getRemoteHost();
        }

        return remoteHostName;
    }

    /**
     * @return the simulated remote user name if any or the real one.
     *
     * @see HttpServletRequest#getRemoteUser()
     */
    public String getRemoteUser() {
        String remoteUser;

        if (this.remoteUser != null) {
            remoteUser = this.remoteUser;
        } else {
            remoteUser = this.request.getRemoteUser();
        }

        return remoteUser;
    }

    // Not modified methods --------------------------------------------------

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#isRequestedSessionIdFromURL()
     */
    public boolean isRequestedSessionIdFromURL() {
        return this.request.isRequestedSessionIdFromURL();
    }

    /**
     * {@inheritDoc} 
     * @see HttpServletRequest#isRequestedSessionIdFromUrl()
     */
    public boolean isRequestedSessionIdFromUrl() {
        return this.request.isRequestedSessionIdFromURL();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#isUserInRole(String)
     */
    public boolean isUserInRole(String theRole) {
        return this.request.isUserInRole(theRole);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#isRequestedSessionIdValid()
     */
    public boolean isRequestedSessionIdValid() {
        return this.request.isRequestedSessionIdValid();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#isRequestedSessionIdFromCookie()
     */
    public boolean isRequestedSessionIdFromCookie() {
        return this.request.isRequestedSessionIdFromCookie();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getLocales()
     */
    public Enumeration getLocales() {
        return this.request.getLocales();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getHeader(String)
     */
    public String getHeader(String theName) {
        return this.request.getHeader(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getHeaders(String)
     */
    public Enumeration getHeaders(String theName) {
        return this.request.getHeaders(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getHeaderNames()
     */
    public Enumeration getHeaderNames() {
        return this.request.getHeaderNames();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getScheme()
     */
    public String getScheme() {
        return this.request.getScheme();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getAuthType()
     */
    public String getAuthType() {
        return this.request.getAuthType();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getRealPath(String)
     */
    public String getRealPath(String thePath) {
        return this.request.getRealPath(thePath);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getSession()
     */
    public HttpSession getSession() {
        return this.request.getSession();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getSession(boolean)
     */
    public HttpSession getSession(boolean isCreate) {
        return this.request.getSession(isCreate);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getReader()
     */
    public BufferedReader getReader() throws IOException {
        return this.request.getReader();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getContentLength()
     */
    public int getContentLength() {
        return this.request.getContentLength();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getParameterValues(String)
     */
    public String[] getParameterValues(String theName) {
        return this.request.getParameterValues(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getContentType()
     */
    public String getContentType() {
        return this.request.getContentType();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getLocale()
     */
    public Locale getLocale() {
        return this.request.getLocale();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#removeAttribute(String)
     */
    public void removeAttribute(String theName) {
        this.request.removeAttribute(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getParameter(String)
     */
    public String getParameter(String theName) {
        return this.request.getParameter(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getInputStream()
     */
    public ServletInputStream getInputStream() throws IOException {
        return this.request.getInputStream();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getUserPrincipal()
     */
    public Principal getUserPrincipal() {
        return this.request.getUserPrincipal();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#isSecure()
     */
    public boolean isSecure() {
        return this.request.isSecure();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getCharacterEncoding()
     */
    public String getCharacterEncoding() {
        return this.request.getCharacterEncoding();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getParameterNames()
     */
    public Enumeration getParameterNames() {
        return this.request.getParameterNames();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getMethod()
     */
    public String getMethod() {
        return this.request.getMethod();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#setAttribute(String, Object)
     */
    public void setAttribute(String theName, Object theAttribute) {
        this.request.setAttribute(theName, theAttribute);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getAttribute(String)
     */
    public Object getAttribute(String theName) {
        return this.request.getAttribute(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getIntHeader(String)
     */
    public int getIntHeader(String theName) {
        return this.request.getIntHeader(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getDateHeader(String)
     */
    public long getDateHeader(String theName) {
        return this.request.getDateHeader(theName);
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getAttributeNames()
     */
    public Enumeration getAttributeNames() {
        return this.request.getAttributeNames();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getRequestedSessionId()
     */
    public String getRequestedSessionId() {
        return this.request.getRequestedSessionId();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getCookies()
     */
    public Cookie[] getCookies() {
        return this.request.getCookies();
    }

    /**
     * {@inheritDoc}
     * @see HttpServletRequest#getProtocol()
     */
    public String getProtocol() {
        return this.request.getProtocol();
    }
}