(I'll fix this as well) On Wed, Jul 2, 2008 at 10:07 AM, Kevin Brown <[EMAIL PROTECTED]> wrote:
> The style is also off on this patch -- underscores shouldn't be used. See > also http://cwiki.apache.org/SHINDIGxSITE/java-style.html (this should > have > been linked on incubator.apache.org/shindig, but I guess it never got > added). > > On Wed, Jul 2, 2008 at 9:40 AM, Evan Gilbert <[EMAIL PROTECTED]> wrote: > > > Hi all - I was just following existing convention - the package was > already > > there. If we agree this is the wrong place I'll move the code. > > > > One reason I've heard for putting test utilities in common is so unit > test > > projects can be simple and not have cross-package dependencies. This > > doesn't > > strike me as particularly compelling (anyone know other reasons?). > However, > > I'm also not too worried about shipping a small set of test utilities > along > > with production code. > > > > So put me at +0 either way - I'll follow the group on this one. > > > > Evan > > > > > > On Wed, Jul 2, 2008 at 6:39 AM, Henning P. Schmiedehausen < > > [EMAIL PROTECTED]> > > wrote: > > > > > "Vincent Siveton" <[EMAIL PROTECTED]> writes: > > > > > > >Hi, > > > > > > >Creating a testing harness project will solve your good point. > > > > > > +1 > > > > > > Ciao > > > Henning > > > > > > > > > >2008/7/2, Henning P. Schmiedehausen <[EMAIL PROTECTED]>: > > > >> [EMAIL PROTECTED] writes: > > > >> > > > >> Folks, if this is *TEST* code, it belongs in src/test. Else it gets > > > >> shipped with the product and at some point, it will no longer be > > > >> possible to distinguish between "we need this for running" and "we > > > >> need this for testing". > > > >> > > > >> Same for maven dependencies that are used only for testing. They > > > >> should be marked as test, else the artifact will drag this as > > > >> dependency around. > > > >> > > > >> Ciao > > > >> Henning > > > >> > > > >> > > > >> >Author: evan > > > >> >Date: Tue Jul 1 17:48:26 2008 > > > >> >New Revision: 673243 > > > >> > > > >> >URL: http://svn.apache.org/viewvc?rev=673243&view=rev > > > >> >Log: > > > >> >Working on supporting end-to-end testing of social data APIs... > > added > > > FakeHttpServletRequest utility that can be passed into calls to > > HttpServlet. > > > >> > > > >> >Added: > > > >> > > > > > > > > incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/FakeHttpServletRequest.java > > > >> >Modified: > > > >> > incubator/shindig/trunk/java/common/pom.xml > > > >> > > > >> >Modified: incubator/shindig/trunk/java/common/pom.xml > > > >> >URL: > > > > > > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/pom.xml?rev=673243&r1=673242&r2=673243&view=diff > > > >> > > > > > > > >============================================================================== > > > >> >--- incubator/shindig/trunk/java/common/pom.xml (original) > > > >> >+++ incubator/shindig/trunk/java/common/pom.xml Tue Jul 1 > 17:48:26 > > > 2008 > > > >> >@@ -46,6 +46,10 @@ > > > >> > <artifactId>guice</artifactId> > > > >> > </dependency> > > > >> > <dependency> > > > >> >+ <groupId>com.google.code.google-collections</groupId> > > > >> >+ <artifactId>google-collect</artifactId> > > > >> >+ </dependency> > > > >> >+ <dependency> > > > >> > <groupId>commons-codec</groupId> > > > >> > <artifactId>commons-codec</artifactId> > > > >> > </dependency> > > > >> > > > >> >Added: > > > > > > incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/FakeHttpServletRequest.java > > > >> >URL: > > > > > > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/FakeHttpServletRequest.java?rev=673243&view=auto > > > >> > > > > > > > >============================================================================== > > > >> >--- > > > > > > incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/FakeHttpServletRequest.java > > > (added) > > > >> >+++ > > > > > > incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/testing/FakeHttpServletRequest.java > > > Tue Jul 1 17:48:26 2008 > > > >> >@@ -0,0 +1,881 @@ > > > >> >+/* > > > >> >+ * 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.shindig.common.testing; > > > >> >+ > > > >> >+import com.google.common.collect.Maps; > > > >> >+ > > > >> >+import java.io.BufferedReader; > > > >> >+import java.io.ByteArrayInputStream; > > > >> >+import java.io.IOException; > > > >> >+import java.io.InputStream; > > > >> >+import java.io.InputStreamReader; > > > >> >+import java.io.UnsupportedEncodingException; > > > >> >+import java.net.MalformedURLException; > > > >> >+import java.net.URL; > > > >> >+import java.net.URLDecoder; > > > >> >+import java.net.URLEncoder; > > > >> >+import java.text.ParseException; > > > >> >+import java.text.SimpleDateFormat; > > > >> >+import java.util.ArrayList; > > > >> >+import java.util.Collections; > > > >> >+import java.util.Date; > > > >> >+import java.util.Enumeration; > > > >> >+import java.util.HashSet; > > > >> >+import java.util.Hashtable; > > > >> >+import java.util.Iterator; > > > >> >+import java.util.LinkedHashMap; > > > >> >+import java.util.List; > > > >> >+import java.util.Locale; > > > >> >+import java.util.Map; > > > >> >+import java.util.Set; > > > >> >+import java.util.StringTokenizer; > > > >> >+import java.util.TimeZone; > > > >> >+ > > > >> >+import javax.servlet.RequestDispatcher; > > > >> >+import javax.servlet.ServletInputStream; > > > >> >+import javax.servlet.http.Cookie; > > > >> >+import javax.servlet.http.HttpServletRequest; > > > >> >+import javax.servlet.http.HttpSession; > > > >> >+ > > > >> >+/** > > > >> >+ * This class fakes a HttpServletRequest for unit test purposes. > > > Currently, it > > > >> >+ * supports servlet API 2.4. > > > >> >+ * > > > >> >+ * <p> > > > >> >+ * To use this class, you specify the request info (URL, > > parameters) > > > in the > > > >> >+ * constructors. > > > >> >+ * > > > >> >+ * <p> > > > >> >+ * Lots of stuff are still not implemented here. Feel free to > > > implement them. > > > >> >+ */ > > > >> >+public class FakeHttpServletRequest implements HttpServletRequest > { > > > >> >+ protected static final String DEFAULT_HOST = "localhost"; > > > >> >+ protected static final int DEFAULT_PORT = 80; > > > >> >+ private static final String COOKIE_HEADER = "Cookie"; > > > >> >+ private static final String HOST_HEADER = "Host"; > > > >> >+ private static final String DATE_FORMAT = "EEE, dd MMM yyyy > > > HH:mm:ss zzz"; > > > >> >+ > > > >> >+ protected String scheme_ = "http"; > > > >> >+ protected String host_; > > > >> >+ protected int port_; > > > >> >+ protected boolean secure_ = false; > > > >> >+ protected String method_ = "GET"; > > > >> >+ protected String protocol_ = "HTTP/1.0"; > > > >> >+ protected String contextPath_; > > > >> >+ protected String servletPath_; > > > >> >+ protected String pathInfo_ = null; > > > >> >+ protected String queryString_; > > > >> >+ protected String ip_ = "127.0.0.1"; > > > >> >+ protected String contentType_; > > > >> >+ > > > >> >+ protected Hashtable<String, String> headers_ = > > > >> >+ new Hashtable<String, String>(); > > > >> >+ > > > >> >+ // Use a LinkedHashMap so we can generate a query string that > is > > in > > > the same > > > >> >+ // order that we set the parameters > > > >> >+ protected Map<String, String[]> parameters_ = > > > >> >+ new LinkedHashMap<String, String[]>(); > > > >> >+ > > > >> >+ protected Set<String> postParameters_ = new HashSet<String>(); > > > >> >+ > > > >> >+ protected Map<String, Cookie> cookies_ = new Hashtable<String, > > > Cookie>(); > > > >> >+ > > > >> >+ > > > >> >+ // Use a Map rather than a table since the specified behavior > of > > > >> >+ // setAttribute() allows null values. > > > >> >+ protected Map<String, Object> attributes_ = Maps.newHashMap(); > > > >> >+ > > > >> >+ protected Locale locale_ = Locale.US; > > > >> >+ protected List<Locale> locales_ = null; > > > >> >+ > > > >> >+ // used by POST methods > > > >> >+ protected byte[] postData; > > > >> >+ protected String characterEncoding; > > > >> >+ > > > >> >+ // the following two booleans ensure that either getReader() or > > > >> >+ // getInputStream is called, but not both, to conform to specs > > for > > > the > > > >> >+ // HttpServletRequest class. > > > >> >+ protected boolean getReaderCalled = false; > > > >> >+ protected boolean getInputStreamCalled = false; > > > >> >+ > > > >> >+ private HttpSession session; > > > >> >+ > > > >> >+ static final String METHOD_POST = "POST"; > > > >> >+ > > > >> >+ /** > > > >> >+ * Example: http://www.example.com:1234/foo/bar?abc=xyz " > > > www.example.com" is > > > >> >+ * the host 1234 is the port "/foo" is the contextPath "/bar" > is > > > the > > > >> >+ * servletPath "abc=xyz" is the queryString > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest(String host, int port, String > > > contextPath, > > > >> >+ String servletPath, String queryString) { > > > >> >+ constructor(host, port, contextPath, servletPath, > queryString); > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest(String host, String port, String > > > contextPath, > > > >> >+ String servletPath, String queryString) { > > > >> >+ this(host, Integer.parseInt(port), contextPath, servletPath, > > > queryString); > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest(String contextPath, String > > > servletPath, > > > >> >+ String queryString) { > > > >> >+ this(DEFAULT_HOST, -1, contextPath, servletPath, > queryString); > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest() { > > > >> >+ this(DEFAULT_HOST, DEFAULT_PORT, "", null, null); > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest(String urlStr) throws > > > MalformedURLException { > > > >> >+ URL url = new URL(urlStr); > > > >> >+ String contextPath; > > > >> >+ String servletPath; > > > >> >+ String path = url.getPath(); > > > >> >+ if (path.length() <= 1) { > > > >> >+ // path must be either empty string or "/" > > > >> >+ contextPath = path; > > > >> >+ servletPath = null; > > > >> >+ } else { > > > >> >+ // Look for the second slash which separates the servlet > path > > > from the > > > >> >+ // context path. e.g. "/foo/bar" > > > >> >+ int secondSlash = path.indexOf("/", 1); > > > >> >+ if (secondSlash < 0) { > > > >> >+ // No second slash > > > >> >+ contextPath = path; > > > >> >+ servletPath = null; > > > >> >+ } else { > > > >> >+ contextPath = path.substring(0, secondSlash); > > > >> >+ servletPath = path.substring(secondSlash); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ // Set the scheme > > > >> >+ scheme_ = url.getProtocol(); > > > >> >+ if (scheme_.equalsIgnoreCase("https")) { > > > >> >+ secure_ = true; > > > >> >+ } > > > >> >+ > > > >> >+ int port = url.getPort(); > > > >> >+ > > > >> >+ // Call constructor() instead of this() because the later is > > only > > > allowed > > > >> >+ // at the begining of a constructor > > > >> >+ constructor(url.getHost(), port, contextPath, servletPath, > > > url.getQuery()); > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setLocale(Locale locale) { > > > >> >+ locale_ = locale; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setLocales(List<Locale> locales) > { > > > >> >+ locales_ = locales; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setProtocol(String prot) { > > > >> >+ protocol_ = prot; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setSecure(boolean secure) { > > > >> >+ secure_ = secure; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /* > > > >> >+ * Set a header on this request. Note that if the header > implies > > > other > > > >> >+ * attributes of the request I will set them accordingly. > > > Specifically: > > > >> >+ * > > > >> >+ * If the header is "Cookie:" then I will automatically call > > > setCookie on all > > > >> >+ * of the name-value pairs found therein. > > > >> >+ * > > > >> >+ * This makes the object easier to use because you can just > feed > > it > > > headers > > > >> >+ * and the object will remain consistent with the behavior > you'd > > > expect from a > > > >> >+ * request. > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setHeader(String name, String > > value) > > > { > > > >> >+ if (name.equals(COOKIE_HEADER)) { > > > >> >+ String[] pairs = splitAndTrim(value, ";"); > > > >> >+ for (int i = 0; i < pairs.length; i++) { > > > >> >+ int equalsPos = pairs[i].indexOf('='); > > > >> >+ if (equalsPos != -1) { > > > >> >+ String cookieName = pairs[i].substring(0, equalsPos); > > > >> >+ String cookieValue = pairs[i].substring(equalsPos + 1); > > > >> >+ addToCookieMap(new Cookie(cookieName, cookieValue)); > > > >> >+ } > > > >> >+ } > > > >> >+ setCookieHeader(); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ addToHeaderMap(name, value); > > > >> >+ > > > >> >+ if (name.equals(HOST_HEADER)) { > > > >> >+ host_ = value; > > > >> >+ } > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ private void addToHeaderMap(String name, String value) { > > > >> >+ headers_.put(name.toLowerCase(), value); > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Associates a set of cookies with this fake request. > > > >> >+ * > > > >> >+ * @param cookies the cookies associated with this request. > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setCookies(Cookie... cookies) { > > > >> >+ for (Cookie cookie : cookies) { > > > >> >+ addToCookieMap(cookie); > > > >> >+ } > > > >> >+ setCookieHeader(); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets a single cookie associated with this fake request. > > Cookies > > > are > > > >> >+ * cumulative, but ones with the same name will overwrite one > > > another. > > > >> >+ * > > > >> >+ * @param c the cookie to associate with this request. > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setCookie(Cookie c) { > > > >> >+ addToCookieMap(c); > > > >> >+ setCookieHeader(); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ private void addToCookieMap(Cookie c) { > > > >> >+ cookies_.put(c.getName(), c); > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the "Cookie" HTTP header based on the current cookies. > > > >> >+ */ > > > >> >+ private void setCookieHeader() { > > > >> >+ StringBuilder sb = new StringBuilder(); > > > >> >+ boolean isFirst = true; > > > >> >+ for (Cookie c : cookies_.values()) { > > > >> >+ if (!isFirst) { > > > >> >+ sb.append("; "); > > > >> >+ } > > > >> >+ sb.append(c.getName()); > > > >> >+ sb.append("="); > > > >> >+ sb.append(c.getValue()); > > > >> >+ isFirst = false; > > > >> >+ } > > > >> >+ > > > >> >+ // We cannot use setHeader() here, because setHeader() calls > > this > > > method > > > >> >+ addToHeaderMap(COOKIE_HEADER, sb.toString()); > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the a parameter in this fake request. > > > >> >+ * > > > >> >+ * @param name the string key > > > >> >+ * @param values the string array value > > > >> >+ * @param isPost if the paramenter comes in the post body. > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setParameter(String name, boolean > > > isPost, String... values) { > > > >> >+ if (isPost) { > > > >> >+ postParameters_.add(name); > > > >> >+ } > > > >> >+ parameters_.put(name, values); > > > >> >+ // Old query string no longer matches up, so set it to null > so > > it > > > can be > > > >> >+ // regenerated on the next call of getQueryString() > > > >> >+ queryString_ = null; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the a parameter in this fake request. > > > >> >+ * > > > >> >+ * @param name the string key > > > >> >+ * @param values the string array value > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setParameter(String name, > String... > > > values) { > > > >> >+ setParameter(name, false, values); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ > > > >> >+ /** Set the path info field. */ > > > >> >+ public FakeHttpServletRequest setPathInfo(String path) { > > > >> >+ pathInfo_ = path; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Specify the mock POST data. > > > >> >+ * > > > >> >+ * @param postString the mock post data > > > >> >+ * @param encoding format with which to encode mock post data > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setPostData(String postString, > > String > > > encoding) > > > >> >+ throws UnsupportedEncodingException { > > > >> >+ setPostData(postString.getBytes(encoding)); > > > >> >+ characterEncoding = encoding; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Specify the mock POST data in raw binary format. > > > >> >+ * > > > >> >+ * This implicitly sets character encoding to not specified. > > > >> >+ * > > > >> >+ * @param data the mock post data; this is owned by the caller, > > so > > > >> >+ * modifications made after this call will show up when > > the > > > post data > > > >> >+ * is read > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setPostData(byte[] data) { > > > >> >+ postData = data; > > > >> >+ characterEncoding = null; > > > >> >+ method_ = METHOD_POST; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Set a new value for the query string. The query string will > be > > > parsed and > > > >> >+ * all parameters reset. > > > >> >+ * > > > >> >+ * @param queryString representing the new value. i.e.: > > > "bug=1&id=23" > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setQueryString(String > queryString) > > { > > > >> >+ queryString_ = queryString; > > > >> >+ parameters_.clear(); > > > >> >+ decodeQueryString(queryString, parameters_); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the session for this request. > > > >> >+ * > > > >> >+ * @param session the new session > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setSession(HttpSession session) { > > > >> >+ this.session = session; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the content type. > > > >> >+ * > > > >> >+ * @param contentType of the request. > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setContentType(String > contentType) > > { > > > >> >+ this.contentType_ = contentType; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ // > > > > > > /////////////////////////////////////////////////////////////////////////// > > > >> >+ // Implements methods from HttpServletRequest > > > >> >+ // > > > > > > /////////////////////////////////////////////////////////////////////////// > > > >> >+ > > > >> >+ public String getAuthType() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public java.lang.String getContextPath() { > > > >> >+ return contextPath_; > > > >> >+ } > > > >> >+ > > > >> >+ public Cookie[] getCookies() { > > > >> >+ if (cookies_.isEmpty()) { > > > >> >+ // API promises null return if no cookies > > > >> >+ return null; > > > >> >+ } > > > >> >+ return cookies_.values().toArray(new Cookie[0]); > > > >> >+ } > > > >> >+ > > > >> >+ public long getDateHeader(String name) { > > > >> >+ String value = getHeader(name); > > > >> >+ if (value == null) return -1; > > > >> >+ > > > >> >+ SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT, > > > Locale.US); > > > >> >+ format.setTimeZone(TimeZone.getTimeZone("GMT")); > > > >> >+ try { > > > >> >+ return format.parse(value).getTime(); > > > >> >+ } catch (ParseException e) { > > > >> >+ throw new IllegalArgumentException("Cannot parse number > from > > > header " > > > >> >+ + name + ":" + value, e); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setDateHeader(String name, long > > > value) { > > > >> >+ SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT, > > > Locale.US); > > > >> >+ format.setTimeZone(TimeZone.getTimeZone("GMT")); > > > >> >+ setHeader(name, format.format(new Date(value))); > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public String getHeader(String name) { > > > >> >+ return headers_.get(name.toLowerCase()); > > > >> >+ } > > > >> >+ > > > >> >+ public Enumeration<String> getHeaderNames() { > > > >> >+ return headers_.keys(); > > > >> >+ } > > > >> >+ > > > >> >+ public Enumeration<?> getHeaders(String name) { > > > >> >+ List<String> values = new ArrayList<String>(); > > > >> >+ for (Map.Entry<String, String> entry : headers_.entrySet()) { > > > >> >+ if (name.equalsIgnoreCase(entry.getKey())) { > > > >> >+ values.add(entry.getValue()); > > > >> >+ } > > > >> >+ } > > > >> >+ return Collections.enumeration(values); > > > >> >+ } > > > >> >+ > > > >> >+ public int getIntHeader(String name) { > > > >> >+ return Integer.parseInt(getHeader(name)); > > > >> >+ } > > > >> >+ > > > >> >+ public String getMethod() { > > > >> >+ return method_; > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setMethod(String method) { > > > >> >+ method_ = method; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public String getPathInfo() { > > > >> >+ return pathInfo_; > > > >> >+ } > > > >> >+ > > > >> >+ public String getPathTranslated() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public String getQueryString() { > > > >> >+ try { > > > >> >+ if (queryString_ == null && !parameters_.isEmpty()) { > > > >> >+ boolean hasPrevious = false; > > > >> >+ StringBuilder queryString = new StringBuilder(); > > > >> >+ for (Iterator<String> it = > parameters_.keySet().iterator(); > > > it.hasNext();) { > > > >> >+ String key = it.next(); > > > >> >+ > > > >> >+ // We're not interested in blank keys > > > >> >+ if (key == null || key.equals("") || > > > postParameters_.contains(key)) { > > > >> >+ continue; > > > >> >+ } > > > >> >+ if (hasPrevious) { > > > >> >+ queryString.append("&"); > > > >> >+ } > > > >> >+ > > > >> >+ String[] values = parameters_.get(key); > > > >> >+ // Append the parameters to the query string > > > >> >+ if (values.length == 0) { > > > >> >+ queryString.append(URLEncoder.encode(key, "UTF-8")); > > > >> >+ } else { > > > >> >+ for (int i = 0; i < values.length; i++) { > > > >> >+ queryString.append(URLEncoder.encode(key, > > > "UTF-8")).append("=").append( > > > >> >+ URLEncoder.encode(values[i], "UTF-8")); > > > >> >+ if (i < values.length - 1) { > > > >> >+ queryString.append("&"); > > > >> >+ } > > > >> >+ } > > > >> >+ } > > > >> >+ hasPrevious = true; > > > >> >+ > > > >> >+ } > > > >> >+ queryString_ = queryString.toString(); > > > >> >+ } > > > >> >+ return queryString_; > > > >> >+ } catch (UnsupportedEncodingException e) { > > > >> >+ throw new RuntimeException("Should always support UTF-8", > e); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ public String getRemoteUser() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public String getRequestedSessionId() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public String getRequestURI() { > > > >> >+ StringBuffer buf = new StringBuffer(); > > > >> >+ if (!contextPath_.equals("")) { > > > >> >+ buf.append(contextPath_); > > > >> >+ } > > > >> >+ > > > >> >+ if (servletPath_ != null && !"".equals(servletPath_)) { > > > >> >+ buf.append(servletPath_); > > > >> >+ } > > > >> >+ > > > >> >+ if (buf.length() == 0) { > > > >> >+ buf.append('/'); > > > >> >+ } > > > >> >+ > > > >> >+ return buf.toString(); > > > >> >+ } > > > >> >+ > > > >> >+ public StringBuffer getRequestURL() { > > > >> >+ StringBuffer buf = > > > >> >+ secure_ ? new StringBuffer("https://") : new > > > StringBuffer("http://"); > > > >> >+ buf.append(host_); > > > >> >+ if (port_ >= 0) { > > > >> >+ buf.append(':'); > > > >> >+ buf.append(port_); > > > >> >+ } > > > >> >+ buf.append(getRequestURI()); // always begins with '/' > > > >> >+ return buf; > > > >> >+ } > > > >> >+ > > > >> >+ public String getServletPath() { > > > >> >+ return servletPath_; > > > >> >+ } > > > >> >+ > > > >> >+ public FakeHttpServletRequest setServletPath(String > servletPath) > > { > > > >> >+ this.servletPath_ = servletPath; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public HttpSession getSession() { > > > >> >+ return getSession(true); > > > >> >+ } > > > >> >+ > > > >> >+ public HttpSession getSession(boolean create) { > > > >> >+ // TODO return fake session if create && session == null > > > >> >+ return session; > > > >> >+ } > > > >> >+ > > > >> >+ public java.security.Principal getUserPrincipal() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public boolean isRequestedSessionIdFromCookie() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ @Deprecated > > > >> >+ public boolean isRequestedSessionIdFromUrl() { > > > >> >+ throw new UnsupportedOperationException("This method is > > > deprecated"); > > > >> >+ } > > > >> >+ > > > >> >+ public boolean isRequestedSessionIdFromURL() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public boolean isRequestedSessionIdValid() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public boolean isUserInRole(String role) { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ // Implements methods from ServletRequest > > > /////////////////////////////////// > > > >> >+ > > > >> >+ public Object getAttribute(String name) { > > > >> >+ return attributes_.get(name); > > > >> >+ } > > > >> >+ > > > >> >+ public Enumeration<?> getAttributeNames() { > > > >> >+ return Collections.enumeration(attributes_.keySet()); > > > >> >+ } > > > >> >+ > > > >> >+ public String getCharacterEncoding() { > > > >> >+ return characterEncoding; > > > >> >+ } > > > >> >+ > > > >> >+ public int getContentLength() { > > > >> >+ return (postData == null) ? 0 : postData.length; > > > >> >+ } > > > >> >+ > > > >> >+ public String getContentType() { > > > >> >+ return contentType_; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Get the body of the request (i.e. the POST data) as a binary > > > stream. As per > > > >> >+ * Java docs, this OR getReader() may be called, but not both > > > (attempting that > > > >> >+ * will result in an IllegalStateException) > > > >> >+ * > > > >> >+ */ > > > >> >+ public ServletInputStream getInputStream() { > > > >> >+ if (getReaderCalled) { > > > >> >+ throw new IllegalStateException( > > > >> >+ "getInputStream() called after getReader()"); > > > >> >+ } > > > >> >+ getInputStreamCalled = true; // so that getReader() can no > > longer > > > be called > > > >> >+ > > > >> >+ final InputStream in = new ByteArrayInputStream(postData); > > > >> >+ return new ServletInputStream() { > > > >> >+ @Override public int read() throws IOException { > > > >> >+ return in.read(); > > > >> >+ } > > > >> >+ }; > > > >> >+ } > > > >> >+ > > > >> >+ public Locale getLocale() { > > > >> >+ return locale_; > > > >> >+ } > > > >> >+ > > > >> >+ public Enumeration<?> getLocales() { > > > >> >+ return Collections.enumeration(locales_); > > > >> >+ } > > > >> >+ > > > >> >+ public String getParameter(String name) { > > > >> >+ String[] parameters = getParameterValues(name); > > > >> >+ if (parameters == null || parameters.length < 1) { > > > >> >+ return null; > > > >> >+ } else { > > > >> >+ return parameters[0]; > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ public Map<String, String[]> getParameterMap() { > > > >> >+ return parameters_; > > > >> >+ } > > > >> >+ > > > >> >+ public Enumeration<String> getParameterNames() { > > > >> >+ return Collections.enumeration(parameters_.keySet()); > > > >> >+ } > > > >> >+ > > > >> >+ public String[] getParameterValues(String name) { > > > >> >+ return parameters_.get(name); > > > >> >+ } > > > >> >+ > > > >> >+ public String getProtocol() { > > > >> >+ return protocol_; > > > >> >+ } > > > >> >+ > > > >> >+ public BufferedReader getReader() throws IOException { > > > >> >+ if (getInputStreamCalled) { > > > >> >+ throw new IllegalStateException( > > > >> >+ "getReader() called after getInputStream()"); > > > >> >+ } > > > >> >+ > > > >> >+ getReaderCalled = true; > > > >> >+ BufferedReader br = null; > > > >> >+ ByteArrayInputStream bais = new > ByteArrayInputStream(postData); > > > >> >+ InputStreamReader isr; > > > >> >+ if (characterEncoding != null) { > > > >> >+ isr = new InputStreamReader(bais, characterEncoding); > > > >> >+ } else { > > > >> >+ isr = new InputStreamReader(bais); > > > >> >+ } > > > >> >+ br = new BufferedReader(isr); > > > >> >+ return br; > > > >> >+ } > > > >> >+ > > > >> >+ @Deprecated > > > >> >+ public String getRealPath(String path) { > > > >> >+ throw new UnsupportedOperationException("This method is > > > deprecated"); > > > >> >+ } > > > >> >+ > > > >> >+ public String getRemoteAddr() { > > > >> >+ return ip_; > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * Sets the remote IP address for this [EMAIL PROTECTED] > > > FakeHttpServletRequest}. > > > >> >+ * > > > >> >+ * @param ip the IP to set > > > >> >+ * @return this [EMAIL PROTECTED] FakeHttpServletRequest} object > > > >> >+ */ > > > >> >+ public FakeHttpServletRequest setRemoteAddr(String ip) { > > > >> >+ ip_ = ip; > > > >> >+ return this; > > > >> >+ } > > > >> >+ > > > >> >+ public String getRemoteHost() { > > > >> >+ return "localhost"; > > > >> >+ } > > > >> >+ > > > >> >+ > > > >> >+ /* > > > >> >+ * (non-Javadoc) > > > >> >+ * > > > >> >+ * New Servlet 2.4 method > > > >> >+ * > > > >> >+ * @see javax.servlet.ServletRequest#getLocalPort() > > > >> >+ */ > > > >> >+ public int getLocalPort() { > > > >> >+ return 8080; > > > >> >+ } > > > >> >+ > > > >> >+ /* > > > >> >+ * (non-Javadoc) > > > >> >+ * > > > >> >+ * New Servlet 2.4 method > > > >> >+ * > > > >> >+ * @see javax.servlet.ServletRequest#getLocalAddr() > > > >> >+ */ > > > >> >+ public String getLocalAddr() { > > > >> >+ return "127.0.0.1"; > > > >> >+ } > > > >> >+ > > > >> >+ /* > > > >> >+ * (non-Javadoc) > > > >> >+ * > > > >> >+ * New Servlet 2.4 method > > > >> >+ * > > > >> >+ * @see javax.servlet.ServletRequest#getLocalName() > > > >> >+ */ > > > >> >+ public String getLocalName() { > > > >> >+ return "localhost"; > > > >> >+ } > > > >> >+ > > > >> >+ /* > > > >> >+ * (non-Javadoc) > > > >> >+ * > > > >> >+ * New Servlet 2.4 method > > > >> >+ * > > > >> >+ * @see javax.servlet.ServletRequest#getRemotePort() > > > >> >+ */ > > > >> >+ public int getRemotePort() { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ > > > >> >+ public RequestDispatcher getRequestDispatcher(String path) { > > > >> >+ throw new UnsupportedOperationException(); > > > >> >+ } > > > >> >+ > > > >> >+ public String getScheme() { > > > >> >+ return scheme_; > > > >> >+ } > > > >> >+ > > > >> >+ public String getServerName() { > > > >> >+ return host_; > > > >> >+ } > > > >> >+ > > > >> >+ public int getServerPort() { > > > >> >+ return (port_ < 0) ? DEFAULT_PORT : port_; > > > >> >+ } > > > >> >+ > > > >> >+ public boolean isSecure() { > > > >> >+ return secure_; > > > >> >+ } > > > >> >+ > > > >> >+ public void removeAttribute(String name) { > > > >> >+ attributes_.remove(name); > > > >> >+ } > > > >> >+ > > > >> >+ public void setAttribute(String name, Object value) { > > > >> >+ attributes_.put(name, value); > > > >> >+ } > > > >> >+ > > > >> >+ /** > > > >> >+ * @inheritDoc > > > >> >+ * > > > >> >+ * For POST requests, this affects interpretation of POST body. > > > >> >+ * > > > >> >+ * For non-POST requests (original author's comment): Do > nothing > > - > > > all request > > > >> >+ * components were created as unicode Strings, so this can't > > affect > > > how > > > >> >+ * they're interpreted anyway. > > > >> >+ */ > > > >> >+ public void setCharacterEncoding(String env) { > > > >> >+ if (method_.equals(METHOD_POST)) { > > > >> >+ characterEncoding = env; > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ // Helper methods > > > /////////////////////////////////////////////////////////// > > > >> >+ > > > >> >+ /** > > > >> >+ * This method serves as the central constructor of this class. > > The > > > reason it > > > >> >+ * is not an actual constructor is that Java doesn't allow > > calling > > > another > > > >> >+ * constructor at the end of a constructor. e.g. > > > >> >+ * > > > >> >+ * <pre> > > > >> >+ * public FakeHttpServletRequest(String foo) { > > > >> >+ * // Do something here > > > >> >+ * this(foo, bar); // calling another constructor here is not > > > allowed > > > >> >+ * } > > > >> >+ * </pre> > > > >> >+ */ > > > >> >+ protected void constructor(String host, int port, String > > > contextPath, > > > >> >+ String servletPath, String queryString) { > > > >> >+ setHeader(HOST_HEADER, host); > > > >> >+ port_ = port; > > > >> >+ contextPath_ = contextPath; > > > >> >+ servletPath_ = servletPath; > > > >> >+ queryString_ = queryString; > > > >> >+ if (queryString != null) { > > > >> >+ decodeQueryString(queryString, parameters_); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ protected void decodeQueryString(String queryString, > > > >> >+ Map<String, String[]> parameters) { > > > >> >+ for (String param : queryString.split("&")) { > > > >> >+ // The first '=' separates the name and value > > > >> >+ int sepPos = param.indexOf('='); > > > >> >+ String name, value; > > > >> >+ if (sepPos < 0) { > > > >> >+ // if no equal is present, assume a blank value > > > >> >+ name = param; > > > >> >+ value = ""; > > > >> >+ } else { > > > >> >+ name = param.substring(0, sepPos); > > > >> >+ value = param.substring(sepPos + 1); > > > >> >+ } > > > >> >+ > > > >> >+ addParameter(parameters, decodeParameterPart(name), > > > >> >+ decodeParameterPart(value)); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ private String decodeParameterPart(String str) { > > > >> >+ // borrowed from FormUrlDecoder > > > >> >+ try { > > > >> >+ // we could infer proper encoding from headers, but > > > setCharacterEncoding > > > >> >+ // is a noop. > > > >> >+ return URLDecoder.decode(str, "UTF-8"); > > > >> >+ } catch (IllegalArgumentException iae) { > > > >> >+ // According to the javadoc of URLDecoder, when the input > > > string is > > > >> >+ // illegal, it could either leave the illegal characters > > alone > > > or throw > > > >> >+ // an IllegalArgumentException! To deal with both > > consistently, > > > we > > > >> >+ // ignore IllegalArgumentException and just return the > > original > > > string. > > > >> >+ return str; > > > >> >+ } catch (UnsupportedEncodingException e) { > > > >> >+ return str; > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ protected void addParameter(Map<String, String[]> parameters, > > > String name, > > > >> >+ String value) { > > > >> >+ if (parameters.containsKey(name)) { > > > >> >+ String[] existingParamValues = parameters.get(name); > > > >> >+ String[] newParamValues = new > > String[existingParamValues.length > > > + 1]; > > > >> >+ System.arraycopy(existingParamValues, 0, newParamValues, 0, > > > >> >+ existingParamValues.length); > > > >> >+ newParamValues[newParamValues.length - 1] = value; > > > >> >+ parameters.put(name, newParamValues); > > > >> >+ } else { > > > >> >+ String[] paramValues = {value,}; > > > >> >+ parameters.put(name, paramValues); > > > >> >+ } > > > >> >+ } > > > >> >+ > > > >> >+ private static String[] splitAndTrim(String str, String delims) > { > > > >> >+ StringTokenizer tokenizer = new StringTokenizer(str, delims); > > > >> >+ int n = tokenizer.countTokens(); > > > >> >+ String[] list = new String[n]; > > > >> >+ for (int i = 0; i < n; i++) { > > > >> >+ list[i] = tokenizer.nextToken().trim(); > > > >> >+ } > > > >> >+ return list; > > > >> >+ } > > > >> >+} > > > >> > > > >> > > > >> -- > > > >> Henning P. Schmiedehausen -- [EMAIL PROTECTED] | J2EE, Linux, > > > >> 91054 Buckenhof, Germany -- +49 9131 506540 | Apache person > > > >> Open Source Consulting, Development, Design | Velocity - Turbine > > guy > > > >> > > > >> INTERMETA - Gesellschaft fuer Mehrwertdienste mbH - RG Fuerth, HRB > > 7350 > > > >> Sitz der Gesellschaft: Buckenhof. Geschaeftsfuehrer: Henning > > > Schmiedehausen > > > >> > > > >> "Professor Peach in the library with the lead piping!" -- Donna > > > >> > > > > > > -- > > > Henning P. Schmiedehausen -- [EMAIL PROTECTED] | J2EE, Linux, > > > 91054 Buckenhof, Germany -- +49 9131 506540 | Apache person > > > Open Source Consulting, Development, Design | Velocity - Turbine guy > > > > > > INTERMETA - Gesellschaft fuer Mehrwertdienste mbH - RG Fuerth, HRB 7350 > > > Sitz der Gesellschaft: Buckenhof. Geschaeftsfuehrer: Henning > > Schmiedehausen > > > > > > "Professor Peach in the library with the lead piping!" -- Donna > > > > > > > > > > > -- > > > --