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