/*
* Copyright (C) 2007 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 static com.google.common.base.
Preconditions.checkNotNull;
import com.google.common.annotations.
GwtCompatible;
import com.google.common.annotations.
GwtIncompatible;
import com.google.common.annotations.
VisibleForTesting;
import java.io.
IOException;
import java.io.
ObjectOutputStream;
import java.io.
Serializable;
import java.util.
Collection;
import java.util.
Comparator;
import java.util.
Deque;
import java.util.
Iterator;
import java.util.
List;
import java.util.
ListIterator;
import java.util.
Map;
import java.util.
Map.
Entry;
import java.util.
NavigableMap;
import java.util.
NavigableSet;
import java.util.
Queue;
import java.util.
RandomAccess;
import java.util.
Set;
import java.util.
SortedMap;
import java.util.
SortedSet;
import javax.annotation.
Nullable;
/**
* Synchronized collection views. The returned synchronized collection views are
* serializable if the backing collection and the mutex are serializable.
*
* <p>If {@code null} is passed as the {@code mutex} parameter to any of this
* class's top-level methods or inner class constructors, the created object
* uses itself as the synchronization mutex.
*
* <p>This class should be used by other collection classes only.
*
* @author Mike Bostock
* @author Jared Levy
*/
@
GwtCompatible(emulated = true)
final class
Synchronized {
private
Synchronized() {}
static class
SynchronizedObject implements
Serializable {
final
Object delegate;
final
Object mutex;
SynchronizedObject(
Object delegate, @
Nullable Object mutex) {
this.
delegate =
checkNotNull(
delegate);
this.
mutex = (
mutex == null) ? this :
mutex;
}
Object delegate() {
return
delegate;
}
// No equals and hashCode; see ForwardingObject for details.
@
Override public
String toString() {
synchronized (
mutex) {
return
delegate.
toString();
}
}
// Serialization invokes writeObject only when it's private.
// The SynchronizedObject subclasses don't need a writeObject method since
// they don't contain any non-transient member variables, while the
// following writeObject() handles the SynchronizedObject members.
@
GwtIncompatible("java.io.ObjectOutputStream")
private void
writeObject(
ObjectOutputStream stream) throws
IOException {
synchronized (
mutex) {
stream.
defaultWriteObject();
}
}
@
GwtIncompatible("not needed in emulated source")
private static final long
serialVersionUID = 0;
}
private static <E>
Collection<E>
collection(
Collection<E>
collection, @
Nullable Object mutex) {
return new
SynchronizedCollection<E>(
collection,
mutex);
}
@
VisibleForTesting static class
SynchronizedCollection<E>
extends
SynchronizedObject implements
Collection<E> {
private
SynchronizedCollection(
Collection<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
SuppressWarnings("unchecked")
@
Override Collection<E>
delegate() {
return (
Collection<E>) super.delegate();
}
@
Override
public boolean
add(E
e) {
synchronized (
mutex) {
return
delegate().
add(
e);
}
}
@
Override
public boolean
addAll(
Collection<? extends E>
c) {
synchronized (
mutex) {
return
delegate().
addAll(
c);
}
}
@
Override
public void
clear() {
synchronized (
mutex) {
delegate().
clear();
}
}
@
Override
public boolean
contains(
Object o) {
synchronized (
mutex) {
return
delegate().
contains(
o);
}
}
@
Override
public boolean
containsAll(
Collection<?>
c) {
synchronized (
mutex) {
return
delegate().
containsAll(
c);
}
}
@
Override
public boolean
isEmpty() {
synchronized (
mutex) {
return
delegate().
isEmpty();
}
}
@
Override
public
Iterator<E>
iterator() {
return
delegate().
iterator(); // manually synchronized
}
@
Override
public boolean
remove(
Object o) {
synchronized (
mutex) {
return
delegate().
remove(
o);
}
}
@
Override
public boolean
removeAll(
Collection<?>
c) {
synchronized (
mutex) {
return
delegate().
removeAll(
c);
}
}
@
Override
public boolean
retainAll(
Collection<?>
c) {
synchronized (
mutex) {
return
delegate().
retainAll(
c);
}
}
@
Override
public int
size() {
synchronized (
mutex) {
return
delegate().
size();
}
}
@
Override
public
Object[]
toArray() {
synchronized (
mutex) {
return
delegate().
toArray();
}
}
@
Override
public <T> T[]
toArray(T[]
a) {
synchronized (
mutex) {
return
delegate().
toArray(
a);
}
}
private static final long
serialVersionUID = 0;
}
@
VisibleForTesting static <E>
Set<E>
set(
Set<E>
set, @
Nullable Object mutex) {
return new
SynchronizedSet<E>(
set,
mutex);
}
static class
SynchronizedSet<E>
extends
SynchronizedCollection<E> implements
Set<E> {
SynchronizedSet(
Set<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override Set<E>
delegate() {
return (
Set<E>) super.delegate();
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
delegate().
equals(
o);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
private static final long
serialVersionUID = 0;
}
private static <E>
SortedSet<E>
sortedSet(
SortedSet<E>
set, @
Nullable Object mutex) {
return new
SynchronizedSortedSet<E>(
set,
mutex);
}
static class
SynchronizedSortedSet<E> extends
SynchronizedSet<E>
implements
SortedSet<E> {
SynchronizedSortedSet(
SortedSet<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override SortedSet<E>
delegate() {
return (
SortedSet<E>) super.delegate();
}
@
Override
public
Comparator<? super E>
comparator() {
synchronized (
mutex) {
return
delegate().
comparator();
}
}
@
Override
public
SortedSet<E>
subSet(E
fromElement, E
toElement) {
synchronized (
mutex) {
return
sortedSet(
delegate().
subSet(
fromElement,
toElement),
mutex);
}
}
@
Override
public
SortedSet<E>
headSet(E
toElement) {
synchronized (
mutex) {
return
sortedSet(
delegate().
headSet(
toElement),
mutex);
}
}
@
Override
public
SortedSet<E>
tailSet(E
fromElement) {
synchronized (
mutex) {
return
sortedSet(
delegate().
tailSet(
fromElement),
mutex);
}
}
@
Override
public E
first() {
synchronized (
mutex) {
return
delegate().
first();
}
}
@
Override
public E
last() {
synchronized (
mutex) {
return
delegate().
last();
}
}
private static final long
serialVersionUID = 0;
}
private static <E>
List<E>
list(
List<E>
list, @
Nullable Object mutex) {
return (
list instanceof
RandomAccess)
? new
SynchronizedRandomAccessList<E>(
list,
mutex)
: new
SynchronizedList<E>(
list,
mutex);
}
private static class
SynchronizedList<E> extends
SynchronizedCollection<E>
implements
List<E> {
SynchronizedList(
List<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override List<E>
delegate() {
return (
List<E>) super.delegate();
}
@
Override
public void
add(int
index, E
element) {
synchronized (
mutex) {
delegate().
add(
index,
element);
}
}
@
Override
public boolean
addAll(int
index,
Collection<? extends E>
c) {
synchronized (
mutex) {
return
delegate().
addAll(
index,
c);
}
}
@
Override
public E
get(int
index) {
synchronized (
mutex) {
return
delegate().
get(
index);
}
}
@
Override
public int
indexOf(
Object o) {
synchronized (
mutex) {
return
delegate().
indexOf(
o);
}
}
@
Override
public int
lastIndexOf(
Object o) {
synchronized (
mutex) {
return
delegate().
lastIndexOf(
o);
}
}
@
Override
public
ListIterator<E>
listIterator() {
return
delegate().
listIterator(); // manually synchronized
}
@
Override
public
ListIterator<E>
listIterator(int
index) {
return
delegate().
listIterator(
index); // manually synchronized
}
@
Override
public E
remove(int
index) {
synchronized (
mutex) {
return
delegate().
remove(
index);
}
}
@
Override
public E
set(int
index, E
element) {
synchronized (
mutex) {
return
delegate().
set(
index,
element);
}
}
@
Override
public
List<E>
subList(int
fromIndex, int
toIndex) {
synchronized (
mutex) {
return
list(
delegate().
subList(
fromIndex,
toIndex),
mutex);
}
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
delegate().
equals(
o);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
private static final long
serialVersionUID = 0;
}
private static class
SynchronizedRandomAccessList<E>
extends
SynchronizedList<E> implements
RandomAccess {
SynchronizedRandomAccessList(
List<E>
list, @
Nullable Object mutex) {
super(
list,
mutex);
}
private static final long
serialVersionUID = 0;
}
static <E>
Multiset<E>
multiset(
Multiset<E>
multiset, @
Nullable Object mutex) {
if (
multiset instanceof
SynchronizedMultiset ||
multiset instanceof
ImmutableMultiset) {
return
multiset;
}
return new
SynchronizedMultiset<E>(
multiset,
mutex);
}
private static class
SynchronizedMultiset<E> extends
SynchronizedCollection<E>
implements
Multiset<E> {
transient
Set<E>
elementSet;
transient
Set<
Entry<E>>
entrySet;
SynchronizedMultiset(
Multiset<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override Multiset<E>
delegate() {
return (
Multiset<E>) super.delegate();
}
@
Override
public int
count(
Object o) {
synchronized (
mutex) {
return
delegate().
count(
o);
}
}
@
Override
public int
add(E
e, int
n) {
synchronized (
mutex) {
return
delegate().
add(
e,
n);
}
}
@
Override
public int
remove(
Object o, int
n) {
synchronized (
mutex) {
return
delegate().
remove(
o,
n);
}
}
@
Override
public int
setCount(E
element, int
count) {
synchronized (
mutex) {
return
delegate().
setCount(
element,
count);
}
}
@
Override
public boolean
setCount(E
element, int
oldCount, int
newCount) {
synchronized (
mutex) {
return
delegate().
setCount(
element,
oldCount,
newCount);
}
}
@
Override
public
Set<E>
elementSet() {
synchronized (
mutex) {
if (
elementSet == null) {
elementSet =
typePreservingSet(
delegate().
elementSet(),
mutex);
}
return
elementSet;
}
}
@
Override
public
Set<
Entry<E>>
entrySet() {
synchronized (
mutex) {
if (
entrySet == null) {
entrySet =
typePreservingSet(
delegate().
entrySet(),
mutex);
}
return
entrySet;
}
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
delegate().
equals(
o);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
Multimap<K, V>
multimap(
Multimap<K, V>
multimap, @
Nullable Object mutex) {
if (
multimap instanceof
SynchronizedMultimap ||
multimap instanceof
ImmutableMultimap) {
return
multimap;
}
return new
SynchronizedMultimap<K, V>(
multimap,
mutex);
}
private static class
SynchronizedMultimap<K, V> extends
SynchronizedObject
implements
Multimap<K, V> {
transient
Set<K>
keySet;
transient
Collection<V>
valuesCollection;
transient
Collection<
Map.
Entry<K, V>>
entries;
transient
Map<K,
Collection<V>>
asMap;
transient
Multiset<K>
keys;
@
SuppressWarnings("unchecked")
@
Override Multimap<K, V>
delegate() {
return (
Multimap<K, V>) super.delegate();
}
SynchronizedMultimap(
Multimap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override
public int
size() {
synchronized (
mutex) {
return
delegate().
size();
}
}
@
Override
public boolean
isEmpty() {
synchronized (
mutex) {
return
delegate().
isEmpty();
}
}
@
Override
public boolean
containsKey(
Object key) {
synchronized (
mutex) {
return
delegate().
containsKey(
key);
}
}
@
Override
public boolean
containsValue(
Object value) {
synchronized (
mutex) {
return
delegate().
containsValue(
value);
}
}
@
Override
public boolean
containsEntry(
Object key,
Object value) {
synchronized (
mutex) {
return
delegate().
containsEntry(
key,
value);
}
}
@
Override
public
Collection<V>
get(K
key) {
synchronized (
mutex) {
return
typePreservingCollection(
delegate().
get(
key),
mutex);
}
}
@
Override
public boolean
put(K
key, V
value) {
synchronized (
mutex) {
return
delegate().
put(
key,
value);
}
}
@
Override
public boolean
putAll(K
key,
Iterable<? extends V>
values) {
synchronized (
mutex) {
return
delegate().
putAll(
key,
values);
}
}
@
Override
public boolean
putAll(
Multimap<? extends K, ? extends V>
multimap) {
synchronized (
mutex) {
return
delegate().
putAll(
multimap);
}
}
@
Override
public
Collection<V>
replaceValues(K
key,
Iterable<? extends V>
values) {
synchronized (
mutex) {
return
delegate().
replaceValues(
key,
values); // copy not synchronized
}
}
@
Override
public boolean
remove(
Object key,
Object value) {
synchronized (
mutex) {
return
delegate().
remove(
key,
value);
}
}
@
Override
public
Collection<V>
removeAll(
Object key) {
synchronized (
mutex) {
return
delegate().
removeAll(
key); // copy not synchronized
}
}
@
Override
public void
clear() {
synchronized (
mutex) {
delegate().
clear();
}
}
@
Override
public
Set<K>
keySet() {
synchronized (
mutex) {
if (
keySet == null) {
keySet =
typePreservingSet(
delegate().
keySet(),
mutex);
}
return
keySet;
}
}
@
Override
public
Collection<V>
values() {
synchronized (
mutex) {
if (
valuesCollection == null) {
valuesCollection =
collection(
delegate().
values(),
mutex);
}
return
valuesCollection;
}
}
@
Override
public
Collection<
Map.
Entry<K, V>>
entries() {
synchronized (
mutex) {
if (
entries == null) {
entries =
typePreservingCollection(
delegate().
entries(),
mutex);
}
return
entries;
}
}
@
Override
public
Map<K,
Collection<V>>
asMap() {
synchronized (
mutex) {
if (
asMap == null) {
asMap = new
SynchronizedAsMap<K, V>(
delegate().
asMap(),
mutex);
}
return
asMap;
}
}
@
Override
public
Multiset<K>
keys() {
synchronized (
mutex) {
if (
keys == null) {
keys =
multiset(
delegate().
keys(),
mutex);
}
return
keys;
}
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
delegate().
equals(
o);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
ListMultimap<K, V>
listMultimap(
ListMultimap<K, V>
multimap, @
Nullable Object mutex) {
if (
multimap instanceof
SynchronizedListMultimap ||
multimap instanceof
ImmutableListMultimap) {
return
multimap;
}
return new
SynchronizedListMultimap<K, V>(
multimap,
mutex);
}
private static class
SynchronizedListMultimap<K, V>
extends
SynchronizedMultimap<K, V> implements
ListMultimap<K, V> {
SynchronizedListMultimap(
ListMultimap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override ListMultimap<K, V>
delegate() {
return (
ListMultimap<K, V>) super.delegate();
}
@
Override public
List<V>
get(K
key) {
synchronized (
mutex) {
return
list(
delegate().
get(
key),
mutex);
}
}
@
Override public
List<V>
removeAll(
Object key) {
synchronized (
mutex) {
return
delegate().
removeAll(
key); // copy not synchronized
}
}
@
Override public
List<V>
replaceValues(
K
key,
Iterable<? extends V>
values) {
synchronized (
mutex) {
return
delegate().
replaceValues(
key,
values); // copy not synchronized
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
SetMultimap<K, V>
setMultimap(
SetMultimap<K, V>
multimap, @
Nullable Object mutex) {
if (
multimap instanceof
SynchronizedSetMultimap ||
multimap instanceof
ImmutableSetMultimap) {
return
multimap;
}
return new
SynchronizedSetMultimap<K, V>(
multimap,
mutex);
}
private static class
SynchronizedSetMultimap<K, V>
extends
SynchronizedMultimap<K, V> implements
SetMultimap<K, V> {
transient
Set<
Map.
Entry<K, V>>
entrySet;
SynchronizedSetMultimap(
SetMultimap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override SetMultimap<K, V>
delegate() {
return (
SetMultimap<K, V>) super.delegate();
}
@
Override public
Set<V>
get(K
key) {
synchronized (
mutex) {
return
set(
delegate().
get(
key),
mutex);
}
}
@
Override public
Set<V>
removeAll(
Object key) {
synchronized (
mutex) {
return
delegate().
removeAll(
key); // copy not synchronized
}
}
@
Override public
Set<V>
replaceValues(
K
key,
Iterable<? extends V>
values) {
synchronized (
mutex) {
return
delegate().
replaceValues(
key,
values); // copy not synchronized
}
}
@
Override public
Set<
Map.
Entry<K, V>>
entries() {
synchronized (
mutex) {
if (
entrySet == null) {
entrySet =
set(
delegate().
entries(),
mutex);
}
return
entrySet;
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
SortedSetMultimap<K, V>
sortedSetMultimap(
SortedSetMultimap<K, V>
multimap, @
Nullable Object mutex) {
if (
multimap instanceof
SynchronizedSortedSetMultimap) {
return
multimap;
}
return new
SynchronizedSortedSetMultimap<K, V>(
multimap,
mutex);
}
private static class
SynchronizedSortedSetMultimap<K, V>
extends
SynchronizedSetMultimap<K, V> implements
SortedSetMultimap<K, V> {
SynchronizedSortedSetMultimap(
SortedSetMultimap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override SortedSetMultimap<K, V>
delegate() {
return (
SortedSetMultimap<K, V>) super.delegate();
}
@
Override public
SortedSet<V>
get(K
key) {
synchronized (
mutex) {
return
sortedSet(
delegate().
get(
key),
mutex);
}
}
@
Override public
SortedSet<V>
removeAll(
Object key) {
synchronized (
mutex) {
return
delegate().
removeAll(
key); // copy not synchronized
}
}
@
Override public
SortedSet<V>
replaceValues(
K
key,
Iterable<? extends V>
values) {
synchronized (
mutex) {
return
delegate().
replaceValues(
key,
values); // copy not synchronized
}
}
@
Override
public
Comparator<? super V>
valueComparator() {
synchronized (
mutex) {
return
delegate().
valueComparator();
}
}
private static final long
serialVersionUID = 0;
}
private static <E>
Collection<E>
typePreservingCollection(
Collection<E>
collection, @
Nullable Object mutex) {
if (
collection instanceof
SortedSet) {
return
sortedSet((
SortedSet<E>)
collection,
mutex);
}
if (
collection instanceof
Set) {
return
set((
Set<E>)
collection,
mutex);
}
if (
collection instanceof
List) {
return
list((
List<E>)
collection,
mutex);
}
return
collection(
collection,
mutex);
}
private static <E>
Set<E>
typePreservingSet(
Set<E>
set, @
Nullable Object mutex) {
if (
set instanceof
SortedSet) {
return
sortedSet((
SortedSet<E>)
set,
mutex);
} else {
return
set(
set,
mutex);
}
}
private static class
SynchronizedAsMapEntries<K, V>
extends
SynchronizedSet<
Map.
Entry<K,
Collection<V>>> {
SynchronizedAsMapEntries(
Set<
Map.
Entry<K,
Collection<V>>>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override public
Iterator<
Map.
Entry<K,
Collection<V>>>
iterator() {
// Must be manually synchronized.
final
Iterator<
Map.
Entry<K,
Collection<V>>>
iterator = super.iterator();
return new
ForwardingIterator<
Map.
Entry<K,
Collection<V>>>() {
@
Override protected
Iterator<
Map.
Entry<K,
Collection<V>>>
delegate() {
return
iterator;
}
@
Override public
Map.
Entry<K,
Collection<V>>
next() {
final
Map.
Entry<K,
Collection<V>>
entry = super.next();
return new
ForwardingMapEntry<K,
Collection<V>>() {
@
Override protected
Map.
Entry<K,
Collection<V>>
delegate() {
return
entry;
}
@
Override public
Collection<V>
getValue() {
return
typePreservingCollection(
entry.
getValue(),
mutex);
}
};
}
};
}
// See Collections.CheckedMap.CheckedEntrySet for details on attacks.
@
Override public
Object[]
toArray() {
synchronized (
mutex) {
return
ObjectArrays.
toArrayImpl(
delegate());
}
}
@
Override public <T> T[]
toArray(T[]
array) {
synchronized (
mutex) {
return
ObjectArrays.
toArrayImpl(
delegate(),
array);
}
}
@
Override public boolean
contains(
Object o) {
synchronized (
mutex) {
return
Maps.
containsEntryImpl(
delegate(),
o);
}
}
@
Override public boolean
containsAll(
Collection<?>
c) {
synchronized (
mutex) {
return
Collections2.
containsAllImpl(
delegate(),
c);
}
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
Sets.
equalsImpl(
delegate(),
o);
}
}
@
Override public boolean
remove(
Object o) {
synchronized (
mutex) {
return
Maps.
removeEntryImpl(
delegate(),
o);
}
}
@
Override public boolean
removeAll(
Collection<?>
c) {
synchronized (
mutex) {
return
Iterators.
removeAll(
delegate().
iterator(),
c);
}
}
@
Override public boolean
retainAll(
Collection<?>
c) {
synchronized (
mutex) {
return
Iterators.
retainAll(
delegate().
iterator(),
c);
}
}
private static final long
serialVersionUID = 0;
}
@
VisibleForTesting
static <K, V>
Map<K, V>
map(
Map<K, V>
map, @
Nullable Object mutex) {
return new
SynchronizedMap<K, V>(
map,
mutex);
}
private static class
SynchronizedMap<K, V> extends
SynchronizedObject
implements
Map<K, V> {
transient
Set<K>
keySet;
transient
Collection<V>
values;
transient
Set<
Map.
Entry<K, V>>
entrySet;
SynchronizedMap(
Map<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
SuppressWarnings("unchecked")
@
Override Map<K, V>
delegate() {
return (
Map<K, V>) super.delegate();
}
@
Override
public void
clear() {
synchronized (
mutex) {
delegate().
clear();
}
}
@
Override
public boolean
containsKey(
Object key) {
synchronized (
mutex) {
return
delegate().
containsKey(
key);
}
}
@
Override
public boolean
containsValue(
Object value) {
synchronized (
mutex) {
return
delegate().
containsValue(
value);
}
}
@
Override
public
Set<
Map.
Entry<K, V>>
entrySet() {
synchronized (
mutex) {
if (
entrySet == null) {
entrySet =
set(
delegate().
entrySet(),
mutex);
}
return
entrySet;
}
}
@
Override
public V
get(
Object key) {
synchronized (
mutex) {
return
delegate().
get(
key);
}
}
@
Override
public boolean
isEmpty() {
synchronized (
mutex) {
return
delegate().
isEmpty();
}
}
@
Override
public
Set<K>
keySet() {
synchronized (
mutex) {
if (
keySet == null) {
keySet =
set(
delegate().
keySet(),
mutex);
}
return
keySet;
}
}
@
Override
public V
put(K
key, V
value) {
synchronized (
mutex) {
return
delegate().
put(
key,
value);
}
}
@
Override
public void
putAll(
Map<? extends K, ? extends V>
map) {
synchronized (
mutex) {
delegate().
putAll(
map);
}
}
@
Override
public V
remove(
Object key) {
synchronized (
mutex) {
return
delegate().
remove(
key);
}
}
@
Override
public int
size() {
synchronized (
mutex) {
return
delegate().
size();
}
}
@
Override
public
Collection<V>
values() {
synchronized (
mutex) {
if (
values == null) {
values =
collection(
delegate().
values(),
mutex);
}
return
values;
}
}
@
Override public boolean
equals(
Object o) {
if (
o == this) {
return true;
}
synchronized (
mutex) {
return
delegate().
equals(
o);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
SortedMap<K, V>
sortedMap(
SortedMap<K, V>
sortedMap, @
Nullable Object mutex) {
return new
SynchronizedSortedMap<K, V>(
sortedMap,
mutex);
}
static class
SynchronizedSortedMap<K, V> extends
SynchronizedMap<K, V>
implements
SortedMap<K, V> {
SynchronizedSortedMap(
SortedMap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override SortedMap<K, V>
delegate() {
return (
SortedMap<K, V>) super.delegate();
}
@
Override public
Comparator<? super K>
comparator() {
synchronized (
mutex) {
return
delegate().
comparator();
}
}
@
Override public K
firstKey() {
synchronized (
mutex) {
return
delegate().
firstKey();
}
}
@
Override public
SortedMap<K, V>
headMap(K
toKey) {
synchronized (
mutex) {
return
sortedMap(
delegate().
headMap(
toKey),
mutex);
}
}
@
Override public K
lastKey() {
synchronized (
mutex) {
return
delegate().
lastKey();
}
}
@
Override public
SortedMap<K, V>
subMap(K
fromKey, K
toKey) {
synchronized (
mutex) {
return
sortedMap(
delegate().
subMap(
fromKey,
toKey),
mutex);
}
}
@
Override public
SortedMap<K, V>
tailMap(K
fromKey) {
synchronized (
mutex) {
return
sortedMap(
delegate().
tailMap(
fromKey),
mutex);
}
}
private static final long
serialVersionUID = 0;
}
static <K, V>
BiMap<K, V>
biMap(
BiMap<K, V>
bimap, @
Nullable Object mutex) {
if (
bimap instanceof
SynchronizedBiMap ||
bimap instanceof
ImmutableBiMap) {
return
bimap;
}
return new
SynchronizedBiMap<K, V>(
bimap,
mutex, null);
}
@
VisibleForTesting static class
SynchronizedBiMap<K, V>
extends
SynchronizedMap<K, V> implements
BiMap<K, V>,
Serializable {
private transient
Set<V>
valueSet;
private transient
BiMap<V, K>
inverse;
private
SynchronizedBiMap(
BiMap<K, V>
delegate, @
Nullable Object mutex,
@
Nullable BiMap<V, K>
inverse) {
super(
delegate,
mutex);
this.
inverse =
inverse;
}
@
Override BiMap<K, V>
delegate() {
return (
BiMap<K, V>) super.delegate();
}
@
Override public
Set<V>
values() {
synchronized (
mutex) {
if (
valueSet == null) {
valueSet =
set(
delegate().
values(),
mutex);
}
return
valueSet;
}
}
@
Override
public V
forcePut(K
key, V
value) {
synchronized (
mutex) {
return
delegate().
forcePut(
key,
value);
}
}
@
Override
public
BiMap<V, K>
inverse() {
synchronized (
mutex) {
if (
inverse == null) {
inverse
= new
SynchronizedBiMap<V, K>(
delegate().
inverse(),
mutex, this);
}
return
inverse;
}
}
private static final long
serialVersionUID = 0;
}
private static class
SynchronizedAsMap<K, V>
extends
SynchronizedMap<K,
Collection<V>> {
transient
Set<
Map.
Entry<K,
Collection<V>>>
asMapEntrySet;
transient
Collection<
Collection<V>>
asMapValues;
SynchronizedAsMap(
Map<K,
Collection<V>>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override public
Collection<V>
get(
Object key) {
synchronized (
mutex) {
Collection<V>
collection = super.get(
key);
return (
collection == null) ? null
:
typePreservingCollection(
collection,
mutex);
}
}
@
Override public
Set<
Map.
Entry<K,
Collection<V>>>
entrySet() {
synchronized (
mutex) {
if (
asMapEntrySet == null) {
asMapEntrySet = new
SynchronizedAsMapEntries<K, V>(
delegate().
entrySet(),
mutex);
}
return
asMapEntrySet;
}
}
@
Override public
Collection<
Collection<V>>
values() {
synchronized (
mutex) {
if (
asMapValues == null) {
asMapValues
= new
SynchronizedAsMapValues<V>(
delegate().
values(),
mutex);
}
return
asMapValues;
}
}
@
Override public boolean
containsValue(
Object o) {
// values() and its contains() method are both synchronized.
return
values().
contains(
o);
}
private static final long
serialVersionUID = 0;
}
private static class
SynchronizedAsMapValues<V>
extends
SynchronizedCollection<
Collection<V>> {
SynchronizedAsMapValues(
Collection<
Collection<V>>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override public
Iterator<
Collection<V>>
iterator() {
// Must be manually synchronized.
final
Iterator<
Collection<V>>
iterator = super.iterator();
return new
ForwardingIterator<
Collection<V>>() {
@
Override protected
Iterator<
Collection<V>>
delegate() {
return
iterator;
}
@
Override public
Collection<V>
next() {
return
typePreservingCollection(super.next(),
mutex);
}
};
}
private static final long
serialVersionUID = 0;
}
@
GwtIncompatible("NavigableSet")
@
VisibleForTesting
static class
SynchronizedNavigableSet<E> extends
SynchronizedSortedSet<E>
implements
NavigableSet<E> {
SynchronizedNavigableSet(
NavigableSet<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override NavigableSet<E>
delegate() {
return (
NavigableSet<E>) super.delegate();
}
@
Override public E
ceiling(E
e) {
synchronized (
mutex) {
return
delegate().
ceiling(
e);
}
}
@
Override public
Iterator<E>
descendingIterator() {
return
delegate().
descendingIterator(); // manually synchronized
}
transient
NavigableSet<E>
descendingSet;
@
Override public
NavigableSet<E>
descendingSet() {
synchronized (
mutex) {
if (
descendingSet == null) {
NavigableSet<E>
dS =
Synchronized.
navigableSet(
delegate().
descendingSet(),
mutex);
descendingSet =
dS;
return
dS;
}
return
descendingSet;
}
}
@
Override public E
floor(E
e) {
synchronized (
mutex) {
return
delegate().
floor(
e);
}
}
@
Override public
NavigableSet<E>
headSet(E
toElement, boolean
inclusive) {
synchronized (
mutex) {
return
Synchronized.
navigableSet(
delegate().
headSet(
toElement,
inclusive),
mutex);
}
}
@
Override public E
higher(E
e) {
synchronized (
mutex) {
return
delegate().
higher(
e);
}
}
@
Override public E
lower(E
e) {
synchronized (
mutex) {
return
delegate().
lower(
e);
}
}
@
Override public E
pollFirst() {
synchronized (
mutex) {
return
delegate().
pollFirst();
}
}
@
Override public E
pollLast() {
synchronized (
mutex) {
return
delegate().
pollLast();
}
}
@
Override public
NavigableSet<E>
subSet(E
fromElement,
boolean
fromInclusive, E
toElement, boolean
toInclusive) {
synchronized (
mutex) {
return
Synchronized.
navigableSet(
delegate().
subSet(
fromElement,
fromInclusive,
toElement,
toInclusive),
mutex);
}
}
@
Override public
NavigableSet<E>
tailSet(E
fromElement, boolean
inclusive) {
synchronized (
mutex) {
return
Synchronized.
navigableSet(
delegate().
tailSet(
fromElement,
inclusive),
mutex);
}
}
@
Override public
SortedSet<E>
headSet(E
toElement) {
return
headSet(
toElement, false);
}
@
Override public
SortedSet<E>
subSet(E
fromElement, E
toElement) {
return
subSet(
fromElement, true,
toElement, false);
}
@
Override public
SortedSet<E>
tailSet(E
fromElement) {
return
tailSet(
fromElement, true);
}
private static final long
serialVersionUID = 0;
}
@
GwtIncompatible("NavigableSet")
static <E>
NavigableSet<E>
navigableSet(
NavigableSet<E>
navigableSet, @
Nullable Object mutex) {
return new
SynchronizedNavigableSet<E>(
navigableSet,
mutex);
}
@
GwtIncompatible("NavigableSet")
static <E>
NavigableSet<E>
navigableSet(
NavigableSet<E>
navigableSet) {
return
navigableSet(
navigableSet, null);
}
@
GwtIncompatible("NavigableMap")
static <K, V>
NavigableMap<K, V>
navigableMap(
NavigableMap<K, V>
navigableMap) {
return
navigableMap(
navigableMap, null);
}
@
GwtIncompatible("NavigableMap")
static <K, V>
NavigableMap<K, V>
navigableMap(
NavigableMap<K, V>
navigableMap, @
Nullable Object mutex) {
return new
SynchronizedNavigableMap<K, V>(
navigableMap,
mutex);
}
@
GwtIncompatible("NavigableMap")
@
VisibleForTesting static class
SynchronizedNavigableMap<K, V>
extends
SynchronizedSortedMap<K, V> implements
NavigableMap<K, V> {
SynchronizedNavigableMap(
NavigableMap<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override NavigableMap<K, V>
delegate() {
return (
NavigableMap<K, V>) super.delegate();
}
@
Override public
Entry<K, V>
ceilingEntry(K
key) {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
ceilingEntry(
key),
mutex);
}
}
@
Override public K
ceilingKey(K
key) {
synchronized (
mutex) {
return
delegate().
ceilingKey(
key);
}
}
transient
NavigableSet<K>
descendingKeySet;
@
Override public
NavigableSet<K>
descendingKeySet() {
synchronized (
mutex) {
if (
descendingKeySet == null) {
return
descendingKeySet =
Synchronized.
navigableSet(
delegate().
descendingKeySet(),
mutex);
}
return
descendingKeySet;
}
}
transient
NavigableMap<K, V>
descendingMap;
@
Override public
NavigableMap<K, V>
descendingMap() {
synchronized (
mutex) {
if (
descendingMap == null) {
return
descendingMap =
navigableMap(
delegate().
descendingMap(),
mutex);
}
return
descendingMap;
}
}
@
Override public
Entry<K, V>
firstEntry() {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
firstEntry(),
mutex);
}
}
@
Override public
Entry<K, V>
floorEntry(K
key) {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
floorEntry(
key),
mutex);
}
}
@
Override public K
floorKey(K
key) {
synchronized (
mutex) {
return
delegate().
floorKey(
key);
}
}
@
Override public
NavigableMap<K, V>
headMap(K
toKey, boolean
inclusive) {
synchronized (
mutex) {
return
navigableMap(
delegate().
headMap(
toKey,
inclusive),
mutex);
}
}
@
Override public
Entry<K, V>
higherEntry(K
key) {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
higherEntry(
key),
mutex);
}
}
@
Override public K
higherKey(K
key) {
synchronized (
mutex) {
return
delegate().
higherKey(
key);
}
}
@
Override public
Entry<K, V>
lastEntry() {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
lastEntry(),
mutex);
}
}
@
Override public
Entry<K, V>
lowerEntry(K
key) {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
lowerEntry(
key),
mutex);
}
}
@
Override public K
lowerKey(K
key) {
synchronized (
mutex) {
return
delegate().
lowerKey(
key);
}
}
@
Override public
Set<K>
keySet() {
return
navigableKeySet();
}
transient
NavigableSet<K>
navigableKeySet;
@
Override public
NavigableSet<K>
navigableKeySet() {
synchronized (
mutex) {
if (
navigableKeySet == null) {
return
navigableKeySet =
Synchronized.
navigableSet(
delegate().
navigableKeySet(),
mutex);
}
return
navigableKeySet;
}
}
@
Override public
Entry<K, V>
pollFirstEntry() {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
pollFirstEntry(),
mutex);
}
}
@
Override public
Entry<K, V>
pollLastEntry() {
synchronized (
mutex) {
return
nullableSynchronizedEntry(
delegate().
pollLastEntry(),
mutex);
}
}
@
Override public
NavigableMap<K, V>
subMap(
K
fromKey, boolean
fromInclusive, K
toKey, boolean
toInclusive) {
synchronized (
mutex) {
return
navigableMap(
delegate().
subMap(
fromKey,
fromInclusive,
toKey,
toInclusive),
mutex);
}
}
@
Override public
NavigableMap<K, V>
tailMap(K
fromKey, boolean
inclusive) {
synchronized (
mutex) {
return
navigableMap(
delegate().
tailMap(
fromKey,
inclusive),
mutex);
}
}
@
Override public
SortedMap<K, V>
headMap(K
toKey) {
return
headMap(
toKey, false);
}
@
Override public
SortedMap<K, V>
subMap(K
fromKey, K
toKey) {
return
subMap(
fromKey, true,
toKey, false);
}
@
Override public
SortedMap<K, V>
tailMap(K
fromKey) {
return
tailMap(
fromKey, true);
}
private static final long
serialVersionUID = 0;
}
@
GwtIncompatible("works but is needed only for NavigableMap")
private static <K, V>
Entry<K, V>
nullableSynchronizedEntry(
@
Nullable Entry<K, V>
entry, @
Nullable Object mutex) {
if (
entry == null) {
return null;
}
return new
SynchronizedEntry<K, V>(
entry,
mutex);
}
@
GwtIncompatible("works but is needed only for NavigableMap")
private static class
SynchronizedEntry<K, V> extends
SynchronizedObject
implements
Entry<K, V> {
SynchronizedEntry(
Entry<K, V>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
SuppressWarnings("unchecked") // guaranteed by the constructor
@
Override Entry<K, V>
delegate() {
return (
Entry<K, V>) super.delegate();
}
@
Override public boolean
equals(
Object obj) {
synchronized (
mutex) {
return
delegate().
equals(
obj);
}
}
@
Override public int
hashCode() {
synchronized (
mutex) {
return
delegate().
hashCode();
}
}
@
Override public K
getKey() {
synchronized (
mutex) {
return
delegate().
getKey();
}
}
@
Override public V
getValue() {
synchronized (
mutex) {
return
delegate().
getValue();
}
}
@
Override public V
setValue(V
value) {
synchronized (
mutex) {
return
delegate().
setValue(
value);
}
}
private static final long
serialVersionUID = 0;
}
static <E>
Queue<E>
queue(
Queue<E>
queue, @
Nullable Object mutex) {
return (
queue instanceof
SynchronizedQueue)
?
queue
: new
SynchronizedQueue<E>(
queue,
mutex);
}
private static class
SynchronizedQueue<E> extends
SynchronizedCollection<E>
implements
Queue<E> {
SynchronizedQueue(
Queue<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override Queue<E>
delegate() {
return (
Queue<E>) super.delegate();
}
@
Override
public E
element() {
synchronized (
mutex) {
return
delegate().
element();
}
}
@
Override
public boolean
offer(E
e) {
synchronized (
mutex) {
return
delegate().
offer(
e);
}
}
@
Override
public E
peek() {
synchronized (
mutex) {
return
delegate().
peek();
}
}
@
Override
public E
poll() {
synchronized (
mutex) {
return
delegate().
poll();
}
}
@
Override
public E
remove() {
synchronized (
mutex) {
return
delegate().
remove();
}
}
private static final long
serialVersionUID = 0;
}
@
GwtIncompatible("Deque")
static <E>
Deque<E>
deque(
Deque<E>
deque, @
Nullable Object mutex) {
return new
SynchronizedDeque<E>(
deque,
mutex);
}
@
GwtIncompatible("Deque")
private static final class
SynchronizedDeque<E>
extends
SynchronizedQueue<E> implements
Deque<E> {
SynchronizedDeque(
Deque<E>
delegate, @
Nullable Object mutex) {
super(
delegate,
mutex);
}
@
Override Deque<E>
delegate() {
return (
Deque<E>) super.delegate();
}
@
Override
public void
addFirst(E
e) {
synchronized (
mutex) {
delegate().
addFirst(
e);
}
}
@
Override
public void
addLast(E
e) {
synchronized (
mutex) {
delegate().
addLast(
e);
}
}
@
Override
public boolean
offerFirst(E
e) {
synchronized (
mutex) {
return
delegate().
offerFirst(
e);
}
}
@
Override
public boolean
offerLast(E
e) {
synchronized (
mutex) {
return
delegate().
offerLast(
e);
}
}
@
Override
public E
removeFirst() {
synchronized (
mutex) {
return
delegate().
removeFirst();
}
}
@
Override
public E
removeLast() {
synchronized (
mutex) {
return
delegate().
removeLast();
}
}
@
Override
public E
pollFirst() {
synchronized (
mutex) {
return
delegate().
pollFirst();
}
}
@
Override
public E
pollLast() {
synchronized (
mutex) {
return
delegate().
pollLast();
}
}
@
Override
public E
getFirst() {
synchronized (
mutex) {
return
delegate().
getFirst();
}
}
@
Override
public E
getLast() {
synchronized (
mutex) {
return
delegate().
getLast();
}
}
@
Override
public E
peekFirst() {
synchronized (
mutex) {
return
delegate().
peekFirst();
}
}
@
Override
public E
peekLast() {
synchronized (
mutex) {
return
delegate().
peekLast();
}
}
@
Override
public boolean
removeFirstOccurrence(
Object o) {
synchronized (
mutex) {
return
delegate().
removeFirstOccurrence(
o);
}
}
@
Override
public boolean
removeLastOccurrence(
Object o) {
synchronized (
mutex) {
return
delegate().
removeLastOccurrence(
o);
}
}
@
Override
public void
push(E
e) {
synchronized (
mutex) {
delegate().
push(
e);
}
}
@
Override
public E
pop() {
synchronized (
mutex) {
return
delegate().
pop();
}
}
@
Override
public
Iterator<E>
descendingIterator() {
synchronized (
mutex) {
return
delegate().
descendingIterator();
}
}
private static final long
serialVersionUID = 0;
}
}