001/*
002 * Copyright (C) 2012 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.GwtIncompatible;
020import java.util.Iterator;
021import java.util.NavigableSet;
022import java.util.SortedSet;
023import javax.annotation.CheckForNull;
024import org.checkerframework.checker.nullness.qual.Nullable;
025
026/**
027 * A navigable set which forwards all its method calls to another navigable set. Subclasses should
028 * override one or more methods to modify the behavior of the backing set as desired per the <a
029 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
030 *
031 * <p><b>Warning:</b> The methods of {@code ForwardingNavigableSet} forward <i>indiscriminately</i>
032 * to the methods of the delegate. For example, overriding {@link #add} alone <i>will not</i> change
033 * the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you should
034 * override {@code addAll} as well, either providing your own implementation, or delegating to the
035 * provided {@code standardAddAll} method.
036 *
037 * <p><b>{@code default} method warning:</b> This class does <i>not</i> forward calls to {@code
038 * default} methods. Instead, it inherits their default implementations. When those implementations
039 * invoke methods, they invoke methods on the {@code ForwardingNavigableSet}.
040 *
041 * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of the
042 * elements, if there is no comparator) to test element equality. As a result, if the comparator is
043 * not consistent with equals, some of the standard implementations may violate the {@code Set}
044 * contract.
045 *
046 * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
047 * thread-safe, even when all of the methods that they depend on are thread-safe.
048 *
049 * @author Louis Wasserman
050 * @since 12.0
051 */
052@GwtIncompatible
053@ElementTypesAreNonnullByDefault
054public abstract class ForwardingNavigableSet<E extends @Nullable Object>
055    extends ForwardingSortedSet<E> implements NavigableSet<E> {
056
057  /** Constructor for use by subclasses. */
058  protected ForwardingNavigableSet() {}
059
060  @Override
061  protected abstract NavigableSet<E> delegate();
062
063  @Override
064  @CheckForNull
065  public E lower(@ParametricNullness E e) {
066    return delegate().lower(e);
067  }
068
069  /**
070   * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
071   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
072   * wish to override {@link #lower} to forward to this implementation.
073   */
074  @CheckForNull
075  protected E standardLower(@ParametricNullness E e) {
076    return Iterators.getNext(headSet(e, false).descendingIterator(), null);
077  }
078
079  @Override
080  @CheckForNull
081  public E floor(@ParametricNullness E e) {
082    return delegate().floor(e);
083  }
084
085  /**
086   * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
087   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
088   * wish to override {@link #floor} to forward to this implementation.
089   */
090  @CheckForNull
091  protected E standardFloor(@ParametricNullness E e) {
092    return Iterators.getNext(headSet(e, true).descendingIterator(), null);
093  }
094
095  @Override
096  @CheckForNull
097  public E ceiling(@ParametricNullness E e) {
098    return delegate().ceiling(e);
099  }
100
101  /**
102   * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of {@link
103   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
104   * override {@link #ceiling} to forward to this implementation.
105   */
106  @CheckForNull
107  protected E standardCeiling(@ParametricNullness E e) {
108    return Iterators.getNext(tailSet(e, true).iterator(), null);
109  }
110
111  @Override
112  @CheckForNull
113  public E higher(@ParametricNullness E e) {
114    return delegate().higher(e);
115  }
116
117  /**
118   * A sensible definition of {@link #higher} in terms of the {@code iterator} method of {@link
119   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
120   * override {@link #higher} to forward to this implementation.
121   */
122  @CheckForNull
123  protected E standardHigher(@ParametricNullness E e) {
124    return Iterators.getNext(tailSet(e, false).iterator(), null);
125  }
126
127  @Override
128  @CheckForNull
129  public E pollFirst() {
130    return delegate().pollFirst();
131  }
132
133  /**
134   * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
135   * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
136   * implementation.
137   */
138  @CheckForNull
139  protected E standardPollFirst() {
140    return Iterators.pollNext(iterator());
141  }
142
143  @Override
144  @CheckForNull
145  public E pollLast() {
146    return delegate().pollLast();
147  }
148
149  /**
150   * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
151   * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
152   * forward to this implementation.
153   */
154  @CheckForNull
155  protected E standardPollLast() {
156    return Iterators.pollNext(descendingIterator());
157  }
158
159  @ParametricNullness
160  protected E standardFirst() {
161    return iterator().next();
162  }
163
164  @ParametricNullness
165  protected E standardLast() {
166    return descendingIterator().next();
167  }
168
169  @Override
170  public NavigableSet<E> descendingSet() {
171    return delegate().descendingSet();
172  }
173
174  /**
175   * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
176   * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
177   *
178   * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
179   * forward to this implementation or a subclass thereof.
180   *
181   * @since 12.0
182   */
183  protected class StandardDescendingSet extends Sets.DescendingSet<E> {
184    /** Constructor for use by subclasses. */
185    public StandardDescendingSet() {
186      super(ForwardingNavigableSet.this);
187    }
188  }
189
190  @Override
191  public Iterator<E> descendingIterator() {
192    return delegate().descendingIterator();
193  }
194
195  @Override
196  public NavigableSet<E> subSet(
197      @ParametricNullness E fromElement,
198      boolean fromInclusive,
199      @ParametricNullness E toElement,
200      boolean toInclusive) {
201    return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
202  }
203
204  /**
205   * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
206   * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override {@link
207   * #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
208   */
209  protected NavigableSet<E> standardSubSet(
210      @ParametricNullness E fromElement,
211      boolean fromInclusive,
212      @ParametricNullness E toElement,
213      boolean toInclusive) {
214    return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
215  }
216
217  /**
218   * A sensible definition of {@link #subSet(Object, Object)} in terms of the {@link #subSet(Object,
219   * boolean, Object, boolean)} method. If you override {@link #subSet(Object, boolean, Object,
220   * boolean)}, you may wish to override {@link #subSet(Object, Object)} to forward to this
221   * implementation.
222   */
223  @Override
224  protected SortedSet<E> standardSubSet(
225      @ParametricNullness E fromElement, @ParametricNullness E toElement) {
226    return subSet(fromElement, true, toElement, false);
227  }
228
229  @Override
230  public NavigableSet<E> headSet(@ParametricNullness E toElement, boolean inclusive) {
231    return delegate().headSet(toElement, inclusive);
232  }
233
234  /**
235   * A sensible definition of {@link #headSet(Object)} in terms of the {@link #headSet(Object,
236   * boolean)} method. If you override {@link #headSet(Object, boolean)}, you may wish to override
237   * {@link #headSet(Object)} to forward to this implementation.
238   */
239  protected SortedSet<E> standardHeadSet(@ParametricNullness E toElement) {
240    return headSet(toElement, false);
241  }
242
243  @Override
244  public NavigableSet<E> tailSet(@ParametricNullness E fromElement, boolean inclusive) {
245    return delegate().tailSet(fromElement, inclusive);
246  }
247
248  /**
249   * A sensible definition of {@link #tailSet(Object)} in terms of the {@link #tailSet(Object,
250   * boolean)} method. If you override {@link #tailSet(Object, boolean)}, you may wish to override
251   * {@link #tailSet(Object)} to forward to this implementation.
252   */
253  protected SortedSet<E> standardTailSet(@ParametricNullness E fromElement) {
254    return tailSet(fromElement, true);
255  }
256}