Allow generic types to be parameterized by Void and passed through GWT RPC.
http://gwt-code-reviews.appspot.com/294801
Patch by: bobv
Review by: rice


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7837 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java
new file mode 100644
index 0000000..240edf8
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/rpc/core/java/lang/Void_CustomFieldSerializer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * 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 com.google.gwt.user.client.rpc.core.java.lang;
+
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.client.rpc.SerializationStreamReader;
+import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+
+/**
+ * Custom field serializer for {@link java.lang.Void}.
+ */
+public final class Void_CustomFieldSerializer {
+
+  public static void deserialize(SerializationStreamReader streamReader,
+      Void instance) {
+  }
+
+  public static Void instantiate(SerializationStreamReader streamReader)
+      throws SerializationException {
+    return null;
+  }
+
+  public static void serialize(SerializationStreamWriter streamWriter,
+      Void instance) throws SerializationException {
+  }
+}
diff --git a/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java b/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
index 2b32fbd..eb718d3 100644
--- a/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
+++ b/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
@@ -106,6 +106,23 @@
           }
         });
   }
+  
+  public void testArrayListVoid() {
+    CollectionsTestServiceAsync service = getServiceAsync();
+    delayTestFinishForRpc();
+    service.echoArrayListVoid(TestSetFactory.createArrayListVoid(),
+        new AsyncCallback<ArrayList<Void>>() {
+          public void onFailure(Throwable caught) {
+            TestSetValidator.rethrowException(caught);
+          }
+
+          public void onSuccess(ArrayList<Void> result) {
+            assertNotNull(result);
+            assertTrue(TestSetValidator.isValidArrayListVoid(result));
+            finishTest();
+          }
+        });
+  }
 
   public void testArraysAsList() {
     CollectionsTestServiceAsync service = getServiceAsync();
diff --git a/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java b/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
index 4902177..9c0b520 100644
--- a/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
+++ b/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
@@ -145,6 +145,9 @@
   Vector<MarkerTypeVector> echo(Vector<MarkerTypeVector> value)
       throws CollectionsTestServiceException;
 
+  ArrayList<Void> echoArrayListVoid(ArrayList<Void> value)
+      throws CollectionsTestServiceException;
+
   List<MarkerTypeArraysAsList> echoArraysAsList(
       List<MarkerTypeArraysAsList> value)
       throws CollectionsTestServiceException;
diff --git a/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java b/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
index 24221f3..e6c5e38 100644
--- a/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
+++ b/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
@@ -127,6 +127,9 @@
   void echo(Vector<MarkerTypeVector> value,
       AsyncCallback<Vector<MarkerTypeVector>> callback);
 
+  void echoArrayListVoid(ArrayList<Void> value,
+      AsyncCallback<ArrayList<Void>> callback);
+
   void echoArraysAsList(List<MarkerTypeArraysAsList> value,
       AsyncCallback<List<MarkerTypeArraysAsList>> callback);
 }
diff --git a/user/test/com/google/gwt/user/client/rpc/SerializableGenericWrapperType.java b/user/test/com/google/gwt/user/client/rpc/SerializableGenericWrapperType.java
new file mode 100644
index 0000000..2e6bd1a
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/rpc/SerializableGenericWrapperType.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * 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 com.google.gwt.user.client.rpc;
+
+import java.io.Serializable;
+
+/**
+ * Used to test serialization of generic types.
+ * 
+ * @param <T> any type
+ */
+public class SerializableGenericWrapperType<T> implements Serializable {
+  private T value;
+
+  public T getValue() {
+    return value;
+  }
+
+  public void setValue(T value) {
+    this.value = value;
+  }
+}
diff --git a/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java b/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
index 5b75365..7f749d9 100644
--- a/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
+++ b/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
@@ -366,6 +366,13 @@
     return list;
   }
 
+  public static ArrayList<Void> createArrayListVoid() {
+    ArrayList<Void> list = new ArrayList<Void>();
+    list.add(null);
+    list.add(null);
+    return list;
+  }
+
   public static List<MarkerTypeArraysAsList> createArraysAsList() {
     return Arrays.asList(new MarkerTypeArraysAsList("foo"),
         new MarkerTypeArraysAsList("bar"), new MarkerTypeArraysAsList("baz"),
diff --git a/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java b/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
index 91e1743..8bb3bd6 100644
--- a/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
+++ b/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
@@ -447,6 +447,18 @@
     return true;
   }
 
+  public static boolean isValidArrayListVoid(ArrayList<Void> list) {
+    if (list.size() != 2) {
+      return false;
+    }
+
+    if (list.get(0) != null || list.get(1) != null) {
+      return false;
+    }
+
+    return true;
+  }
+
   public static boolean isValidAsList(List<?> list) {
     if (list == null) {
       return false;
diff --git a/user/test/com/google/gwt/user/client/rpc/ValueTypesTest.java b/user/test/com/google/gwt/user/client/rpc/ValueTypesTest.java
index d650250..d602443 100644
--- a/user/test/com/google/gwt/user/client/rpc/ValueTypesTest.java
+++ b/user/test/com/google/gwt/user/client/rpc/ValueTypesTest.java
@@ -577,6 +577,24 @@
     });
   }
 
