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