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