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

Reply via email to