Revision: 8793
Author: [email protected]
Date: Wed Sep 15 15:23:04 2010
Log: Ugly hack to address the RequestFactory tests being constructed around
a static singleton instance not playing nicely when testing with multiple
browsers.
Patch by: bobv
Review by: rjrjr
http://code.google.com/p/google-web-toolkit/source/detail?r=8793
Modified:
/trunk/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
/trunk/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
/trunk/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
Fri Aug 27 13:26:53 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
Wed Sep 15 15:23:04 2010
@@ -38,10 +38,9 @@
* request, returning SC_UNAUTHORIZED if authentication fails, as well as a
* header named "login" which contains the URL the user should be sent in
to
* login. Note that the servlet expects a "pageurl" header in the request,
- * indicating the page to redirect to after authentication.
- * If authentication succeeds, a header named "userId" is returned, which
- * will be unique to the user (so the app can react if the signed in user
has
- * changed).
+ * indicating the page to redirect to after authentication. If
authentication
+ * succeeds, a header named "userId" is returned, which will be unique to
the
+ * user (so the app can react if the signed in user has changed).
*
* Configured via servlet init params.
* <p>
@@ -60,39 +59,62 @@
private static final String JSON_CHARSET = "UTF-8";
private static final String JSON_CONTENT_TYPE = "application/json";
private static final Logger log =
Logger.getLogger(RequestFactoryServlet.class.getCanonicalName());
-
+
+ /**
+ * These ThreadLocals are used to allow service objects to obtain access
to
+ * the HTTP transaction.
+ */
+ private static final ThreadLocal<HttpServletRequest> perThreadRequest =
new ThreadLocal<HttpServletRequest>();
+ private static final ThreadLocal<HttpServletResponse> perThreadResponse
= new ThreadLocal<HttpServletResponse>();
+
+ public static HttpServletRequest getThreadLocalRequest() {
+ return perThreadRequest.get();
+ }
+
+ public static HttpServletResponse getThreadLocalResponse() {
+ return perThreadResponse.get();
+ }
+
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws IOException, ServletException {
- ensureConfig();
- String jsonRequestString = RPCServletUtils.readContent(
- request, JSON_CONTENT_TYPE, JSON_CHARSET);
- response.setStatus(HttpServletResponse.SC_OK);
- PrintWriter writer = response.getWriter();
-
+ perThreadRequest.set(request);
+ perThreadResponse.set(response);
+
+ // No new code should be placed outside of this try block.
try {
- // Check that user is logged in before proceeding
- UserInformation userInfo =
-
UserInformation.getCurrentUserInformation(request.getHeader("pageurl"));
- if (!userInfo.isUserLoggedIn()) {
- response.setHeader("login", userInfo.getLoginUrl());
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
- } else {
- response.setHeader("userId", String.format("%d",
userInfo.getId()));
- response.setStatus(HttpServletResponse.SC_OK);
- RequestProcessor<String> requestProcessor = new
JsonRequestProcessor();
- requestProcessor.setOperationRegistry(new
ReflectionBasedOperationRegistry(
- new DefaultSecurityProvider()));
- response.setHeader(
- "Content-Type", RequestFactory.JSON_CONTENT_TYPE_UTF8);
-
writer.print(requestProcessor.decodeAndInvokeRequest(jsonRequestString));
+ ensureConfig();
+ String jsonRequestString = RPCServletUtils.readContent(request,
+ JSON_CONTENT_TYPE, JSON_CHARSET);
+ response.setStatus(HttpServletResponse.SC_OK);
+ PrintWriter writer = response.getWriter();
+
+ try {
+ // Check that user is logged in before proceeding
+ UserInformation userInfo =
UserInformation.getCurrentUserInformation(request.getHeader("pageurl"));
+ if (!userInfo.isUserLoggedIn()) {
+ response.setHeader("login", userInfo.getLoginUrl());
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ } else {
+ response.setHeader("userId", String.format("%d",
userInfo.getId()));
+ response.setStatus(HttpServletResponse.SC_OK);
+ RequestProcessor<String> requestProcessor = new
JsonRequestProcessor();
+ requestProcessor.setOperationRegistry(new
ReflectionBasedOperationRegistry(
+ new DefaultSecurityProvider()));
+ response.setHeader("Content-Type",
+ RequestFactory.JSON_CONTENT_TYPE_UTF8);
+
writer.print(requestProcessor.decodeAndInvokeRequest(jsonRequestString));
+ writer.flush();
+ }
+ } catch (RequestProcessingException e) {
+ writer.print((String) e.getResponse());
writer.flush();
- }
- } catch (RequestProcessingException e) {
- writer.print((String) e.getResponse());
- writer.flush();
- log.log(Level.SEVERE, "Unexpected error", e);
+ log.log(Level.SEVERE, "Unexpected error", e);
+ }
+ } finally {
+ perThreadRequest.set(null);
+ perThreadResponse.set(null);
}
}
=======================================
--- /trunk/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
Wed Aug 25 17:41:41 2010
+++ /trunk/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
Wed Sep 15 15:23:04 2010
@@ -20,12 +20,32 @@
import java.util.Collections;
import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+
/**
* Domain object for SimpleFooRequest.
*/
public class SimpleBar {
- static SimpleBar singleton = new SimpleBar();
+ /**
+ * This is an ugly hack.
+ */
+ static ThreadLocal<SimpleBar> singleton = new ThreadLocal<SimpleBar>() {
+ @Override
+ protected SimpleBar initialValue() {
+ SimpleBar value = null;
+ HttpServletRequest req =
RequestFactoryServlet.getThreadLocalRequest();
+ // May be in a JRE test case
+ if (req != null) {
+ value = (SimpleBar) req.getSession().getAttribute(
+ SimpleBar.class.getCanonicalName());
+ }
+ if (value == null) {
+ value = reset();
+ }
+ return value;
+ }
+ };
private static Long nextId = 1L;
@@ -34,7 +54,7 @@
}
public static List<SimpleBar> findAll() {
- return Collections.singletonList(singleton);
+ return Collections.singletonList(singleton.get());
}
public static SimpleBar findSimpleBar(Long id) {
@@ -42,16 +62,23 @@
}
public static SimpleBar findSimpleBarById(Long id) {
- singleton.setId(id);
- return singleton;
+ singleton.get().setId(id);
+ return singleton.get();
}
public static SimpleBar getSingleton() {
- return singleton;
+ return singleton.get();
}
- public static void reset() {
- singleton = new SimpleBar();
+ public static SimpleBar reset() {
+ SimpleBar instance = new SimpleBar();
+ singleton.set(instance);
+ HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest();
+ if (req != null) {
+ req.getSession().setAttribute(SimpleBar.class.getCanonicalName(),
+ instance);
+ }
+ return instance;
}
Integer version = 1;
@@ -80,9 +107,9 @@
public void persist() {
setId(nextId++);
- singleton.setUserName(userName);
- }
-
+ singleton.get().setUserName(userName);
+ }
+
public SimpleBar persistAndReturnSelf() {
persist();
return this;
=======================================
--- /trunk/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
Tue Sep 14 11:13:50 2010
+++ /trunk/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
Wed Sep 15 15:23:04 2010
@@ -24,6 +24,7 @@
import java.util.Date;
import java.util.List;
+import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Size;
/**
@@ -31,7 +32,25 @@
*/
public class SimpleFoo {
- static SimpleFoo singleton = new SimpleFoo();
+ /**
+ * This is an ugly hack.
+ */
+ static ThreadLocal<SimpleFoo> singleton = new ThreadLocal<SimpleFoo>() {
+ @Override
+ protected SimpleFoo initialValue() {
+ SimpleFoo value = null;
+ HttpServletRequest req =
RequestFactoryServlet.getThreadLocalRequest();
+ // May be in a JRE test case
+ if (req != null) {
+ value = (SimpleFoo) req.getSession().getAttribute(
+ SimpleFoo.class.getCanonicalName());
+ }
+ if (value == null) {
+ value = reset();
+ }
+ return value;
+ }
+ };
private static Long nextId = 1L;
@@ -40,7 +59,7 @@
}
public static List<SimpleFoo> findAll() {
- return Collections.singletonList(singleton);
+ return Collections.singletonList(singleton.get());
}
public static SimpleFoo findSimpleFoo(Long id) {
@@ -48,16 +67,23 @@
}
public static SimpleFoo findSimpleFooById(Long id) {
- singleton.setId(id);
- return singleton;
+ singleton.get().setId(id);
+ return singleton.get();
}
public static SimpleFoo getSingleton() {
- return singleton;
+ return singleton.get();
}
- public static void reset() {
- singleton = new SimpleFoo();
+ public static SimpleFoo reset() {
+ SimpleFoo instance = new SimpleFoo();
+ singleton.set(instance);
+ HttpServletRequest req = RequestFactoryServlet.getThreadLocalRequest();
+ if (req != null) {
+ req.getSession().setAttribute(SimpleFoo.class.getCanonicalName(),
+ instance);
+ }
+ return instance;
}
@SuppressWarnings("unused")
@@ -78,18 +104,18 @@
private Long longField;
private BigDecimal bigDecimalField;
-
+
private BigInteger bigIntField;
private Integer intId = -1;
private Short shortField;
-
+
private Byte byteField;
-
+
private Date created;
private Double doubleField;
-
+
private Float floatField;
-
+
private SimpleEnum enumField;
private Boolean boolField;
@@ -97,7 +123,7 @@
private SimpleBar barField;
private SimpleFoo fooField;
-
+
private String nullField;
private SimpleBar barNullField;
@@ -115,7 +141,7 @@
}
public Long countSimpleFooWithUserNameSideEffect() {
- singleton.setUserName(userName);
+ singleton.get().setUserName(userName);
return 1L;
}
@@ -207,6 +233,7 @@
public Boolean getOtherBoolField() {
return otherBoolField;
}
+
public String getPassword() {
return password;
}
@@ -227,7 +254,7 @@
}
public String hello(SimpleBar bar) {
- return "Greetings " + bar.getUserName() + " from " + getUserName();
+ return "Greetings " + bar.getUserName() + " from " + getUserName();
}
public void persist() {
@@ -300,7 +327,7 @@
public void setFloatField(Float floatField) {
this.floatField = floatField;
}
-
+
public void setFooField(SimpleFoo fooField) {
this.fooField = fooField;
}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors