KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > databinding > internal > beans > JavaBeanObservableList


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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 171616
11  *******************************************************************************/

12
13 package org.eclipse.core.internal.databinding.internal.beans;
14
15 import java.beans.PropertyChangeListener JavaDoc;
16 import java.beans.PropertyDescriptor JavaDoc;
17 import java.lang.reflect.Array JavaDoc;
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Arrays JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.eclipse.core.databinding.BindingException;
27 import org.eclipse.core.databinding.beans.IBeanObservable;
28 import org.eclipse.core.databinding.observable.Diffs;
29 import org.eclipse.core.databinding.observable.Realm;
30 import org.eclipse.core.databinding.observable.list.ListDiffEntry;
31 import org.eclipse.core.databinding.observable.list.ObservableList;
32
33 /**
34  * @since 1.0
35  *
36  */

37 public class JavaBeanObservableList extends ObservableList implements
38         IBeanObservable {
39
40     private final Object JavaDoc object;
41
42     private PropertyChangeListener JavaDoc collectionListener = new PropertyChangeListener JavaDoc() {
43         public void propertyChange(java.beans.PropertyChangeEvent JavaDoc event) {
44             if (!updating) {
45                 updateWrappedList(Arrays.asList(getValues()));
46             }
47         }
48     };
49
50     private boolean updating = false;
51
52     private PropertyDescriptor JavaDoc descriptor;
53
54     private ListenerSupport collectionListenSupport;
55
56     /**
57      * @param realm
58      * @param object
59      * @param descriptor
60      * @param elementType
61      */

62     public JavaBeanObservableList(Realm realm, Object JavaDoc object,
63             PropertyDescriptor JavaDoc descriptor, Class JavaDoc elementType) {
64         super(realm, new ArrayList JavaDoc(), elementType);
65         this.object = object;
66         this.descriptor = descriptor;
67         this.collectionListenSupport = new ListenerSupport(collectionListener,
68                 descriptor.getName());
69
70         // initialize list without firing events
71
wrappedList.addAll(Arrays.asList(getValues()));
72     }
73
74     protected void firstListenerAdded() {
75         collectionListenSupport.hookListener(this.object);
76     }
77
78     protected void lastListenerRemoved() {
79         if (collectionListenSupport != null) {
80             collectionListenSupport.dispose();
81         }
82     }
83
84     public void dispose() {
85         super.dispose();
86         lastListenerRemoved();
87     }
88
89     private Object JavaDoc primGetValues() {
90         Exception JavaDoc ex = null;
91         try {
92             Method JavaDoc readMethod = descriptor.getReadMethod();
93             if (!readMethod.isAccessible()) {
94                 readMethod.setAccessible(true);
95             }
96             return readMethod.invoke(object, new Object JavaDoc[0]);
97         } catch (IllegalArgumentException JavaDoc e) {
98             ex = e;
99         } catch (IllegalAccessException JavaDoc e) {
100             ex = e;
101         } catch (InvocationTargetException JavaDoc e) {
102             ex = e;
103         }
104         throw new BindingException("Could not read collection values", ex); //$NON-NLS-1$
105
}
106
107     private Object JavaDoc[] getValues() {
108         Object JavaDoc[] values = null;
109
110         Object JavaDoc result = primGetValues();
111         if (descriptor.getPropertyType().isArray())
112             values = (Object JavaDoc[]) result;
113         else {
114             // TODO add jUnit for POJO (var. SettableValue) collections
115
Collection JavaDoc list = (Collection JavaDoc) result;
116             if (list != null) {
117                 values = list.toArray();
118             } else {
119                 values = new Object JavaDoc[] {};
120             }
121         }
122         return values;
123     }
124
125     public Object JavaDoc getObserved() {
126         return object;
127     }
128
129     public PropertyDescriptor JavaDoc getPropertyDescriptor() {
130         return descriptor;
131     }
132
133     private void setValues() {
134         if (descriptor.getPropertyType().isArray()) {
135             Class JavaDoc componentType = descriptor.getPropertyType()
136                     .getComponentType();
137             Object JavaDoc[] newArray = (Object JavaDoc[]) Array.newInstance(componentType,
138                     wrappedList.size());
139             wrappedList.toArray(newArray);
140             primSetValues(newArray);
141         } else {
142             // assume that it is a java.util.List
143
primSetValues(new ArrayList JavaDoc(wrappedList));
144         }
145     }
146
147     private void primSetValues(Object JavaDoc newValue) {
148         Exception JavaDoc ex = null;
149         try {
150             Method JavaDoc writeMethod = descriptor.getWriteMethod();
151             if (!writeMethod.isAccessible()) {
152                 writeMethod.setAccessible(true);
153             }
154             writeMethod.invoke(object, new Object JavaDoc[] { newValue });
155             return;
156         } catch (IllegalArgumentException JavaDoc e) {
157             ex = e;
158         } catch (IllegalAccessException JavaDoc e) {
159             ex = e;
160         } catch (InvocationTargetException JavaDoc e) {
161             ex = e;
162         }
163         throw new BindingException("Could not write collection values", ex); //$NON-NLS-1$
164
}
165
166     public Object JavaDoc set(int index, Object JavaDoc element) {
167         getterCalled();
168         updating = true;
169         try {
170             Object JavaDoc oldElement = wrappedList.set(index, element);
171             setValues();
172             fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
173                     index, true, element), Diffs.createListDiffEntry(index + 1,
174                     false, oldElement)));
175             return oldElement;
176         } finally {
177             updating = false;
178         }
179     }
180
181     public Object JavaDoc remove(int index) {
182         getterCalled();
183         updating = true;
184         try {
185             Object JavaDoc oldElement = wrappedList.remove(index);
186             setValues();
187             fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
188                     index, false, oldElement)));
189             return oldElement;
190         } finally {
191             updating = false;
192         }
193     }
194
195     public boolean add(Object JavaDoc element) {
196         updating = true;
197         try {
198             int index = wrappedList.size();
199             boolean result = wrappedList.add(element);
200             setValues();
201             fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
202                     index, true, element)));
203             return result;
204         } finally {
205             updating = false;
206         }
207     }
208
209     public void add(int index, Object JavaDoc element) {
210         updating = true;
211         try {
212             wrappedList.add(index, element);
213             setValues();
214             fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
215                     index, true, element)));
216         } finally {
217             updating = false;
218         }
219     }
220
221     public boolean addAll(Collection JavaDoc c) {
222         if (c.isEmpty()) {
223             return false;
224         }
225         updating = true;
226         try {
227             int index = wrappedList.size();
228             boolean result = wrappedList.addAll(c);
229             setValues();
230             ListDiffEntry[] entries = new ListDiffEntry[c.size()];
231             int i = 0;
232             for (Iterator JavaDoc it = c.iterator(); it.hasNext();) {
233                 Object JavaDoc o = it.next();
234                 entries[i++] = Diffs.createListDiffEntry(index++, true, o);
235             }
236             fireListChange(Diffs.createListDiff(entries));
237             return result;
238         } finally {
239             updating = false;
240         }
241     }
242
243     public boolean addAll(int index, Collection JavaDoc c) {
244         if (c.isEmpty()) {
245             return false;
246         }
247         updating = true;
248         try {
249             boolean result = wrappedList.addAll(index, c);
250             setValues();
251             ListDiffEntry[] entries = new ListDiffEntry[c.size()];
252             int i = 0;
253             for (Iterator JavaDoc it = c.iterator(); it.hasNext();) {
254                 Object JavaDoc o = it.next();
255                 entries[i++] = Diffs.createListDiffEntry(index++, true, o);
256             }
257             fireListChange(Diffs.createListDiff(entries));
258             return result;
259         } finally {
260             updating = false;
261         }
262     }
263
264     public boolean remove(Object JavaDoc o) {
265         getterCalled();
266         int index = wrappedList.indexOf(o);
267         if (index == -1) {
268             return false;
269         }
270         updating = true;
271         try {
272             Object JavaDoc oldElement = wrappedList.remove(index);
273             setValues();
274             fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
275                     index, false, oldElement)));
276             return true;
277         } finally {
278             updating = false;
279         }
280     }
281
282     public boolean removeAll(Collection JavaDoc c) {
283         getterCalled();
284         boolean changed = false;
285         updating = true;
286         try {
287             List JavaDoc diffEntries = new ArrayList JavaDoc();
288             for (Iterator JavaDoc it = c.iterator(); it.hasNext();) {
289                 Object JavaDoc o = it.next();
290                 int index = wrappedList.indexOf(o);
291                 if (index != -1) {
292                     changed = true;
293                     Object JavaDoc oldElement = wrappedList.remove(index);
294                     diffEntries.add(Diffs.createListDiffEntry(index, false,
295                             oldElement));
296                 }
297             }
298             setValues();
299             fireListChange(Diffs.createListDiff((ListDiffEntry[]) diffEntries
300                     .toArray(new ListDiffEntry[diffEntries.size()])));
301             return changed;
302         } finally {
303             updating = false;
304         }
305     }
306
307     public boolean retainAll(Collection JavaDoc c) {
308         getterCalled();
309         boolean changed = false;
310         updating = true;
311         try {
312             List JavaDoc diffEntries = new ArrayList JavaDoc();
313             int index = 0;
314             for (Iterator JavaDoc it = wrappedList.iterator(); it.hasNext();) {
315                 Object JavaDoc o = it.next();
316                 boolean retain = c.contains(o);
317                 if (retain) {
318                     index++;
319                 } else {
320                     changed = true;
321                     it.remove();
322                     diffEntries.add(Diffs.createListDiffEntry(index, false, o));
323                 }
324             }
325             setValues();
326             fireListChange(Diffs.createListDiff((ListDiffEntry[]) diffEntries
327                     .toArray(new ListDiffEntry[diffEntries.size()])));
328             return changed;
329         } finally {
330             updating = false;
331         }
332     }
333
334     public void clear() {
335         updating = true;
336         try {
337             List JavaDoc diffEntries = new ArrayList JavaDoc();
338             for (Iterator JavaDoc it = wrappedList.iterator(); it.hasNext();) {
339                 Object JavaDoc o = it.next();
340                 diffEntries.add(Diffs.createListDiffEntry(0, false, o));
341             }
342             setValues();
343             fireListChange(Diffs.createListDiff((ListDiffEntry[]) diffEntries
344                     .toArray(new ListDiffEntry[diffEntries.size()])));
345         } finally {
346             updating = false;
347         }
348     }
349
350 }
351
Popular Tags