Mercurial > projects > dwt2
comparison org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/list/ObservableList.d @ 78:0a55d2d5a946
Added file for databinding
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 14 Apr 2009 11:35:29 +0200 |
parents | |
children | 383ce7bd736b |
comparison
equal
deleted
inserted
replaced
76:f05e6e8b2f2d | 78:0a55d2d5a946 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2006, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Brad Reynolds - bug 164653 | |
11 * Brad Reynolds - bug 167204 | |
12 * Matthew Hall - bug 208858 | |
13 * Matthew Hall - bug 208332 | |
14 *******************************************************************************/ | |
15 | |
16 module org.eclipse.core.databinding.observable.list.ObservableList; | |
17 | |
18 import java.lang.all; | |
19 | |
20 import java.util.Collection; | |
21 import java.util.Iterator; | |
22 import java.util.List; | |
23 import java.util.ListIterator; | |
24 | |
25 import org.eclipse.core.databinding.observable.AbstractObservable; | |
26 import org.eclipse.core.databinding.observable.Diffs; | |
27 import org.eclipse.core.databinding.observable.ObservableTracker; | |
28 import org.eclipse.core.databinding.observable.Realm; | |
29 | |
30 /** | |
31 * | |
32 * Abstract implementation of {@link IObservableList}, based on an underlying regular list. | |
33 * <p> | |
34 * This class is thread safe. All state accessing methods must be invoked from | |
35 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing | |
36 * listeners may be invoked from any thread. | |
37 * </p> | |
38 * @since 1.0 | |
39 * | |
40 */ | |
41 public abstract class ObservableList : AbstractObservable , | |
42 IObservableList { | |
43 | |
44 protected List wrappedList; | |
45 | |
46 /** | |
47 * Stale state of the list. Access must occur in the current realm. | |
48 */ | |
49 private bool stale = false; | |
50 | |
51 private Object elementType; | |
52 | |
53 protected this(List wrappedList, Object elementType) { | |
54 this(Realm.getDefault(), wrappedList, elementType); | |
55 } | |
56 | |
57 protected this(Realm realm, List wrappedList, Object elementType) { | |
58 super(realm); | |
59 this.wrappedList = wrappedList; | |
60 this.elementType = elementType; | |
61 } | |
62 | |
63 public synchronized void addListChangeListener(IListChangeListener listener) { | |
64 addListener(ListChangeEvent.TYPE, listener); | |
65 } | |
66 | |
67 public synchronized void removeListChangeListener(IListChangeListener listener) { | |
68 removeListener(ListChangeEvent.TYPE, listener); | |
69 } | |
70 | |
71 protected void fireListChange(ListDiff diff) { | |
72 // fire general change event first | |
73 super.fireChange(); | |
74 fireEvent(new ListChangeEvent(this, diff)); | |
75 } | |
76 | |
77 public bool contains(Object o) { | |
78 getterCalled(); | |
79 return wrappedList.contains(o); | |
80 } | |
81 | |
82 public bool containsAll(Collection c) { | |
83 getterCalled(); | |
84 return wrappedList.containsAll(c); | |
85 } | |
86 | |
87 public override bool opEquals(Object o) { | |
88 getterCalled(); | |
89 return wrappedList.equals(o); | |
90 } | |
91 | |
92 public int hashCode() { | |
93 getterCalled(); | |
94 return wrappedList.hashCode(); | |
95 } | |
96 | |
97 public bool isEmpty() { | |
98 getterCalled(); | |
99 return wrappedList.isEmpty(); | |
100 } | |
101 | |
102 public Iterator iterator() { | |
103 getterCalled(); | |
104 final Iterator wrappedIterator = wrappedList.iterator(); | |
105 return new class() Iterator { | |
106 | |
107 public void remove() { | |
108 throw new UnsupportedOperationException(); | |
109 } | |
110 | |
111 public bool hasNext() { | |
112 return wrappedIterator.hasNext(); | |
113 } | |
114 | |
115 public Object next() { | |
116 return wrappedIterator.next(); | |
117 } | |
118 }; | |
119 } | |
120 | |
121 public int size() { | |
122 getterCalled(); | |
123 return wrappedList.size(); | |
124 } | |
125 | |
126 public Object[] toArray() { | |
127 getterCalled(); | |
128 return wrappedList.toArray(); | |
129 } | |
130 | |
131 public Object[] toArray(Object[] a) { | |
132 getterCalled(); | |
133 return wrappedList.toArray(a); | |
134 } | |
135 | |
136 public String toString() { | |
137 getterCalled(); | |
138 return wrappedList.toString(); | |
139 } | |
140 | |
141 /** | |
142 * @TrackedGetter | |
143 */ | |
144 public Object get(int index) { | |
145 getterCalled(); | |
146 return wrappedList.get(index); | |
147 } | |
148 | |
149 /** | |
150 * @TrackedGetter | |
151 */ | |
152 public int indexOf(Object o) { | |
153 getterCalled(); | |
154 return wrappedList.indexOf(o); | |
155 } | |
156 | |
157 /** | |
158 * @TrackedGetter | |
159 */ | |
160 public int lastIndexOf(Object o) { | |
161 getterCalled(); | |
162 return wrappedList.lastIndexOf(o); | |
163 } | |
164 | |
165 // List Iterators | |
166 | |
167 /** | |
168 * @TrackedGetter | |
169 */ | |
170 public ListIterator listIterator() { | |
171 return listIterator(0); | |
172 } | |
173 | |
174 /** | |
175 * @TrackedGetter | |
176 */ | |
177 public ListIterator listIterator(int index) { | |
178 getterCalled(); | |
179 final ListIterator wrappedIterator = wrappedList.listIterator(index); | |
180 return new class() ListIterator { | |
181 | |
182 public int nextIndex() { | |
183 return wrappedIterator.nextIndex(); | |
184 } | |
185 | |
186 public int previousIndex() { | |
187 return wrappedIterator.previousIndex(); | |
188 } | |
189 | |
190 public void remove() { | |
191 throw new UnsupportedOperationException(); | |
192 } | |
193 | |
194 public bool hasNext() { | |
195 return wrappedIterator.hasNext(); | |
196 } | |
197 | |
198 public bool hasPrevious() { | |
199 return wrappedIterator.hasPrevious(); | |
200 } | |
201 | |
202 public Object next() { | |
203 return wrappedIterator.next(); | |
204 } | |
205 | |
206 public Object previous() { | |
207 return wrappedIterator.previous(); | |
208 } | |
209 | |
210 public void add(Object o) { | |
211 throw new UnsupportedOperationException(); | |
212 } | |
213 | |
214 public void set(Object o) { | |
215 throw new UnsupportedOperationException(); | |
216 } | |
217 }; | |
218 } | |
219 | |
220 | |
221 public List subList(int fromIndex, int toIndex) { | |
222 getterCalled(); | |
223 if (fromIndex < 0 || fromIndex > toIndex || toIndex > size()) { | |
224 throw new IndexOutOfBoundsException(); | |
225 } | |
226 return new class(getRealm(), fromIndex, toIndex ) AbstractObservableList { | |
227 int fromIndex_; int toIndex_; | |
228 this( Realm r, int f, int t){ | |
229 super(r); | |
230 fromIndex_ = r; | |
231 toIndex_ = t; | |
232 } | |
233 | |
234 public Object getElementType() { | |
235 return this.outer.getElementType(); | |
236 } | |
237 | |
238 public Object get(int location) { | |
239 return this.outer.get(fromIndex_ + location); | |
240 } | |
241 | |
242 protected int doGetSize() { | |
243 return toIndex_ - fromIndex_; | |
244 } | |
245 }; | |
246 } | |
247 | |
248 protected void getterCalled() { | |
249 ObservableTracker.getterCalled(this); | |
250 } | |
251 | |
252 public Object set(int index, Object element) { | |
253 throw new UnsupportedOperationException(); | |
254 } | |
255 | |
256 /** | |
257 * Moves the element located at <code>oldIndex</code> to | |
258 * <code>newIndex</code>. This method is equivalent to calling | |
259 * <code>add(newIndex, remove(oldIndex))</code>. | |
260 * <p> | |
261 * Subclasses should override this method to deliver list change | |
262 * notification for the remove and add operations in the same | |
263 * ListChangeEvent, as this allows {@link ListDiff#acceptcast(ListDiffVisitor)} | |
264 * to recognize the operation as a move. | |
265 * | |
266 * @param oldIndex | |
267 * the element's position before the move. Must be within the | |
268 * range <code>0 <= oldIndex < size()</code>. | |
269 * @param newIndex | |
270 * the element's position after the move. Must be within the | |
271 * range <code>0 <= newIndex < size()</code>. | |
272 * @return the element that was moved. | |
273 * @throws IndexOutOfBoundsException | |
274 * if either argument is out of range (<code>0 <= index < size()</code>). | |
275 * @see ListDiffVisitor#handleMove(int, int, Object) | |
276 * @see ListDiff#acceptcast(ListDiffVisitor) | |
277 * @since 1.1 | |
278 */ | |
279 public Object move(int oldIndex, int newIndex) { | |
280 checkRealm(); | |
281 int size = wrappedList.size(); | |
282 if (oldIndex < 0 || oldIndex >= size) | |
283 throw new IndexOutOfBoundsException( | |
284 "oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$ | |
285 if (newIndex < 0 || newIndex >= size) | |
286 throw new IndexOutOfBoundsException( | |
287 "newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$ | |
288 Object element = remove(oldIndex); | |
289 add(newIndex, element); | |
290 return element; | |
291 } | |
292 | |
293 public Object remove(int index) { | |
294 throw new UnsupportedOperationException(); | |
295 } | |
296 | |
297 public bool add(Object o) { | |
298 throw new UnsupportedOperationException(); | |
299 } | |
300 | |
301 public void add(int index, Object element) { | |
302 throw new UnsupportedOperationException(); | |
303 } | |
304 | |
305 public bool addAll(Collection c) { | |
306 throw new UnsupportedOperationException(); | |
307 } | |
308 | |
309 public bool addAll(int index, Collection c) { | |
310 throw new UnsupportedOperationException(); | |
311 } | |
312 | |
313 public bool remove(Object o) { | |
314 throw new UnsupportedOperationException(); | |
315 } | |
316 | |
317 public bool removeAll(Collection c) { | |
318 throw new UnsupportedOperationException(); | |
319 } | |
320 | |
321 public bool retainAll(Collection c) { | |
322 throw new UnsupportedOperationException(); | |
323 } | |
324 | |
325 public void clear() { | |
326 throw new UnsupportedOperationException(); | |
327 } | |
328 | |
329 /** | |
330 * Returns the stale state. Must be invoked from the current realm. | |
331 * | |
332 * @return stale state | |
333 */ | |
334 public bool isStale() { | |
335 getterCalled(); | |
336 return stale; | |
337 } | |
338 | |
339 /** | |
340 * Sets the stale state. Must be invoked from the current realm. | |
341 * | |
342 * @param stale | |
343 * The stale state to list. This will fire a stale event if the | |
344 * given bool is true and this observable list was not already | |
345 * stale. | |
346 */ | |
347 public void setStale(bool stale) { | |
348 checkRealm(); | |
349 | |
350 bool wasStale = this.stale; | |
351 this.stale = stale; | |
352 if (!wasStale && stale) { | |
353 fireStale(); | |
354 } | |
355 } | |
356 | |
357 protected void fireChange() { | |
358 throw new RuntimeException("fireChange should not be called, use fireListChange() instead"); //$NON-NLS-1$ | |
359 } | |
360 | |
361 /* (non-Javadoc) | |
362 * @see org.eclipse.jface.provisional.databinding.observable.AbstractObservable#dispose() | |
363 */ | |
364 public synchronized void dispose() { | |
365 super.dispose(); | |
366 } | |
367 | |
368 public Object getElementType() { | |
369 return elementType; | |
370 } | |
371 | |
372 protected void updateWrappedList(List newList) { | |
373 List oldList = wrappedList; | |
374 ListDiff listDiff = Diffs.computeListDiff(oldList, newList); | |
375 wrappedList = newList; | |
376 fireListChange(listDiff); | |
377 } | |
378 | |
379 } |