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.Beta;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ListIterator;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.RandomAccess;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Factories and utilities pertaining to the {@link Constraint} interface.
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @see MapConstraints
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 3.0
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Constraints {
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private Constraints() {}
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // enum singleton pattern
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private enum NotNullConstraint implements Constraint<Object> {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    INSTANCE;
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Object checkElement(Object element) {
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return checkNotNull(element);
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return "Not null";
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constraint that verifies that the element is not null. If the
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * element is null, a {@link NullPointerException} is thrown.
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // safe to narrow the type since checkElement returns its argument directly
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked")
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> Constraint<E> notNull() {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (Constraint<E>) NotNullConstraint.INSTANCE;
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified collection, using the specified
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the collection will
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * call the provided constraint. However, this method does not verify that
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * existing elements satisfy the constraint.
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned collection is not serializable.
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param collection the collection to constrain
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the collection
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> Collection<E> constrainedCollection(
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<E> collection, Constraint<? super E> constraint) {
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedCollection<E>(collection, constraint);
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedCollection */
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedCollection<E> extends ForwardingCollection<E> {
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Collection<E> delegate;
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ConstrainedCollection(
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Collection<E> delegate, Constraint<? super E> constraint) {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Collection<E> delegate() {
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean add(E element) {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(Collection<? extends E> elements) {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified set, using the specified
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the set will call the
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * provided constraint. However, this method does not verify that existing
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * elements satisfy the constraint.
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned set is not serializable.
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param set the set to constrain
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the set
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> Set<E> constrainedSet(
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Set<E> set, Constraint<? super E> constraint) {
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedSet<E>(set, constraint);
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedSet */
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedSet<E> extends ForwardingSet<E> {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Set<E> delegate;
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ConstrainedSet(Set<E> delegate, Constraint<? super E> constraint) {
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Set<E> delegate() {
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean add(E element) {
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(Collection<? extends E> elements) {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified sorted set, using the specified
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the sorted set will
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * call the provided constraint. However, this method does not verify that
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * existing elements satisfy the constraint.
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned set is not serializable.
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param sortedSet the sorted set to constrain
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the sorted set
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> SortedSet<E> constrainedSortedSet(
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      SortedSet<E> sortedSet, Constraint<? super E> constraint) {
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedSortedSet<E>(sortedSet, constraint);
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedSortedSet */
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class ConstrainedSortedSet<E> extends ForwardingSortedSet<E> {
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final SortedSet<E> delegate;
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Constraint<? super E> constraint;
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConstrainedSortedSet(
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        SortedSet<E> delegate, Constraint<? super E> constraint) {
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected SortedSet<E> delegate() {
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> headSet(E toElement) {
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet(delegate.headSet(toElement), constraint);
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> subSet(E fromElement, E toElement) {
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet(
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          delegate.subSet(fromElement, toElement), constraint);
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public SortedSet<E> tailSet(E fromElement) {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet(delegate.tailSet(fromElement), constraint);
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean add(E element) {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(Collection<? extends E> elements) {
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified list, using the specified
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the list will call the
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * provided constraint. However, this method does not verify that existing
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * elements satisfy the constraint.
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>If {@code list} implements {@link RandomAccess}, so will the returned
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * list. The returned list is not serializable.
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param list the list to constrain
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the list
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> List<E> constrainedList(
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      List<E> list, Constraint<? super E> constraint) {
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (list instanceof RandomAccess)
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ? new ConstrainedRandomAccessList<E>(list, constraint)
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : new ConstrainedList<E>(list, constraint);
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedList */
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtCompatible
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class ConstrainedList<E> extends ForwardingList<E> {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final List<E> delegate;
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Constraint<? super E> constraint;
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConstrainedList(List<E> delegate, Constraint<? super E> constraint) {
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected List<E> delegate() {
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean add(E element) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element);
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void add(int index, E element) {
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.add(index, element);
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(Collection<? extends E> elements) {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(int index, Collection<? extends E> elements)
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    {
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(index, checkElements(elements, constraint));
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ListIterator<E> listIterator() {
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedListIterator(delegate.listIterator(), constraint);
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public ListIterator<E> listIterator(int index) {
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedListIterator(delegate.listIterator(index), constraint);
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public E set(int index, E element) {
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.set(index, element);
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<E> subList(int fromIndex, int toIndex) {
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedList(
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          delegate.subList(fromIndex, toIndex), constraint);
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedList */
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedRandomAccessList<E> extends ConstrainedList<E>
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements RandomAccess {
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ConstrainedRandomAccessList(
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        List<E> delegate, Constraint<? super E> constraint) {
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate, constraint);
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified list iterator, using the
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * specified constraint. Any operations that would add new elements to the
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying list will be verified by the constraint.
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param listIterator the iterator for which to return a constrained view
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint for elements in the list
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the specified iterator
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> ListIterator<E> constrainedListIterator(
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ListIterator<E> listIterator, Constraint<? super E> constraint) {
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedListIterator<E>(listIterator, constraint);
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedListIterator */
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedListIterator<E> extends ForwardingListIterator<E> {
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final ListIterator<E> delegate;
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ConstrainedListIterator(
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ListIterator<E> delegate, Constraint<? super E> constraint) {
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = delegate;
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = constraint;
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected ListIterator<E> delegate() {
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void add(E element) {
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.add(element);
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void set(E element) {
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      delegate.set(element);
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static <E> Collection<E> constrainedTypePreservingCollection(
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<E> collection, Constraint<E> constraint) {
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (collection instanceof SortedSet) {
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSortedSet((SortedSet<E>) collection, constraint);
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof Set) {
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedSet((Set<E>) collection, constraint);
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (collection instanceof List) {
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedList((List<E>) collection, constraint);
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return constrainedCollection(collection, constraint);
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a constrained view of the specified multiset, using the specified
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * constraint. Any operations that add new elements to the multiset will call
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the provided constraint. However, this method does not verify that
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * existing elements satisfy the constraint.
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned multiset is not serializable.
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param multiset the multiset to constrain
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param constraint the constraint that validates added elements
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return a constrained view of the multiset
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E> Multiset<E> constrainedMultiset(
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Multiset<E> multiset, Constraint<? super E> constraint) {
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ConstrainedMultiset<E>(multiset, constraint);
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** @see Constraints#constrainedMultiset */
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class ConstrainedMultiset<E> extends ForwardingMultiset<E> {
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private Multiset<E> delegate;
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final Constraint<? super E> constraint;
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ConstrainedMultiset(
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Multiset<E> delegate, Constraint<? super E> constraint) {
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.constraint = checkNotNull(constraint);
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Multiset<E> delegate() {
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean add(E element) {
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardAdd(element);
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean addAll(Collection<? extends E> elements) {
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.addAll(checkElements(elements, constraint));
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int add(E element, int occurrences) {
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.add(element, occurrences);
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int setCount(E element, int count) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.setCount(element, count);
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean setCount(E element, int oldCount, int newCount) {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate.setCount(element, oldCount, newCount);
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * TODO(kevinb): For better performance, avoid making a copy of the elements
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * by having addAll() call add() repeatedly instead.
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <E> Collection<E> checkElements(
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Collection<E> elements, Constraint<? super E> constraint) {
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<E> copy = Lists.newArrayList(elements);
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (E element : copy) {
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      constraint.checkElement(element);
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return copy;
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
383