+  public void testVoidParameterizedType() {
+    ValueTypesTestServiceAsync service = getServiceAsync();
+    delayTestFinishForRpc();
+    service.echo(new SerializableGenericWrapperType<Void>(),
+        new AsyncCallback<SerializableGenericWrapperType<Void>>() {
+
+          public void onFailure(Throwable caught) {
+            TestSetValidator.rethrowException(caught);
+          }
+
+          public void onSuccess(SerializableGenericWrapperType<Void> result) {
+            assertNotNull(result);
+            assertNull(result.getValue());
+            finishTest();
+          }
+        });
+  }
+  
   private void assertEcho(final BigDecimal value) {
     ValueTypesTestServiceAsync service = getServiceAsync();
     delayTestFinishForRpc();
diff --git a/user/test/com/google/gwt/user/client/rpc/ValueTypesTestService.java b/user/test/com/google/gwt/user/client/rpc/ValueTypesTestService.java
index 18f3537..cecbf1b 100644
--- a/user/test/com/google/gwt/user/client/rpc/ValueTypesTestService.java
+++ b/user/test/com/google/gwt/user/client/rpc/ValueTypesTestService.java
@@ -40,6 +40,9 @@
 
   BigInteger echo(BigInteger value);
 
+  SerializableGenericWrapperType<Void> echo(
+      SerializableGenericWrapperType<Void> value);
+
   boolean echo_FALSE(boolean value);
 
   byte echo_MAX_VALUE(byte value);
diff --git a/user/test/com/google/gwt/user/client/rpc/ValueTypesTestServiceAsync.java b/user/test/com/google/gwt/user/client/rpc/ValueTypesTestServiceAsync.java
index 74eaa72..1a79fda 100644
--- a/user/test/com/google/gwt/user/client/rpc/ValueTypesTestServiceAsync.java
+++ b/user/test/com/google/gwt/user/client/rpc/ValueTypesTestServiceAsync.java
@@ -41,6 +41,9 @@
 
   void echo(BigInteger value, AsyncCallback<BigInteger> callback);
 
+  void echo(SerializableGenericWrapperType<Void> value,
+      AsyncCallback<SerializableGenericWrapperType<Void>> callback);
+
   void echo_FALSE(boolean value, AsyncCallback<Boolean> callback);
 
   void echo_MAX_VALUE(byte value, AsyncCallback<Byte> callback);
diff --git a/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
index 2c15ab7..0b5ca20 100644
--- a/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
@@ -408,6 +408,17 @@
     return actual;
   }
 
+  public ArrayList<Void> echoArrayListVoid(ArrayList<Void> value)
+      throws CollectionsTestServiceException {
+    ArrayList<Void> expected = TestSetFactory.createArrayListVoid();
+    if (!TestSetValidator.isValidArrayListVoid(value)) {
+      throw new CollectionsTestServiceException("expected: "
+          + expected.toString() + " actual: " + value.toString());
+    }
+
+    return value;
+  }
+
   public List<MarkerTypeArraysAsList> echoArraysAsList(
       List<MarkerTypeArraysAsList> value)
       throws CollectionsTestServiceException {
diff --git a/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java b/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
index 4ce0e7f..16604ac 100644
--- a/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
+++ b/user/test/com/google/gwt/user/server/rpc/ValueTypesTestServiceImpl.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.server.rpc;
 
+import com.google.gwt.user.client.rpc.SerializableGenericWrapperType;
 import com.google.gwt.user.client.rpc.ValueTypesTestService;
 
 import java.math.BigDecimal;
@@ -65,6 +66,11 @@
     return value;
   }
 
+  public SerializableGenericWrapperType<Void> echo(
+      SerializableGenericWrapperType<Void> value) {
+    return value;
+  }
+
   public boolean echo_FALSE(boolean value) {
     if (value != false) {
       throw new RuntimeException();