    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    }