[seam-commits] Seam SVN: r10978 - in branches/community/Seam_2_1: examples/restbay/src/org/jboss/seam/example/restbay/test and 3 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue May 26 07:16:58 EDT 2009


Author: christian.bauer at jboss.com
Date: 2009-05-26 07:16:58 -0400 (Tue, 26 May 2009)
New Revision: 10978

Added:
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletInputStream.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletOutputStream.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/HeaderValueHolder.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletRequest.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletResponse.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockRequestDispatcher.java
   branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/ResourceSeamTest.java
Removed:
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/fwk/
   branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/fwk/
Modified:
   branches/community/Seam_2_1/build/resteasy.pom.xml
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/AuctionServiceTest.java
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceHomeTest.java
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceQueryTest.java
   branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/SecurityTest.java
   branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ContextResourceTest.java
   branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ResolvedTaskResourceQueryTest.java
   branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/TaskResourceTest.java
Log:
JBSEAM-4195, moved ResourceSeamTest from examples to resteasy module

Modified: branches/community/Seam_2_1/build/resteasy.pom.xml
===================================================================
--- branches/community/Seam_2_1/build/resteasy.pom.xml	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/build/resteasy.pom.xml	2009-05-26 11:16:58 UTC (rev 10978)
@@ -53,7 +53,27 @@
          <artifactId>hibernate</artifactId>
          <scope>provided</scope>
       </dependency>
-      
+
+       <!-- The following two dependencies can be removed when we move resteasy.testfwk -->
+       <dependency>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+          <optional>true</optional>
+       </dependency>
+
+       <dependency>
+         <groupId>org.testng</groupId>
+         <artifactId>testng</artifactId>
+         <version>5.6</version>
+         <optional>true</optional>
+         <exclusions>
+           <exclusion>
+             <groupId>junit</groupId>
+             <artifactId>junit</artifactId>
+           </exclusion>
+         </exclusions>
+       </dependency>
+
    </dependencies>
 
 </project>
\ No newline at end of file

Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/AuctionServiceTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/AuctionServiceTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/AuctionServiceTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -1,7 +1,7 @@
 package org.jboss.seam.example.restbay.test;
 
-import org.jboss.seam.example.restbay.test.fwk.ResourceSeamTest;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
 import org.testng.annotations.Test;
 
 import java.util.HashMap;

Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/BasicServiceTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -1,8 +1,8 @@
 package org.jboss.seam.example.restbay.test;
 
-import org.jboss.seam.example.restbay.test.fwk.ResourceSeamTest;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletRequest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
 import org.testng.annotations.Test;
 import org.testng.annotations.DataProvider;
 import static org.testng.Assert.assertEquals;
@@ -76,6 +76,12 @@
       }};
    }
 
