|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 package org.chromium.sdk.internal; |
|
6 |
|
7 import java.util.LinkedHashMap; |
|
8 import java.util.Map; |
|
9 import java.util.concurrent.ConcurrentHashMap; |
|
10 |
|
11 /** |
|
12 * Utility class that behaves similarly to ConcurrentHashMap, but also |
|
13 * provides {@link #close} operation that stops all new registrations. |
|
14 */ |
|
15 public class CloseableMap<K, V> { |
|
16 public static <K, V> CloseableMap<K, V> newMap() { |
|
17 return new CloseableMap<K, V>(new ConcurrentHashMap<K, V>()); |
|
18 } |
|
19 |
|
20 public static <K, V> CloseableMap<K, V> newLinkedMap() { |
|
21 // Creates linked hash map and makes "get" synchronized. |
|
22 return new CloseableMap<K, V>(new LinkedHashMap<K, V>()) { |
|
23 @Override |
|
24 public synchronized V get(K key) { |
|
25 // Base "get" is not synchronized, because we rely on ConcurrentHashMap. |
|
26 return super.get(key); |
|
27 } |
|
28 }; |
|
29 } |
|
30 |
|
31 private final Map<K, V> map; |
|
32 private boolean mutationClosed = false; |
|
33 |
|
34 protected CloseableMap(Map<K, V> map) { |
|
35 this.map = map; |
|
36 } |
|
37 |
|
38 public V get(K key) { |
|
39 return map.get(key); |
|
40 } |
|
41 |
|
42 public synchronized Map<K, V> close() { |
|
43 if (mutationClosed) { |
|
44 throw new IllegalStateException(); |
|
45 } |
|
46 mutationClosed = true; |
|
47 return map; |
|
48 } |
|
49 |
|
50 public synchronized V remove(K key) { |
|
51 if (mutationClosed) { |
|
52 // We probably can safely ignore this. |
|
53 return null; |
|
54 } |
|
55 V result = map.remove(key); |
|
56 if (result == null) { |
|
57 throw new IllegalArgumentException("This key is not registered"); |
|
58 } |
|
59 return result; |
|
60 } |
|
61 |
|
62 public synchronized V removeIfContains(K key) { |
|
63 if (mutationClosed) { |
|
64 // We probably can safely ignore this. |
|
65 return null; |
|
66 } |
|
67 return map.remove(key); |
|
68 } |
|
69 |
|
70 public synchronized void put(K key, V value) { |
|
71 if (mutationClosed) { |
|
72 throw new IllegalStateException(); |
|
73 } |
|
74 if (map.containsKey(key)) { |
|
75 throw new IllegalStateException("Such key is already registered"); |
|
76 } |
|
77 map.put(key, value); |
|
78 } |
|
79 } |