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      @Override protected abstract Map<K, V> delegate();
067    
068      @Override
069      public int size() {
070        return delegate().size();
071      }
072    
073      @Override
074      public boolean isEmpty() {
075        return delegate().isEmpty();
076      }
077    
078      @Override
079      public V remove(Object object) {
080        return delegate().remove(object);
081      }
082    
083      @Override
084      public void clear() {
085        delegate().clear();
086      }
087    
088      @Override
089      public boolean containsKey(Object key) {
090        return delegate().containsKey(key);
091      }
092    
093      @Override
094      public boolean containsValue(Object value) {
095        return delegate().containsValue(value);
096      }
097    
098      @Override
099      public V get(Object key) {
100        return delegate().get(key);
101      }
102    
103      @Override
104      public V put(K key, V value) {
105        return delegate().put(key, value);
106      }
107    
108      @Override
109      public void putAll(Map<? extends K, ? extends V> map) {
110        delegate().putAll(map);
111      }
112    
113      @Override
114      public Set<K> keySet() {
115        return delegate().keySet();
116      }
117    
118      @Override
119      public Collection<V> values() {
120        return delegate().values();
121      }
122    
123      @Override
124      public Set<Entry<K, V>> entrySet() {
125        return delegate().entrySet();
126      }
127    
128      @Override public boolean equals(@Nullable Object object) {
129        return object == this || delegate().equals(object);
130      }
131    
132      @Override public int hashCode() {
133        return delegate().hashCode();
134      }
135    
136      /**
137       * A sensible definition of {@link #putAll(Map)} in terms of {@link
138       * #put(Object, Object)}. If you override {@link #put(Object, Object)}, you
139       * may wish to override {@link #putAll(Map)} to forward to this
140       * implementation.
141       *
142       * @since 7.0
143       */
144      @Beta protected void standardPutAll(Map<? extends K, ? extends V> map) {
145        Maps.putAllImpl(this, map);
146      }
147    
148      /**
149       * A sensible, albeit inefficient, definition of {@link #remove} in terms of
150       * the {@code iterator} method of {@link #entrySet}. If you override {@link
151       * #entrySet}, you may wish to override {@link #remove} to forward to this
152       * implementation.
153       *
154       * <p>Alternately, you may wish to override {@link #remove} with {@code
155       * keySet().remove}, assuming that approach would not lead to an infinite
156       * loop.
157       *
158       * @since 7.0
159       */
160      @Beta protected V standardRemove(@Nullable Object key) {
161        Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
162        while (entryIterator.hasNext()) {
163          Entry<K, V> entry = entryIterator.next();
164          if (Objects.equal(entry.getKey(), key)) {
165            V value = entry.getValue();
166            entryIterator.remove();
167            return value;
168          }
169        }
170        return null;
171      }
172    
173      /**
174       * A sensible definition of {@link #clear} in terms of the {@code iterator}
175       * method of {@link #entrySet}. In many cases, you may wish to override
176       * {@link #clear} to forward to this implementation.
177       *
178       * @since 7.0
179       */
180      @Beta protected void standardClear() {
181        Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
182        while (entryIterator.hasNext()) {
183          entryIterator.next();
184          entryIterator.remove();
185        }
186      }
187    
188      /**
189       * A sensible implementation of {@link Map#keySet} in terms of the following
190       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey},
191       * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#remove}, {@link
192       * ForwardingMap#size}, and the {@link Set#iterator} method of {@link
193       * ForwardingMap#entrySet}. In many cases, you may wish to override {@link
194       * ForwardingMap#keySet} to forward to this implementation or a subclass
195       * thereof.
196       *
197       * @since 10.0
198       */
199      @Beta
200      protected class StandardKeySet extends Maps.KeySet<K, V> {
201        /** Constructor for use by subclasses. */
202        public StandardKeySet() {}
203    
204        @Override
205        Map<K, V> map() {
206          return ForwardingMap.this;
207        }
208      }
209    
210      /**
211       * A sensible, albeit inefficient, definition of {@link #containsKey} in terms
212       * of the {@code iterator} method of {@link #entrySet}. If you override {@link
213       * #entrySet}, you may wish to override {@link #containsKey} to forward to
214       * this implementation.
215       *
216       * @since 7.0
217       */
218      @Beta protected boolean standardContainsKey(@Nullable Object key) {
219        return Maps.containsKeyImpl(this, key);
220      }
221    
222      /**
223       * A sensible implementation of {@link Map#values} in terms of the following
224       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsValue},
225       * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#size}, and the {@link
226       * Set#iterator} method of {@link ForwardingMap#entrySet}. In many cases, you
227       * may wish to override {@link ForwardingMap#values} to forward to this
228       * implementation or a subclass thereof.
229       *
230       * @since 10.0
231       */
232      @Beta
233      protected class StandardValues extends Maps.Values<K, V> {
234        /** Constructor for use by subclasses. */
235        public StandardValues() {}
236    
237        @Override
238        Map<K, V> map() {
239          return ForwardingMap.this;
240        }
241      }
242    
243      /**
244       * A sensible definition of {@link #containsValue} in terms of the {@code
245       * iterator} method of {@link #entrySet}. If you override {@link #entrySet},
246       * you may wish to override {@link #containsValue} to forward to this
247       * implementation.
248       *
249       * @since 7.0
250       */
251      @Beta protected boolean standardContainsValue(@Nullable Object value) {
252        return Maps.containsValueImpl(this, value);
253      }
254    
255      /**
256       * A sensible implementation of {@link Map#entrySet} in terms of the following
257       * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey},
258       * {@link ForwardingMap#get}, {@link ForwardingMap#isEmpty}, {@link
259       * ForwardingMap#remove}, and {@link ForwardingMap#size}. In many cases, you
260       * may wish to override {@link #entrySet} to forward to this implementation
261       * or a subclass thereof.
262       *
263       * @since 10.0
264       */
265      @Beta
266      protected abstract class StandardEntrySet extends Maps.EntrySet<K, V> {
267        /** Constructor for use by subclasses. */
268        public StandardEntrySet() {}
269    
270        @Override
271        Map<K, V> map() {
272          return ForwardingMap.this;
273        }
274      }
275    
276      /**
277       * A sensible definition of {@link #isEmpty} in terms of the {@code iterator}
278       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
279       * wish to override {@link #isEmpty} to forward to this implementation.
280       *
281       * @since 7.0
282       */
283      @Beta protected boolean standardIsEmpty() {
284        return !entrySet().iterator().hasNext();
285      }
286    
287      /**
288       * A sensible definition of {@link #equals} in terms of the {@code equals}
289       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
290       * wish to override {@link #equals} to forward to this implementation.
291       *
292       * @since 7.0
293       */
294      @Beta protected boolean standardEquals(@Nullable Object object) {
295        return Maps.equalsImpl(this, object);
296      }
297    
298      /**
299       * A sensible definition of {@link #hashCode} in terms of the {@code iterator}
300       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
301       * wish to override {@link #hashCode} to forward to this implementation.
302       *
303       * @since 7.0
304       */
305      @Beta protected int standardHashCode() {
306        return Sets.hashCodeImpl(entrySet());
307      }
308    
309      /**
310       * A sensible definition of {@link #toString} in terms of the {@code iterator}
311       * method of {@link #entrySet}. If you override {@link #entrySet}, you may
312       * wish to override {@link #toString} to forward to this implementation.
313       *
314       * @since 7.0
315       */
316      @Beta protected String standardToString() {
317        return Maps.toStringImpl(this);
318      }
319    }