Home | History | Annotate | Download | only in collect
      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 
     21 import java.io.Serializable;
     22 import java.util.Comparator;
     23 import java.util.HashMap;
     24 import java.util.TreeMap;
     25 
     26 /**
     27  * Contains dummy collection implementations to convince GWT that part of
     28  * serializing a collection is serializing its elements.
     29  *
     30  * <p>Because of our use of final fields in our collections, GWT's normal
     31  * heuristic for determining which classes might be serialized fails. That
     32  * heuristic is, roughly speaking, to look at each parameter and return type of
     33  * each RPC interface and to assume that implementations of those types might be
     34  * serialized. Those types have their own dependencies -- their fields -- which
     35  * are analyzed recursively and analogously.
     36  *
     37  * <p>For classes with final fields, GWT assumes that the class itself might be
     38  * serialized but doesn't assume the same about its final fields. To work around
     39  * this, we provide dummy implementations of our collections with their
     40  * dependencies as non-final fields. Even though these implementations are never
     41  * instantiated, they are visible to GWT when it performs its serialization
     42  * analysis, and it assumes that their fields may be serialized.
     43  *
     44  * <p>Currently we provide dummy implementations of all the immutable
     45  * collection classes necessary to support declarations like
     46  * {@code ImmutableMultiset<String>} in RPC interfaces. Support for
     47  * {@code ImmutableMultiset} in the interface is support for {@code Multiset},
     48  * so there is nothing further to be done to support the new collection
     49  * interfaces. It is not support, however, for an RPC interface in terms of
     50  * {@code HashMultiset}. It is still possible to send a {@code HashMultiset}
     51  * over GWT RPC; it is only the declaration of an interface in terms of
     52  * {@code HashMultiset} that we haven't tried to support. (We may wish to
     53  * revisit this decision in the future.)
     54  *
     55  * @author Chris Povirk
     56  */
     57 @GwtCompatible
     58 // None of these classes are instantiated, let alone serialized:
     59 @SuppressWarnings("serial")
     60 final class GwtSerializationDependencies {
     61   private GwtSerializationDependencies() {}
     62 
     63   static final class ImmutableListMultimapDependencies<K, V>
     64       extends ImmutableListMultimap<K, V> {
     65     K key;
     66     V value;
     67 
     68     ImmutableListMultimapDependencies() {
     69       super(null, 0);
     70     }
     71   }
     72 
     73   // ImmutableMap is covered by ImmutableSortedMap/ImmutableBiMap.
     74 
     75   // ImmutableMultimap is covered by ImmutableSetMultimap/ImmutableListMultimap.
     76 
     77   static final class ImmutableSetMultimapDependencies<K, V>
     78       extends ImmutableSetMultimap<K, V> {
     79     K key;
     80     V value;
     81 
     82     ImmutableSetMultimapDependencies() {
     83       super(null, 0, null);
     84     }
     85   }
     86 
     87   /*
     88    * We support an interface declared in terms of LinkedListMultimap because it
     89    * supports entry ordering not supported by other implementations.
     90    */
     91   static final class LinkedListMultimapDependencies<K, V>
     92       extends LinkedListMultimap<K, V> {
     93     K key;
     94     V value;
     95 
     96     LinkedListMultimapDependencies() {}
     97   }
     98 
     99   static final class HashBasedTableDependencies<R, C, V>
    100       extends HashBasedTable<R, C, V> {
    101     HashMap<R, HashMap<C, V>> data;
    102 
    103     HashBasedTableDependencies() {
    104       super(null, null);
    105     }
    106   }
    107 
    108   static final class TreeBasedTableDependencies<R, C, V>
    109       extends TreeBasedTable<R, C, V> {
    110     TreeMap<R, TreeMap<C, V>> data;
    111 
    112     TreeBasedTableDependencies() {
    113       super(null, null);
    114     }
    115   }
    116 
    117   /*
    118    * We don't normally need "implements Serializable," but we do here. That's
    119    * because ImmutableTable itself is not Serializable as of this writing. We
    120    * need for GWT to believe that this dummy class is serializable, or else it
    121    * won't generate serialization code for R, C, and V.
    122    */
    123   static final class ImmutableTableDependencies<R, C, V>
    124       extends SingletonImmutableTable<R, C, V> implements Serializable {
    125     R rowKey;
    126     C columnKey;
    127     V value;
    128 
    129     ImmutableTableDependencies() {
    130       super(null, null, null);
    131     }
    132   }
    133 
    134   static final class TreeMultimapDependencies<K, V>
    135       extends TreeMultimap<K, V> {
    136     Comparator<? super K> keyComparator;
    137     Comparator<? super V> valueComparator;
    138     K key;
    139     V value;
    140 
    141     TreeMultimapDependencies() {
    142       super(null, null);
    143     }
    144   }
    145 }
    146