11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ListIterator;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.RandomAccess;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Factories and utilities pertaining to the {@link Constraint} interface.
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
375cab40b862c21656c2ace19596874eb3ffe1b649Paul Duffinfinal class Constraints {
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private Constraints() {}
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified collection, using the specified
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the collection will
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * call the provided constraint. However, this method does not verify that
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * existing elements satisfy the constraint.
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned collection is not serializable.
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param collection the collection to constrain
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the collection
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static <E> Collection<E> constrainedCollection(
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collection<E> collection, Constraint<? super E> constraint) {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedCollection<E>(collection, constraint);
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedCollection */
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedCollection<E> extends ForwardingCollection<E> {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Collection<E> delegate;
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public ConstrainedCollection(
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Collection<E> delegate, Constraint<? super E> constraint) {
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected Collection<E> delegate() {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean add(E element) {
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean addAll(Collection<? extends E> elements) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified set, using the specified
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the set will call the
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * provided constraint. However, this method does not verify that existing
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * elements satisfy the constraint.
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned set is not serializable.
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param set the set to constrain
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the set
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static <E> Set<E> constrainedSet(
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Set<E> set, Constraint<? super E> constraint) {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedSet<E>(set, constraint);
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedSet */
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedSet<E> extends ForwardingSet<E> {
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Set<E> delegate;
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ConstrainedSet(Set<E> delegate, Constraint<? super E> constraint) {
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected Set<E> delegate() {
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean add(E element) {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean addAll(Collection<? extends E> elements) {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified sorted set, using the specified
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the sorted set will
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * call the provided constraint. However, this method does not verify that
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * existing elements satisfy the constraint.
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned set is not serializable.
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sortedSet the sorted set to constrain
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the sorted set
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static <E> SortedSet<E> constrainedSortedSet(
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin      SortedSet<E> sortedSet, Constraint<? super E> constraint) {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedSortedSet<E>(sortedSet, constraint);
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedSortedSet */
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class ConstrainedSortedSet<E> extends ForwardingSortedSet<E> {
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedSet<E> delegate;
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Constraint<? super E> constraint;
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ConstrainedSortedSet(
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin        SortedSet<E> delegate, Constraint<? super E> constraint) {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected SortedSet<E> delegate() {
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public SortedSet<E> headSet(E toElement) {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet(delegate.headSet(toElement), constraint);
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public SortedSet<E> subSet(E fromElement, E toElement) {
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return constrainedSortedSet(
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin          delegate.subSet(fromElement, toElement), constraint);
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public SortedSet<E> tailSet(E fromElement) {
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet(delegate.tailSet(fromElement), constraint);
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean add(E element) {
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean addAll(Collection<? extends E> elements) {
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified list, using the specified
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the list will call the
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * provided constraint. However, this method does not verify that existing
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * elements satisfy the constraint.
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>If {@code list} implements {@link RandomAccess}, so will the returned
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * list. The returned list is not serializable.
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param list the list to constrain
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the list
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static <E> List<E> constrainedList(
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin      List<E> list, Constraint<? super E> constraint) {
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return (list instanceof RandomAccess)
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ? new ConstrainedRandomAccessList<E>(list, constraint)
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : new ConstrainedList<E>(list, constraint);
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedList */
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtCompatible
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class ConstrainedList<E> extends ForwardingList<E> {
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final List<E> delegate;
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Constraint<? super E> constraint;
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConstrainedList(List<E> delegate, Constraint<? super E> constraint) {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected List<E> delegate() {
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean add(E element) {
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public void add(int index, E element) {
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.add(index, element);
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean addAll(Collection<? extends E> elements) {
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean addAll(int index, Collection<? extends E> elements)
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    {
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(index, checkElements(elements, constraint));
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public ListIterator<E> listIterator() {
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedListIterator(delegate.listIterator(), constraint);
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public ListIterator<E> listIterator(int index) {
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedListIterator(delegate.listIterator(index), constraint);
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public E set(int index, E element) {
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.set(index, element);
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public List<E> subList(int fromIndex, int toIndex) {
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return constrainedList(
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin          delegate.subList(fromIndex, toIndex), constraint);
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedList */
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static class ConstrainedRandomAccessList<E> extends ConstrainedList<E>
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin      implements RandomAccess {
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ConstrainedRandomAccessList(
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        List<E> delegate, Constraint<? super E> constraint) {
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate, constraint);
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified list iterator, using the
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * specified constraint. Any operations that would add new elements to the
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying list will be verified by the constraint.
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param listIterator the iterator for which to return a constrained view
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint for elements in the list
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the specified iterator
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static <E> ListIterator<E> constrainedListIterator(
2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin      ListIterator<E> listIterator, Constraint<? super E> constraint) {
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedListIterator<E>(listIterator, constraint);
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedListIterator */
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedListIterator<E> extends ForwardingListIterator<E> {
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final ListIterator<E> delegate;
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public ConstrainedListIterator(
2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ListIterator<E> delegate, Constraint<? super E> constraint) {
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = delegate;
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = constraint;
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected ListIterator<E> delegate() {
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public void add(E element) {
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.add(element);
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public void set(E element) {
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.set(element);
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static <E> Collection<E> constrainedTypePreservingCollection(
2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collection<E> collection, Constraint<E> constraint) {
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (collection instanceof SortedSet) {
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet((SortedSet<E>) collection, constraint);
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof Set) {
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSet((Set<E>) collection, constraint);
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof List) {
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedList((List<E>) collection, constraint);
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedCollection(collection, constraint);
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * TODO(kevinb): For better performance, avoid making a copy of the elements
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * by having addAll() call add() repeatedly instead.
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static <E> Collection<E> checkElements(
2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collection<E> elements, Constraint<? super E> constraint) {
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<E> copy = Lists.newArrayList(elements);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (E element : copy) {
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copy;
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
305