1 /* 2 * Copyright (C) 2009 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS-IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import com.google.common.annotations.GwtCompatible; 20 import java.io.Serializable; 21 import java.util.Comparator; 22 import java.util.HashMap; 23 import java.util.TreeMap; 24 25 /** 26 * Contains dummy collection implementations to convince GWT that part of serializing a collection 27 * is serializing its elements. 28 * 29 * <p>Because of our use of final fields in our collections, GWT's normal heuristic for determining 30 * which classes might be serialized fails. That heuristic is, roughly speaking, to look at each 31 * parameter and return type of each RPC interface and to assume that implementations of those types 32 * might be serialized. Those types have their own dependencies -- their fields -- which are 33 * analyzed recursively and analogously. 34 * 35 * <p>For classes with final fields, GWT assumes that the class itself might be serialized but 36 * doesn't assume the same about its final fields. To work around this, we provide dummy 37 * implementations of our collections with their dependencies as non-final fields. Even though these 38 * implementations are never instantiated, they are visible to GWT when it performs its 39 * serialization analysis, and it assumes that their fields may be serialized. 40 * 41 * <p>Currently we provide dummy implementations of all the immutable collection classes necessary 42 * to support declarations like {@code ImmutableMultiset<String>} in RPC interfaces. Support for 43 * {@code ImmutableMultiset} in the interface is support for {@code Multiset}, so there is nothing 44 * further to be done to support the new collection interfaces. It is not support, however, for an 45 * RPC interface in terms of {@code HashMultiset}. It is still possible to send a {@code 46 * HashMultiset} over GWT RPC; it is only the declaration of an interface in terms of {@code 47 * HashMultiset} that we haven't tried to support. (We may wish to revisit this decision in the 48 * future.) 49 * 50 * @author Chris Povirk 51 */ 52 @GwtCompatible 53 // None of these classes are instantiated, let alone serialized: 54 @SuppressWarnings("serial") 55 final class GwtSerializationDependencies { GwtSerializationDependencies()56 private GwtSerializationDependencies() {} 57 58 static final class ImmutableListMultimapDependencies<K, V> extends ImmutableListMultimap<K, V> { 59 K key; 60 V value; 61 ImmutableListMultimapDependencies()62 ImmutableListMultimapDependencies() { 63 super(null, 0); 64 } 65 } 66 67 // ImmutableMap is covered by ImmutableSortedMap/ImmutableBiMap. 68 69 // ImmutableMultimap is covered by ImmutableSetMultimap/ImmutableListMultimap. 70 71 static final class ImmutableSetMultimapDependencies<K, V> extends ImmutableSetMultimap<K, V> { 72 K key; 73 V value; 74 ImmutableSetMultimapDependencies()75 ImmutableSetMultimapDependencies() { 76 super(null, 0, null); 77 } 78 } 79 80 /* 81 * We support an interface declared in terms of LinkedListMultimap because it 82 * supports entry ordering not supported by other implementations. 83 */ 84 static final class LinkedListMultimapDependencies<K, V> extends LinkedListMultimap<K, V> { 85 K key; 86 V value; 87 LinkedListMultimapDependencies()88 LinkedListMultimapDependencies() {} 89 } 90 91 static final class HashBasedTableDependencies<R, C, V> extends HashBasedTable<R, C, V> { 92 HashMap<R, HashMap<C, V>> data; 93 HashBasedTableDependencies()94 HashBasedTableDependencies() { 95 super(null, null); 96 } 97 } 98 99 static final class TreeBasedTableDependencies<R, C, V> extends TreeBasedTable<R, C, V> { 100 TreeMap<R, TreeMap<C, V>> data; 101 TreeBasedTableDependencies()102 TreeBasedTableDependencies() { 103 super(null, null); 104 } 105 } 106 107 /* 108 * We don't normally need "implements Serializable," but we do here. That's 109 * because ImmutableTable itself is not Serializable as of this writing. We 110 * need for GWT to believe that this dummy class is serializable, or else it 111 * won't generate serialization code for R, C, and V. 112 */ 113 static final class ImmutableTableDependencies<R, C, V> extends SingletonImmutableTable<R, C, V> 114 implements Serializable { 115 R rowKey; 116 C columnKey; 117 V value; 118 ImmutableTableDependencies()119 ImmutableTableDependencies() { 120 super(null, null, null); 121 } 122 } 123 124 static final class TreeMultimapDependencies<K, V> extends TreeMultimap<K, V> { 125 Comparator<? super K> keyComparator; 126 Comparator<? super V> valueComparator; 127 K key; 128 V value; 129 TreeMultimapDependencies()130 TreeMultimapDependencies() { 131 super(null, null); 132 } 133 } 134 } 135