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.Comparator; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Factory and utilities pertaining to the {@code MapConstraint} interface. 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @see Constraints 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mike Bostock 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 3.0 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class MapConstraints { 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private MapConstraints() {} 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constraint that verifies that neither the key nor the value is 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null. If either is null, a {@link NullPointerException} is thrown. 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static MapConstraint<Object, Object> notNull() { 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return NotNullMapConstraint.INSTANCE; 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // enum singleton pattern 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private enum NotNullMapConstraint implements MapConstraint<Object, Object> { 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert INSTANCE; 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void checkKeyValue(Object key, Object value) { 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(key); 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(value); 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return "Not null"; 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified map, using the specified 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. Any operations that add new mappings will call the provided 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. However, this method does not verify that existing mappings 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy the constraint. 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned map is not serializable. 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the map to constrain 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified map 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Map<K, V> constrainedMap( 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> map, MapConstraint<? super K, ? super V> constraint) { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedMap<K, V>(map, constraint); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified multimap, using the specified 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. Any operations that add new mappings will call the provided 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. However, this method does not verify that existing mappings 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * satisfy the constraint. 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are not 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constrained. 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not serializable. 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to constrain 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the multimap 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> Multimap<K, V> constrainedMultimap( 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<K, V> multimap, MapConstraint<? super K, ? super V> constraint) { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedMultimap<K, V>(multimap, constraint); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified list multimap, using the 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified constraint. Any operations that add new mappings will call the 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided constraint. However, this method does not verify that existing 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings satisfy the constraint. 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are not 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constrained. 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not serializable. 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to constrain 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified multimap 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> ListMultimap<K, V> constrainedListMultimap( 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListMultimap<K, V> multimap, 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedListMultimap<K, V>(multimap, constraint); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified set multimap, using the 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified constraint. Any operations that add new mappings will call the 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided constraint. However, this method does not verify that existing 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings satisfy the constraint. 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are not 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constrained. 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not serializable. 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to constrain 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified multimap 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SetMultimap<K, V> constrainedSetMultimap( 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SetMultimap<K, V> multimap, 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedSetMultimap<K, V>(multimap, constraint); 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified sorted-set multimap, using the 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified constraint. Any operations that add new mappings will call the 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided constraint. However, this method does not verify that existing 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mappings satisfy the constraint. 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the generated multimap's {@link Multimap#removeAll} and 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Multimap#replaceValues} methods return collections that are not 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constrained. 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not serializable. 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param multimap the multimap to constrain 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified multimap 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> SortedSetMultimap<K, V> constrainedSortedSetMultimap( 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SortedSetMultimap<K, V> multimap, 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedSortedSetMultimap<K, V>(multimap, constraint); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified entry, using the specified 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. The {@link Entry#setValue} operation will be verified with the 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entry the entry to constrain 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint for the entry 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified entry 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Entry<K, V> constrainedEntry( 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<K, V> entry, 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super K, ? super V> constraint) { 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(constraint); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingMapEntry<K, V>() { 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<K, V> delegate() { 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(getKey(), value); 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry.setValue(value); 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified {@code asMap} entry, using the 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified constraint. The {@link Entry#setValue} operation will be verified 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with the constraint, and the collection returned by {@link Entry#getValue} 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be similarly constrained. 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entry the {@code asMap} entry to constrain 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint for the entry 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified entry 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Entry<K, Collection<V>> constrainedAsMapEntry( 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Entry<K, Collection<V>> entry, 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super K, ? super V> constraint) { 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(constraint); 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingMapEntry<K, Collection<V>>() { 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<K, Collection<V>> delegate() { 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> getValue() { 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Constraints.constrainedTypePreservingCollection( 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.getValue(), new Constraint<V>() { 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V checkElement(V value) { 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(getKey(), value); 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value; 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified set of {@code asMap} entries, 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * using the specified constraint. The {@link Entry#setValue} operation will 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be verified with the constraint, and the collection returned by {@link 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Entry#getValue} will be similarly constrained. The {@code add} and {@code 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * addAll} operations simply forward to the underlying set, which throws an 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link UnsupportedOperationException} per the multimap specification. 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entries the entries to constrain 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint for the entries 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the entries 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Set<Entry<K, Collection<V>>> constrainedAsMapEntries( 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> entries, 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedAsMapEntries<K, V>(entries, constraint); 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified collection (or set) of entries, 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * using the specified constraint. The {@link Entry#setValue} operation will 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be verified with the constraint, along with add operations on the returned 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * collection. The {@code add} and {@code addAll} operations simply forward to 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the underlying collection, which throws an {@link 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * UnsupportedOperationException} per the map and multimap specification. 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entries the entries to constrain 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint for the entries 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified entries 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Collection<Entry<K, V>> constrainedEntries( 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> entries, 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (entries instanceof Set) { 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return constrainedEntrySet((Set<Entry<K, V>>) entries, constraint); 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedEntries<K, V>(entries, constraint); 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified set of entries, using the 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified constraint. The {@link Entry#setValue} operation will be verified 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with the constraint, along with add operations on the returned set. The 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code add} and {@code addAll} operations simply forward to the underlying 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * set, which throws an {@link UnsupportedOperationException} per the map and 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * multimap specification. 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned multimap is not serializable. 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entries the entries to constrain 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint for the entries 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified entries 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Set<Entry<K, V>> constrainedEntrySet( 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> entries, 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedEntrySet<K, V>(entries, constraint); 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedMap */ 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class ConstrainedMap<K, V> extends ForwardingMap<K, V> { 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Map<K, V> delegate; 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super K, ? super V> constraint; 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Set<Entry<K, V>> entrySet; 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedMap( 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> delegate, MapConstraint<? super K, ? super V> constraint) { 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = checkNotNull(delegate); 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.constraint = checkNotNull(constraint); 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Map<K, V> delegate() { 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, V>> entrySet() { 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, V>> result = entrySet; 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constrainedEntrySet(delegate.entrySet(), constraint); 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(K key, V value) { 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(key, value); 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.put(key, value); 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void putAll(Map<? extends K, ? extends V> map) { 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate.putAll(checkMap(map, constraint)); 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a constrained view of the specified bimap, using the specified 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constraint. Any operations that modify the bimap will have the associated 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys and values verified with the constraint. 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned bimap is not serializable. 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param map the bimap to constrain 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param constraint the constraint that validates added entries 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a constrained view of the specified bimap 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> BiMap<K, V> constrainedBiMap( 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BiMap<K, V> map, MapConstraint<? super K, ? super V> constraint) { 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ConstrainedBiMap<K, V>(map, null, constraint); 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedBiMap */ 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedBiMap<K, V> extends ConstrainedMap<K, V> 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements BiMap<K, V> { 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * We could switch to racy single-check lazy init and remove volatile, but 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * there's a downside. That's because this field is also written in the 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor. Without volatile, the constructor's write of the existing 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * inverse BiMap could occur after inverse()'s read of the field's initial 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * null value, leading inverse() to overwrite the existing inverse with a 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * doubly indirect version. This wouldn't be catastrophic, but it's 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * something to keep in mind if we make the change. 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Note that UnmodifiableBiMap *does* use racy single-check lazy init. 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(cpovirk): pick one and standardize 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert volatile BiMap<V, K> inverse; 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedBiMap(BiMap<K, V> delegate, @Nullable BiMap<V, K> inverse, 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate, constraint); 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.inverse = inverse; 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected BiMap<K, V> delegate() { 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (BiMap<K, V>) super.delegate(); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V forcePut(K key, V value) { 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(key, value); 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate().forcePut(key, value); 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public BiMap<V, K> inverse() { 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (inverse == null) { 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert inverse = new ConstrainedBiMap<V, K>(delegate().inverse(), this, 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new InverseConstraint<V, K>(constraint)); 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return inverse; 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> values() { 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate().values(); 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedBiMap */ 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class InverseConstraint<K, V> implements MapConstraint<K, V> { 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super V, ? super K> constraint; 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public InverseConstraint(MapConstraint<? super V, ? super K> constraint) { 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.constraint = checkNotNull(constraint); 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void checkKeyValue(K key, V value) { 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(value, key); 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedMultimap */ 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedMultimap<K, V> 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingMultimap<K, V> { 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super K, ? super V> constraint; 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multimap<K, V> delegate; 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Collection<Entry<K, V>> entries; 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient Map<K, Collection<V>> asMap; 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ConstrainedMultimap(Multimap<K, V> delegate, 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = checkNotNull(delegate); 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.constraint = checkNotNull(constraint); 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Multimap<K, V> delegate() { 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<K, Collection<V>> asMap() { 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, Collection<V>> result = asMap; 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Map<K, Collection<V>> asMapDelegate = delegate.asMap(); 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert asMap = result = new ForwardingMap<K, Collection<V>>() { 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> entrySet; 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Collection<V>> values; 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Map<K, Collection<V>> delegate() { 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return asMapDelegate; 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<K, Collection<V>>> entrySet() { 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> result = entrySet; 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entrySet = result = constrainedAsMapEntries( 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert asMapDelegate.entrySet(), constraint); 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(Object key) { 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> collection = ConstrainedMultimap.this.get((K) key); 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return collection.isEmpty() ? null : collection; 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException e) { 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; // key wasn't a K 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Collection<V>> values() { 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Collection<V>> result = values; 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert values = result = new ConstrainedAsMapValues<K, V>( 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate().values(), entrySet()); 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsValue(Object o) { 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return values().contains(o); 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<Entry<K, V>> entries() { 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<Entry<K, V>> result = entries; 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result == null) { 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entries = result = constrainedEntries(delegate.entries(), constraint); 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> get(final K key) { 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Constraints.constrainedTypePreservingCollection( 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate.get(key), new Constraint<V>() { 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V checkElement(V value) { 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(key, value); 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value; 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean put(K key, V value) { 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(key, value); 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.put(key, value); 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll(K key, Iterable<? extends V> values) { 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.putAll(key, checkValues(key, values, constraint)); 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean putAll( 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multimap<? extends K, ? extends V> multimap) { 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean changed = false; 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends K, ? extends V> entry : multimap.entries()) { 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changed |= put(entry.getKey(), entry.getValue()); 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return changed; 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Collection<V> replaceValues( 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate.replaceValues(key, checkValues(key, values, constraint)); 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see ConstrainedMultimap#asMap */ 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedAsMapValues<K, V> 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingCollection<Collection<V>> { 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Collection<Collection<V>> delegate; 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Set<Entry<K, Collection<V>>> entrySet; 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param entrySet map entries, linking each key with its corresponding 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values, that already enforce the constraint 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedAsMapValues(Collection<Collection<V>> delegate, 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Set<Entry<K, Collection<V>>> entrySet) { 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.delegate = delegate; 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.entrySet = entrySet; 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Collection<Collection<V>> delegate() { 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Collection<V>> iterator() { 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, Collection<V>>> iterator = entrySet.iterator(); 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Iterator<Collection<V>>() { 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean hasNext() { 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.hasNext(); 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Collection<V> next() { 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator.next().getValue(); 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void remove() { 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert iterator.remove(); 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContains(o); 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsAll(Collection<?> c) { 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContainsAll(c); 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRemove(o); 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRemoveAll(c); 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRetainAll(c); 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedEntries */ 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedEntries<K, V> 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingCollection<Entry<K, V>> { 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final MapConstraint<? super K, ? super V> constraint; 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Collection<Entry<K, V>> entries; 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedEntries(Collection<Entry<K, V>> entries, 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.entries = entries; 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.constraint = constraint; 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Collection<Entry<K, V>> delegate() { 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries; 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, V>> iterator() { 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, V>> iterator = entries.iterator(); 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingIterator<Entry<K, V>>() { 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, V> next() { 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return constrainedEntry(iterator.next(), constraint); 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Iterator<Entry<K, V>> delegate() { 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator; 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See Collections.CheckedMap.CheckedEntrySet for details on attacks. 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.containsEntryImpl(delegate(), o); 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsAll(Collection<?> c) { 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContainsAll(c); 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.removeEntryImpl(delegate(), o); 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRemoveAll(c); 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRetainAll(c); 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedEntrySet */ 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class ConstrainedEntrySet<K, V> 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ConstrainedEntries<K, V> implements Set<Entry<K, V>> { 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedEntrySet(Set<Entry<K, V>> entries, 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(entries, constraint); 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See Collections.CheckedMap.CheckedEntrySet for details on attacks. 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.equalsImpl(this, object); 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(this); 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** @see MapConstraints#constrainedAsMapEntries */ 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class ConstrainedAsMapEntries<K, V> 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingSet<Entry<K, Collection<V>>> { 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final MapConstraint<? super K, ? super V> constraint; 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final Set<Entry<K, Collection<V>>> entries; 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedAsMapEntries(Set<Entry<K, Collection<V>>> entries, 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.entries = entries; 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.constraint = constraint; 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Set<Entry<K, Collection<V>>> delegate() { 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entries; 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<K, Collection<V>>> iterator() { 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterator<Entry<K, Collection<V>>> iterator = entries.iterator(); 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ForwardingIterator<Entry<K, Collection<V>>>() { 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Entry<K, Collection<V>> next() { 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return constrainedAsMapEntry(iterator.next(), constraint); 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Iterator<Entry<K, Collection<V>>> delegate() { 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return iterator; 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // See Collections.CheckedMap.CheckedEntrySet for details on attacks. 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Object[] toArray() { 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(); 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> T[] toArray(T[] array) { 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardToArray(array); 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object o) { 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.containsEntryImpl(delegate(), o); 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsAll(Collection<?> c) { 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardContainsAll(c); 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object object) { 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardEquals(object); 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardHashCode(); 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean remove(Object o) { 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.removeEntryImpl(delegate(), o); 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean removeAll(Collection<?> c) { 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRemoveAll(c); 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean retainAll(Collection<?> c) { 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return standardRetainAll(c); 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedListMultimap<K, V> 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ConstrainedMultimap<K, V> implements ListMultimap<K, V> { 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedListMultimap(ListMultimap<K, V> delegate, 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate, constraint); 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> get(K key) { 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (List<V>) super.get(key); 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> removeAll(Object key) { 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (List<V>) super.removeAll(key); 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public List<V> replaceValues( 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (List<V>) super.replaceValues(key, values); 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedSetMultimap<K, V> 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ConstrainedMultimap<K, V> implements SetMultimap<K, V> { 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedSetMultimap(SetMultimap<K, V> delegate, 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate, constraint); 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> get(K key) { 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Set<V>) super.get(key); 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Map.Entry<K, V>> entries() { 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Set<Map.Entry<K, V>>) super.entries(); 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> removeAll(Object key) { 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Set<V>) super.removeAll(key); 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<V> replaceValues( 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Set<V>) super.replaceValues(key, values); 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class ConstrainedSortedSetMultimap<K, V> 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ConstrainedSetMultimap<K, V> implements SortedSetMultimap<K, V> { 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ConstrainedSortedSetMultimap(SortedSetMultimap<K, V> delegate, 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate, constraint); 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> get(K key) { 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedSet<V>) super.get(key); 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> removeAll(Object key) { 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedSet<V>) super.removeAll(key); 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public SortedSet<V> replaceValues( 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, Iterable<? extends V> values) { 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (SortedSet<V>) super.replaceValues(key, values); 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Comparator<? super V> valueComparator() { 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ((SortedSetMultimap<K, V>) delegate()).valueComparator(); 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Collection<V> checkValues(K key, 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<? extends V> values, 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> copy = Lists.newArrayList(values); 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V value : copy) { 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(key, value); 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copy; 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> Map<K, V> checkMap(Map<? extends K, ? extends V> map, 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MapConstraint<? super K, ? super V> constraint) { 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> copy = new LinkedHashMap<K, V>(map); 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<K, V> entry : copy.entrySet()) { 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert constraint.checkKeyValue(entry.getKey(), entry.getValue()); 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copy; 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 784