+   @Override
+   public String getServletPath()
+   {
+      return "/override/seam/resource/is/not/my/path/for/SeamResourceServlet";
+   }
+
    @DataProvider(name = "queryPaths")
    public Object[][] getData()
    {

Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceHomeTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceHomeTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceHomeTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -1,8 +1,8 @@
 package org.jboss.seam.example.restbay.test;
 
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.restbay.test.fwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -19,8 +19,7 @@
    @DataProvider(name = "queryPaths")
    public Object[][] getData()
    {
-      String[][] data = { { "/configuredCategory" }, { "/extendedCategory" } };
-      return data;
+      return new String[][]{ { "/configuredCategory" }, { "/extendedCategory" } };
    }
 
    @Test(dataProvider = "queryPaths")

Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceQueryTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceQueryTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/ResourceQueryTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -2,9 +2,9 @@
 
 import static org.testng.Assert.assertEquals;
 
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.restbay.test.fwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 

Modified: branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/SecurityTest.java
===================================================================
--- branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/SecurityTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/restbay/src/org/jboss/seam/example/restbay/test/SecurityTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -2,9 +2,9 @@
 
 import static org.testng.Assert.assertEquals;
 
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.restbay.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.restbay.test.fwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
 import org.testng.annotations.Test;
 
 import java.util.HashMap;

Modified: branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ContextResourceTest.java
===================================================================
--- branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ContextResourceTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ContextResourceTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -24,9 +24,9 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.tasks.test.fwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 

Modified: branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ResolvedTaskResourceQueryTest.java
===================================================================
--- branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ResolvedTaskResourceQueryTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/ResolvedTaskResourceQueryTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -24,9 +24,9 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletResponse;
-import org.jboss.seam.example.tasks.test.fwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;

Modified: branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/TaskResourceTest.java
===================================================================
--- branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/TaskResourceTest.java	2009-05-25 21:04:13 UTC (rev 10977)
+++ branches/community/Seam_2_1/examples/tasks/src/main/org/jboss/seam/example/tasks/test/TaskResourceTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -24,9 +24,9 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
-import org.jboss.seam.example.tasks.test.fwk.ResourceSeamTest;
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletRequest;
-import org.jboss.seam.example.tasks.test.fwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
+import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
 import org.testng.annotations.Test;
 
 /**

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletInputStream.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletInputStream.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletInputStream.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletInputStream;
+
+/**
+ * Delegating implementation of {@link javax.servlet.ServletInputStream}.
+ *
+ * <p>Used by {@link MockHttpServletRequest}; typically not directly
+ * used for testing application controllers.
+ *
+ * @author Juergen Hoeller
+ * @since 1.0.2
+ * @see MockHttpServletRequest
+ */
+public class DelegatingServletInputStream extends ServletInputStream {
+
+	private final InputStream sourceStream;
+
+
+	/**
+	 * Create a DelegatingServletInputStream for the given source stream.
+	 * @param sourceStream the source stream (never <code>null</code>)
+	 */
+	public DelegatingServletInputStream(InputStream sourceStream) {
+		this.sourceStream = sourceStream;
+	}
+
+	/**
+	 * Return the underlying source stream (never <code>null</code>).
+	 */
+	public final InputStream getSourceStream() {
+		return this.sourceStream;
+	}
+
+
+	public int read() throws IOException {
+		return this.sourceStream.read();
+	}
+
+	public void close() throws IOException {
+		super.close();
+		this.sourceStream.close();
+	}
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletOutputStream.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletOutputStream.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/DelegatingServletOutputStream.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletOutputStream;
+
+
+/**
+ * Delegating implementation of {@link javax.servlet.ServletOutputStream}.
+ * <p/>
+ * <p>Used by {@link MockHttpServletResponse}; typically not directly
+ * used for testing application controllers.
+ *
+ * @author Juergen Hoeller
+ * @see MockHttpServletResponse
+ * @since 1.0.2
+ */
+public class DelegatingServletOutputStream extends ServletOutputStream
+{
+
+   private final OutputStream targetStream;
+
+
+   /**
+    * Create a DelegatingServletOutputStream for the given target stream.
+    *
+    * @param targetStream the target stream (never <code>null</code>)
+    */
+   public DelegatingServletOutputStream(OutputStream targetStream)
+   {
+      this.targetStream = targetStream;
+   }
+
+   /**
+    * Return the underlying target stream (never <code>null</code>).
+    */
+   public final OutputStream getTargetStream()
+   {
+      return this.targetStream;
+   }
+
+
+   public void write(int b) throws IOException
+   {
+      this.targetStream.write(b);
+   }
+
+   public void flush() throws IOException
+   {
+      super.flush();
+      this.targetStream.flush();
+   }
+
+   public void close() throws IOException
+   {
+      super.close();
+      this.targetStream.close();
+	}
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/HeaderValueHolder.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/HeaderValueHolder.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/HeaderValueHolder.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import java.util.*;
+import java.lang.reflect.Array;
+
+/**
+ * Internal helper class that serves as value holder for request headers.
+ *
+ * @author Juergen Hoeller
+ * @author Rick Evans
+ * @since 2.0.1
+ */
+class HeaderValueHolder {
+
+	private final List values = new LinkedList();
+
+
+	public void setValue(Object value) {
+		this.values.clear();
+		this.values.add(value);
+	}
+
+	public void addValue(Object value) {
+		this.values.add(value);
+	}
+
+	public void addValues(Collection values) {
+		this.values.addAll(values);
+	}
+
+	public void addValueArray(Object values) {
+		Object[] arr = toObjectArray(values);
+      this.values.addAll(Arrays.asList(arr));
+	}
+
+	public List getValues() {
+		return Collections.unmodifiableList(this.values);
+	}
+
+	public Object getValue() {
+		return (!this.values.isEmpty() ? this.values.get(0) : null);
+	}
+
+
+	/**
+	 * Find a HeaderValueHolder by name, ignoring casing.
+	 * @param headers the Map of header names to HeaderValueHolders
+	 * @param name the name of the desired header
+	 * @return the corresponding HeaderValueHolder,
+	 * or <code>null</code> if none found
+	 */
+	public static HeaderValueHolder getByName(Map headers, String name) {
+		for (Iterator it = headers.keySet().iterator(); it.hasNext();) {
+			String headerName = (String) it.next();
+			if (headerName.equalsIgnoreCase(name)) {
+				return (HeaderValueHolder) headers.get(headerName);
+			}
+		}
+		return null;
+	}
+
+   public static Object[] toObjectArray(Object source) {
+		if (source instanceof Object[]) {
+			return (Object[]) source;
+		}
+		if (source == null) {
+			return new Object[0];
+		}
+		if (!source.getClass().isArray()) {
+			throw new IllegalArgumentException("Source is not an array: " + source);
+		}
+		int length = Array.getLength(source);
+		if (length == 0) {
+			return new Object[0];
+		}
+		Class wrapperType = Array.get(source, 0).getClass();
+		Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
+		for (int i = 0; i < length; i++) {
+			newArray[i] = Array.get(source, i);
+		}
+		return newArray;
+	}
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletRequest.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletRequest.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletRequest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,876 @@
+/*
+ * Copyright 2002-2008 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.*;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.jboss.seam.mock.MockServletContext;
+import org.jboss.seam.mock.MockHttpSession;
+
+/**
+ * Mock implementation of the {@link javax.servlet.http.HttpServletRequest}
+ * interface. Supports the Servlet 2.4 API level.
+ *
+ * <p>Used for testing the web framework; also useful for testing
+ * application controllers.
+ *
+ * @author Juergen Hoeller
+ * @author Rod Johnson
+ * @author Rick Evans
+ * @author Mark Fisher
+ * @since 1.0.2
+ */
+public class MockHttpServletRequest implements HttpServletRequest {
+
+	/**
+	 * The default protocol: 'http'.
+	 */
+	public static final String DEFAULT_PROTOCOL = "http";
+
+	/**
+	 * The default server address: '127.0.0.1'.
+	 */
+	public static final String DEFAULT_SERVER_ADDR = "127.0.0.1";
+
+	/**
+	 * The default server name: 'localhost'.
+	 */
+	public static final String DEFAULT_SERVER_NAME = "localhost";
+
+	/**
+	 * The default server port: '80'.
+	 */
+	public static final int DEFAULT_SERVER_PORT = 80;
+
+	/**
+	 * The default remote address: '127.0.0.1'.
+	 */
+	public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1";
+
+	/**
+	 * The default remote host: 'localhost'.
+	 */
+	public static final String DEFAULT_REMOTE_HOST = "localhost";
+
+	private boolean active = true;
+
+
+	//---------------------------------------------------------------------
+	// ServletRequest properties
+	//---------------------------------------------------------------------
+
+	private final Hashtable attributes = new Hashtable();
+
+	private String characterEncoding;
+
+	private byte[] content;
+
+	private String contentType;
+
+	private final Map parameters = new LinkedHashMap(16);
+
+	private String protocol = DEFAULT_PROTOCOL;
+
+	private String scheme = DEFAULT_PROTOCOL;
+
+	private String serverName = DEFAULT_SERVER_NAME;
+
+	private int serverPort = DEFAULT_SERVER_PORT;
+
+	private String remoteAddr = DEFAULT_REMOTE_ADDR;
+
+	private String remoteHost = DEFAULT_REMOTE_HOST;
+
+	/** List of locales in descending order */
+	private final Vector locales = new Vector();
+
+	private boolean secure = false;
+
+	private final ServletContext servletContext;
+
+	private int remotePort = DEFAULT_SERVER_PORT;
+
+	private String localName = DEFAULT_SERVER_NAME;
+
+	private String localAddr = DEFAULT_SERVER_ADDR;
+
+	private int localPort = DEFAULT_SERVER_PORT;
+
+
+	//---------------------------------------------------------------------
+	// HttpServletRequest properties
+	//---------------------------------------------------------------------
+
+	private String authType;
+
+	private Cookie[] cookies;
+
+	/**
+	 * The key is the lowercase header name; the value is a {@link HeaderValueHolder} object.
+	 */
+	private final Hashtable headers = new Hashtable();
+
+	private String method;
+
+	private String pathInfo;
+
+	private String contextPath = "";
+
+	private String queryString;
+
+   private Map<String,String> queryParameters = new HashMap();
+
+	private String remoteUser;
+
+	private final Set userRoles = new HashSet();
+
+	private Principal userPrincipal;
+
+	private String requestURI;
+
+	private String servletPath = "";
+
+	private HttpSession session;
+
+	private boolean requestedSessionIdValid = true;
+
+	private boolean requestedSessionIdFromCookie = true;
+
+	private boolean requestedSessionIdFromURL = false;
+
+
+   //---------------------------------------------------------------------
+	// Constructors
+	//---------------------------------------------------------------------
+
+	/**
+	 * Create a new MockHttpServletRequest with a default
+	 * {@link org.jboss.seam.mock.MockServletContext}.
+	 * @see org.jboss.seam.mock.MockServletContext
+	 */
+	public MockHttpServletRequest() {
+		this(null, "", "");
+	}
+
+	/**
+	 * Create a new MockHttpServletRequest with a default
+	 * {@link org.jboss.seam.mock.MockServletContext}.
+	 * @param method the request method (may be <code>null</code>)
+	 * @param requestURI the request URI (may be <code>null</code>)
+	 * @see #setMethod
+	 * @see #setRequestURI
+	 * @see org.jboss.seam.mock.MockServletContext
+	 */
+	public MockHttpServletRequest(String method, String requestURI) {
+		this(null, method, requestURI);
+	}
+
+	/**
+	 * Create a new MockHttpServletRequest.
+	 * @param servletContext the ServletContext that the request runs in
+	 * (may be <code>null</code> to use a default MockServletContext)
+	 * @see org.jboss.seam.mock.MockServletContext
+	 */
+	public MockHttpServletRequest(ServletContext servletContext) {
+		this(servletContext, "", "");
+	}
+
+	/**
+	 * Create a new MockHttpServletRequest.
+	 * @param servletContext the ServletContext that the request runs in
+	 * (may be <code>null</code> to use a default MockServletContext)
+	 * @param method the request method (may be <code>null</code>)
+	 * @param requestURI the request URI (may be <code>null</code>)
+	 * @see #setMethod
+	 * @see #setRequestURI
+	 * @see org.jboss.seam.mock.MockServletContext
+	 */
+	public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
+		this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
+		this.method = method;
+		this.requestURI = requestURI;
+		this.locales.add(Locale.ENGLISH);
+	}
+
+
+	//---------------------------------------------------------------------
+	// Lifecycle methods
+	//---------------------------------------------------------------------
+
+	/**
+	 * Return the ServletContext that this request is associated with.
+	 * (Not available in the standard HttpServletRequest interface for some reason.)
+	 */
+	public ServletContext getServletContext() {
+		return this.servletContext;
+	}
+
+	/**
+	 * Return whether this request is still active (that is, not completed yet).
+	 */
+	public boolean isActive() {
+		return this.active;
+	}
+
+	/**
+	 * Mark this request as completed, keeping its state.
+	 */
+	public void close() {
+		this.active = false;
+	}
+
+	/**
+	 * Invalidate this request, clearing its state.
+	 */
+	public void invalidate() {
+		close();
+		clearAttributes();
+	}
+
+	/**
+	 * Check whether this request is still active (that is, not completed yet),
+	 * throwing an IllegalStateException if not active anymore.
+	 */
+	protected void checkActive() throws IllegalStateException {
+		if (!this.active) {
+			throw new IllegalStateException("Request is not active anymore");
+		}
+	}
+
+
+	//---------------------------------------------------------------------
+	// ServletRequest interface
+	//---------------------------------------------------------------------
+
+	public Object getAttribute(String name) {
+		checkActive();
+		return this.attributes.get(name);
+	}
+
+	public Enumeration getAttributeNames() {
+		checkActive();
+		return this.attributes.keys();
+	}
+
+	public String getCharacterEncoding() {
+		return this.characterEncoding;
+	}
+
+	public void setCharacterEncoding(String characterEncoding) {
+		this.characterEncoding = characterEncoding;
+	}
+
+	public void setContent(byte[] content) {
+		this.content = content;
+	}
+
+	public int getContentLength() {
+		return (this.content != null ? this.content.length : -1);
+	}
+
+	public void setContentType(String contentType) {
+		this.contentType = contentType;
+	}
+
+	public String getContentType() {
+		return this.contentType;
+	}
+
+	public ServletInputStream getInputStream() {
+		if (this.content != null) {
+			return new DelegatingServletInputStream(new ByteArrayInputStream(this.content));
+		}
+		else {
+			return null;
+		}
+	}
+
+	/**
+	 * Set a single value for the specified HTTP parameter.
+	 * <p>If there are already one or more values registered for the given
+	 * parameter name, they will be replaced.
+	 */
+	public void setParameter(String name, String value) {
+		setParameter(name, new String[] {value});
+	}
+
+	/**
+	 * Set an array of values for the specified HTTP parameter.
+	 * <p>If there are already one or more values registered for the given
+	 * parameter name, they will be replaced.
+	 */
+	public void setParameter(String name, String[] values) {
+		this.parameters.put(name, values);
+	}
+
+	/**
+	 * Sets all provided parameters <emphasis>replacing</emphasis> any
+	 * existing values for the provided parameter names. To add without
+	 * replacing existing values, use {@link #addParameters(java.util.Map)}.
+	 */
+	public void setParameters(Map params) {
+		for (Iterator it = params.keySet().iterator(); it.hasNext();) {
+			Object key = it.next();
+			Object value = params.get(key);
+			if (value instanceof String) {
+				this.setParameter((String) key, (String) value);
+			}
+			else if (value instanceof String[]) {
+				this.setParameter((String) key, (String[]) value);
+			}
+			else {
+				throw new IllegalArgumentException("Parameter map value must be single value " +
+						" or array of type [" + String.class.getName() + "]");
+			}
+		}
+	}
+
+	/**
+	 * Add a single value for the specified HTTP parameter.
+	 * <p>If there are already one or more values registered for the given
+	 * parameter name, the given value will be added to the end of the list.
+	 */
+	public void addParameter(String name, String value) {
+		addParameter(name, new String[] {value});
+	}
+
+	/**
+	 * Add an array of values for the specified HTTP parameter.
+	 * <p>If there are already one or more values registered for the given
+	 * parameter name, the given values will be added to the end of the list.
+	 */
+	public void addParameter(String name, String[] values) {
+		String[] oldArr = (String[]) this.parameters.get(name);
+		if (oldArr != null) {
+			String[] newArr = new String[oldArr.length + values.length];
+			System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
+			System.arraycopy(values, 0, newArr, oldArr.length, values.length);
+			this.parameters.put(name, newArr);
+		}
+		else {
+			this.parameters.put(name, values);
+		}
+	}
+
+	/**
+	 * Adds all provided parameters <emphasis>without</emphasis> replacing
+	 * any existing values. To replace existing values, use
+	 * {@link #setParameters(java.util.Map)}.
+	 */
+	public void addParameters(Map params) {
+		for (Iterator it = params.keySet().iterator(); it.hasNext();) {
+			Object key = it.next();
+			Object value = params.get(key);
+			if (value instanceof String) {
+				this.addParameter((String) key, (String) value);
+			}
+			else if (value instanceof String[]) {
+				this.addParameter((String) key, (String[]) value);
+			}
+			else {
+				throw new IllegalArgumentException("Parameter map value must be single value " +
+						" or array of type [" + String.class.getName() + "]");
+			}
+		}
+	}
+
+	/**
+	 * Remove already registered values for the specified HTTP parameter, if any.
+	 */
+	public void removeParameter(String name) {
+		this.parameters.remove(name);
+	}
+
+	/**
+	 * Removes all existing parameters.
+	 */
+	public void removeAllParameters() {
+		this.parameters.clear();
+	}
+
+	public String getParameter(String name) {
+		String[] arr = (String[]) this.parameters.get(name);
+		return (arr != null && arr.length > 0 ? arr[0] : null);
+	}
+
+	public Enumeration getParameterNames() {
+		return Collections.enumeration(this.parameters.keySet());
+	}
+
+	public String[] getParameterValues(String name) {
+		return (String[]) this.parameters.get(name);
+	}
+
+	public Map getParameterMap() {
+		return Collections.unmodifiableMap(this.parameters);
+	}
+
+   /**
+    * Add a query parameter that will be appended to the URI query string.
+    */
+   public void addQueryParameter(String name, String value) {
+      addParameter(name, value);
+      this.queryParameters.put(name, value);
+   }
+
+   public void removeQueryParameter(String name) {
+      removeParameter(name);
+      this.queryParameters.remove(name);
+   }
+
+   public Map<String, String> getQueryParameters()
+   {
+      return queryParameters;
+   }
+
+   public void setProtocol(String protocol) {
+		this.protocol = protocol;
+	}
+
+	public String getProtocol() {
+		return this.protocol;
+	}
+
+	public void setScheme(String scheme) {
+		this.scheme = scheme;
+	}
+
+	public String getScheme() {
+		return this.scheme;
+	}
+
+	public void setServerName(String serverName) {
+		this.serverName = serverName;
+	}
+
+	public String getServerName() {
+		return this.serverName;
+	}
+
+	public void setServerPort(int serverPort) {
+		this.serverPort = serverPort;
+	}
+
+	public int getServerPort() {
+		return this.serverPort;
+	}
+
+	public BufferedReader getReader() throws UnsupportedEncodingException {
+		if (this.content != null) {
+			InputStream sourceStream = new ByteArrayInputStream(this.content);
+			Reader sourceReader = (this.characterEncoding != null) ?
+					new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream);
+			return new BufferedReader(sourceReader);
+		}
+		else {
+			return null;
+		}
+	}
+
+	public void setRemoteAddr(String remoteAddr) {
+		this.remoteAddr = remoteAddr;
+	}
+
+	public String getRemoteAddr() {
+		return this.remoteAddr;
+	}
+
+	public void setRemoteHost(String remoteHost) {
+		this.remoteHost = remoteHost;
+	}
+
+	public String getRemoteHost() {
+		return this.remoteHost;
+	}
+
+	public void setAttribute(String name, Object value) {
+		checkActive();
+		if (value != null) {
+			this.attributes.put(name, value);
+		}
+		else {
+			this.attributes.remove(name);
+		}
+	}
+
+	public void removeAttribute(String name) {
+		checkActive();
+		this.attributes.remove(name);
+	}
+
+	/**
+	 * Clear all of this request's attributes.
+	 */
+	public void clearAttributes() {
+		this.attributes.clear();
+	}
+
+	/**
+	 * Add a new preferred locale, before any existing locales.
+	 */
+	public void addPreferredLocale(Locale locale) {
+		this.locales.add(0, locale);
+	}
+
+	public Locale getLocale() {
+		return (Locale) this.locales.get(0);
+	}
+
+	public Enumeration getLocales() {
+		return this.locales.elements();
+	}
+
+	public void setSecure(boolean secure) {
+		this.secure = secure;
+	}
+
+	public boolean isSecure() {
+		return this.secure;
+	}
+
+	public RequestDispatcher getRequestDispatcher(String path) {
+		return new MockRequestDispatcher(path);
+	}
+
+	public String getRealPath(String path) {
+		return this.servletContext.getRealPath(path);
+	}
+
+	public void setRemotePort(int remotePort) {
+		this.remotePort = remotePort;
+	}
+
+	public int getRemotePort() {
+		return this.remotePort;
+	}
+
+	public void setLocalName(String localName) {
+		this.localName = localName;
+	}
+
+	public String getLocalName() {
+		return this.localName;
+	}
+
+	public void setLocalAddr(String localAddr) {
+		this.localAddr = localAddr;
+	}
+
+	public String getLocalAddr() {
+		return this.localAddr;
+	}
+
+	public void setLocalPort(int localPort) {
+		this.localPort = localPort;
+	}
+
+	public int getLocalPort() {
+		return this.localPort;
+	}
+
+
+	//---------------------------------------------------------------------
+	// HttpServletRequest interface
+	//---------------------------------------------------------------------
+
+	public void setAuthType(String authType) {
+		this.authType = authType;
+	}
+
+	public String getAuthType() {
+		return this.authType;
+	}
+
+	public void setCookies(Cookie[] cookies) {
+		this.cookies = cookies;
+	}
+
+	public Cookie[] getCookies() {
+		return this.cookies;
+	}
+
+   public void addCookie(Cookie cookie) {
+      this.cookies = new Cookie[this.cookies.length+1];
+      this.cookies[this.cookies.length-1] = cookie;
+   }
+
+	/**
+	 * Add a header entry for the given name.
+	 * <p>If there was no entry for that header name before,
+	 * the value will be used as-is. In case of an existing entry,
+	 * a String array will be created, adding the given value (more
+	 * specifically, its toString representation) as further element.
+	 * <p>Multiple values can only be stored as list of Strings,
+	 * following the Servlet spec (see <code>getHeaders</code> accessor).
+	 * As alternative to repeated <code>addHeader</code> calls for
+	 * individual elements, you can use a single call with an entire
+	 * array or Collection of values as parameter.
+	 * @see #getHeaderNames
+	 * @see #getHeader
+	 * @see #getHeaders
+	 * @see #getDateHeader
+	 * @see #getIntHeader
+	 */
+	public void addHeader(String name, Object value) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		if (header == null) {
+			header = new HeaderValueHolder();
+			this.headers.put(name, header);
+		}
+		if (value instanceof Collection) {
+			header.addValues((Collection) value);
+		}
+		else if (value.getClass().isArray()) {
+			header.addValueArray(value);
+		}
+		else {
+			header.addValue(value);
+		}
+	}
+
+	public long getDateHeader(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		Object value = (header != null ? header.getValue() : null);
+		if (value instanceof Date) {
+			return ((Date) value).getTime();
+		}
+		else if (value instanceof Number) {
+			return ((Number) value).longValue();
+		}
+		else if (value != null) {
+			throw new IllegalArgumentException(
+					"Value for header '" + name + "' is neither a Date nor a Number: " + value);
+		}
+		else {
+			return -1L;
+		}
+	}
+
+	public String getHeader(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		return (header != null ? header.getValue().toString() : null);
+	}
+
+	public Enumeration getHeaders(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		return Collections.enumeration(header != null ? header.getValues() : Collections.EMPTY_LIST);
+	}
+
+	public Enumeration getHeaderNames() {
+		return this.headers.keys();
+	}
+
+	public int getIntHeader(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		Object value = (header != null ? header.getValue() : null);
+		if (value instanceof Number) {
+			return ((Number) value).intValue();
+		}
+		else if (value instanceof String) {
+			return Integer.parseInt((String) value);
+		}
+		else if (value != null) {
+			throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value);
+		}
+		else {
+			return -1;
+		}
+	}
+
+	public void setMethod(String method) {
+		this.method = method;
+	}
+
+	public String getMethod() {
+		return this.method;
+	}
+
+	public void setPathInfo(String pathInfo) {
+		this.pathInfo = pathInfo;
+	}
+
+	public String getPathInfo() {
+		return this.pathInfo;
+	}
+
+	public String getPathTranslated() {
+		return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
+	}
+
+	public void setContextPath(String contextPath) {
+		this.contextPath = contextPath;
+	}
+
+	public String getContextPath() {
+		return this.contextPath;
+	}
+
+	public void setQueryString(String queryString) {
+		this.queryString = queryString;
+	}
+
+	public String getQueryString() {
+      if (getQueryParameters().size() > 0) {
+         StringBuilder q = new StringBuilder(queryString);
+         if (!queryString.endsWith("&")) q.append("&");
+         for (Map.Entry<String, String> entry : getQueryParameters().entrySet())
+         {
+            q.append(entry.getKey());
+            q.append("=");
+            q.append(entry.getValue());
+            q.append("&");
+         }
+         if (q.toString().endsWith("&")) {
+            q.deleteCharAt(q.length()-1);
+         }
+         return q.toString();
+      }
+		return this.queryString;
+	}
+
+	public void setRemoteUser(String remoteUser) {
+		this.remoteUser = remoteUser;
+	}
+
+	public String getRemoteUser() {
+		return this.remoteUser;
+	}
+
+	/**
+	 * @deprecated in favor of addUserRole
+	 * @see #addUserRole
+	 */
+	public void addRole(String role) {
+		addUserRole(role);
+	}
+
+	public void addUserRole(String role) {
+		this.userRoles.add(role);
+	}
+
+	public boolean isUserInRole(String role) {
+		return this.userRoles.contains(role);
+	}
+
+	public void setUserPrincipal(Principal userPrincipal) {
+		this.userPrincipal = userPrincipal;
+	}
+
+	public Principal getUserPrincipal() {
+		return this.userPrincipal;
+	}
+
+	public String getRequestedSessionId() {
+		HttpSession session = getSession();
+		return (session != null ? session.getId() : null);
+	}
+
+	public void setRequestURI(String requestURI) {
+		this.requestURI = requestURI;
+	}
+
+	public String getRequestURI() {
+		return this.requestURI;
+	}
+
+	public StringBuffer getRequestURL() {
+		StringBuffer url = new StringBuffer(this.scheme);
+		url.append("://").append(this.serverName).append(':').append(this.serverPort);
+		url.append(getRequestURI());
+		return url;
+	}
+
+	public void setServletPath(String servletPath) {
+		this.servletPath = servletPath;
+	}
+
+	public String getServletPath() {
+		return this.servletPath;
+	}
+
+	public void setSession(HttpSession session) {
+		if (session instanceof MockHttpSession) {
+			MockHttpSession mockSession = ((MockHttpSession) session);
+			//TODO: We don't track access times in mocks (yet) mockSession.access();
+		}
+      this.session = session;
+	}
+
+	public HttpSession getSession(boolean create) {
+		checkActive();
+		// Reset session if invalidated.
+		if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) {
+			this.session = null;
+		}
+		// Create new session if necessary.
+		if (this.session == null && create) {
+			this.session = new MockHttpSession(this.servletContext);
+		}
+		return this.session;
+	}
+
+	public HttpSession getSession() {
+		return getSession(true);
+	}
+
+	public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
+		this.requestedSessionIdValid = requestedSessionIdValid;
+	}
+
+	public boolean isRequestedSessionIdValid() {
+		return this.requestedSessionIdValid;
+	}
+
+	public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) {
+		this.requestedSessionIdFromCookie = requestedSessionIdFromCookie;
+	}
+
+	public boolean isRequestedSessionIdFromCookie() {
+		return this.requestedSessionIdFromCookie;
+	}
+
+	public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) {
+		this.requestedSessionIdFromURL = requestedSessionIdFromURL;
+	}
+
+	public boolean isRequestedSessionIdFromURL() {
+		return this.requestedSessionIdFromURL;
+	}
+
+	public boolean isRequestedSessionIdFromUrl() {
+		return isRequestedSessionIdFromURL();
+	}
+
+   public boolean isAllParametersInQueryString() {
+      return true;
+   }
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletResponse.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletResponse.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockHttpServletResponse.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,516 @@
+/*
+ * Copyright 2002-2008 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * Mock implementation of the {@link javax.servlet.http.HttpServletResponse}
+ * interface. Supports the Servlet 2.4 API level.
+ *
+ * <p>Used for testing the web framework; also useful for testing
+ * application controllers.
+ *
+ * @author Juergen Hoeller
+ * @author Rod Johnson
+ * @since 1.0.2
+ */
+public class MockHttpServletResponse implements HttpServletResponse {
+
+	public static final int DEFAULT_SERVER_PORT = 80;
+
+	private static final String CHARSET_PREFIX = "charset=";
+
+
+	//---------------------------------------------------------------------
+	// ServletResponse properties
+	//---------------------------------------------------------------------
+
+	private boolean outputStreamAccessAllowed = true;
+
+	private boolean writerAccessAllowed = true;
+
+	private String characterEncoding = "ISO-8859-1";
+
+	private final ByteArrayOutputStream content = new ByteArrayOutputStream();
+
+	private final ServletOutputStream outputStream = new ResponseServletOutputStream(this.content);
+
+	private PrintWriter writer;
+
+	private int contentLength = 0;
+
+	private String contentType;
+
+	private int bufferSize = 4096;
+
+	private boolean committed;
+
+	private Locale locale = Locale.getDefault();
+
+
+	//---------------------------------------------------------------------
+	// HttpServletResponse properties
+	//---------------------------------------------------------------------
+
+	private final List cookies = new ArrayList();
+
+	/**
+	 * The key is the lowercase header name; the value is a {@link HeaderValueHolder} object.
+	 */
+	private final Map headers = new HashMap();
+
+	private int status = HttpServletResponse.SC_OK;
+
+	private String statusMessage;
+
+	private String redirectedUrl;
+
+	private String forwardedUrl;
+
+	private String includedUrl;
+
+
+   //---------------------------------------------------------------------
+	// ServletResponse interface
+	//---------------------------------------------------------------------
+
+	/**
+	 * Set whether {@link #getOutputStream()} access is allowed.
+	 * <p>Default is <code>true</code>.
+	 */
+	public void setOutputStreamAccessAllowed(boolean outputStreamAccessAllowed) {
+		this.outputStreamAccessAllowed = outputStreamAccessAllowed;
+	}
+
+	/**
+	 * Return whether {@link #getOutputStream()} access is allowed.
+	 */
+	public boolean isOutputStreamAccessAllowed() {
+		return this.outputStreamAccessAllowed;
+	}
+
+	/**
+	 * Set whether {@link #getWriter()} access is allowed.
+	 * <p>Default is <code>true</code>.
+	 */
+	public void setWriterAccessAllowed(boolean writerAccessAllowed) {
+		this.writerAccessAllowed = writerAccessAllowed;
+	}
+
+	/**
+	 * Return whether {@link #getOutputStream()} access is allowed.
+	 */
+	public boolean isWriterAccessAllowed() {
+		return this.writerAccessAllowed;
+	}
+
+	public void setCharacterEncoding(String characterEncoding) {
+		this.characterEncoding = characterEncoding;
+	}
+
+	public String getCharacterEncoding() {
+		return this.characterEncoding;
+	}
+
+	public ServletOutputStream getOutputStream() {
+		if (!this.outputStreamAccessAllowed) {
+			throw new IllegalStateException("OutputStream access not allowed");
+		}
+		return this.outputStream;
+	}
+
+	public PrintWriter getWriter() throws UnsupportedEncodingException {
+		if (!this.writerAccessAllowed) {
+			throw new IllegalStateException("Writer access not allowed");
+		}
+		if (this.writer == null) {
+			Writer targetWriter = (this.characterEncoding != null ?
+					new OutputStreamWriter(this.content, this.characterEncoding) : new OutputStreamWriter(this.content));
+			this.writer = new ResponsePrintWriter(targetWriter);
+		}
+		return this.writer;
+	}
+
+	public byte[] getContentAsByteArray() {
+		flushBuffer();
+		return this.content.toByteArray();
+	}
+
+	public String getContentAsString() {
+		flushBuffer();
+      try {
+         return (this.characterEncoding != null) ?
+               this.content.toString(this.characterEncoding) : this.content.toString();
+      } catch (UnsupportedEncodingException ex) {
+         throw new RuntimeException(ex);
+      }
+	}
+
+	public void setContentLength(int contentLength) {
+		this.contentLength = contentLength;
+	}
+
+	public int getContentLength() {
+		return this.contentLength;
+	}
+
+	public void setContentType(String contentType) {
+		this.contentType = contentType;
+		if (contentType != null) {
+			int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
+			if (charsetIndex != -1) {
+				String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
+				setCharacterEncoding(encoding);
+			}
+		}
+	}
+
+	public String getContentType() {
+		return this.contentType;
+	}
+
+	public void setBufferSize(int bufferSize) {
+		this.bufferSize = bufferSize;
+	}
+
+	public int getBufferSize() {
+		return this.bufferSize;
+	}
+
+	public void flushBuffer() {
+		setCommitted(true);
+	}
+
+	public void resetBuffer() {
+		if (isCommitted()) {
+			throw new IllegalStateException("Cannot reset buffer - response is already committed");
+		}
+		this.content.reset();
+	}
+
+	private void setCommittedIfBufferSizeExceeded() {
+		int bufSize = getBufferSize();
+		if (bufSize > 0 && this.content.size() > bufSize) {
+			setCommitted(true);
+		}
+	}
+
+	public void setCommitted(boolean committed) {
+		this.committed = committed;
+	}
+
+	public boolean isCommitted() {
+		return this.committed;
+	}
+
+	public void reset() {
+		resetBuffer();
+		this.characterEncoding = null;
+		this.contentLength = 0;
+		this.contentType = null;
+		this.locale = null;
+		this.cookies.clear();
+		this.headers.clear();
+		this.status = HttpServletResponse.SC_OK;
+		this.statusMessage = null;
+	}
+
+	public void setLocale(Locale locale) {
+		this.locale = locale;
+	}
+
+	public Locale getLocale() {
+		return this.locale;
+	}
+
+
+	//---------------------------------------------------------------------
+	// HttpServletResponse interface
+	//---------------------------------------------------------------------
+
+	public void addCookie(Cookie cookie) {
+		this.cookies.add(cookie);
+	}
+
+	public Cookie[] getCookies() {
+		return (Cookie[]) this.cookies.toArray(new Cookie[this.cookies.size()]);
+	}
+
+	public Cookie getCookie(String name) {
+		for (Iterator it = this.cookies.iterator(); it.hasNext();) {
+			Cookie cookie = (Cookie) it.next();
+			if (name.equals(cookie.getName())) {
+				return cookie;
+			}
+		}
+		return null;
+	}
+
+	public boolean containsHeader(String name) {
+		return (HeaderValueHolder.getByName(this.headers, name) != null);
+	}
+
+	/**
+	 * Return the names of all specified headers as a Set of Strings.
+	 * @return the <code>Set</code> of header name <code>Strings</code>, or an empty <code>Set</code> if none
+	 */
+	public Set getHeaderNames() {
+		return this.headers.keySet();
+	}
+
+	/**
+	 * Return the primary value for the given header, if any.
+	 * <p>Will return the first value in case of multiple values.
+	 * @param name the name of the header
+	 * @return the associated header value, or <code>null<code> if none
+	 */
+	public Object getHeader(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		return (header != null ? header.getValue() : null);
+	}
+
+	/**
+	 * Return all values for the given header as a List of value objects.
+	 * @param name the name of the header
+	 * @return the associated header values, or an empty List if none
+	 */
+	public List getHeaders(String name) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		return (header != null ? header.getValues() : Collections.EMPTY_LIST);
+	}
+
+	/**
+	 * The default implementation returns the given URL String as-is.
+	 * <p>Can be overridden in subclasses, appending a session id or the like.
+	 */
+	public String encodeURL(String url) {
+		return url;
+	}
+
+	/**
+	 * The default implementation delegates to {@link #encodeURL},
+	 * returning the given URL String as-is.
+	 * <p>Can be overridden in subclasses, appending a session id or the like
+	 * in a redirect-specific fashion. For general URL encoding rules,
+	 * override the common {@link #encodeURL} method instead, appyling
+	 * to redirect URLs as well as to general URLs.
+	 */
+	public String encodeRedirectURL(String url) {
+		return encodeURL(url);
+	}
+
+	public String encodeUrl(String url) {
+		return encodeURL(url);
+	}
+
+	public String encodeRedirectUrl(String url) {
+		return encodeRedirectURL(url);
+	}
+
+	public void sendError(int status, String errorMessage) throws IOException {
+		if (isCommitted()) {
+			throw new IllegalStateException("Cannot set error status - response is already committed");
+		}
+		this.status = status;
+		this.statusMessage = errorMessage;
+		setCommitted(true);
+	}
+
+	public void sendError(int status) throws IOException {
+		if (isCommitted()) {
+			throw new IllegalStateException("Cannot set error status - response is already committed");
+		}
+		this.status = status;
+		setCommitted(true);
+	}
+
+	public void sendRedirect(String url) throws IOException {
+		if (isCommitted()) {
+			throw new IllegalStateException("Cannot send redirect - response is already committed");
+		}
+		this.redirectedUrl = url;
+		setCommitted(true);
+	}
+
+	public String getRedirectedUrl() {
+		return this.redirectedUrl;
+	}
+
+	public void setDateHeader(String name, long value) {
+		setHeaderValue(name, new Long(value));
+	}
+
+	public void addDateHeader(String name, long value) {
+		addHeaderValue(name, new Long(value));
+	}
+
+	public void setHeader(String name, String value) {
+		setHeaderValue(name, value);
+	}
+
+	public void addHeader(String name, String value) {
+		addHeaderValue(name, value);
+	}
+
+	public void setIntHeader(String name, int value) {
+		setHeaderValue(name, new Integer(value));
+	}
+
+	public void addIntHeader(String name, int value) {
+		addHeaderValue(name, new Integer(value));
+	}
+
+	private void setHeaderValue(String name, Object value) {
+		doAddHeaderValue(name, value, true);
+	}
+
+	private void addHeaderValue(String name, Object value) {
+		doAddHeaderValue(name, value, false);
+	}
+
+	private void doAddHeaderValue(String name, Object value, boolean replace) {
+		HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
+		if (header == null) {
+			header = new HeaderValueHolder();
+			this.headers.put(name, header);
+		}
+		if (replace) {
+			header.setValue(value);
+		}
+		else {
+			header.addValue(value);
+		}
+	}
+
+	public void setStatus(int status) {
+		this.status = status;
+	}
+
+	public void setStatus(int status, String statusMessage) {
+		this.status = status;
+		this.statusMessage = statusMessage;
+	}
+
+	public int getStatus() {
+		return this.status;
+	}
+
+	public String getStatusMessage() {
+		return this.statusMessage;
+	}
+
+
+	//---------------------------------------------------------------------
+	// Methods for MockRequestDispatcher
+	//---------------------------------------------------------------------
+
+	public void setForwardedUrl(String forwardedUrl) {
+		this.forwardedUrl = forwardedUrl;
+	}
+
+	public String getForwardedUrl() {
+		return this.forwardedUrl;
+	}
+
+	public void setIncludedUrl(String includedUrl) {
+		this.includedUrl = includedUrl;
+	}
+
+	public String getIncludedUrl() {
+		return this.includedUrl;
+	}
+
+
+   /**
+	 * Inner class that adapts the ServletOutputStream to mark the
+	 * response as committed once the buffer size is exceeded.
+	 */
+	private class ResponseServletOutputStream extends DelegatingServletOutputStream
+   {
+
+		public ResponseServletOutputStream(OutputStream out) {
+			super(out);
+		}
+
+		public void write(int b) throws IOException {
+			super.write(b);
+			super.flush();
+			setCommittedIfBufferSizeExceeded();
+		}
+
+		public void flush() throws IOException {
+			super.flush();
+			setCommitted(true);
+		}
+	}
+
+
+	/**
+	 * Inner class that adapts the PrintWriter to mark the
+	 * response as committed once the buffer size is exceeded.
+	 */
+	private class ResponsePrintWriter extends PrintWriter {
+
+		public ResponsePrintWriter(Writer out) {
+			super(out, true);
+		}
+
+		public void write(char buf[], int off, int len) {
+			super.write(buf, off, len);
+			super.flush();
+			setCommittedIfBufferSizeExceeded();
+		}
+
+		public void write(String s, int off, int len) {
+			super.write(s, off, len);
+			super.flush();
+			setCommittedIfBufferSizeExceeded();
+		}
+
+		public void write(int c) {
+			super.write(c);
+			super.flush();
+			setCommittedIfBufferSizeExceeded();
+		}
+
+		public void flush() {
+			super.flush();
+			setCommitted(true);
+		}
+	}
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockRequestDispatcher.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockRequestDispatcher.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/MockRequestDispatcher.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed 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.jboss.seam.resteasy.testfwk;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface.
+ *
+ * <p>Used for testing the web framework; typically not necessary for
+ * testing application controllers.
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @since 1.0.2
+ */
+public class MockRequestDispatcher implements RequestDispatcher {
+
+	private final Log logger = LogFactory.getLog(getClass());
+
+	private final String url;
+
+
+	/**
+	 * Create a new MockRequestDispatcher for the given URL.
+	 * @param url the URL to dispatch to.
+	 */
+	public MockRequestDispatcher(String url) {
+		this.url = url;
+	}
+
+
+	public void forward(ServletRequest request, ServletResponse response) {
+		if (response.isCommitted()) {
+			throw new IllegalStateException("Cannot perform forward - response is already committed");
+		}
+		getMockHttpServletResponse(response).setForwardedUrl(this.url);
+		if (logger.isDebugEnabled()) {
+			logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
+		}
+	}
+
+	public void include(ServletRequest request, ServletResponse response) {
+		getMockHttpServletResponse(response).setIncludedUrl(this.url);
+		if (logger.isDebugEnabled()) {
+			logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
+		}
+	}
+
+	/**
+	 * Obtain the underlying MockHttpServletResponse,
+	 * unwrapping {@link javax.servlet.http.HttpServletResponseWrapper} decorators if necessary.
+	 */
+	protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
+		if (response instanceof MockHttpServletResponse) {
+			return (MockHttpServletResponse) response;
+		}
+		if (response instanceof HttpServletResponseWrapper) {
+			return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse());
+		}
+		throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse");
+	}
+
+}
\ No newline at end of file

