1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ch.qos.logback.core.util;
16
17 import java.util.Collection;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.ListIterator;
21 import java.util.concurrent.CopyOnWriteArrayList;
22 import java.util.concurrent.atomic.AtomicBoolean;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class COWArrayList<E> implements List<E> {
64
65
66
67
68
69
70
71
72 AtomicBoolean fresh = new AtomicBoolean(false);
73 CopyOnWriteArrayList<E> underlyingList = new CopyOnWriteArrayList<E>();
74 E[] ourCopy;
75 final E[] modelArray;
76
77 public COWArrayList(E[] modelArray) {
78 this.modelArray = modelArray;
79 }
80
81 @Override
82 public int size() {
83 return underlyingList.size();
84 }
85
86 @Override
87 public boolean isEmpty() {
88 return underlyingList.isEmpty();
89 }
90
91 @Override
92 public boolean contains(Object o) {
93 return underlyingList.contains(o);
94 }
95
96 @Override
97 public Iterator<E> iterator() {
98 return underlyingList.iterator();
99 }
100
101 private void refreshCopyIfNecessary() {
102 if (!isFresh()) {
103 refreshCopy();
104 }
105 }
106
107 private boolean isFresh() {
108 return fresh.get();
109 }
110
111 private void refreshCopy() {
112 ourCopy = underlyingList.toArray(modelArray);
113 fresh.set(true);
114 }
115
116 @Override
117 public Object[] toArray() {
118 refreshCopyIfNecessary();
119 return ourCopy;
120 }
121
122 @SuppressWarnings("unchecked")
123 @Override
124 public <T> T[] toArray(T[] a) {
125 refreshCopyIfNecessary();
126 return (T[]) ourCopy;
127 }
128
129
130
131
132
133
134
135
136 public E[] asTypedArray() {
137 refreshCopyIfNecessary();
138 return ourCopy;
139 }
140
141 private void markAsStale() {
142 fresh.set(false);
143 }
144
145 public void addIfAbsent(E e) {
146 underlyingList.addIfAbsent(e);
147 markAsStale();
148 }
149
150 @Override
151 public boolean add(E e) {
152 boolean result = underlyingList.add(e);
153 markAsStale();
154 return result;
155 }
156
157 @Override
158 public boolean remove(Object o) {
159 boolean result = underlyingList.remove(o);
160 markAsStale();
161 return result;
162 }
163
164 @Override
165 public boolean containsAll(Collection<?> c) {
166 return underlyingList.containsAll(c);
167 }
168
169 @Override
170 public boolean addAll(Collection<? extends E> c) {
171 markAsStale();
172 boolean result = underlyingList.addAll(c);
173 return result;
174 }
175
176 @Override
177 public boolean addAll(int index, Collection<? extends E> col) {
178 markAsStale();
179 boolean result = underlyingList.addAll(index, col);
180 return result;
181 }
182
183 @Override
184 public boolean removeAll(Collection<?> col) {
185 markAsStale();
186 boolean result = underlyingList.removeAll(col);
187 return result;
188 }
189
190 @Override
191 public boolean retainAll(Collection<?> col) {
192 markAsStale();
193 boolean result = underlyingList.retainAll(col);
194 return result;
195 }
196
197 @Override
198 public void clear() {
199 markAsStale();
200 underlyingList.clear();
201 }
202
203 @Override
204 public E get(int index) {
205 refreshCopyIfNecessary();
206 return (E) ourCopy[index];
207 }
208
209 @Override
210 public E set(int index, E element) {
211 markAsStale();
212 E e = underlyingList.set(index, element);
213 return e;
214 }
215
216 @Override
217 public void add(int index, E element) {
218 markAsStale();
219 underlyingList.add(index, element);
220 }
221
222 @Override
223 public E remove(int index) {
224 markAsStale();
225 E e = (E) underlyingList.remove(index);
226 return e;
227 }
228
229 @Override
230 public int indexOf(Object o) {
231 return underlyingList.indexOf(o);
232 }
233
234 @Override
235 public int lastIndexOf(Object o) {
236 return underlyingList.lastIndexOf(o);
237 }
238
239 @Override
240 public ListIterator<E> listIterator() {
241 return underlyingList.listIterator();
242 }
243
244 @Override
245 public ListIterator<E> listIterator(int index) {
246 return underlyingList.listIterator(index);
247 }
248
249 @Override
250 public List<E> subList(int fromIndex, int toIndex) {
251 return underlyingList.subList(fromIndex, toIndex);
252 }
253
254 }