001    /*
002     * Copyright (C) 2007 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.collect;
018    
019    import com.google.common.annotations.Beta;
020    import com.google.common.annotations.GwtCompatible;
021    import com.google.common.base.Objects;
022    
023    import java.util.Collection;
024    import java.util.Iterator;
025    import java.util.Map;
026    import java.util.Set;
027    
028    import javax.annotation.Nullable;
029    
030    /**
031     * A map which forwards all its method calls to another map. Subclasses should
032     * override one or more methods to modify the behavior of the backing map as
033     * desired per the <a
034     * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
035     *
036     * <p><i>Warning:</i> The methods of {@code ForwardingMap} forward
037     * <i>indiscriminately</i> to the methods of the delegate. For example,
038     * overriding {@link #put} alone <i>will not</i> change the behavior of {@link
039     * #putAll}, which can lead to unexpected behavior. In this case, you should
040     * override {@code putAll} as well, either providing your own implementation, or
041     * delegating to the provided {@code standardPutAll} method.
042     *
043     * <p>Each of the {@code standard} methods, where appropriate, use {@link
044     * Objects#equal} to test equality for both keys and values. This may not be
045     * the desired behavior for map implementations that use non-standard notions of
046     * key equality, such as a {@code SortedMap} whose comparator is not consistent
047     * with {@code equals}.
048     *
049     * <p>The {@code standard} methods and the collection views they return are not
050     * guaranteed to be thread-safe, even when all of the methods that they depend
051     * on are thread-safe.
052     *
053     * @author Kevin Bourrillion
054     * @author Jared Levy
055     * @author Louis Wasserman
056     * @since 2.0 (imported from Google Collections Library)
057     */
058    @GwtCompatible
059    public abstract class ForwardingMap<K, V> extends ForwardingObject
060        implements Map<K, V> {
061      // TODO(user): identify places where thread safety is actually lost
062    
063      /** Constructor for use by subclasses. */
064      protected ForwardingMap() {}
065    
066      
067      @Override
068      protected abstract Map<K, V> delegate();
069    
070      public int size() {
071        return delegate().size();
072      }
073    
074      public boolean isEmpty() {
075        return delegate().isEmpty();
076      }
077    
078      public V remove(Object object) {
079        return delegate().remove(object);
080      }
081    
082      public void clear() {
083        delegate().clear();
084      }
085    
086      public boolean containsKey(Object key) {
087        return delegate().containsKey(key);
088      }
089    
090      public boolean containsValue(Object value) {
091        return delegate().containsValue(value);
092      }
093    
094      public V get(Object key) {
095        return delegate().get(key);
096      }
097    
098      public V put(K key, V value) {
099        return delegate().put(key, value);
100      }
101    
102      public void putAll(Map<? extends K, ? extends V> map) {
103        delegate().putAll(map);
104      }
105    
106      public Set<K> keySet() {
107        return delegate().keySet();
108      }
109    
110      public Collection<V> values() {
111        return delegate().values();
112      }
113    
114      public Set<Entry<K, V>> entrySet() {
115        return delegate().entrySet();
116      }
117    
118      
119      @Override
120      public boolean equals(@Nullable Object object) {
121        return object == this || delegate().equals(object);
122      }
123    
124      
125      @Override
126      public int hashCode() {
127        return delegate().hashCode();
128      }
129    
130      /**
131       * A sensible definition of {@link #putAll(Map)} in terms of {@link
132       * #put(Object, Object)}. If you override {@link #put(Object, Object)}, you
133       * may wish to override {@link #putAll(Map)} to forward to this
134       * implementation.
135       *
136       * @since 7.0
137       */
138      @Beta protected void standardPutAll(Map<? extends K, ? extends V> map) {
139        Maps.putAllImpl(this, map);
140      }
141    
142      /**
143       * A sensible, albeit inefficient, definition of {@link #remove} in terms of
144       * the {@code iterator} method of {@link #entrySet}. If you override {@link
145       * #entrySet}, you may wish to override {@link #remove} to forward to this
146       * implementation.
147       *
148       * <p>Alternately, you may wish to override {@link #remove} with {@code
149       * keySet().remove}, assuming that approach would not lead to an infinite
150       * loop.
151       *
152       * @since 7.0
153       */
154      @Beta protected V standardRemove(@Nullable Object key) {
155        Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
156        while (entryIterator.hasNext()) {
157          Entry<K, V> entry = entryIterator.next();
158          if (Objects.equal(entry.getKey(), key)) {
159            V value = entry.getValue();
160            entryIterator.remove();
161            return value;
162          }
163        }
164        return null;
165      }
166    
167      /**
168       * A sensible definition of {@link #clear} in terms of the {@code iterator}
169       * method of {@link #entrySet}. In many cases, you may wish to override
170       * {@link #clear} to forward to this implementation.
171       *
172       * @since 7.0
173       */
174      @Beta protected void standardClear() {
175        Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
176        while (entryIterator.hasNext()) {
177          entryIterator.next();
178          entryIterator.remove();
179        }
180      }
181    
182      /**
183       * A sensible implementation of {@link Map#keySet} in terms of the following
184       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey},
185       * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#remove}, {@link
186       * ForwardingMap#size}, and the {@link Set#iterator} method of {@link
187       * ForwardingMap#entrySet}. In many cases, you may wish to override {@link
188       * ForwardingMap#keySet} to forward to this implementation or a subclass
189       * thereof.
190       *
191       * @since 10.0
192       */
193      @Beta
194      protected class StandardKeySet extends Maps.KeySet<K, V> {
195        /** Constructor for use by subclasses. */
196        public StandardKeySet() {}
197    
198        
199        @Override
200        Map<K, V> map() {
201          return ForwardingMap.this;
202        }
203      }
204    
205      /**
206       * A sensible, albeit inefficient, definition of {@link #containsKey} in terms
207       * of the {@code iterator} method of {@link #entrySet}. If you override {@link
208       * #entrySet}, you may wish to override {@link #containsKey} to forward to
209       * this implementation.
210       *
211       * @since 7.0
212       */
213      @Beta protected boolean standardContainsKey(@Nullable Object key) {
214        return Maps.containsKeyImpl(this, key);
215      }
216    
217      /**
218       * A sensible implementation of {@link Map#values} in terms of the following
219       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsValue},
220       * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#size}, and the {@link
221       * Set#iterator} method of {@link ForwardingMap#entrySet}. In many cases, you
222       * may wish to override {@link ForwardingMap#values} to forward to this
223       * implementation or a subclass thereof.
224       *
225       * @since 10.0
226       */
227      @Beta
228      protected class StandardValues extends Maps.Values<K, V> {
229        /** Constructor for use by subclasses. */
230        public StandardValues() {}
231    
232        
233        @Override
234        Map<K, V> map() {
235          return ForwardingMap.this;
236        }
237      }
238    
239      /**
240       * A sensible definition of {@link #containsValue} in terms of the {@code
241       * iterator} method of {@link #entrySet}. If you override {@link #entrySet},
242       * you may wish to override {@link #containsValue} to forward to this
243       * implementation.
244       *
245       * @since 7.0
246       */
247      @Beta protected boolean standardContainsValue(@Nullable Object value) {
248        return Maps.containsValueImpl(this, value);
249      }
250    
251      /**
252       * A sensible implementation of {@link Map#entrySet} in terms of the following
253       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey},
254       * {@link ForwardingMap#get}, {@link ForwardingMap#isEmpty}, {@link
255       * ForwardingMap#remove}, and {@link ForwardingMap#size}. In many cases, you
256       * may wish to override {@link #entrySet} to forward to this implementation
257       * or a subclass thereof.
258       *
259       * @since 10.0
260       */
261      @Beta
262      protected abstract class StandardEntrySet extends Maps.EntrySet<K, V> {
263        /** Constructor for use by subclasses. */
264        public StandardEntrySet() {}
265    
266        
267        @Override
268        Map<K, V> map() {
269          return ForwardingMap.this;
270        }
271      }
272    
273      /**
274       * A sensible definition of {@link #isEmpty} in terms of the {@code iterator}
275       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
276       * wish to override {@link #isEmpty} to forward to this implementation.
277       *
278       * @since 7.0
279       */
280      @Beta protected boolean standardIsEmpty() {
281        return !entrySet().iterator().hasNext();
282      }
283    
284      /**
285       * A sensible definition of {@link #equals} in terms of the {@code equals}
286       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
287       * wish to override {@link #equals} to forward to this implementation.
288       *
289       * @since 7.0
290       */
291      @Beta protected boolean standardEquals(@Nullable Object object) {
292        return Maps.equalsImpl(this, object);
293      }
294    
295      /**
296       * A sensible definition of {@link #hashCode} in terms of the {@code iterator}
297       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
298       * wish to override {@link #hashCode} to forward to this implementation.
299       *
300       * @since 7.0
301       */
302      @Beta protected int standardHashCode() {
303        return Sets.hashCodeImpl(entrySet());
304      }
305    
306      /**
307       * A sensible definition of {@link #toString} in terms of the {@code iterator}
308       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
309       * wish to override {@link #toString} to forward to this implementation.
310       *
311       * @since 7.0
312       */
313      @Beta protected String standardToString() {
314        return Maps.toStringImpl(this);
315      }
316    }