/* * Copyright (C) 2010 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import com.google.common.collect.Synchronized.SynchronizedNavigableMap; import com.google.common.collect.Synchronized.SynchronizedNavigableSet; import com.google.common.collect.Synchronized.SynchronizedSortedMap; import com.google.common.collect.testing.NavigableMapTestSuiteBuilder; import com.google.common.collect.testing.SafeTreeMap; import com.google.common.collect.testing.TestStringSortedMapGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.testing.SerializableTester; import junit.framework.TestSuite; import java.io.Serializable; import java.util.Comparator; import java.util.Map.Entry; import java.util.NavigableMap; import java.util.NavigableSet; import java.util.SortedMap; /** * Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}. * * @author Louis Wasserman */ public class SynchronizedNavigableMapTest extends SynchronizedMapTest { @Override protected NavigableMap create() { @SuppressWarnings("unchecked") NavigableMap innermost = new SafeTreeMap( (Comparator) Ordering.natural().nullsFirst()); TestMap inner = new TestMap(innermost, mutex); NavigableMap outer = Synchronized.navigableMap(inner, mutex); return outer; } static class TestEntry extends ForwardingMapEntry implements Serializable { private final Entry delegate; private final Object mutex; TestEntry(Entry delegate, Object mutex) { this.delegate = delegate; this.mutex = mutex; } @Override protected Entry delegate() { return delegate; } @Override public boolean equals(Object object) { assertTrue(Thread.holdsLock(mutex)); return super.equals(object); } @Override public K getKey() { assertTrue(Thread.holdsLock(mutex)); return super.getKey(); } @Override public V getValue() { assertTrue(Thread.holdsLock(mutex)); return super.getValue(); } @Override public int hashCode() { assertTrue(Thread.holdsLock(mutex)); return super.hashCode(); } @Override public V setValue(V value) { assertTrue(Thread.holdsLock(mutex)); return super.setValue(value); } private static final long serialVersionUID = 0; } static class TestMap extends SynchronizedMapTest.TestMap implements NavigableMap { public TestMap(NavigableMap delegate, Object mutex) { super(delegate, mutex); } @Override protected NavigableMap delegate() { return (NavigableMap) super.delegate(); } @Override public Entry ceilingEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().ceilingEntry(key); } @Override public K ceilingKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().ceilingKey(key); } @Override public NavigableSet descendingKeySet() { assertTrue(Thread.holdsLock(mutex)); return delegate().descendingKeySet(); } @Override public NavigableMap descendingMap() { assertTrue(Thread.holdsLock(mutex)); return delegate().descendingMap(); } @Override public Entry firstEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().firstEntry(); } @Override public Entry floorEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().floorEntry(key); } @Override public K floorKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().floorKey(key); } @Override public NavigableMap headMap(K toKey, boolean inclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().headMap(toKey, inclusive); } @Override public SortedMap headMap(K toKey) { return headMap(toKey, false); } @Override public Entry higherEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().higherEntry(key); } @Override public K higherKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().higherKey(key); } @Override public Entry lastEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().lastEntry(); } @Override public Entry lowerEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().lowerEntry(key); } @Override public K lowerKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().lowerKey(key); } @Override public NavigableSet navigableKeySet() { assertTrue(Thread.holdsLock(mutex)); return delegate().navigableKeySet(); } @Override public Entry pollFirstEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().pollFirstEntry(); } @Override public Entry pollLastEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().pollLastEntry(); } @Override public NavigableMap subMap( K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive); } @Override public SortedMap subMap(K fromKey, K toKey) { return delegate().subMap(fromKey, true, toKey, false); } @Override public NavigableMap tailMap(K fromKey, boolean inclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().tailMap(fromKey, inclusive); } @Override public SortedMap tailMap(K fromKey) { return tailMap(fromKey, true); } @Override public Comparator comparator() { assertTrue(Thread.holdsLock(mutex)); return delegate().comparator(); } @Override public K firstKey() { assertTrue(Thread.holdsLock(mutex)); return delegate().firstKey(); } @Override public K lastKey() { assertTrue(Thread.holdsLock(mutex)); return delegate().lastKey(); } private static final long serialVersionUID = 0; } public static TestSuite suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(SynchronizedNavigableMapTest.class); suite.addTest( NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { private final Object mutex = new Integer(1); @Override protected SortedMap create( Entry[] entries) { NavigableMap innermost = new SafeTreeMap(); for (Entry entry : entries) { innermost.put(entry.getKey(), entry.getValue()); } TestMap inner = new TestMap(innermost, mutex); NavigableMap outer = Synchronized.navigableMap(inner, mutex); return outer; } }).named("Maps.synchronizedNavigableMap[SafeTreeMap]") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_VALUES, CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); return suite; } public void testComparator() { create().comparator(); } public void testCeilingEntry() { create().ceilingEntry("a"); } public void testCeilingKey() { create().ceilingKey("a"); } public void testDescendingKeySet() { NavigableMap map = create(); NavigableSet descendingKeySet = map.descendingKeySet(); assertTrue(descendingKeySet instanceof SynchronizedNavigableSet); assertSame( mutex, ((SynchronizedNavigableSet) descendingKeySet).mutex); } public void testDescendingMap() { NavigableMap map = create(); NavigableMap descendingMap = map.descendingMap(); assertTrue(descendingMap instanceof SynchronizedNavigableMap); assertSame(mutex, ((SynchronizedNavigableMap) descendingMap).mutex); } public void testFirstEntry() { create().firstEntry(); } public void testFirstKey() { NavigableMap map = create(); map.put("a", 1); map.firstKey(); } public void testFloorEntry() { create().floorEntry("a"); } public void testFloorKey() { create().floorKey("a"); } public void testHeadMap_K() { NavigableMap map = create(); SortedMap headMap = map.headMap("a"); assertTrue(headMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap) headMap).mutex); } public void testHeadMap_K_B() { NavigableMap map = create(); NavigableMap headMap = map.headMap("a", true); assertTrue(headMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap) headMap).mutex); } public void testHigherEntry() { create().higherEntry("a"); } public void testHigherKey() { create().higherKey("a"); } public void testLastEntry() { create().lastEntry(); } public void testLastKey() { NavigableMap map = create(); map.put("a", 1); map.lastKey(); } public void testLowerEntry() { create().lowerEntry("a"); } public void testLowerKey() { create().lowerKey("a"); } public void testNavigableKeySet() { NavigableMap map = create(); NavigableSet navigableKeySet = map.navigableKeySet(); assertTrue(navigableKeySet instanceof SynchronizedNavigableSet); assertSame( mutex, ((SynchronizedNavigableSet) navigableKeySet).mutex); } public void testPollFirstEntry() { create().pollFirstEntry(); } public void testPollLastEntry() { create().pollLastEntry(); } public void testSubMap_K_K() { NavigableMap map = create(); SortedMap subMap = map.subMap("a", "b"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap) subMap).mutex); } public void testSubMap_K_B_K_B() { NavigableMap map = create(); NavigableMap subMap = map.subMap("a", true, "b", false); assertTrue(subMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap) subMap).mutex); } public void testTailMap_K() { NavigableMap map = create(); SortedMap subMap = map.tailMap("a"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap) subMap).mutex); } public void testTailMap_K_B() { NavigableMap map = create(); NavigableMap subMap = map.tailMap("a", true); assertTrue(subMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap) subMap).mutex); } @Override public void testSerialization() { SerializableTester.reserializeAndAssert(create()); } }