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
053public abstract class ForwardingNavigableSet<E extends @Nullable Object>
054    extends ForwardingSortedSet<E> implements NavigableSet<E> {
055
056  /** Constructor for use by subclasses. */
057  protected ForwardingNavigableSet() {}
058
059  @Override
060  protected abstract NavigableSet<E> delegate();
061
062  @Override
063  @CheckForNull
064  public E lower(@ParametricNullness E e) {
065    return delegate().lower(e);
066  }
067
068  /**
069   * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
070   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
071   * wish to override {@link #lower} to forward to this implementation.
072   */
073  @CheckForNull
074  protected E standardLower(@ParametricNullness E e) {
075    return Iterators.getNext(headSet(e, false).descendingIterator(), null);
076  }
077
078  @Override
079  @CheckForNull
080  public E floor(@ParametricNullness E e) {
081    return delegate().floor(e);
082  }
083
084  /**
085   * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
086   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
087   * wish to override {@link #floor} to forward to this implementation.
088   */
089  @CheckForNull
090  protected E standardFloor(@ParametricNullness E e) {
091    return Iterators.getNext(headSet(e, true).descendingIterator(), null);
092  }
093
094  @Override
095  @CheckForNull
096  public E ceiling(@ParametricNullness E e) {
097    return delegate().ceiling(e);
098  }
099
100  /**
101   * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of {@link
102   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
103   * override {@link #ceiling} to forward to this implementation.
104   */
105  @CheckForNull
106  protected E standardCeiling(@ParametricNullness E e) {
107    return Iterators.getNext(tailSet(e, true).iterator(), null);
108  }
109
110  @Override
111  @CheckForNull
112  public E higher(@ParametricNullness E e) {
113    return delegate().higher(e);
114  }
115
116  /**
117   * A sensible definition of {@link #higher} in terms of the {@code iterator} method of {@link
118   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
119   * override {@link #higher} to forward to this implementation.
120   */
121  @CheckForNull
122  protected E standardHigher(@ParametricNullness E e) {
123    return Iterators.getNext(tailSet(e, false).iterator(), null);
124  }
125
126  @Override
127  @CheckForNull
128  public E pollFirst() {
129    return delegate().pollFirst();
130  }
131
132  /**
133   * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
134   * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
135   * implementation.
136   */
137  @CheckForNull
138  protected E standardPollFirst() {
139    return Iterators.pollNext(iterator());
140  }
141
142  @Override
143  @CheckForNull
144  public E pollLast() {
145    return delegate().pollLast();
146  }
147
148  /**
149   * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
150   * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
151   * forward to this implementation.
152   */
153  @CheckForNull
154  protected E standardPollLast() {
155    return Iterators.pollNext(descendingIterator());
156  }
157
158  @ParametricNullness
159  protected E standardFirst() {
160    return iterator().next();
161  }
162
163  @ParametricNullness
164  protected E standardLast() {
165    return descendingIterator().next();
166  }
167
168  @Override
169  public NavigableSet<E> descendingSet() {
170    return delegate().descendingSet();
171  }
172
173  /**
174   * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
175   * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
176   *
177   * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
178   * forward to this implementation or a subclass thereof.
179   *
180   * @since 12.0
181   */
182  protected class StandardDescendingSet extends Sets.DescendingSet<E> {
183    /** Constructor for use by subclasses. */
184    public StandardDescendingSet() {
185      super(ForwardingNavigableSet.this);
186    }
187  }
188
189  @Override
190  public Iterator<E> descendingIterator() {
191    return delegate().descendingIterator();
192  }
193
194  @Override
195  public NavigableSet<E> subSet(
196      @ParametricNullness E fromElement,
197      boolean fromInclusive,
198      @ParametricNullness E toElement,
199      boolean toInclusive) {
200    return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
201  }
202
203  /**
204   * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
205   * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override {@link
206   * #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
207   */
208  protected NavigableSet<E> standardSubSet(
209      @ParametricNullness E fromElement,
210      boolean fromInclusive,
211      @ParametricNullness E toElement,
212      boolean toInclusive) {
213    return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
214  }
215
216  /**
217   * A sensible definition of {@link #subSet(Object, Object)} in terms of the {@link #subSet(Object,
218   * boolean, Object, boolean)} method. If you override {@link #subSet(Object, boolean, Object,
219   * boolean)}, you may wish to override {@link #subSet(Object, Object)} to forward to this
220   * implementation.
221   */
222  @Override
223  protected SortedSet<E> standardSubSet(
224      @ParametricNullness E fromElement, @ParametricNullness E toElement) {
225    return subSet(fromElement, true, toElement, false);
226  }
227
228  @Override
229  public NavigableSet<E> headSet(@ParametricNullness E toElement, boolean inclusive) {
230    return delegate().headSet(toElement, inclusive);
231  }
232
233  /**
234   * A sensible definition of {@link #headSet(Object)} in terms of the {@link #headSet(Object,
235   * boolean)} method. If you override {@link #headSet(Object, boolean)}, you may wish to override
236   * {@link #headSet(Object)} to forward to this implementation.
237   */
238  protected SortedSet<E> standardHeadSet(@ParametricNullness E toElement) {
239    return headSet(toElement, false);
240  }
241
242  @Override
243  public NavigableSet<E> tailSet(@ParametricNullness E fromElement, boolean inclusive) {
244    return delegate().tailSet(fromElement, inclusive);
245  }
246
247  /**
248   * A sensible definition of {@link #tailSet(Object)} in terms of the {@link #tailSet(Object,
249   * boolean)} method. If you override {@link #tailSet(Object, boolean)}, you may wish to override
250   * {@link #tailSet(Object)} to forward to this implementation.
251   */
252  protected SortedSet<E> standardTailSet(@ParametricNullness E fromElement) {
253    return tailSet(fromElement, true);
254  }
255}