    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
    026    import javax.annotation.Nullable;
    027
    028    /**
    029     * A collection which forwards all its method calls to another collection.
    030     * Subclasses should override one or more methods to modify the behavior of the
    031     * backing collection as desired per the <a
    032     * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
    033     *
    034     * <p><b>Warning:</b> The methods of {@code ForwardingCollection} forward
    035     * <b>indiscriminately</b> to the methods of the delegate. For example,
    036     * overriding {@link #add} alone <b>will not</b> change the behavior of {@link
    037     * #addAll}, which can lead to unexpected behavior. In this case, you should
    038     * override {@code addAll} as well, either providing your own implementation, or
    039     * delegating to the provided {@code standardAddAll} method.
    040     *
    041     * <p>The {@code standard} methods are not guaranteed to be thread-safe, even
    042     * when all of the methods that they depend on are thread-safe.
    043     *
    044     * @author Kevin Bourrillion
    045     * @author Louis Wasserman
    046     * @since 2.0 (imported from Google Collections Library)
    047     */
    048    @GwtCompatible
    049    public abstract class ForwardingCollection<E> extends ForwardingObject
    050        implements Collection<E> {
    051      // TODO(user): identify places where thread safety is actually lost
    052
    053      /** Constructor for use by subclasses. */
    054      protected ForwardingCollection() {}
    055
    056      @Override protected abstract Collection<E> delegate();
    057
    058      @Override
    059      public Iterator<E> iterator() {
    060        return delegate().iterator();
    061      }
    062
    063      @Override
    064      public int size() {
    065        return delegate().size();
    066      }
    067
    068      @Override
    069      public boolean removeAll(Collection<?> collection) {
    070        return delegate().removeAll(collection);
    071      }
    072
    073      @Override
    074      public boolean isEmpty() {
    075        return delegate().isEmpty();
    076      }
    077
    078      @Override
    079      public boolean contains(Object object) {
    080        return delegate().contains(object);
    081      }
    082
    083      @Override
    084      public boolean add(E element) {
    085        return delegate().add(element);
    086      }
    087
    088      @Override
    089      public boolean remove(Object object) {
    090        return delegate().remove(object);
    091      }
    092
    093      @Override
    094      public boolean containsAll(Collection<?> collection) {
    095        return delegate().containsAll(collection);
    096      }
    097
    098      @Override
    099      public boolean addAll(Collection<? extends E> collection) {
    100        return delegate().addAll(collection);
    101      }
    102
    103      @Override
    104      public boolean retainAll(Collection<?> collection) {
    105        return delegate().retainAll(collection);
    106      }
    107
    108      @Override
    109      public void clear() {
    110        delegate().clear();
    111      }
    112
    113      @Override
    114      public Object[] toArray() {
    115        return delegate().toArray();
    116      }
    117
    118      @Override
    119      public <T> T[] toArray(T[] array) {
    120        return delegate().toArray(array);
    121      }
    122
    123      /**
    124       * A sensible definition of {@link #contains} in terms of {@link #iterator}.
    125       * If you override {@link #iterator}, you may wish to override {@link
    126       * #contains} to forward to this implementation.
    127       *
    128       * @since 7.0
    129       */
    130      @Beta protected boolean standardContains(@Nullable Object object) {
    131        return Iterators.contains(iterator(), object);
    132      }
    133
    134      /**
    135       * A sensible definition of {@link #containsAll} in terms of {@link #contains}
    136       * . If you override {@link #contains}, you may wish to override {@link
    137       * #containsAll} to forward to this implementation.
    138       *
    139       * @since 7.0
    140       */
    141      @Beta protected boolean standardContainsAll(Collection<?> collection) {
    142        for (Object o : collection) {
    143          if (!contains(o)) {
    144            return false;
    145          }
    146        }
    147        return true;
    148      }
    149
    150      /**
    151       * A sensible definition of {@link #addAll} in terms of {@link #add}. If you
    152       * override {@link #add}, you may wish to override {@link #addAll} to forward
    153       * to this implementation.
    154       *
    155       * @since 7.0
    156       */
    157      @Beta protected boolean standardAddAll(Collection<? extends E> collection) {
    158        return Iterators.addAll(this, collection.iterator());
    159      }
    160
    161      /**
    162       * A sensible definition of {@link #remove} in terms of {@link #iterator},
    163       * using the iterator's {@code remove} method. If you override {@link
    164       * #iterator}, you may wish to override {@link #remove} to forward to this
    165       * implementation.
    166       *
    167       * @since 7.0
    168       */
    169      @Beta protected boolean standardRemove(@Nullable Object object) {
    170        Iterator<E> iterator = iterator();
    171        while (iterator.hasNext()) {
    172          if (Objects.equal(iterator.next(), object)) {
    173            iterator.remove();
    174            return true;
    175          }
    176        }
    177        return false;
    178      }
    179
    180      /**
    181       * A sensible definition of {@link #removeAll} in terms of {@link #iterator},
    182       * using the iterator's {@code remove} method. If you override {@link
    183       * #iterator}, you may wish to override {@link #removeAll} to forward to this
    184       * implementation.
    185       *
    186       * @since 7.0
    187       */
    188      @Beta protected boolean standardRemoveAll(Collection<?> collection) {
    189        return Iterators.removeAll(iterator(), collection);
    190      }
    191
    192      /**
    193       * A sensible definition of {@link #retainAll} in terms of {@link #iterator},
    194       * using the iterator's {@code remove} method. If you override {@link
    195       * #iterator}, you may wish to override {@link #retainAll} to forward to this
    196       * implementation.
    197       *
    198       * @since 7.0
    199       */
    200      @Beta protected boolean standardRetainAll(Collection<?> collection) {
    201        return Iterators.retainAll(iterator(), collection);
    202      }
    203
    204      /**
    205       * A sensible definition of {@link #clear} in terms of {@link #iterator},
    206       * using the iterator's {@code remove} method. If you override {@link
    207       * #iterator}, you may wish to override {@link #clear} to forward to this
    208       * implementation.
    209       *
    210       * @since 7.0
    211       */
    212      @Beta protected void standardClear() {
    213        Iterator<E> iterator = iterator();
    214        while (iterator.hasNext()) {
    215          iterator.next();
    216          iterator.remove();
    217        }
    218      }
    219
    220      /**
    221       * A sensible definition of {@link #isEmpty} as {@code !iterator().hasNext}.
    222       * If you override {@link #isEmpty}, you may wish to override {@link #isEmpty}
    223       * to forward to this implementation. Alternately, it may be more efficient to
    224       * implement {@code isEmpty} as {@code size() == 0}.
    225       *
    226       * @since 7.0
    227       */
    228      @Beta protected boolean standardIsEmpty() {
    229        return !iterator().hasNext();
    230      }
    231
    232      /**
    233       * A sensible definition of {@link #toString} in terms of {@link #iterator}.
    234       * If you override {@link #iterator}, you may wish to override {@link
    235       * #toString} to forward to this implementation.
    236       *
    237       * @since 7.0
    238       */
    239      @Beta protected String standardToString() {
    240        return Collections2.toStringImpl(this);
    241      }
    242
    243      /**
    244       * A sensible definition of {@link #toArray()} in terms of {@link
    245       * #toArray(Object[])}. If you override {@link #toArray(Object[])}, you may
    246       * wish to override {@link #toArray} to forward to this implementation.
    247       *
    248       * @since 7.0
    249       */
    250      @Beta protected Object[] standardToArray() {
    251        Object[] newArray = new Object[size()];
    252        return toArray(newArray);
    253      }
    254
    255      /**
    256       * A sensible definition of {@link #toArray(Object[])} in terms of {@link
    257       * #size} and {@link #iterator}. If you override either of these methods, you
    258       * may wish to override {@link #toArray} to forward to this implementation.
    259       *
    260       * @since 7.0
    261       */
    262      @Beta protected <T> T[] standardToArray(T[] array) {
    263        return ObjectArrays.toArrayImpl(this, array);
    264      }
    265    }