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

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, 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.mapper.CannotResolveClassException;
27 import com.thoughtworks.xstream.converters.Converter;
28 import com.thoughtworks.xstream.converters.MarshallingContext;
29 import com.thoughtworks.xstream.converters.UnmarshallingContext;
30 import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter;
31 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
32 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
33 import com.thoughtworks.xstream.mapper.Mapper;
34
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Arrays;
41 import java.util.logging.Logger;
42
43 import static java.util.logging.Level.WARNING;
44
45 /**
46 * {@link List}-like implementation that has copy-on-write semantics.
47 *
48 * <p>
49 * This class is suitable where highly concurrent access is needed, yet
50 * the write operation is relatively uncommon.
51 *
52 * @author Kohsuke Kawaguchi
53 */
54 public class CopyOnWriteList<E> implements Iterable<E> {
55 private volatile List<? extends E> core;
56
57 public CopyOnWriteList(List<E> core) {
58 this(core,false);
59 }
60
61 private CopyOnWriteList(List<E> core, boolean noCopy) {
62 this.core = noCopy ? core : new ArrayList<E>(core);
63 }
64
65 public CopyOnWriteList() {
66 this.core = Collections.emptyList();
67 }
68
69 public synchronized void add(E e) {
70 List<E> n = new ArrayList<E>(core);
71 n.add(e);
72 core = n;
73 }
74
75 public synchronized void addAll(Collection<? extends E> items) {
76 List<E> n = new ArrayList<E>(core);
77 n.addAll(items);
78 core = n;
79 }
80
81 /**
82 * Removes an item from the list.
83 *
84 * @return
85 * true if the list contained the item. False if it didn't,
86 * in which case there's no change.
87 */
88 public synchronized boolean remove(E e) {
89 List<E> n = new ArrayList<E>(core);
90 boolean r = n.remove(e);
91 core = n;
92 return r;
93 }
94
95 /**
96 * Returns an iterator.
97 */
98 public Iterator<E> iterator() {
99 final Iterator<? extends E> itr = core.iterator();
100 return new Iterator<E>() {
101 private E last;
102 public boolean hasNext() {
103 return itr.hasNext();
104 }
105
106 public E next() {
107 return last=itr.next();
108 }
109
110 public void remove() {
111 CopyOnWriteList.this.remove(last);
112 }
113 };
114 }
115
116 /**
117 * Completely replaces this list by the contents of the given list.
118 */
119 public void replaceBy(CopyOnWriteList<? extends E> that) {
120 this.core = that.core;
121 }
122
123 /**
124 * Completely replaces this list by the contents of the given list.
125 */
126 public void replaceBy(Collection<? extends E> that) {
127 this.core = new ArrayList<E>(that);
128 }
129
130 /**
131 * Completely replaces this list by the contents of the given list.
132 */
133 public void replaceBy(E... that) {
134 replaceBy(Arrays.asList(that));
135 }
136
137 public void clear() {
138 this.core = new ArrayList<E>();
139 }
140
141 public E[] toArray(E[] array) {
142 return core.toArray(array);
143 }
144
145 public List<E> getView() {
146 return Collections.unmodifiableList(core);
147 }
148
149 public void addAllTo(Collection<? super E> dst) {
150 dst.addAll(core);
151 }
152
153 public E get(int index) {
154 return core.get(index);
155 }
156
157 public boolean isEmpty() {
158 return core.isEmpty();
159 }
160
161 public int size() {
162 return core.size();
163 }
164
165 public boolean contains(Object item) {
166 return core.contains(item);
167 }
168
169 /**
170 * {@link Converter} implementation for XStream.
171 */
172 public static final class ConverterImpl extends AbstractCollectionConverter {
173 public ConverterImpl(Mapper mapper) {
174 super(mapper);
175 }
176
177 public boolean canConvert(Class type) {
178 return type==CopyOnWriteList.class;
179 }
180
181 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
182 for (Object o : (CopyOnWriteList) source)
183 writeItem(o, context, writer);
184 }
185
186 @SuppressWarnings("unchecked")
187 public CopyOnWriteList unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
188 // read the items from xml into a list
189 List items = new ArrayList();
190 while (reader.hasMoreChildren()) {
191 reader.moveDown();
192 try {
193 Object item = readItem(reader, context, items);
194 items.add(item);
195 } catch (CannotResolveClassException e) {
196 LOGGER.log(WARNING,"Failed to resolve class",e);
197 RobustReflectionConverter.addErrorInContext(context, e);
198 } catch (LinkageError e) {
199 LOGGER.log(WARNING,"Failed to resolve class",e);
200 RobustReflectionConverter.addErrorInContext(context, e);
201 }
202 reader.moveUp();
203 }
204
205 return new CopyOnWriteList(items,true);
206 }
207 }
208
209 private static final Logger LOGGER = Logger.getLogger(CopyOnWriteList.class.getName());
210 }
211