// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.sdk.internal;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Utility class that behaves similarly to ConcurrentHashMap, but also
* provides {@link #close} operation that stops all new registrations.
*/
public class CloseableMap<K, V> {
public static <K, V> CloseableMap<K, V> newMap() {
return new CloseableMap<K, V>(new ConcurrentHashMap<K, V>());
}
public static <K, V> CloseableMap<K, V> newLinkedMap() {
// Creates linked hash map and makes "get" synchronized.
return new CloseableMap<K, V>(new LinkedHashMap<K, V>()) {
@Override
public synchronized V get(K key) {
// Base "get" is not synchronized, because we rely on ConcurrentHashMap.
return super.get(key);
}
};
}
private final Map<K, V> map;
private boolean mutationClosed = false;
protected CloseableMap(Map<K, V> map) {
this.map = map;
}
public V get(K key) {
return map.get(key);
}
public synchronized Map<K, V> close() {
if (mutationClosed) {
throw new IllegalStateException();
}
mutationClosed = true;
return map;
}
public synchronized V remove(K key) {
if (mutationClosed) {
// We probably can safely ignore this.
return null;
}
V result = map.remove(key);
if (result == null) {
throw new IllegalArgumentException("This key is not registered");
}
return result;
}
public synchronized V removeIfContains(K key) {
if (mutationClosed) {
// We probably can safely ignore this.
return null;
}
return map.remove(key);
}
public synchronized void put(K key, V value) {
if (mutationClosed) {
throw new IllegalStateException();
}
if (map.containsKey(key)) {
throw new IllegalStateException("Such key is already registered");
}
map.put(key, value);
}
}