File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\util\CopyOnWriteMap.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.util;
25
26 import com.thoughtworks.xstream.converters.MarshallingContext;
27 import com.thoughtworks.xstream.converters.UnmarshallingContext;
28 import com.thoughtworks.xstream.converters.collections.MapConverter;
29 import com.thoughtworks.xstream.converters.collections.TreeMapConverter;
30 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
31 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
32 import com.thoughtworks.xstream.mapper.Mapper;
33
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.HashMap;
38 import java.util.LinkedHashMap;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.TreeMap;
42
43 /**
44 * {@link Map} that has copy-on-write semantics.
45 *
46 * <p>
47 * This class is suitable where highly concurrent access is needed, yet
48 * the write operation is relatively uncommon.
49 *
50 * @author Kohsuke Kawaguchi
51 */
52 public abstract class CopyOnWriteMap<K,V> implements Map<K,V> {
53 protected volatile Map<K,V> core;
54 /**
55 * Read-only view of {@link #core}.
56 */
57 private volatile Map<K,V> view;
58
59 protected CopyOnWriteMap(Map<K,V> core) {
60 update(core);
61 }
62
63 protected CopyOnWriteMap() {
64 update(Collections.<K,V>emptyMap());
65 }
66
67 protected void update(Map<K,V> m) {
68 core = m;
69 view = Collections.unmodifiableMap(core);
70 }
71
72 /**
73 * Atomically replaces the entire map by the copy of the specified map.
74 */
75 public void replaceBy(Map<? extends K, ? extends V> data) {
76 Map<K, V> d = copy();
77 d.clear();
78 d.putAll(data);
79 update(d);
80 }
81
82 public int size() {
83 return core.size();
84 }
85
86 public boolean isEmpty() {
87 return core.isEmpty();
88 }
89
90 public boolean containsKey(Object key) {
91 return core.containsKey(key);
92 }
93
94 public boolean containsValue(Object value) {
95 return core.containsValue(value);
96 }
97
98 public V get(Object key) {
99 return core.get(key);
100 }
101
102 public synchronized V put(K key, V value) {
103 Map<K,V> m = copy();
104 V r = m.put(key,value);
105 update(m);
106
107 return r;
108 }
109
110 public synchronized V remove(Object key) {
111 Map<K,V> m = copy();
112 V r = m.remove(key);
113 update(m);
114
115 return r;
116 }
117
118 public synchronized void putAll(Map<? extends K, ? extends V> t) {
119 Map<K,V> m = copy();
120 m.putAll(t);
121 update(m);
122 }
123
124 protected abstract Map<K,V> copy();
125
126 public synchronized void clear() {
127 update(Collections.<K,V>emptyMap());
128 }
129
130 /**
131 * This method will return a read-only {@link Set}.
132 */
133 public Set<K> keySet() {
134 return view.keySet();
135 }
136
137 /**
138 * This method will return a read-only {@link Collection}.
139 */
140 public Collection<V> values() {
141 return view.values();
142 }
143
144 /**
145 * This method will return a read-only {@link Set}.
146 */
147 public Set<Entry<K,V>> entrySet() {
148 return view.entrySet();
149 }
150
151 /**
152 * {@link CopyOnWriteMap} backed by {@link HashMap}.
153 */
154 public static final class Hash<K,V> extends CopyOnWriteMap<K,V> {
155 public Hash(Map<K,V> core) {
156 super(new LinkedHashMap<K,V>(core));
157 }
158
159 public Hash() {
160 }
161
162 protected Map<K,V> copy() {
163 return new LinkedHashMap<K,V>(core);
164 }
165
166 public static class ConverterImpl extends MapConverter {
167 public ConverterImpl(Mapper mapper) {
168 super(mapper);
169 }
170
171 @Override
172 public boolean canConvert(Class type) {
173 return type==Hash.class;
174 }
175
176 @Override
177 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
178 return new Hash((Map) super.unmarshal(reader,context));
179 }
180
181 @Override
182 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
183 super.marshal(((Hash)source).core,writer,context);
184 }
185 }
186 }
187
188 /**
189 * {@link CopyOnWriteMap} backed by {@link TreeMap}.
190 */
191 public static final class Tree<K,V> extends CopyOnWriteMap<K,V> {
192 private final Comparator<K> comparator;
193
194 public Tree(Map<K,V> core, Comparator<K> comparator) {
195 this(comparator);
196 putAll(core);
197 }
198
199 public Tree(Comparator<K> comparator) {
200 super(new TreeMap<K,V>(comparator));
201 this.comparator = comparator;
202 }
203
204 public Tree() {
205 this(null);
206 }
207
208 protected Map<K,V> copy() {
209 TreeMap<K,V> m = new TreeMap<K,V>(comparator);
210 m.putAll(core);
211 return m;
212 }
213
214 @Override
215 public synchronized void clear() {
216 update(new TreeMap<K,V>(comparator));
217 }
218
219 public static class ConverterImpl extends TreeMapConverter {
220 public ConverterImpl(Mapper mapper) {
221 super(mapper);
222 }
223
224 @Override
225 public boolean canConvert(Class type) {
226 return type==Tree.class;
227 }
228
229 @Override
230 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
231 TreeMap tm = (TreeMap) super.unmarshal(reader,context);
232 return new Tree(tm,tm.comparator());
233 }
234
235 @Override
236 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
237 super.marshal(((Tree)source).core,writer,context);
238 }
239 }
240 }
241 }
242