Added: branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/ResourceSeamTest.java
===================================================================
--- branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/ResourceSeamTest.java	                        (rev 0)
+++ branches/community/Seam_2_1/src/resteasy/org/jboss/seam/resteasy/testfwk/ResourceSeamTest.java	2009-05-26 11:16:58 UTC (rev 10978)
@@ -0,0 +1,238 @@
+package org.jboss.seam.resteasy.testfwk;
+
+import org.jboss.seam.mock.SeamTest;
+import org.jboss.seam.servlet.SeamResourceServlet;
+import org.testng.annotations.BeforeClass;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.Cookie;
+import java.util.*;
+import java.io.IOException;
+import java.security.Principal;
+
+/**
+ * Executes (through local calls, not TCP sockets) an HTTP request in a unit test.
+ *
+ * <pre>
+ * import org.jboss.seam.resteasy.testfwk.ResourceSeamTest;
+ * import org.jboss.seam.resteasy.testfwk.MockHttpServletResponse;
+ * import org.jboss.seam.resteasy.testfwk.MockHttpServletRequest;
+ *  
+ * public class MyTest extends ResourceSeamTest {
+ *
+ *    &#064;Override
+ *    public String getServletPath()
+ *    {
+ *       return "/seam/resource/.../is/not/my/web.xml/configured/path/for/SeamResourceServlet";
+ *    }
+ *
+ *    &#064;Override
+ *    public Map<String, Object> getDefaultHeaders()
+ *    {
+ *       return new HashMap<String, Object>()
+ *       {{
+ *             put("Accept", "text/plain");
+ *       }};
+ *    }
+ * 
+ *    &#064;Test
+ *    public void test() throws Exception
+ *    {
+ *       new ResourceRequest(Method.GET, "/my/relative/uri)
+ *       {
+ * 
+ *          &#064;Override
+ *          protected void prepareRequest(MockHttpServletRequest request)
+ *          {
+ *             request.addQueryParameter("foo", "123");
+ *             request.addHeader("Accept-Language", "en_US, de");
+ *          }
+ * 
+ *          &#064;Override
+ *          protected void onResponse(MockHttpServletResponse response)
+ *          {
+ *             assert response.getStatus() == 200;
+ *             assert response.getContentAsString().equals("foobar");
+ *          }
+ * 
+ *       }.run();
+ *    }
+ * 
+ * }
+ * </pre>
+ *
+ * <p>
+ * Note that you currently can only execute <tt>ResourceRequest</tt> inside an actual
+ * <tt>@Test</tt> method or in a <tt>@BeforeMethod</tt> callback. You can (or should)
+ * not run it in any other callback such as <tt>@BeforeClass</tt> or <tt>@BeforeTest</tt>.
+ * </p>
+ *
+ * @author Christian Bauer
+ */
+public class ResourceSeamTest extends SeamTest
+{
+
+   public enum Method
+   {
+      GET, PUT, POST, DELETE, HEAD, OPTIONS
+   }
+
+   protected SeamResourceServlet resourceServlet;
+
+   @BeforeClass
+   public void initResourceServlet() throws Exception
+   {
+      resourceServlet = new SeamResourceServlet();
+      resourceServlet.init(
+            new ServletConfig()
+            {
+               public String getServletName()
+               {
+                  return "Seam Resource Servlet";
+               }
+
+               public ServletContext getServletContext()
+               {
+                  return servletContext;
+               }
+
+               public String getInitParameter(String s)
+               {
+                  return null;
+               }
+
+               public Enumeration getInitParameterNames()
+               {
+                  return null;
+               }
+            }
+      );
+
+   }
+
+   public abstract class ResourceRequest
+   {
+
+      private Method httpMethod;
+      private String requestPath;
+      private MockHttpServletRequest request;
+      private MockHttpServletResponse response;
+
+      protected ResourceRequest(Method httpMethod, String requestPath)
+      {
+         this.httpMethod = httpMethod;
+         this.requestPath = getServletPath() + (requestPath.startsWith("/") ? requestPath : "/" + requestPath);
+      }
+
+      public void run() throws Exception
+      {
+         init();
+         prepareRequest(request);
+         seamFilter.doFilter(request, response, new FilterChain()
+         {
+            public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
+            {
+               resourceServlet.service(request, response);
+            }
+         });
+         seamFilter.destroy();
+         onResponse(getResponse());
+      }
+
+      protected void init()
+      {
+         request = createRequest();
+         response = createResponse();
+
+         request.setMethod(httpMethod.toString());
+         request.setRequestURI(requestPath);
+
+         request.setServletPath(getServletPath());
+
+         request.setCookies(getCookies().toArray(new Cookie[getCookies().size()]));
+
+         for (Map.Entry<String, Object> entry : getDefaultHeaders().entrySet())
+         {
+            request.addHeader(entry.getKey(), entry.getValue());
+         }
+
+         request.setUserPrincipal(
+               new Principal()
+               {
+                  public String getName()
+                  {
+                     return getPrincipalName();
+                  }
+               }
+         );
+         for (String role : getPrincipalRoles())
+         {
+            request.addUserRole(role);
+         }
+
+         // Use the (mock) HttpSession that Seam uses, see AbstractSeamTest
+         request.setSession(session);
+
+      }
+
+      protected MockHttpServletRequest createRequest()
+      {
+         return new MockHttpServletRequest();
+      }
+
+      protected MockHttpServletResponse createResponse()
+      {
+         return new MockHttpServletResponse();
+      }
+
+      protected Map<String, String> getRequestQueryParameters()
+      {
+         return Collections.EMPTY_MAP;
+      }
+
+      protected List<Cookie> getCookies()
+      {
+         return Collections.EMPTY_LIST;
+      }
+
+      protected String getPrincipalName()
+      {
+         return null;
+      }
+
+      protected Set<String> getPrincipalRoles()
+      {
+         return Collections.EMPTY_SET;
+      }
+
+      protected void prepareRequest(MockHttpServletRequest request)
+      {
+      }
+
+      protected void onResponse(MockHttpServletResponse response)
+      {
+      }
+
+      public HttpServletRequest getRequest()
+      {
+         return request;
+      }
+
+      public MockHttpServletResponse getResponse()
+      {
+         return response;
+      }
+
+   }
+
+   public String getServletPath()
+   {
+      return "/seam/resource";
+   }
+
+   public Map<String, Object> getDefaultHeaders() {
+      return Collections.EMPTY_MAP;
+   }
+
+}




More information about the seam-commits mailing list