Java tutorial
/* * ======================================================================== * * 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(); } }