Revision: 8394
Author: [email protected]
Date: Tue Jul 20 05:31:21 2010
Log: Allow RPC for unmodifiable collections
Review at http://gwt-code-reviews.appspot.com/620805
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8394
Modified:
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
/trunk/user/super/com/google/gwt/emul/java/util/Collections.java
/trunk/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
/trunk/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java
/trunk/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
/trunk/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
=======================================
---
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
Tue Jun 22 06:26:45 2010
+++
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/Collections.java
Tue Jul 20 05:31:21 2010
@@ -19,9 +19,18 @@
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
/**
* Dummy class for nesting the custom serializer.
@@ -122,4 +131,210 @@
streamWriter.writeObject(instance.get(0));
}
}
-}
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$SingletonMap}.
+ */
+ public static final class SingletonMap_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ Map instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map instantiate(SerializationStreamReader streamReader)
+ throws SerializationException {
+ Object key = streamReader.readObject();
+ Object value = streamReader.readObject();
+ return java.util.Collections.singletonMap(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ Map instance) throws SerializationException {
+ Map.Entry entry = (Map.Entry) instance.entrySet().iterator().next();
+ streamWriter.writeObject(entry.getKey());
+ streamWriter.writeObject(entry.getValue());
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableCollection}.
+ */
+ public static final class UnmodifiableCollection_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ Collection instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Collection instantiate(SerializationStreamReader
streamReader)
+ throws SerializationException {
+ Collection collection = new ArrayList();
+ Collection_CustomFieldSerializerBase.deserialize(streamReader,
collection);
+ return java.util.Collections.unmodifiableCollection(collection);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ Collection instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(streamWriter,
instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableList}.
+ */
+ public static final class UnmodifiableList_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ List instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List instantiate(SerializationStreamReader streamReader)
+ throws SerializationException {
+ ArrayList list = new ArrayList();
+ Collection_CustomFieldSerializerBase.deserialize(streamReader, list);
+ return java.util.Collections.unmodifiableList(list);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ List instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(streamWriter,
instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableMap}.
+ */
+ public static final class UnmodifiableMap_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ Map instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map instantiate(SerializationStreamReader streamReader)
+ throws SerializationException {
+ HashMap map = new HashMap();
+ Map_CustomFieldSerializerBase.deserialize(streamReader, map);
+ return java.util.Collections.unmodifiableMap(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ Map instance) throws SerializationException {
+ Map_CustomFieldSerializerBase.serialize(streamWriter, instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableRandomAccessList}.
+ */
+ public static final class
UnmodifiableRandomAccessList_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ List instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List instantiate(SerializationStreamReader streamReader)
+ throws SerializationException {
+ ArrayList list = new ArrayList();
+ Collection_CustomFieldSerializerBase.deserialize(streamReader, list);
+ return java.util.Collections.unmodifiableList(list);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ List instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(streamWriter,
instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableSet}.
+ */
+ public static final class UnmodifiableSet_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ Set instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Set instantiate(SerializationStreamReader streamReader)
+ throws SerializationException {
+ HashSet set = new HashSet();
+ Collection_CustomFieldSerializerBase.deserialize(streamReader, set);
+ return java.util.Collections.unmodifiableSet(set);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ Set instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(streamWriter,
instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableSortedMap}.
+ */
+ public static final class UnmodifiableSortedMap_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ SortedMap instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static SortedMap instantiate(SerializationStreamReader
streamReader)
+ throws SerializationException {
+ Comparator comparator = (Comparator) streamReader.readObject();
+ TreeMap map = new TreeMap(comparator);
+ Map_CustomFieldSerializerBase.deserialize(streamReader, map);
+ return java.util.Collections.unmodifiableSortedMap(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ SortedMap instance) throws SerializationException {
+ streamWriter.writeObject(instance.comparator());
+ Map_CustomFieldSerializerBase.serialize(streamWriter, instance);
+ }
+ }
+
+ /**
+ * Custom field serializer for {...@link
java.util.Collections$UnmodifiableSortedSet}.
+ */
+ public static final class UnmodifiableSortedSet_CustomFieldSerializer {
+
+ @SuppressWarnings({"unused", "unchecked"})
+ public static void deserialize(SerializationStreamReader streamReader,
+ SortedSet instance) throws SerializationException {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static SortedSet instantiate(SerializationStreamReader
streamReader)
+ throws SerializationException {
+ Comparator comparator = (Comparator) streamReader.readObject();
+ TreeSet set = new TreeSet(comparator);
+ Collection_CustomFieldSerializerBase.deserialize(streamReader, set);
+ return java.util.Collections.unmodifiableSortedSet(set);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void serialize(SerializationStreamWriter streamWriter,
+ SortedSet instance) throws SerializationException {
+ streamWriter.writeObject(instance.comparator());
+ Collection_CustomFieldSerializerBase.serialize(streamWriter,
instance);
+ }
+ }
+}
=======================================
---
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
Wed Oct 28 09:10:53 2009
+++
/trunk/user/src/com/google/gwt/user/client/rpc/core/java/util/TreeSet_CustomFieldSerializer.java
Tue Jul 20 05:31:21 2010
@@ -23,7 +23,7 @@
import java.util.TreeSet;
/**
- * Custom field serializer for {...@link java.util.TreeMap}.
+ * Custom field serializer for {...@link java.util.TreeSet}.
*/
@SuppressWarnings("unchecked")
public class TreeSet_CustomFieldSerializer {
=======================================
--- /trunk/user/super/com/google/gwt/emul/java/util/Collections.java Mon
Apr 19 10:54:02 2010
+++ /trunk/user/super/com/google/gwt/emul/java/util/Collections.java Tue
Jul 20 05:31:21 2010
@@ -134,12 +134,122 @@
}
}
- /*
- * TODO: make the unmodifiable collections serializable.
+ /**
+ * A Map containing exactly one key/value pair, used to implement
+ * the singletonMap(K key, V value) method. The map is unmodifiable
+ * and attempt to modify it directly, by iterators, or using the
+ * sets returned from keySet(), entrySet(), or values() will fail
+ * with an UnsupportedOperationException. Null keys and values are
+ * allowed.
*/
+ private static final class SingletonMap<K, V> extends AbstractMap<K, V>
implements Serializable {
+ Set<Map.Entry<K, V>> entrySet = null;
+ final K key;
+ Set<K> keySet = null;
+ final V value;
+ Set<V> valueSet = null;
+
+ public SingletonMap(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean containsKey(Object key) {
+ return Utility.equalsWithNullCheck(this.key, key);
+ }
+
+ public boolean containsValue(Object value) {
+ return Utility.equalsWithNullCheck(this.value, value);
+ }
+
+ public Set<Map.Entry<K, V>> entrySet() {
+ if (entrySet == null) {
+ HashSet set = new HashSet();
+ set.add(new AbstractMapEntry<K, V>() {
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V value) {
+ throw new UnsupportedOperationException();
+ }
+ });
+ entrySet = unmodifiableSet(set);
+ }
+ return entrySet;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Map)) {
+ return false;
+ }
+ Map other = (Map) o;
+ return other.size() == 1
+ && other.containsKey(key)
+ && Utility.equalsWithNullCheck(other.get(key), value);
+ }
+
+ public V get(Object key) {
+ return Utility.equalsWithNullCheck(this.key, key) ? value : null;
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ public Set<K> keySet() {
+ if (keySet == null) {
+ HashSet<K> set = new HashSet<K>();
+ set.add(key);
+ keySet = unmodifiableSet(set);
+ }
+ return keySet;
+ }
+
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void putAll(Map<? extends K, ? extends V> t) {
+ if (t.size() > 0) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public V remove(Object key) {
+ if (Utility.equalsWithNullCheck(this.key, key)) {
+ throw new UnsupportedOperationException();
+ }
+ return null;
+ }
+
+ public int size() {
+ return 1;
+ }
+
+ public Collection<V> values() {
+ if (valueSet == null) {
+ HashSet<V> set = new HashSet<V>();
+ set.add(value);
+ valueSet = unmodifiableSet(set);
+ }
+ return valueSet;
+ }
+ }
static class UnmodifiableCollection<T> implements Collection<T> {
- protected final Collection<? extends T> coll;
+ protected Collection<? extends T> coll;
+
+ public UnmodifiableCollection() {
+ }
public UnmodifiableCollection(Collection<? extends T> coll) {
this.coll = coll;
@@ -203,8 +313,11 @@
}
static class UnmodifiableList<T> extends UnmodifiableCollection<T>
implements
- List<T> {
- private final List<? extends T> list;
+ List<T>, Serializable {
+ private List<? extends T> list;
+
+ public UnmodifiableList() {
+ }
public UnmodifiableList(List<? extends T> list) {
super(list);
@@ -267,7 +380,7 @@
}
}
- static class UnmodifiableMap<K, V> implements Map<K, V> {
+ static class UnmodifiableMap<K, V> implements Map<K, V>, Serializable {
static class UnmodifiableEntrySet<K, V> extends
UnmodifiableSet<Map.Entry<K, V>> {
@@ -373,9 +486,12 @@
private transient UnmodifiableSet<Map.Entry<K, V>> entrySet;
private transient UnmodifiableSet<K> keySet;
- private final Map<? extends K, ? extends V> map;
+ private Map<? extends K, ? extends V> map;
private transient UnmodifiableCollection<V> values;
+ public UnmodifiableMap() {
+ }
+
public UnmodifiableMap(Map<? extends K, ? extends V> map) {
this.map = map;
}
@@ -454,14 +570,22 @@
}
static class UnmodifiableRandomAccessList<T> extends UnmodifiableList<T>
- implements RandomAccess {
+ implements RandomAccess, Serializable {
+
+ public UnmodifiableRandomAccessList() {
+ }
+
public UnmodifiableRandomAccessList(List<? extends T> list) {
super(list);
}
}
static class UnmodifiableSet<T> extends UnmodifiableCollection<T>
implements
- Set<T> {
+ Set<T>, Serializable {
+
+ public UnmodifiableSet() {
+ }
+
public UnmodifiableSet(Set<? extends T> set) {
super(set);
}
@@ -478,10 +602,13 @@
}
static class UnmodifiableSortedMap<K, V> extends UnmodifiableMap<K, V>
- implements SortedMap<K, V> {
+ implements SortedMap<K, V>, Serializable {
private SortedMap<K, ? extends V> sortedMap;
+ public UnmodifiableSortedMap() {
+ }
+
public UnmodifiableSortedMap(SortedMap<K, ? extends V> sortedMap) {
super(sortedMap);
this.sortedMap = sortedMap;
@@ -523,9 +650,12 @@
}
static class UnmodifiableSortedSet<E> extends UnmodifiableSet<E>
implements
- SortedSet<E> {
+ SortedSet<E>, Serializable {
private SortedSet<E> sortedSet;
+ public UnmodifiableSortedSet() {
+ }
+
@SuppressWarnings("unchecked")
public UnmodifiableSortedSet(SortedSet<? extends E> sortedSet) {
super(sortedSet);
@@ -939,9 +1069,7 @@
}
public static <K, V> Map<K, V> singletonMap(K key, V value) {
- Map<K, V> map = new HashMap<K, V>(1);
- map.put(key, value);
- return unmodifiableMap(map);
+ return new SingletonMap<K, V>(key, value);
}
public static <T> void sort(List<T> target) {
=======================================
--- /trunk/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
Thu Dec 17 20:58:44 2009
+++ /trunk/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
Tue Jul 20 05:31:21 2010
@@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -155,6 +156,116 @@
Collections.reverse(b);
assertEquals(b, createRandomList());
}
+
+ public void testSingletonMap() {
+ Map<String, Integer> map = Collections.singletonMap("two", 2);
+ assertEquals(1, map.size());
+ assertFalse(map.isEmpty());
+ assertEquals(Integer.valueOf(2), map.get("two"));
+ assertTrue(map.containsKey("two"));
+ assertFalse(map.containsKey("three"));
+ assertTrue(map.containsValue(2));
+ assertFalse(map.containsValue(3));
+
+ try {
+ map.clear();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ try {
+ map.put("three", 3);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ try {
+ HashMap<String, Integer> m = new HashMap<String, Integer>();
+ map.putAll(m);
+ } catch (UnsupportedOperationException e) {
+ fail();
+ }
+
+ try {
+ HashMap<String, Integer> m = new HashMap<String, Integer>();
+ m.put("three", 3);
+ map.putAll(m);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ try {
+ map.remove("three");
+ } catch (UnsupportedOperationException e) {
+ fail();
+ }
+
+ try {
+ map.remove("two");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ // Test equals, hashCode, keySet, entrySet and values against a
+ // HashMap
+ HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
+ hashMap.put("two", 2);
+ assertEquals(hashMap, map);
+ assertEquals(hashMap.hashCode(), map.hashCode());
+ assertEquals(hashMap.keySet(), map.keySet());
+ assertEquals(hashMap.entrySet(), map.entrySet());
+
+ Collection<Integer> values = map.values();
+ assertNotNull(values);
+ assertEquals(1, values.size());
+ assertEquals(Integer.valueOf(2), values.iterator().next());
+ try {
+ values.add(3);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ // null key
+ map = Collections.singletonMap(null, 2);
+ assertEquals(1, map.size());
+ assertFalse(map.isEmpty());
+ assertEquals(Integer.valueOf(2), map.get(null));
+ assertTrue(map.containsKey(null));
+ assertFalse(map.containsKey("three"));
+ assertTrue(map.containsValue(2));
+ assertFalse(map.containsValue(3));
+
+ // null value
+ map = Collections.singletonMap("null", null);
+ assertEquals(1, map.size());
+ assertFalse(map.isEmpty());
+ assertNull(map.get("null"));
+ assertTrue(map.containsKey("null"));
+ assertFalse(map.containsKey("three"));
+ assertTrue(map.containsValue(null));
+ assertFalse(map.containsValue(3));
+
+ // null key and value
+ map = Collections.singletonMap(null, null);
+ assertEquals(1, map.size());
+ assertFalse(map.isEmpty());
+ assertNull(map.get(null));
+ assertTrue(map.containsKey(null));
+ assertFalse(map.containsKey("three"));
+ assertTrue(map.containsValue(null));
+ assertFalse(map.containsValue(3));
+
+ // Equality for maps with a null value
+ Map<Integer, String> map2 =
Collections.singletonMap(Integer.valueOf(2), null);
+ HashMap<Integer, String> hashMap2 = new HashMap<Integer, String>();
+ assertFalse(map2.equals(hashMap2));
+ hashMap2.put(Integer.valueOf(1), null);
+ assertFalse(map2.equals(hashMap2));
+ hashMap2.put(Integer.valueOf(2), null);
+ assertFalse(map2.equals(hashMap2));
+ hashMap2.remove(Integer.valueOf(1));
+ assertTrue(map2.equals(hashMap2));
+ }
public void testSort() {
List<String> a = createSortedList();
=======================================
--- /trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
Mon Apr 19 10:54:02 2010
+++ /trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTest.java
Tue Jul 20 05:31:21 2010
@@ -25,12 +25,14 @@
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeSingleton;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeMap;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeSet;
+import
com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeUnmodifiable;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeVector;
import
com.google.gwt.user.client.rpc.core.java.util.LinkedHashMap_CustomFieldSerializer;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -581,6 +583,23 @@
}
});
}
+
+ public void testSingletonMap() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+ service.echoSingletonMap(TestSetFactory.createSingletonMap(),
+ new AsyncCallback<Map<Integer, MarkerTypeSingleton>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Map<Integer, MarkerTypeSingleton> result) {
+ assertNotNull(result);
+ assertTrue(TestSetValidator.isValidSingletonMap(result));
+ finishTest();
+ }
+ });
+ }
public void testSqlDateArray() {
CollectionsTestServiceAsync service = getServiceAsync();
@@ -706,6 +725,125 @@
});
}
}
+
+ public void testUnmodifiableCollection() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+
service.echoUnmodifiableCollection(TestSetFactory.createUnmodifiableCollection(),
+ new AsyncCallback<Collection<MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Collection<MarkerTypeUnmodifiable> result)
{
+ assertNotNull(result);
+
assertTrue(TestSetValidator.isValidUnmodifiableCollection(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableList() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+ service.echoUnmodifiableList(TestSetFactory.createUnmodifiableList(),
+ new AsyncCallback<List<MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(List<MarkerTypeUnmodifiable> result) {
+ assertNotNull(result);
+ assertTrue(TestSetValidator.isValidUnmodifiableList(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableMap() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+ service.echoUnmodifiableMap(TestSetFactory.createUnmodifiableMap(),
+ new AsyncCallback<Map<Integer, MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Map<Integer, MarkerTypeUnmodifiable>
result) {
+ assertNotNull(result);
+ assertTrue(TestSetValidator.isValidUnmodifiableMap(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableRandomAccessList() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+
service.echoUnmodifiableList(TestSetFactory.createUnmodifiableRandomAccessList(),
+ new AsyncCallback<List<MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(List<MarkerTypeUnmodifiable> result) {
+ assertNotNull(result);
+
assertTrue(TestSetValidator.isValidUnmodifiableRandomAccessList(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableSet() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+ service.echoUnmodifiableSet(TestSetFactory.createUnmodifiableSet(),
+ new AsyncCallback<Set<MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Set<MarkerTypeUnmodifiable> result) {
+ assertNotNull(result);
+ assertTrue(TestSetValidator.isValidUnmodifiableSet(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableSortedMap() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+
service.echoUnmodifiableMap(TestSetFactory.createUnmodifiableSortedMap(),
+ new AsyncCallback<Map<Integer, MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Map<Integer, MarkerTypeUnmodifiable>
result) {
+ assertNotNull(result);
+
assertTrue(TestSetValidator.isValidUnmodifiableSortedMap(result));
+ finishTest();
+ }
+ });
+ }
+
+ public void testUnmodifiableSortedSet() {
+ CollectionsTestServiceAsync service = getServiceAsync();
+ delayTestFinishForRpc();
+
service.echoUnmodifiableSet(TestSetFactory.createUnmodifiableSortedSet(),
+ new AsyncCallback<Set<MarkerTypeUnmodifiable>>() {
+ public void onFailure(Throwable caught) {
+ TestSetValidator.rethrowException(caught);
+ }
+
+ public void onSuccess(Set<MarkerTypeUnmodifiable> result) {
+ assertNotNull(result);
+
assertTrue(TestSetValidator.isValidUnmodifiableSortedSet(result));
+ finishTest();
+ }
+ });
+ }
public void testVector() {
CollectionsTestServiceAsync service = getServiceAsync();
=======================================
---
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
Mon Apr 19 10:54:02 2010
+++
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestService.java
Tue Jul 20 05:31:21 2010
@@ -25,11 +25,13 @@
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeSingleton;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeMap;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeSet;
+import
com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeUnmodifiable;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeVector;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -156,4 +158,25 @@
// For Collections.singletonList()
List<MarkerTypeSingleton> echoSingletonList(List<MarkerTypeSingleton>
value)
throws CollectionsTestServiceException;
-}
+
+ // For Collections.singletonMap()
+ Map<Integer, MarkerTypeSingleton> echoSingletonMap(Map<Integer,
MarkerTypeSingleton> value)
+ throws CollectionsTestServiceException;
+
+ // For Collections.unmodifiableCollection()
+ Collection<MarkerTypeUnmodifiable>
echoUnmodifiableCollection(Collection<MarkerTypeUnmodifiable> value)
+ throws CollectionsTestServiceException;
+
+ // For Collections.unmodifiableList()
+ List<MarkerTypeUnmodifiable>
echoUnmodifiableList(List<MarkerTypeUnmodifiable> value)
+ throws CollectionsTestServiceException;
+
+ // For Collections.unmodifiableMap()
+ Map<Integer, MarkerTypeUnmodifiable> echoUnmodifiableMap(
+ Map<Integer, MarkerTypeUnmodifiable> value)
+ throws CollectionsTestServiceException;
+
+ // For Collections.unmodifiableSet()
+ Set<MarkerTypeUnmodifiable>
echoUnmodifiableSet(Set<MarkerTypeUnmodifiable> value)
+ throws CollectionsTestServiceException;
+}
=======================================
---
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
Mon Apr 19 10:54:02 2010
+++
/trunk/user/test/com/google/gwt/user/client/rpc/CollectionsTestServiceAsync.java
Tue Jul 20 05:31:21 2010
@@ -25,11 +25,13 @@
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeSingleton;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeMap;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeSet;
+import
com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeUnmodifiable;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeVector;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -137,4 +139,24 @@
// For Collections.singletonList()
void echoSingletonList(List<MarkerTypeSingleton> value,
AsyncCallback<List<MarkerTypeSingleton>> callback);
-}
+
+ // For Collections.singletonMap()
+ void echoSingletonMap(Map<Integer, MarkerTypeSingleton> value,
+ AsyncCallback<Map<Integer, MarkerTypeSingleton>> callback);
+
+ // For Collections.unmodifiableCollection()
+ void echoUnmodifiableCollection(Collection<MarkerTypeUnmodifiable> value,
+ AsyncCallback<Collection<MarkerTypeUnmodifiable>> callback);
+
+ // For Collections.unmodifiableList()
+ void echoUnmodifiableList(List<MarkerTypeUnmodifiable> value,
+ AsyncCallback<List<MarkerTypeUnmodifiable>> callback);
+
+ // For Collections.unmodifiableMap()
+ void echoUnmodifiableMap(Map<Integer, MarkerTypeUnmodifiable> value,
+ AsyncCallback<Map<Integer, MarkerTypeUnmodifiable>> callback);
+
+ // For Collections.unmodifiableSet()
+ void echoUnmodifiableSet(Set<MarkerTypeUnmodifiable> value,
+ AsyncCallback<Set<MarkerTypeUnmodifiable>> callback);
+}
=======================================
--- /trunk/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java Mon
Jun 7 09:38:44 2010
+++ /trunk/user/test/com/google/gwt/user/client/rpc/TestSetFactory.java Tue
Jul 20 05:31:21 2010
@@ -20,15 +20,19 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
@@ -190,6 +194,16 @@
super("singleton");
}
}
+
+ /**
+ * A single-use marker type to independently check type parameter
exposure in
+ * unmodifiable collections.
+ */
+ public static final class MarkerTypeUnmodifiable extends MarkerBase {
+ MarkerTypeUnmodifiable() {
+ super("unmodifiable");
+ }
+ }
/**
* A single-use marker type to independently check type parameter
exposure in
@@ -587,6 +601,10 @@
public static List<MarkerTypeSingleton> createSingletonList() {
return java.util.Collections.singletonList(new MarkerTypeSingleton());
}
+
+ public static Map<Integer, MarkerTypeSingleton> createSingletonMap() {
+ return java.util.Collections.singletonMap(2, new
MarkerTypeSingleton());
+ }
public static java.sql.Date[] createSqlDateArray() {
return new java.sql.Date[] {
@@ -643,6 +661,50 @@
set.add(new MarkerTypeTreeSet("w00t"));
return set;
}
+
+ public static Collection<MarkerTypeUnmodifiable>
createUnmodifiableCollection() {
+ List<MarkerTypeUnmodifiable> list = new
LinkedList<MarkerTypeUnmodifiable>();
+ list.add(new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableCollection(list);
+ }
+
+ public static List<MarkerTypeUnmodifiable> createUnmodifiableList() {
+ List<MarkerTypeUnmodifiable> list = new
LinkedList<MarkerTypeUnmodifiable>();
+ list.add(new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableList(list);
+ }
+
+ public static Map<Integer, MarkerTypeUnmodifiable>
createUnmodifiableMap() {
+ Map<Integer, MarkerTypeUnmodifiable> map =
+ new HashMap<Integer, MarkerTypeUnmodifiable>();
+ map.put(1, new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableMap(map);
+ }
+
+ public static Map<Integer, MarkerTypeUnmodifiable>
createUnmodifiableSortedMap() {
+ SortedMap<Integer, MarkerTypeUnmodifiable> map =
+ new TreeMap<Integer, MarkerTypeUnmodifiable>();
+ map.put(1, new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableSortedMap(map);
+ }
+
+ public static List<MarkerTypeUnmodifiable>
createUnmodifiableRandomAccessList() {
+ List<MarkerTypeUnmodifiable> list = new
ArrayList<MarkerTypeUnmodifiable>();
+ list.add(new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableList(list);
+ }
+
+ public static Set<MarkerTypeUnmodifiable> createUnmodifiableSet() {
+ Set<MarkerTypeUnmodifiable> set = new
HashSet<MarkerTypeUnmodifiable>();
+ set.add(new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableSet(set);
+ }
+
+ public static Set<MarkerTypeUnmodifiable> createUnmodifiableSortedSet() {
+ SortedSet<MarkerTypeUnmodifiable> set = new
TreeSet<MarkerTypeUnmodifiable>();
+ set.add(new MarkerTypeUnmodifiable());
+ return java.util.Collections.unmodifiableSortedSet(set);
+ }
public static Vector<MarkerTypeVector> createVector() {
Vector<MarkerTypeVector> vector = new Vector<MarkerTypeVector>();
=======================================
--- /trunk/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
Mon Apr 19 10:54:02 2010
+++ /trunk/user/test/com/google/gwt/user/client/rpc/TestSetValidator.java
Tue Jul 20 05:31:21 2010
@@ -19,6 +19,7 @@
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeSingleton;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeMap;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeSet;
+import
com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeUnmodifiable;
import
com.google.gwt.user.client.rpc.TestSetFactory.SerializableDoublyLinkedNode;
import
com.google.gwt.user.client.rpc.TestSetFactory.SerializableGraphWithCFS;
import
com.google.gwt.user.client.rpc.TestSetFactory.SerializablePrivateNoArg;
@@ -30,6 +31,7 @@
import static junit.framework.Assert.assertSame;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -37,7 +39,10 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.RandomAccess;
import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
@@ -550,6 +555,27 @@
}
return true;
}
+
+ public static boolean isValidSingletonMap(Map<Integer,
MarkerTypeSingleton> map) {
+ if (map == null || map.size() != 1) {
+ return false;
+ }
+ try {
+ map.put(3, new MarkerTypeSingleton());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+ Object value = map.get(2);
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeSingleton)) {
+ return false;
+ }
+ MarkerTypeSingleton singleton = (MarkerTypeSingleton) value;
+ if (!"singleton".equals(singleton.getValue())) {
+ return false;
+ }
+ return true;
+ }
public static boolean isValidTrivialCyclicGraph(
SerializableDoublyLinkedNode actual) {
@@ -577,6 +603,169 @@
return true;
}
+
+ public static boolean
isValidUnmodifiableCollection(Collection<MarkerTypeUnmodifiable>
collection) {
+ if (collection == null || collection.size() != 1) {
+ return false;
+ }
+ try {
+ collection.add(new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = collection.iterator().next();
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean
isValidUnmodifiableList(List<MarkerTypeUnmodifiable> list) {
+ if (list == null || list.size() != 1) {
+ return false;
+ }
+ try {
+ list.add(new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = list.get(0);
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isValidUnmodifiableMap(Map<Integer,
MarkerTypeUnmodifiable> map) {
+ if (map == null || map.size() != 1) {
+ return false;
+ }
+ try {
+ map.put(2, new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = map.get(1);
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean
isValidUnmodifiableRandomAccessList(List<MarkerTypeUnmodifiable> list) {
+ if (list == null || list.size() != 1) {
+ return false;
+ }
+ if (!(list instanceof RandomAccess)) {
+ return false;
+ }
+ try {
+ list.add(new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = list.get(0);
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isValidUnmodifiableSet(Set<MarkerTypeUnmodifiable>
set) {
+ if (set == null || set.size() != 1) {
+ return false;
+ }
+ try {
+ set.add(new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = set.iterator().next();
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isValidUnmodifiableSortedMap(Map<Integer,
MarkerTypeUnmodifiable> map) {
+ if (map == null || map.size() != 1) {
+ return false;
+ }
+ if (!(map instanceof SortedMap<?, ?>)) {
+ return false;
+ }
+ try {
+ map.put(2, new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = map.get(1);
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean
isValidUnmodifiableSortedSet(Set<MarkerTypeUnmodifiable> set) {
+ if (set == null || set.size() != 1) {
+ return false;
+ }
+ if (!(set instanceof SortedSet<?>)) {
+ return false;
+ }
+ try {
+ set.add(new MarkerTypeUnmodifiable());
+ return false;
+ } catch (UnsupportedOperationException e) {
+ }
+
+ Object value = set.iterator().next();
+ // Perform instanceof check in case RPC did the wrong thing
+ if (!(value instanceof MarkerTypeUnmodifiable)) {
+ return false;
+ }
+ MarkerTypeUnmodifiable v = (MarkerTypeUnmodifiable) value;
+ if (!"unmodifiable".equals(v.getValue())) {
+ return false;
+ }
+ return true;
+ }
/**
* Wrap an exception in RuntimeException if necessary so it doesn't have
to be
=======================================
---
/trunk/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
Mon Apr 19 10:54:02 2010
+++
/trunk/user/test/com/google/gwt/user/server/rpc/CollectionsTestServiceImpl.java
Tue Jul 20 05:31:21 2010
@@ -28,12 +28,14 @@
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeSingleton;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeMap;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeTreeSet;
+import
com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeUnmodifiable;
import com.google.gwt.user.client.rpc.TestSetFactory.MarkerTypeVector;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -435,6 +437,51 @@
if (!TestSetValidator.isValidSingletonList(value)) {
throw new CollectionsTestServiceException();
}
+
+ return value;
+ }
+
+ public Map<Integer, MarkerTypeSingleton> echoSingletonMap(
+ Map<Integer, MarkerTypeSingleton> value) throws
CollectionsTestServiceException {
+ if (!TestSetValidator.isValidSingletonMap(value)) {
+ throw new CollectionsTestServiceException();
+ }
+
+ return value;
+ }
+
+ public Collection<MarkerTypeUnmodifiable> echoUnmodifiableCollection(
+ Collection<MarkerTypeUnmodifiable> value) throws
CollectionsTestServiceException {
+ if (!TestSetValidator.isValidUnmodifiableCollection(value)) {
+ throw new CollectionsTestServiceException();
+ }
+
+ return value;
+ }
+
+ public List<MarkerTypeUnmodifiable> echoUnmodifiableList(
+ List<MarkerTypeUnmodifiable> value) throws
CollectionsTestServiceException {
+ if (!TestSetValidator.isValidUnmodifiableList(value)) {
+ throw new CollectionsTestServiceException();
+ }
+
+ return value;
+ }
+
+ public Map<Integer, MarkerTypeUnmodifiable> echoUnmodifiableMap(
+ Map<Integer, MarkerTypeUnmodifiable> value) throws
CollectionsTestServiceException {
+ if (!TestSetValidator.isValidUnmodifiableMap(value)) {
+ throw new CollectionsTestServiceException();
+ }
+
+ return value;
+ }
+
+ public Set<MarkerTypeUnmodifiable> echoUnmodifiableSet(
+ Set<MarkerTypeUnmodifiable> value) throws
CollectionsTestServiceException {
+ if (!TestSetValidator.isValidUnmodifiableSet(value)) {
+ throw new CollectionsTestServiceException();
+ }
return value;
}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors