Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 194734 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/tests/databinding/swt/SWTObservablesTest.java (-40 / +58 lines)
Lines 11-29 Link Here
11
11
12
package org.eclipse.jface.tests.databinding.swt;
12
package org.eclipse.jface.tests.databinding.swt;
13
13
14
import org.eclipse.core.databinding.observable.IDecoratingObservable;
14
import org.eclipse.core.databinding.observable.list.IObservableList;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.core.databinding.property.IPropertyObservable;
15
import org.eclipse.jface.databinding.conformance.util.RealmTester;
17
import org.eclipse.jface.databinding.conformance.util.RealmTester;
18
import org.eclipse.jface.databinding.swt.ISWTObservable;
16
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
19
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
17
import org.eclipse.jface.databinding.swt.SWTObservables;
20
import org.eclipse.jface.databinding.swt.SWTObservables;
18
import org.eclipse.jface.internal.databinding.swt.ButtonObservableValue;
21
import org.eclipse.jface.internal.databinding.swt.CComboSelectionProperty;
19
import org.eclipse.jface.internal.databinding.swt.CComboObservableList;
22
import org.eclipse.jface.internal.databinding.swt.CComboTextProperty;
20
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
21
import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
23
import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
22
import org.eclipse.jface.internal.databinding.swt.ComboObservableList;
24
import org.eclipse.jface.internal.databinding.swt.ComboSelectionProperty;
23
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
25
import org.eclipse.jface.internal.databinding.swt.ComboTextProperty;
24
import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
26
import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
25
import org.eclipse.jface.internal.databinding.swt.ListObservableList;
26
import org.eclipse.jface.internal.databinding.swt.ListObservableValue;
27
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
27
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
28
import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
28
import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
29
import org.eclipse.jface.internal.databinding.swt.SpinnerObservableValue;
29
import org.eclipse.jface.internal.databinding.swt.SpinnerObservableValue;
Lines 55-68 Link Here
55
55
56
	protected void setUp() throws Exception {
56
	protected void setUp() throws Exception {
57
		super.setUp();
57
		super.setUp();
58
		
58
59
		shell = getShell();
59
		shell = getShell();
60
		RealmTester.setDefault(SWTObservables.getRealm(shell.getDisplay()));
60
		RealmTester.setDefault(SWTObservables.getRealm(shell.getDisplay()));
61
	}
61
	}
62
62
63
	protected void tearDown() throws Exception {
63
	protected void tearDown() throws Exception {
64
		super.tearDown();
64
		super.tearDown();
65
		
65
66
		RealmTester.setDefault(null);
66
		RealmTester.setDefault(null);
67
	}
67
	}
68
68
Lines 98-139 Link Here
98
		Button button = new Button(shell, SWT.PUSH);
98
		Button button = new Button(shell, SWT.PUSH);
99
		ISWTObservableValue value = SWTObservables.observeSelection(button);
99
		ISWTObservableValue value = SWTObservables.observeSelection(button);
100
		assertNotNull(value);
100
		assertNotNull(value);
101
		assertTrue(value instanceof ButtonObservableValue);
101
		assertTrue(value.getWidget() == button);
102
	}
102
	}
103
103
104
	public void testObserveSelectionOfCombo() throws Exception {
104
	public void testObserveSelectionOfCombo() throws Exception {
105
		Combo combo = new Combo(shell, SWT.NONE);
105
		Combo combo = new Combo(shell, SWT.NONE);
106
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
106
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
107
		assertNotNull(value);
107
		assertNotNull(value);
108
		assertTrue(value instanceof ComboObservableValue);
108
		assertTrue(value.getWidget() == combo);
109
109
110
		ComboObservableValue comboObservable = (ComboObservableValue) value;
110
		IPropertyObservable propertyObservable = getPropertyObservable(value);
111
		assertEquals(SWTProperties.SELECTION, comboObservable.getAttribute());
111
		assertTrue(propertyObservable.getProperty() instanceof ComboSelectionProperty);
112
	}
112
	}
113
113
114
	public void testObserveSelectionOfCCombo() throws Exception {
114
	public void testObserveSelectionOfCCombo() throws Exception {
115
		CCombo combo = new CCombo(shell, SWT.NONE);
115
		CCombo combo = new CCombo(shell, SWT.NONE);
116
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
116
		ISWTObservableValue value = SWTObservables.observeSelection(combo);
117
		assertNotNull(value);
117
		assertNotNull(value);
118
		assertTrue(value instanceof CComboObservableValue);
118
		assertTrue(value.getWidget() == combo);
119
119
120
		CComboObservableValue ccomboObservable = (CComboObservableValue) value;
120
		IDecoratingObservable decorating = (IDecoratingObservable) value;
121
		assertEquals(SWTProperties.SELECTION, ccomboObservable.getAttribute());
121
		IPropertyObservable property = (IPropertyObservable) decorating
122
				.getDecorated();
123
		assertTrue(property.getProperty() instanceof CComboSelectionProperty);
122
	}
124
	}
123
125
124
	public void testObserveSelectionOfList() throws Exception {
126
	public void testObserveSelectionOfList() throws Exception {
125
		List list = new List(shell, SWT.NONE);
127
		List list = new List(shell, SWT.NONE);
126
		ISWTObservableValue value = SWTObservables.observeSelection(list);
128
		ISWTObservableValue value = SWTObservables.observeSelection(list);
127
		assertNotNull(value);
129
		assertNotNull(value);
128
		assertTrue(value instanceof ListObservableValue);
130
		assertTrue(value.getWidget() == list);
129
	}
131
	}
130
	
132
131
	public void testObserveSelectionOfScale() throws Exception {
133
	public void testObserveSelectionOfScale() throws Exception {
132
		Scale scale = new Scale(shell, SWT.NONE);
134
		Scale scale = new Scale(shell, SWT.NONE);
133
		ISWTObservableValue value = SWTObservables.observeSelection(scale);
135
		ISWTObservableValue value = SWTObservables.observeSelection(scale);
134
		assertNotNull(value);
136
		assertNotNull(value);
135
		assertTrue(value instanceof ScaleObservableValue);
137
		assertTrue(value instanceof ScaleObservableValue);
136
		
138
137
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
139
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
138
		assertEquals(SWTProperties.SELECTION, scaleObservable.getAttribute());
140
		assertEquals(SWTProperties.SELECTION, scaleObservable.getAttribute());
139
	}
141
	}
Lines 185-204 Link Here
185
		Combo combo = new Combo(shell, SWT.NONE);
187
		Combo combo = new Combo(shell, SWT.NONE);
186
		ISWTObservableValue value = SWTObservables.observeText(combo);
188
		ISWTObservableValue value = SWTObservables.observeText(combo);
187
		assertNotNull(value);
189
		assertNotNull(value);
188
		assertTrue(value instanceof ComboObservableValue);
190
		assertTrue(value.getWidget() == combo);
189
191
190
		ComboObservableValue comboObservable = (ComboObservableValue) value;
192
		assertTrue(getPropertyObservable(value).getProperty() instanceof ComboTextProperty);
191
		assertEquals(SWTProperties.TEXT, comboObservable.getAttribute());
193
	}
194
195
	/**
196
	 * @param observable
197
	 * @return
198
	 */
199
	private IPropertyObservable getPropertyObservable(
200
			ISWTObservableValue observable) {
201
		IDecoratingObservable decoratingObservable = (IDecoratingObservable) observable;
202
		IPropertyObservable propertyObservable = (IPropertyObservable) decoratingObservable
203
				.getDecorated();
204
		return propertyObservable;
192
	}
205
	}
193
206
194
	public void testObserveTextOfCCombo() throws Exception {
207
	public void testObserveTextOfCCombo() throws Exception {
195
		CCombo combo = new CCombo(shell, SWT.NONE);
208
		CCombo combo = new CCombo(shell, SWT.NONE);
196
		ISWTObservableValue value = SWTObservables.observeText(combo);
209
		ISWTObservableValue value = SWTObservables.observeText(combo);
197
		assertNotNull(value);
210
		assertNotNull(value);
198
		assertTrue(value instanceof CComboObservableValue);
211
		assertTrue(value.getWidget() == combo);
199
212
200
		CComboObservableValue ccomboObservable = (CComboObservableValue) value;
213
		IDecoratingObservable decorating = (IDecoratingObservable) value;
201
		assertEquals(SWTProperties.TEXT, ccomboObservable.getAttribute());
214
		IPropertyObservable property = (IPropertyObservable) decorating
215
				.getDecorated();
216
		assertTrue(property.getProperty() instanceof CComboTextProperty);
202
	}
217
	}
203
218
204
	public void testObserveTextOfUnsupportedControl() throws Exception {
219
	public void testObserveTextOfUnsupportedControl() throws Exception {
Lines 214-234 Link Here
214
		Combo combo = new Combo(shell, SWT.NONE);
229
		Combo combo = new Combo(shell, SWT.NONE);
215
		IObservableList list = SWTObservables.observeItems(combo);
230
		IObservableList list = SWTObservables.observeItems(combo);
216
		assertNotNull(list);
231
		assertNotNull(list);
217
		assertTrue(list instanceof ComboObservableList);
232
		assertTrue(list instanceof ISWTObservable);
233
		assertTrue(((ISWTObservable) list).getWidget() == combo);
218
	}
234
	}
219
235
220
	public void testObserveItemsOfCCombo() throws Exception {
236
	public void testObserveItemsOfCCombo() throws Exception {
221
		CCombo ccombo = new CCombo(shell, SWT.NONE);
237
		CCombo ccombo = new CCombo(shell, SWT.NONE);
222
		IObservableList list = SWTObservables.observeItems(ccombo);
238
		IObservableList list = SWTObservables.observeItems(ccombo);
223
		assertNotNull(list);
239
		assertNotNull(list);
224
		assertTrue(list instanceof CComboObservableList);
240
		ISWTObservable swtObservable = (ISWTObservable) list;
241
		assertTrue(swtObservable.getWidget() == ccombo);
225
	}
242
	}
226
243
227
	public void testObserveItemsOfList() throws Exception {
244
	public void testObserveItemsOfList() throws Exception {
228
		List list = new List(shell, SWT.NONE);
245
		List list = new List(shell, SWT.NONE);
229
		IObservableList observableList = SWTObservables.observeItems(list);
246
		IObservableList observableList = SWTObservables.observeItems(list);
230
		assertNotNull(observableList);
247
		assertNotNull(observableList);
231
		assertTrue(observableList instanceof ListObservableList);
248
		ISWTObservable swtObservable = (ISWTObservable) observableList;
249
		assertTrue(swtObservable.getWidget() == list);
232
	}
250
	}
233
251
234
	public void testObserveItemsOfUnsupportedControl() throws Exception {
252
	public void testObserveItemsOfUnsupportedControl() throws Exception {
Lines 258-280 Link Here
258
276
259
		}
277
		}
260
	}
278
	}
261
	
279
262
	public void testObserveMinOfSpinner() throws Exception {
280
	public void testObserveMinOfSpinner() throws Exception {
263
		Spinner spinner = new Spinner(shell, SWT.NONE);
281
		Spinner spinner = new Spinner(shell, SWT.NONE);
264
		ISWTObservableValue value = SWTObservables.observeMin(spinner);
282
		ISWTObservableValue value = SWTObservables.observeMin(spinner);
265
		assertNotNull(value);
283
		assertNotNull(value);
266
		assertTrue(value instanceof SpinnerObservableValue);
284
		assertTrue(value instanceof SpinnerObservableValue);
267
		
285
268
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
286
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
269
		assertEquals(SWTProperties.MIN, spinnerObservable.getAttribute());
287
		assertEquals(SWTProperties.MIN, spinnerObservable.getAttribute());
270
	}
288
	}
271
	
289
272
	public void testObserveMinOfScale() throws Exception {
290
	public void testObserveMinOfScale() throws Exception {
273
		Scale scale = new Scale(shell, SWT.NONE);
291
		Scale scale = new Scale(shell, SWT.NONE);
274
		ISWTObservableValue value = SWTObservables.observeMin(scale);
292
		ISWTObservableValue value = SWTObservables.observeMin(scale);
275
		assertNotNull(value);
293
		assertNotNull(value);
276
		assertTrue(value instanceof ScaleObservableValue);
294
		assertTrue(value instanceof ScaleObservableValue);
277
		
295
278
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
296
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
279
		assertEquals(SWTProperties.MIN, scaleObservable.getAttribute());
297
		assertEquals(SWTProperties.MIN, scaleObservable.getAttribute());
280
	}
298
	}
Lines 284-313 Link Here
284
		try {
302
		try {
285
			SWTObservables.observeMin(text);
303
			SWTObservables.observeMin(text);
286
			fail("Exception should have been thrown");
304
			fail("Exception should have been thrown");
287
		} catch (IllegalArgumentException e) {	
305
		} catch (IllegalArgumentException e) {
288
		}
306
		}
289
	}
307
	}
290
	
308
291
	public void testObserveMaxOfSpinner() throws Exception {
309
	public void testObserveMaxOfSpinner() throws Exception {
292
		Spinner spinner = new Spinner(shell, SWT.NONE);
310
		Spinner spinner = new Spinner(shell, SWT.NONE);
293
		ISWTObservableValue value = SWTObservables.observeMax(spinner);
311
		ISWTObservableValue value = SWTObservables.observeMax(spinner);
294
		assertNotNull(value);
312
		assertNotNull(value);
295
		assertTrue(value instanceof SpinnerObservableValue);
313
		assertTrue(value instanceof SpinnerObservableValue);
296
		
314
297
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
315
		SpinnerObservableValue spinnerObservable = (SpinnerObservableValue) value;
298
		assertEquals(SWTProperties.MAX, spinnerObservable.getAttribute());
316
		assertEquals(SWTProperties.MAX, spinnerObservable.getAttribute());
299
	}
317
	}
300
	
318
301
	public void testObserveMaxOfScale() throws Exception {
319
	public void testObserveMaxOfScale() throws Exception {
302
		Scale scale = new Scale(shell, SWT.NONE);
320
		Scale scale = new Scale(shell, SWT.NONE);
303
		ISWTObservableValue value = SWTObservables.observeMax(scale);
321
		ISWTObservableValue value = SWTObservables.observeMax(scale);
304
		assertNotNull(value);
322
		assertNotNull(value);
305
		assertTrue(value instanceof ScaleObservableValue);
323
		assertTrue(value instanceof ScaleObservableValue);
306
		
324
307
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
325
		ScaleObservableValue scaleObservable = (ScaleObservableValue) value;
308
		assertEquals(SWTProperties.MAX, scaleObservable.getAttribute());
326
		assertEquals(SWTProperties.MAX, scaleObservable.getAttribute());
309
	}
327
	}
310
	
328
311
	public void testObserveMaxOfUnsupportedControl() throws Exception {
329
	public void testObserveMaxOfUnsupportedControl() throws Exception {
312
		Text text = new Text(shell, SWT.NONE);
330
		Text text = new Text(shell, SWT.NONE);
313
		try {
331
		try {
Lines 316-329 Link Here
316
		} catch (IllegalArgumentException e) {
334
		} catch (IllegalArgumentException e) {
317
		}
335
		}
318
	}
336
	}
319
	
337
320
	public void testObserveEditableOfText() throws Exception {
338
	public void testObserveEditableOfText() throws Exception {
321
		Text text = new Text(shell, SWT.NONE);
339
		Text text = new Text(shell, SWT.NONE);
322
		ISWTObservableValue value = SWTObservables.observeEditable(text);
340
		ISWTObservableValue value = SWTObservables.observeEditable(text);
323
		assertNotNull(value);
341
		assertNotNull(value);
324
		assertTrue(value instanceof TextEditableObservableValue);
342
		assertTrue(value instanceof TextEditableObservableValue);
325
	}
343
	}
326
	
344
327
	public void testObserveEditableOfUnsupportedControl() throws Exception {
345
	public void testObserveEditableOfUnsupportedControl() throws Exception {
328
		Label label = new Label(shell, SWT.NONE);
346
		Label label = new Label(shell, SWT.NONE);
329
		try {
347
		try {
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableMapTest.java (-9 / +22 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Matthew Hall - bugs 213145, 241585
10
 *     Matthew Hall - bugs 213145, 241585, 194734
11
 *******************************************************************************/
11
 *******************************************************************************/
12
12
13
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
Lines 19-30 Link Here
19
import junit.framework.TestCase;
19
import junit.framework.TestCase;
20
import junit.framework.TestSuite;
20
import junit.framework.TestSuite;
21
21
22
import org.eclipse.core.databinding.beans.BeanProperties;
23
import org.eclipse.core.databinding.beans.BeansObservables;
24
import org.eclipse.core.databinding.beans.IBeanObservable;
25
import org.eclipse.core.databinding.beans.IBeanProperty;
26
import org.eclipse.core.databinding.beans.PojoObservables;
22
import org.eclipse.core.databinding.observable.Realm;
27
import org.eclipse.core.databinding.observable.Realm;
23
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
28
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
29
import org.eclipse.core.databinding.observable.map.IObservableMap;
24
import org.eclipse.core.databinding.observable.map.MapChangeEvent;
30
import org.eclipse.core.databinding.observable.map.MapChangeEvent;
25
import org.eclipse.core.databinding.observable.map.MapDiff;
31
import org.eclipse.core.databinding.observable.map.MapDiff;
26
import org.eclipse.core.databinding.observable.set.WritableSet;
32
import org.eclipse.core.databinding.observable.set.WritableSet;
27
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableMap;
28
import org.eclipse.core.tests.databinding.observable.ThreadRealm;
33
import org.eclipse.core.tests.databinding.observable.ThreadRealm;
29
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
34
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
30
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
35
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
Lines 42-48 Link Here
42
47
43
	private PropertyDescriptor propertyDescriptor;
48
	private PropertyDescriptor propertyDescriptor;
44
49
45
	private JavaBeanObservableMap map;
50
	private IObservableMap map;
51
	private IBeanObservable beanObservable;
46
52
47
	protected void setUp() throws Exception {
53
	protected void setUp() throws Exception {
48
		ThreadRealm realm = new ThreadRealm();
54
		ThreadRealm realm = new ThreadRealm();
Lines 54-61 Link Here
54
		set.add(model1);
60
		set.add(model1);
55
		set.add(model2);
61
		set.add(model2);
56
62
57
		propertyDescriptor = new PropertyDescriptor("value", Bean.class);
63
		String propertyName = "value";
58
		map = new JavaBeanObservableMap(set, propertyDescriptor);
64
		propertyDescriptor = ((IBeanProperty) BeanProperties.valueProperty(
65
				Bean.class, propertyName)).getPropertyDescriptor();
66
		map = BeansObservables.observeMap(set, Bean.class, propertyName);
67
		beanObservable = (IBeanObservable) map;
59
	}
68
	}
60
69
61
	public void testGetValue() throws Exception {
70
	public void testGetValue() throws Exception {
Lines 135-145 Link Here
135
	}
144
	}
136
	
145
	
137
	public void testGetObserved() throws Exception {
146
	public void testGetObserved() throws Exception {
138
		assertEquals(set, map.getObserved());
147
		assertEquals(set, beanObservable.getObserved());
139
	}
148
	}
140
	
149
	
141
	public void testGetPropertyDescriptor() throws Exception {
150
	public void testGetPropertyDescriptor() throws Exception {
142
		assertEquals(propertyDescriptor, map.getPropertyDescriptor());
151
		assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
143
	}
152
	}
144
	
153
	
145
	public void testConstructor_SkipRegisterListeners() throws Exception {
154
	public void testConstructor_SkipRegisterListeners() throws Exception {
Lines 148-154 Link Here
148
		Bean bean = new Bean();
157
		Bean bean = new Bean();
149
		set.add(bean);
158
		set.add(bean);
150
		
159
		
151
		JavaBeanObservableMap observable = new JavaBeanObservableMap(set, new PropertyDescriptor("value", Bean.class), false);
160
		IObservableMap observable = PojoObservables.observeMap(set, Bean.class,
161
				"value");
162
		assertFalse(bean.hasListeners("value"));
152
		ChangeEventTracker.observe(observable);
163
		ChangeEventTracker.observe(observable);
153
164
154
		assertFalse(bean.hasListeners("value"));
165
		assertFalse(bean.hasListeners("value"));
Lines 160-166 Link Here
160
		Bean bean = new Bean();
171
		Bean bean = new Bean();
161
		set.add(bean);
172
		set.add(bean);
162
		
173
		
163
		JavaBeanObservableMap observable = new JavaBeanObservableMap(set, new PropertyDescriptor("value", Bean.class));
174
		IObservableMap observable = BeansObservables.observeMap(set,
175
				Bean.class, "value");
176
		assertFalse(bean.hasListeners("value"));
164
		ChangeEventTracker.observe(observable);
177
		ChangeEventTracker.observe(observable);
165
178
166
		assertTrue(bean.hasListeners("value"));
179
		assertTrue(bean.hasListeners("value"));
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableValueTest.java (-26 / +22 lines)
Lines 9-33 Link Here
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Brad Reynolds - bug 171616
10
 *     Brad Reynolds - bug 171616
11
 *     Katarzyna Marszalek - test case for bug 198519
11
 *     Katarzyna Marszalek - test case for bug 198519
12
 *     Matthew Hall - bug 213145
12
 *     Matthew Hall - bugs 213145, 194734
13
 ******************************************************************************/
13
 ******************************************************************************/
14
14
15
package org.eclipse.core.tests.internal.databinding.beans;
15
package org.eclipse.core.tests.internal.databinding.beans;
16
16
17
import java.beans.IntrospectionException;
18
import java.beans.PropertyDescriptor;
17
import java.beans.PropertyDescriptor;
19
18
20
import junit.framework.Test;
19
import junit.framework.Test;
21
import junit.framework.TestSuite;
20
import junit.framework.TestSuite;
22
21
22
import org.eclipse.core.databinding.beans.BeanProperties;
23
import org.eclipse.core.databinding.beans.BeansObservables;
23
import org.eclipse.core.databinding.beans.BeansObservables;
24
import org.eclipse.core.databinding.beans.IBeanObservable;
25
import org.eclipse.core.databinding.beans.IBeanProperty;
26
import org.eclipse.core.databinding.beans.PojoObservables;
24
import org.eclipse.core.databinding.observable.ChangeEvent;
27
import org.eclipse.core.databinding.observable.ChangeEvent;
25
import org.eclipse.core.databinding.observable.IChangeListener;
28
import org.eclipse.core.databinding.observable.IChangeListener;
26
import org.eclipse.core.databinding.observable.IObservable;
29
import org.eclipse.core.databinding.observable.IObservable;
27
import org.eclipse.core.databinding.observable.Realm;
30
import org.eclipse.core.databinding.observable.Realm;
28
import org.eclipse.core.databinding.observable.value.ComputedValue;
31
import org.eclipse.core.databinding.observable.value.ComputedValue;
29
import org.eclipse.core.databinding.observable.value.IObservableValue;
32
import org.eclipse.core.databinding.observable.value.IObservableValue;
30
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableValue;
31
import org.eclipse.jface.databinding.conformance.MutableObservableValueContractTest;
33
import org.eclipse.jface.databinding.conformance.MutableObservableValueContractTest;
32
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
34
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
33
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
35
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
Lines 39-73 Link Here
39
 */
41
 */
40
public class JavaBeanObservableValueTest extends AbstractDefaultRealmTestCase {
42
public class JavaBeanObservableValueTest extends AbstractDefaultRealmTestCase {
41
	private Bean bean;
43
	private Bean bean;
42
	private JavaBeanObservableValue observableValue;
44
	private IObservableValue observableValue;
45
	private IBeanObservable beanObservable;
43
	private PropertyDescriptor propertyDescriptor;
46
	private PropertyDescriptor propertyDescriptor;
44
	private String propertyName;
47
	private String propertyName;
45
48
46
	/* (non-Javadoc)
47
	 * @see junit.framework.TestCase#setUp()
48
	 */
49
	protected void setUp() throws Exception {
49
	protected void setUp() throws Exception {
50
		super.setUp();
50
		super.setUp();
51
		
51
		
52
		bean = new Bean();
52
		bean = new Bean();
53
		propertyName = "value";
53
		propertyName = "value";
54
		propertyDescriptor = new PropertyDescriptor(propertyName, Bean.class);
54
		propertyDescriptor = ((IBeanProperty) BeanProperties.valueProperty(
55
		observableValue = new JavaBeanObservableValue(Realm.getDefault(), bean, propertyDescriptor);
55
				Bean.class, propertyName)).getPropertyDescriptor();
56
		observableValue = BeansObservables.observeValue(bean, propertyName);
57
		beanObservable = (IBeanObservable) observableValue;
56
	}
58
	}
57
59
58
	public void testGetObserved() throws Exception {
60
	public void testGetObserved() throws Exception {
59
		assertEquals(bean, observableValue.getObserved());
61
		assertEquals(bean, beanObservable.getObserved());
60
	}
62
	}
61
63
62
	public void testGetPropertyDescriptor() throws Exception {
64
	public void testGetPropertyDescriptor() throws Exception {
63
    	assertEquals(propertyDescriptor, observableValue.getPropertyDescriptor());
65
    	assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
64
	}
66
	}
65
67
66
	public void testSetValueThrowsExceptionThrownByBean() throws Exception {
68
	public void testSetValueThrowsExceptionThrownByBean() throws Exception {
67
		ThrowsSetException temp = new ThrowsSetException();
69
		ThrowsSetException temp = new ThrowsSetException();
68
		JavaBeanObservableValue observable = new JavaBeanObservableValue(Realm
70
		IObservableValue observable = BeansObservables.observeValue(temp,
69
				.getDefault(), temp,
71
				"value");
70
				new PropertyDescriptor("value", ThrowsSetException.class));
71
72
72
		try {
73
		try {
73
			observable.setValue("");
74
			observable.setValue("");
Lines 79-87 Link Here
79
	
80
	
80
	public void testGetValueThrowsExceptionThrownByBean() throws Exception {
81
	public void testGetValueThrowsExceptionThrownByBean() throws Exception {
81
		ThrowsGetException temp = new ThrowsGetException();
82
		ThrowsGetException temp = new ThrowsGetException();
82
		JavaBeanObservableValue observable = new JavaBeanObservableValue(Realm
83
		IObservableValue observable = BeansObservables.observeValue(temp,
83
				.getDefault(), temp,
84
				"value");
84
				new PropertyDescriptor("value", ThrowsGetException.class));
85
85
86
		try {
86
		try {
87
			observable.getValue();
87
			observable.getValue();
Lines 108-121 Link Here
108
	}
108
	}
109
109
110
	public void testConstructor_RegistersListeners() throws Exception {
110
	public void testConstructor_RegistersListeners() throws Exception {
111
		JavaBeanObservableValue observable = new JavaBeanObservableValue(Realm.getDefault(), bean, propertyDescriptor);
111
		IObservableValue observable = BeansObservables.observeValue(bean,
112
				propertyName);
112
		ChangeEventTracker.observe(observable);
113
		ChangeEventTracker.observe(observable);
113
		
114
		
114
		assertTrue(bean.hasListeners(propertyName));
115
		assertTrue(bean.hasListeners(propertyName));
115
	}
116
	}
116
	
117
	
117
	public void testConstructor_SkipRegisterListeners() throws Exception {
118
	public void testConstructor_SkipRegisterListeners() throws Exception {
118
		JavaBeanObservableValue observable = new JavaBeanObservableValue(Realm.getDefault(), bean, propertyDescriptor, false);
119
		IObservableValue observable = PojoObservables.observeValue(bean,
120
				propertyName);
119
		ChangeEventTracker.observe(observable);
121
		ChangeEventTracker.observe(observable);
120
		
122
		
121
		assertFalse(bean.hasListeners(propertyName));
123
		assertFalse(bean.hasListeners(propertyName));
Lines 138-150 Link Here
138
		}
140
		}
139
		
141
		
140
		public IObservableValue createObservableValue(Realm realm) {
142
		public IObservableValue createObservableValue(Realm realm) {
141
			try {
143
			return BeansObservables.observeValue(realm, bean, "value");
142
				PropertyDescriptor propertyDescriptor = new PropertyDescriptor("value", Bean.class);
143
				return new JavaBeanObservableValue(realm, bean,
144
						propertyDescriptor);					
145
			} catch (IntrospectionException e) {
146
				throw new RuntimeException(e);
147
			}
148
		}
144
		}
149
		
145
		
150
		public void change(IObservable observable) {
146
		public void change(IObservable observable) {
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedListTest.java (-32 / +25 lines)
Lines 7-18 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 221351, 213145
10
 *     Matthew Hall - bugs 221351, 213145, 194734
11
 ******************************************************************************/
11
 ******************************************************************************/
12
12
13
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
14
14
15
import java.beans.IntrospectionException;
16
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeEvent;
17
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyChangeListener;
18
import java.beans.PropertyDescriptor;
17
import java.beans.PropertyDescriptor;
Lines 23-35 Link Here
23
import junit.framework.Test;
22
import junit.framework.Test;
24
import junit.framework.TestSuite;
23
import junit.framework.TestSuite;
25
24
25
import org.eclipse.core.databinding.beans.BeanProperties;
26
import org.eclipse.core.databinding.beans.BeansObservables;
27
import org.eclipse.core.databinding.beans.IBeanObservable;
28
import org.eclipse.core.databinding.beans.IBeanProperty;
26
import org.eclipse.core.databinding.observable.IObservable;
29
import org.eclipse.core.databinding.observable.IObservable;
27
import org.eclipse.core.databinding.observable.IObservableCollection;
30
import org.eclipse.core.databinding.observable.IObservableCollection;
28
import org.eclipse.core.databinding.observable.Realm;
31
import org.eclipse.core.databinding.observable.Realm;
29
import org.eclipse.core.databinding.observable.list.IObservableList;
32
import org.eclipse.core.databinding.observable.list.IObservableList;
30
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
33
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
31
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
34
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
32
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
33
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
35
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
34
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
36
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
35
import org.eclipse.jface.databinding.conformance.util.ListChangeEventTracker;
37
import org.eclipse.jface.databinding.conformance.util.ListChangeEventTracker;
Lines 42-48 Link Here
42
 */
44
 */
43
public class JavaBeanObservableArrayBasedListTest extends
45
public class JavaBeanObservableArrayBasedListTest extends
44
		AbstractDefaultRealmTestCase {
46
		AbstractDefaultRealmTestCase {
45
	private JavaBeanObservableList list;
47
	private IObservableList list;
48
	private IBeanObservable beanObservable;
46
49
47
	private PropertyDescriptor propertyDescriptor;
50
	private PropertyDescriptor propertyDescriptor;
48
51
Lines 59-77 Link Here
59
		super.setUp();
62
		super.setUp();
60
63
61
		propertyName = "array";
64
		propertyName = "array";
62
		propertyDescriptor = new PropertyDescriptor(propertyName, Bean.class);
65
		propertyDescriptor = ((IBeanProperty) BeanProperties.listProperty(
66
				Bean.class, propertyName)).getPropertyDescriptor();
63
		bean = new Bean(new Object[0]);
67
		bean = new Bean(new Object[0]);
64
68
65
		list = new JavaBeanObservableList(SWTObservables.getRealm(Display
69
		list = BeansObservables.observeList(SWTObservables.getRealm(Display
66
				.getDefault()), bean, propertyDescriptor, Bean.class);
70
				.getDefault()), bean, propertyName);
71
		beanObservable = (IBeanObservable) list;
67
	}
72
	}
68
73
69
	public void testGetObserved() throws Exception {
74
	public void testGetObserved() throws Exception {
70
		assertSame(bean, list.getObserved());
75
		assertSame(bean, beanObservable.getObserved());
71
	}
76
	}
72
77
73
	public void testGetPropertyDescriptor() throws Exception {
78
	public void testGetPropertyDescriptor() throws Exception {
74
		assertSame(propertyDescriptor, list.getPropertyDescriptor());
79
		assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
75
	}
80
	}
76
81
77
	public void testRegistersListenerAfterFirstListenerIsAdded()
82
	public void testRegistersListenerAfterFirstListenerIsAdded()
Lines 308-323 Link Here
308
	}
313
	}
309
314
310
	public void testRemoveAll() throws Exception {
315
	public void testRemoveAll() throws Exception {
311
		List elements = Arrays.asList(new String[] { "1", "2" });
316
		list.addAll(Arrays.asList(new String[] { "1", "2", "3", "4" }));
312
		list.addAll(elements);
313
		list.addAll(elements);
314
315
		assertEquals(4, bean.getArray().length);
317
		assertEquals(4, bean.getArray().length);
316
		list.removeAll(elements);
318
319
		list.removeAll(Arrays.asList(new String[] { "2", "4" }));
317
320
318
		assertEquals(2, bean.getArray().length);
321
		assertEquals(2, bean.getArray().length);
319
		assertEquals(elements.get(0), bean.getArray()[0]);
322
		assertEquals("1", bean.getArray()[0]);
320
		assertEquals(elements.get(1), bean.getArray()[1]);
323
		assertEquals("3", bean.getArray()[1]);
321
	}
324
	}
322
325
323
	public void testRemoveAllListChangeEvent() throws Exception {
326
	public void testRemoveAllListChangeEvent() throws Exception {
Lines 471-478 Link Here
471
		PropertyChangeEvent event = listener.evt;
474
		PropertyChangeEvent event = listener.evt;
472
		assertEquals("event did not fire", 1, listener.count);
475
		assertEquals("event did not fire", 1, listener.count);
473
		assertEquals("array", event.getPropertyName());
476
		assertEquals("array", event.getPropertyName());
474
		assertTrue("old value", Arrays.equals(old, (Object[]) event.getOldValue()));
477
		assertTrue("old value", Arrays.equals(old, (Object[]) event
475
		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event.getNewValue()));
478
				.getOldValue()));
479
		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event
480
				.getNewValue()));
476
		assertFalse("lists are equal", Arrays.equals(bean.getArray(), old));
481
		assertFalse("lists are equal", Arrays.equals(bean.getArray(), old));
477
	}
482
	}
478
483
Lines 482-492 Link Here
482
487
483
		PropertyChangeEvent evt;
488
		PropertyChangeEvent evt;
484
489
485
		/*
486
		 * (non-Javadoc)
487
		 * 
488
		 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
489
		 */
490
		public void propertyChange(PropertyChangeEvent evt) {
490
		public void propertyChange(PropertyChangeEvent evt) {
491
			count++;
491
			count++;
492
			this.evt = evt;
492
			this.evt = evt;
Lines 504-520 Link Here
504
		public IObservableCollection createObservableCollection(Realm realm,
504
		public IObservableCollection createObservableCollection(Realm realm,
505
				int elementCount) {
505
				int elementCount) {
506
			String propertyName = "array";
506
			String propertyName = "array";
507
			PropertyDescriptor propertyDescriptor;
508
			try {
509
				propertyDescriptor = new PropertyDescriptor(propertyName,
510
						Bean.class);
511
			} catch (IntrospectionException e) {
512
				throw new RuntimeException(e);
513
			}
514
			Object bean = new Bean(new Object[0]);
507
			Object bean = new Bean(new Object[0]);
515
508
516
			IObservableList list = new JavaBeanObservableList(realm, bean,
509
			IObservableList list = BeansObservables.observeList(realm, bean,
517
					propertyDescriptor, String.class);
510
					propertyName, String.class);
518
			for (int i = 0; i < elementCount; i++)
511
			for (int i = 0; i < elementCount; i++)
519
				list.add(createElement(list));
512
				list.add(createElement(list));
520
			return list;
513
			return list;
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableSetTest.java (-28 / +22 lines)
Lines 7-18 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 221351, 213145
10
 *     Matthew Hall - bugs 221351, 213145, 194734
11
 ******************************************************************************/
11
 ******************************************************************************/
12
12
13
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
14
14
15
import java.beans.IntrospectionException;
16
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
17
import java.util.Arrays;
16
import java.util.Arrays;
18
import java.util.HashSet;
17
import java.util.HashSet;
Lines 21-33 Link Here
21
import junit.framework.TestCase;
20
import junit.framework.TestCase;
22
import junit.framework.TestSuite;
21
import junit.framework.TestSuite;
23
22
23
import org.eclipse.core.databinding.beans.BeanProperties;
24
import org.eclipse.core.databinding.beans.BeansObservables;
25
import org.eclipse.core.databinding.beans.IBeanObservable;
26
import org.eclipse.core.databinding.beans.IBeanProperty;
27
import org.eclipse.core.databinding.beans.PojoObservables;
24
import org.eclipse.core.databinding.observable.IObservable;
28
import org.eclipse.core.databinding.observable.IObservable;
25
import org.eclipse.core.databinding.observable.IObservableCollection;
29
import org.eclipse.core.databinding.observable.IObservableCollection;
26
import org.eclipse.core.databinding.observable.Realm;
30
import org.eclipse.core.databinding.observable.Realm;
27
import org.eclipse.core.databinding.observable.set.IObservableSet;
31
import org.eclipse.core.databinding.observable.set.IObservableSet;
28
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
32
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
29
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
33
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
30
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
31
import org.eclipse.jface.databinding.conformance.MutableObservableSetContractTest;
34
import org.eclipse.jface.databinding.conformance.MutableObservableSetContractTest;
32
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
35
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
33
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
36
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
Lines 39-72 Link Here
39
 * @since 3.3
42
 * @since 3.3
40
 */
43
 */
41
public class JavaBeanObservableSetTest extends TestCase {
44
public class JavaBeanObservableSetTest extends TestCase {
42
	private JavaBeanObservableSet observableSet;
45
	private IObservableSet observableSet;
46
	private IBeanObservable beanObservable;
43
	private Bean bean;
47
	private Bean bean;
44
	private PropertyDescriptor propertyDescriptor;
48
	private PropertyDescriptor propertyDescriptor;
45
	private String propertyName;
49
	private String propertyName;
46
	private SetChangeListener listener;
50
	private SetChangeListener listener;
47
51
48
	/*
49
	 * (non-Javadoc)
50
	 * 
51
	 * @see junit.framework.TestCase#setUp()
52
	 */
53
	protected void setUp() throws Exception {
52
	protected void setUp() throws Exception {
54
		bean = new Bean();
53
		bean = new Bean();
55
		propertyName = "set";
54
		propertyName = "set";
56
		propertyDescriptor = new PropertyDescriptor(propertyName, Bean.class);
55
		propertyDescriptor = ((IBeanProperty) BeanProperties.setProperty(
56
				Bean.class, propertyName)).getPropertyDescriptor();
57
57
58
		observableSet = new JavaBeanObservableSet(SWTObservables
58
		observableSet = BeansObservables
59
				.getRealm(Display.getDefault()), bean, propertyDescriptor,
59
				.observeSet(SWTObservables.getRealm(Display.getDefault()),
60
				Bean.class);
60
						bean, propertyName, Bean.class);
61
		beanObservable = (IBeanObservable) observableSet;
61
		listener = new SetChangeListener();
62
		listener = new SetChangeListener();
62
	}
63
	}
63
64
64
	public void testGetObserved() throws Exception {
65
	public void testGetObserved() throws Exception {
65
		assertEquals(bean, observableSet.getObserved());
66
		assertEquals(bean, beanObservable.getObserved());
66
	}
67
	}
67
68
68
	public void testGetPropertyDescriptor() throws Exception {
69
	public void testGetPropertyDescriptor() throws Exception {
69
		assertEquals(propertyDescriptor, observableSet.getPropertyDescriptor());
70
		assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
70
	}
71
	}
71
	
72
	
72
	public void testGetElementType() throws Exception {
73
	public void testGetElementType() throws Exception {
Lines 97-104 Link Here
97
	public void testConstructor_RegisterListeners() throws Exception {
98
	public void testConstructor_RegisterListeners() throws Exception {
98
		bean = new Bean();
99
		bean = new Bean();
99
100
100
		observableSet = new JavaBeanObservableSet(new CurrentRealm(true), bean,
101
		observableSet = BeansObservables.observeSet(new CurrentRealm(true),
101
				propertyDescriptor, Bean.class);
102
				bean, propertyName);
102
		assertFalse(bean.hasListeners(propertyName));
103
		assertFalse(bean.hasListeners(propertyName));
103
		ChangeEventTracker.observe(observableSet);
104
		ChangeEventTracker.observe(observableSet);
104
		assertTrue(bean.hasListeners(propertyName));
105
		assertTrue(bean.hasListeners(propertyName));
Lines 107-114 Link Here
107
	public void testConstructor_SkipsRegisterListeners() throws Exception {
108
	public void testConstructor_SkipsRegisterListeners() throws Exception {
108
		bean = new Bean();
109
		bean = new Bean();
109
110
110
		observableSet = new JavaBeanObservableSet(new CurrentRealm(true), bean,
111
		observableSet = PojoObservables.observeSet(new CurrentRealm(true),
111
				propertyDescriptor, Bean.class, false);
112
				bean, propertyName);
112
		assertFalse(bean.hasListeners(propertyName));
113
		assertFalse(bean.hasListeners(propertyName));
113
		ChangeEventTracker.observe(observableSet);
114
		ChangeEventTracker.observe(observableSet);
114
		assertFalse(bean.hasListeners(propertyName));
115
		assertFalse(bean.hasListeners(propertyName));
Lines 134-149 Link Here
134
				int elementCount) {
135
				int elementCount) {
135
			Bean bean = new Bean();
136
			Bean bean = new Bean();
136
			String propertyName = "set";
137
			String propertyName = "set";
137
			PropertyDescriptor propertyDescriptor;
138
			try {
139
				propertyDescriptor = new PropertyDescriptor(propertyName,
140
						Bean.class);
141
			} catch (IntrospectionException e) {
142
				throw new RuntimeException(e);
143
			}
144
138
145
			IObservableSet set = new JavaBeanObservableSet(realm,
139
			IObservableSet set = BeansObservables.observeSet(realm, bean,
146
					bean, propertyDescriptor, String.class);
140
					propertyName, String.class);
147
			for (int i = 0; i < elementCount; i++)
141
			for (int i = 0; i < elementCount; i++)
148
				set.add(createElement(set));
142
				set.add(createElement(set));
149
			return set;
143
			return set;
(-)src/org/eclipse/core/tests/internal/databinding/beans/BeanObservableSetDecoratorTest.java (-11 / +18 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 194734
10
 ******************************************************************************/
11
 ******************************************************************************/
11
12
12
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
Lines 15-22 Link Here
15
16
16
import junit.framework.TestCase;
17
import junit.framework.TestCase;
17
18
19
import org.eclipse.core.databinding.beans.BeanProperties;
20
import org.eclipse.core.databinding.beans.BeansObservables;
21
import org.eclipse.core.databinding.beans.IBeanObservable;
22
import org.eclipse.core.databinding.beans.IBeanProperty;
23
import org.eclipse.core.databinding.observable.set.IObservableSet;
18
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
24
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
19
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
20
import org.eclipse.jface.databinding.swt.SWTObservables;
25
import org.eclipse.jface.databinding.swt.SWTObservables;
21
import org.eclipse.swt.widgets.Display;
26
import org.eclipse.swt.widgets.Display;
22
27
Lines 25-31 Link Here
25
 */
30
 */
26
public class BeanObservableSetDecoratorTest extends TestCase {
31
public class BeanObservableSetDecoratorTest extends TestCase {
27
	private PropertyDescriptor propertyDescriptor;
32
	private PropertyDescriptor propertyDescriptor;
28
	private JavaBeanObservableSet observableSet;
33
	private IObservableSet observableSet;
34
	private IBeanObservable beanObservable;
29
	private BeanObservableSetDecorator decorator;
35
	private BeanObservableSetDecorator decorator;
30
36
31
	/*
37
	/*
Lines 37-57 Link Here
37
		super.setUp();
43
		super.setUp();
38
44
39
		Bean bean = new Bean();
45
		Bean bean = new Bean();
40
		propertyDescriptor = new PropertyDescriptor("set",
46
		String propertyName = "set";
41
				Bean.class);
47
		propertyDescriptor = ((IBeanProperty) BeanProperties.setProperty(
42
		observableSet = new JavaBeanObservableSet(
48
				Bean.class, propertyName)).getPropertyDescriptor();
43
				SWTObservables.getRealm(Display.getDefault()), bean,
49
		observableSet = BeansObservables.observeSet(SWTObservables
44
				propertyDescriptor, String.class);
50
				.getRealm(Display.getDefault()), bean, propertyName);
45
		decorator = new BeanObservableSetDecorator(
51
		beanObservable = (IBeanObservable) observableSet;
46
				observableSet, observableSet, propertyDescriptor);
52
		decorator = new BeanObservableSetDecorator(observableSet,
53
				propertyDescriptor);
47
	}
54
	}
48
55
49
	public void testGetDelegate() throws Exception {
56
	public void testGetDelegate() throws Exception {
50
		assertEquals(observableSet, decorator.getDelegate());
57
		assertEquals(observableSet, decorator.getDecorated());
51
	}
58
	}
52
59
53
	public void testGetObserved() throws Exception {
60
	public void testGetObserved() throws Exception {
54
		assertEquals(observableSet, decorator.getObserved());
61
		assertEquals(beanObservable.getObserved(), decorator.getObserved());
55
	}
62
	}
56
63
57
	public void testGetPropertyDescriptor() throws Exception {
64
	public void testGetPropertyDescriptor() throws Exception {
(-)src/org/eclipse/core/tests/internal/databinding/beans/BeanObservableListDecoratorTest.java (-10 / +12 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 208858, 213145
10
 *     Matthew Hall - bugs 208858, 213145, 194734
11
 ******************************************************************************/
11
 ******************************************************************************/
12
12
13
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
Lines 18-30 Link Here
18
import junit.framework.TestCase;
18
import junit.framework.TestCase;
19
import junit.framework.TestSuite;
19
import junit.framework.TestSuite;
20
20
21
import org.eclipse.core.databinding.beans.BeansObservables;
22
import org.eclipse.core.databinding.beans.IBeanObservable;
21
import org.eclipse.core.databinding.observable.IObservable;
23
import org.eclipse.core.databinding.observable.IObservable;
22
import org.eclipse.core.databinding.observable.IObservableCollection;
24
import org.eclipse.core.databinding.observable.IObservableCollection;
23
import org.eclipse.core.databinding.observable.Realm;
25
import org.eclipse.core.databinding.observable.Realm;
24
import org.eclipse.core.databinding.observable.list.IObservableList;
26
import org.eclipse.core.databinding.observable.list.IObservableList;
25
import org.eclipse.core.databinding.observable.list.WritableList;
27
import org.eclipse.core.databinding.observable.list.WritableList;
26
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
28
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
27
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
28
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
29
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
29
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
30
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
30
import org.eclipse.jface.databinding.swt.SWTObservables;
31
import org.eclipse.jface.databinding.swt.SWTObservables;
Lines 35-41 Link Here
35
 */
36
 */
36
public class BeanObservableListDecoratorTest extends TestCase {
37
public class BeanObservableListDecoratorTest extends TestCase {
37
	private PropertyDescriptor propertyDescriptor;
38
	private PropertyDescriptor propertyDescriptor;
38
	private JavaBeanObservableList observableList;
39
	private IObservableList observableList;
40
	private IBeanObservable beanObservable;
39
	private BeanObservableListDecorator decorator;
41
	private BeanObservableListDecorator decorator;
40
42
41
	/*
43
	/*
Lines 49-66 Link Here
49
		Bean bean = new Bean();
51
		Bean bean = new Bean();
50
		propertyDescriptor = new PropertyDescriptor(
52
		propertyDescriptor = new PropertyDescriptor(
51
				"list", Bean.class,"getList","setList");
53
				"list", Bean.class,"getList","setList");
52
		observableList = new JavaBeanObservableList(
54
		observableList = BeansObservables.observeList(SWTObservables
53
				SWTObservables.getRealm(Display.getDefault()), bean,
55
				.getRealm(Display.getDefault()), bean, "list");
54
				propertyDescriptor, Bean.class);
56
		beanObservable = (IBeanObservable) observableList;
55
		decorator = new BeanObservableListDecorator(observableList, observableList, propertyDescriptor);
57
		decorator = new BeanObservableListDecorator(observableList, propertyDescriptor);
56
	}
58
	}
57
59
58
	public void testGetDelegate() throws Exception {
60
	public void testGetDelegate() throws Exception {
59
		assertEquals(observableList, decorator.getDelegate());
61
		assertEquals(observableList, decorator.getDecorated());
60
	}
62
	}
61
63
62
	public void testGetObserved() throws Exception {
64
	public void testGetObserved() throws Exception {
63
		assertEquals(observableList, decorator.getObserved());
65
		assertEquals(beanObservable.getObserved(), decorator.getObserved());
64
	}
66
	}
65
67
66
	public void testGetPropertyDescriptor() throws Exception {
68
	public void testGetPropertyDescriptor() throws Exception {
Lines 80-86 Link Here
80
			final WritableList delegate = new WritableList(realm);
82
			final WritableList delegate = new WritableList(realm);
81
			for (int i = 0; i < elementCount; i++)
83
			for (int i = 0; i < elementCount; i++)
82
				delegate.add(createElement(delegate));
84
				delegate.add(createElement(delegate));
83
			return new BeanObservableListDecorator(delegate, null, null);
85
			return new BeanObservableListDecorator(delegate, null);
84
		}
86
		}
85
87
86
		private int counter;
88
		private int counter;
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableListTest.java (-36 / +26 lines)
Lines 7-18 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bugs 221351, 213145
10
 *     Matthew Hall - bugs 221351, 213145, 194734
11
 ******************************************************************************/
11
 ******************************************************************************/
12
12
13
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
14
14
15
import java.beans.IntrospectionException;
16
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeEvent;
17
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyChangeListener;
18
import java.beans.PropertyDescriptor;
17
import java.beans.PropertyDescriptor;
Lines 24-36 Link Here
24
import junit.framework.Test;
23
import junit.framework.Test;
25
import junit.framework.TestSuite;
24
import junit.framework.TestSuite;
26
25
26
import org.eclipse.core.databinding.beans.BeanProperties;
27
import org.eclipse.core.databinding.beans.BeansObservables;
28
import org.eclipse.core.databinding.beans.IBeanObservable;
29
import org.eclipse.core.databinding.beans.IBeanProperty;
30
import org.eclipse.core.databinding.beans.PojoObservables;
27
import org.eclipse.core.databinding.observable.IObservable;
31
import org.eclipse.core.databinding.observable.IObservable;
28
import org.eclipse.core.databinding.observable.IObservableCollection;
32
import org.eclipse.core.databinding.observable.IObservableCollection;
29
import org.eclipse.core.databinding.observable.Realm;
33
import org.eclipse.core.databinding.observable.Realm;
30
import org.eclipse.core.databinding.observable.list.IObservableList;
34
import org.eclipse.core.databinding.observable.list.IObservableList;
31
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
35
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
32
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
36
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
33
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
34
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
37
import org.eclipse.jface.databinding.conformance.MutableObservableListContractTest;
35
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
38
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
36
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
39
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
Lines 43-49 Link Here
43
 * @since 1.1
46
 * @since 1.1
44
 */
47
 */
45
public class JavaBeanObservableListTest extends AbstractDefaultRealmTestCase {
48
public class JavaBeanObservableListTest extends AbstractDefaultRealmTestCase {
46
	private JavaBeanObservableList list;
49
	private IObservableList list;
50
	private IBeanObservable beanObservable;
47
51
48
	private PropertyDescriptor propertyDescriptor;
52
	private PropertyDescriptor propertyDescriptor;
49
53
Lines 60-78 Link Here
60
		super.setUp();
64
		super.setUp();
61
65
62
		propertyName = "list";
66
		propertyName = "list";
63
		propertyDescriptor = new PropertyDescriptor(propertyName, Bean.class);
67
		propertyDescriptor = ((IBeanProperty) BeanProperties.listProperty(
68
				Bean.class, propertyName)).getPropertyDescriptor();
64
		bean = new Bean(new ArrayList());
69
		bean = new Bean(new ArrayList());
65
70
66
		list = new JavaBeanObservableList(SWTObservables.getRealm(Display
71
		list = BeansObservables.observeList(SWTObservables.getRealm(Display
67
				.getDefault()), bean, propertyDescriptor, String.class);
72
				.getDefault()), bean, propertyName);
73
		beanObservable = (IBeanObservable) list;
68
	}
74
	}
69
75
70
	public void testGetObserved() throws Exception {
76
	public void testGetObserved() throws Exception {
71
		assertEquals(bean, list.getObserved());
77
		assertEquals(bean, beanObservable.getObserved());
72
	}
78
	}
73
79
74
	public void testGetPropertyDescriptor() throws Exception {
80
	public void testGetPropertyDescriptor() throws Exception {
75
		assertEquals(propertyDescriptor, list.getPropertyDescriptor());
81
		assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
76
	}
82
	}
77
83
78
	public void testRegistersListenerAfterFirstListenerIsAdded()
84
	public void testRegistersListenerAfterFirstListenerIsAdded()
Lines 322-337 Link Here
322
	}
328
	}
323
329
324
	public void testRemoveAll() throws Exception {
330
	public void testRemoveAll() throws Exception {
325
		List elements = Arrays.asList(new String[] { "1", "2" });
331
		list.addAll(Arrays.asList(new String[] { "1", "2", "3", "4" }));
326
		list.addAll(elements);
327
		list.addAll(elements);
328
329
		assertEquals(4, bean.getList().size());
332
		assertEquals(4, bean.getList().size());
330
		list.removeAll(elements);
333
334
		list.removeAll(Arrays.asList(new String[] { "2", "4" }));
331
335
332
		assertEquals(2, bean.getList().size());
336
		assertEquals(2, bean.getList().size());
333
		assertEquals(elements.get(0), bean.getList().get(0));
337
		assertEquals("1", bean.getList().get(0));
334
		assertEquals(elements.get(1), bean.getList().get(1));
338
		assertEquals("3", bean.getList().get(1));
335
	}
339
	}
336
340
337
	public void testRemoveAllListChangeEvent() throws Exception {
341
	public void testRemoveAllListChangeEvent() throws Exception {
Lines 467-475 Link Here
467
471
468
	public void testConstructor_RegistersListener() throws Exception {
472
	public void testConstructor_RegistersListener() throws Exception {
469
		Bean bean = new Bean();
473
		Bean bean = new Bean();
470
		JavaBeanObservableList observable = new JavaBeanObservableList(Realm
474
		IObservableList observable = BeansObservables.observeList(Realm
471
				.getDefault(), bean,
475
				.getDefault(), bean, "list");
472
				new PropertyDescriptor("list", Bean.class), Bean.class);
473
476
474
		assertFalse(bean.hasListeners("list"));
477
		assertFalse(bean.hasListeners("list"));
475
		ChangeEventTracker.observe(observable);
478
		ChangeEventTracker.observe(observable);
Lines 478-486 Link Here
478
481
479
	public void testConstructor_SkipsRegisterListener() throws Exception {
482
	public void testConstructor_SkipsRegisterListener() throws Exception {
480
		Bean bean = new Bean();
483
		Bean bean = new Bean();
481
		JavaBeanObservableList observable = new JavaBeanObservableList(Realm
484
		IObservableList observable = PojoObservables.observeList(Realm
482
				.getDefault(), bean,
485
				.getDefault(), bean, "list");
483
				new PropertyDescriptor("list", Bean.class), Bean.class, false);
484
486
485
		assertFalse(bean.hasListeners("list"));
487
		assertFalse(bean.hasListeners("list"));
486
		ChangeEventTracker.observe(observable);
488
		ChangeEventTracker.observe(observable);
Lines 517-527 Link Here
517
519
518
		PropertyChangeEvent evt;
520
		PropertyChangeEvent evt;
519
521
520
		/*
521
		 * (non-Javadoc)
522
		 * 
523
		 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
524
		 */
525
		public void propertyChange(PropertyChangeEvent evt) {
522
		public void propertyChange(PropertyChangeEvent evt) {
526
			count++;
523
			count++;
527
			this.evt = evt;
524
			this.evt = evt;
Lines 539-555 Link Here
539
		public IObservableCollection createObservableCollection(Realm realm,
536
		public IObservableCollection createObservableCollection(Realm realm,
540
				int elementCount) {
537
				int elementCount) {
541
			String propertyName = "list";
538
			String propertyName = "list";
542
			PropertyDescriptor propertyDescriptor;
543
			try {
544
				propertyDescriptor = new PropertyDescriptor(propertyName,
545
						Bean.class);
546
			} catch (IntrospectionException e) {
547
				throw new RuntimeException(e);
548
			}
549
			Object bean = new Bean(new ArrayList());
539
			Object bean = new Bean(new ArrayList());
550
540
551
			IObservableList list = new JavaBeanObservableList(realm, bean,
541
			IObservableList list = BeansObservables.observeList(realm, bean,
552
					propertyDescriptor, String.class);
542
					propertyName, String.class);
553
			for (int i = 0; i < elementCount; i++)
543
			for (int i = 0; i < elementCount; i++)
554
				list.add(createElement(list));
544
				list.add(createElement(list));
555
			return list;
545
			return list;
(-)src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedSetTest.java (-24 / +18 lines)
Lines 8-19 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 221351)
9
 *     Matthew Hall - initial API and implementation (bug 221351)
10
 *     Brad Reynolds - through JavaBeanObservableArrayBasedListTest.java
10
 *     Brad Reynolds - through JavaBeanObservableArrayBasedListTest.java
11
 *     Matthew Hall - bug 213145
11
 *     Matthew Hall - bugs 213145, 194734
12
 ******************************************************************************/
12
 ******************************************************************************/
13
13
14
package org.eclipse.core.tests.internal.databinding.beans;
14
package org.eclipse.core.tests.internal.databinding.beans;
15
15
16
import java.beans.IntrospectionException;
17
import java.beans.PropertyChangeEvent;
16
import java.beans.PropertyChangeEvent;
18
import java.beans.PropertyChangeListener;
17
import java.beans.PropertyChangeListener;
19
import java.beans.PropertyDescriptor;
18
import java.beans.PropertyDescriptor;
Lines 25-36 Link Here
25
import junit.framework.Test;
24
import junit.framework.Test;
26
import junit.framework.TestSuite;
25
import junit.framework.TestSuite;
27
26
27
import org.eclipse.core.databinding.beans.BeanProperties;
28
import org.eclipse.core.databinding.beans.BeansObservables;
29
import org.eclipse.core.databinding.beans.IBeanObservable;
30
import org.eclipse.core.databinding.beans.IBeanProperty;
28
import org.eclipse.core.databinding.observable.IObservable;
31
import org.eclipse.core.databinding.observable.IObservable;
29
import org.eclipse.core.databinding.observable.IObservableCollection;
32
import org.eclipse.core.databinding.observable.IObservableCollection;
30
import org.eclipse.core.databinding.observable.Realm;
33
import org.eclipse.core.databinding.observable.Realm;
31
import org.eclipse.core.databinding.observable.set.IObservableSet;
34
import org.eclipse.core.databinding.observable.set.IObservableSet;
32
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
35
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
33
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
34
import org.eclipse.jface.databinding.conformance.MutableObservableSetContractTest;
36
import org.eclipse.jface.databinding.conformance.MutableObservableSetContractTest;
35
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
37
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableCollectionContractDelegate;
36
import org.eclipse.jface.databinding.conformance.util.SetChangeEventTracker;
38
import org.eclipse.jface.databinding.conformance.util.SetChangeEventTracker;
Lines 43-49 Link Here
43
 */
45
 */
44
public class JavaBeanObservableArrayBasedSetTest extends
46
public class JavaBeanObservableArrayBasedSetTest extends
45
		AbstractDefaultRealmTestCase {
47
		AbstractDefaultRealmTestCase {
46
	private JavaBeanObservableSet set;
48
	private IObservableSet set;
49
	private IBeanObservable beanObservable;
47
50
48
	private PropertyDescriptor propertyDescriptor;
51
	private PropertyDescriptor propertyDescriptor;
49
52
Lines 55-73 Link Here
55
		super.setUp();
58
		super.setUp();
56
59
57
		propertyName = "array";
60
		propertyName = "array";
58
		propertyDescriptor = new PropertyDescriptor(propertyName, Bean.class);
61
		propertyDescriptor = ((IBeanProperty) BeanProperties.setProperty(
62
				Bean.class, propertyName)).getPropertyDescriptor();
59
		bean = new Bean(new HashSet());
63
		bean = new Bean(new HashSet());
60
64
61
		set = new JavaBeanObservableSet(SWTObservables.getRealm(Display
65
		set = BeansObservables.observeSet(SWTObservables.getRealm(Display
62
				.getDefault()), bean, propertyDescriptor, String.class);
66
				.getDefault()), bean, propertyName);
67
		beanObservable = (IBeanObservable) set;
63
	}
68
	}
64
69
65
	public void testGetObserved() throws Exception {
70
	public void testGetObserved() throws Exception {
66
		assertEquals(bean, set.getObserved());
71
		assertEquals(bean, beanObservable.getObserved());
67
	}
72
	}
68
73
69
	public void testGetPropertyDescriptor() throws Exception {
74
	public void testGetPropertyDescriptor() throws Exception {
70
		assertEquals(propertyDescriptor, set.getPropertyDescriptor());
75
		assertEquals(propertyDescriptor, beanObservable.getPropertyDescriptor());
71
	}
76
	}
72
77
73
	public void testRegistersListenerAfterFirstListenerIsAdded()
78
	public void testRegistersListenerAfterFirstListenerIsAdded()
Lines 292-298 Link Here
292
		assertEquals("array", event.getPropertyName());
297
		assertEquals("array", event.getPropertyName());
293
		assertTrue("old value", Arrays.equals(old, (Object[]) event
298
		assertTrue("old value", Arrays.equals(old, (Object[]) event
294
				.getOldValue()));
299
				.getOldValue()));
295
		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event.getNewValue()));
300
		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event
301
				.getNewValue()));
296
		assertFalse("lists are equal", Arrays.equals(bean.getArray(), old));
302
		assertFalse("lists are equal", Arrays.equals(bean.getArray(), old));
297
	}
303
	}
298
304
Lines 302-312 Link Here
302
308
303
		PropertyChangeEvent evt;
309
		PropertyChangeEvent evt;
304
310
305
		/*
306
		 * (non-Javadoc)
307
		 * 
308
		 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
309
		 */
310
		public void propertyChange(PropertyChangeEvent evt) {
311
		public void propertyChange(PropertyChangeEvent evt) {
311
			count++;
312
			count++;
312
			this.evt = evt;
313
			this.evt = evt;
Lines 324-340 Link Here
324
		public IObservableCollection createObservableCollection(Realm realm,
325
		public IObservableCollection createObservableCollection(Realm realm,
325
				int elementCount) {
326
				int elementCount) {
326
			String propertyName = "array";
327
			String propertyName = "array";
327
			PropertyDescriptor propertyDescriptor;
328
			try {
329
				propertyDescriptor = new PropertyDescriptor(propertyName,
330
						Bean.class);
331
			} catch (IntrospectionException e) {
332
				throw new RuntimeException(e);
333
			}
334
			Object bean = new Bean(new Object[0]);
328
			Object bean = new Bean(new Object[0]);
335
329
336
			IObservableSet list = new JavaBeanObservableSet(realm, bean,
330
			IObservableSet list = BeansObservables.observeSet(realm, bean,
337
					propertyDescriptor, String.class);
331
					propertyName, String.class);
338
			for (int i = 0; i < elementCount; i++)
332
			for (int i = 0; i < elementCount; i++)
339
				list.add(createElement(list));
333
				list.add(createElement(list));
340
			return list;
334
			return list;
(-)src/org/eclipse/core/tests/internal/databinding/beans/BeanObservableValueDecoratorTest.java (-16 / +13 lines)
Lines 7-21 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 194734
10
 ******************************************************************************/
11
 ******************************************************************************/
11
12
12
package org.eclipse.core.tests.internal.databinding.beans;
13
package org.eclipse.core.tests.internal.databinding.beans;
13
14
14
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
15
16
16
import org.eclipse.core.databinding.observable.value.WritableValue;
17
import org.eclipse.core.databinding.beans.BeanProperties;
18
import org.eclipse.core.databinding.beans.BeansObservables;
19
import org.eclipse.core.databinding.beans.IBeanProperty;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
17
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
21
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
18
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableValue;
19
import org.eclipse.jface.databinding.swt.SWTObservables;
22
import org.eclipse.jface.databinding.swt.SWTObservables;
20
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
23
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
21
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.swt.widgets.Display;
Lines 25-55 Link Here
25
 */
28
 */
26
public class BeanObservableValueDecoratorTest extends AbstractDefaultRealmTestCase {
29
public class BeanObservableValueDecoratorTest extends AbstractDefaultRealmTestCase {
27
	private Bean bean;
30
	private Bean bean;
28
	private JavaBeanObservableValue observableValue;
31
	private IObservableValue observableValue;
29
	private BeanObservableValueDecorator decorator;
32
	private BeanObservableValueDecorator decorator;
30
	private PropertyDescriptor propertyDescriptor;
33
	private PropertyDescriptor propertyDescriptor;
31
	
34
	
32
	/*
33
	 * (non-Javadoc)
34
	 * 
35
	 * @see junit.framework.TestCase#setUp()
36
	 */
37
	protected void setUp() throws Exception {
35
	protected void setUp() throws Exception {
38
		super.setUp();
36
		super.setUp();
39
		
37
		
40
		bean = new Bean();
38
		bean = new Bean();
41
		propertyDescriptor = new PropertyDescriptor("value",
39
		String propertyName = "value";
42
				Bean.class);
40
		propertyDescriptor = ((IBeanProperty) BeanProperties.valueProperty(
43
		observableValue = new JavaBeanObservableValue(
41
				Bean.class, propertyName)).getPropertyDescriptor();
44
				SWTObservables.getRealm(Display.getDefault()), bean,
42
		observableValue = BeansObservables.observeValue(SWTObservables
43
				.getRealm(Display.getDefault()), bean, propertyName);
44
		decorator = new BeanObservableValueDecorator(observableValue,
45
				propertyDescriptor);
45
				propertyDescriptor);
46
		decorator = new BeanObservableValueDecorator(
47
				observableValue, new WritableValue(bean, Object.class), observableValue
48
						.getPropertyDescriptor());
49
	}
46
	}
50
47
51
	public void testGetDelegate() throws Exception {
48
	public void testGetDelegate() throws Exception {
52
		assertEquals(observableValue, decorator.getDelegate());
49
		assertEquals(observableValue, decorator.getDecorated());
53
	}
50
	}
54
	
51
	
55
	public void testGetObserved() throws Exception {
52
	public void testGetObserved() throws Exception {
(-)src/org/eclipse/jface/tests/internal/databinding/swt/DelayedObservableValueTest.java (-2 / +8 lines)
Lines 21-26 Link Here
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.swt.SWTObservables;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
26
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
27
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
Lines 55-60 Link Here
55
		newValue = new Object();
56
		newValue = new Object();
56
		target.setValue(oldValue);
57
		target.setValue(oldValue);
57
		delayed = new DelayedObservableValue(1, target);
58
		delayed = new DelayedObservableValue(1, target);
59
		// force listeners to be added to target
60
		
61
		ChangeEventTracker.observe(delayed);
58
	}
62
	}
59
63
60
	protected void tearDown() throws Exception {
64
	protected void tearDown() throws Exception {
Lines 231-239 Link Here
231
	}
235
	}
232
236
233
	public static Test suite() {
237
	public static Test suite() {
234
		TestSuite suite = new TestSuite(DelayedObservableValueTest.class.getName());
238
		TestSuite suite = new TestSuite(DelayedObservableValueTest.class
239
				.getName());
235
		suite.addTestSuite(DelayedObservableValueTest.class);
240
		suite.addTestSuite(DelayedObservableValueTest.class);
236
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
241
		suite.addTest(SWTMutableObservableValueContractTest
242
				.suite(new Delegate()));
237
		return suite;
243
		return suite;
238
	}
244
	}
239
245
(-)src/org/eclipse/jface/tests/internal/databinding/swt/CComboObservableValueTextTest.java (-8 / +12 lines)
Lines 19-31 Link Here
19
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.databinding.property.PropertyObservables;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.swt.ISWTObservable;
26
import org.eclipse.jface.databinding.swt.CComboProperties;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
28
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
28
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
29
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.custom.CCombo;
30
import org.eclipse.swt.custom.CCombo;
31
import org.eclipse.swt.widgets.Display;
31
import org.eclipse.swt.widgets.Display;
Lines 66-74 Link Here
66
	}
66
	}
67
67
68
	public static Test suite() {
68
	public static Test suite() {
69
		TestSuite suite = new TestSuite(CComboObservableValueTextTest.class.getName());
69
		TestSuite suite = new TestSuite(CComboObservableValueTextTest.class
70
				.getName());
70
		suite.addTestSuite(CComboObservableValueTextTest.class);
71
		suite.addTestSuite(CComboObservableValueTextTest.class);
71
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
72
		suite.addTest(SWTMutableObservableValueContractTest
73
				.suite(new Delegate()));
72
		return suite;
74
		return suite;
73
	}
75
	}
74
76
Lines 88-99 Link Here
88
		}
90
		}
89
91
90
		public IObservableValue createObservableValue(Realm realm) {
92
		public IObservableValue createObservableValue(Realm realm) {
91
			return new CComboObservableValue(realm, combo, SWTProperties.TEXT);
93
			return new SWTObservableValueDecorator(
94
					PropertyObservables.observeValue(realm, combo,
95
							CComboProperties.textProperty()), combo);
92
		}
96
		}
93
97
94
		public void change(IObservable observable) {
98
		public void change(IObservable observable) {
95
			CCombo combo = (CCombo) ((ISWTObservable) observable).getWidget();
99
			IObservableValue ov = (IObservableValue) observable;
96
			combo.setText(combo.getText() + "a");
100
			ov.setValue(createValue(ov));
97
		}
101
		}
98
102
99
		public Object getValueType(IObservableValue observable) {
103
		public Object getValueType(IObservableValue observable) {
(-)src/org/eclipse/jface/tests/internal/databinding/swt/ComboObservableValueTextTest.java (-8 / +12 lines)
Lines 19-31 Link Here
19
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.databinding.property.PropertyObservables;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.swt.ISWTObservable;
26
import org.eclipse.jface.databinding.swt.ComboProperties;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
28
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
28
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
29
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.widgets.Combo;
30
import org.eclipse.swt.widgets.Combo;
31
import org.eclipse.swt.widgets.Display;
31
import org.eclipse.swt.widgets.Display;
Lines 67-75 Link Here
67
	}
67
	}
68
68
69
	public static Test suite() {
69
	public static Test suite() {
70
		TestSuite suite = new TestSuite(ComboObservableValueTextTest.class.toString());
70
		TestSuite suite = new TestSuite(ComboObservableValueTextTest.class
71
				.toString());
71
		suite.addTestSuite(ComboObservableValueTextTest.class);
72
		suite.addTestSuite(ComboObservableValueTextTest.class);
72
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
73
		suite.addTest(SWTMutableObservableValueContractTest
74
				.suite(new Delegate()));
73
		return suite;
75
		return suite;
74
	}
76
	}
75
77
Lines 89-100 Link Here
89
		}
91
		}
90
92
91
		public IObservableValue createObservableValue(Realm realm) {
93
		public IObservableValue createObservableValue(Realm realm) {
92
			return new ComboObservableValue(realm, combo, SWTProperties.TEXT);
94
			return new SWTObservableValueDecorator(
95
					PropertyObservables.observeValue(realm, combo,
96
							ComboProperties.textProperty()), combo);
93
		}
97
		}
94
98
95
		public void change(IObservable observable) {
99
		public void change(IObservable observable) {
96
			Combo combo = (Combo) ((ISWTObservable) observable).getWidget();
100
			((IObservableValue) observable)
97
			combo.setText(combo.getText() + "a");
101
					.setValue(createValue((IObservableValue) observable));
98
		}
102
		}
99
103
100
		public Object getValueType(IObservableValue observable) {
104
		public Object getValueType(IObservableValue observable) {
(-)src/org/eclipse/jface/tests/internal/databinding/swt/ControlObservableValueTest.java (-41 / +23 lines)
Lines 12-19 Link Here
12
12
13
package org.eclipse.jface.tests.internal.databinding.swt;
13
package org.eclipse.jface.tests.internal.databinding.swt;
14
14
15
import org.eclipse.jface.internal.databinding.swt.ControlObservableValue;
15
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
16
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
16
import org.eclipse.jface.databinding.swt.SWTObservables;
17
import org.eclipse.jface.resource.JFaceResources;
17
import org.eclipse.jface.resource.JFaceResources;
18
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
18
import org.eclipse.jface.tests.databinding.AbstractDefaultRealmTestCase;
19
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.SWT;
Lines 30-36 Link Here
30
30
31
	protected void setUp() throws Exception {
31
	protected void setUp() throws Exception {
32
		super.setUp();
32
		super.setUp();
33
		
33
34
		shell = new Shell();
34
		shell = new Shell();
35
	}
35
	}
36
36
Lines 47-95 Link Here
47
	}
47
	}
48
48
49
	public void testSetValueEnabled() throws Exception {
49
	public void testSetValueEnabled() throws Exception {
50
		ControlObservableValue observableValue = new ControlObservableValue(
50
		ISWTObservableValue observableValue = SWTObservables
51
				shell, SWTProperties.ENABLED);
51
				.observeEnabled(shell);
52
		Boolean value = Boolean.FALSE;
52
		Boolean value = Boolean.FALSE;
53
		observableValue.setValue(value);
53
		observableValue.setValue(value);
54
		assertFalse(shell.isEnabled());
54
		assertFalse(shell.isEnabled());
55
	}
55
	}
56
56
57
	public void testGetValueEnabled() throws Exception {
57
	public void testGetValueEnabled() throws Exception {
58
		ControlObservableValue value = new ControlObservableValue(shell,
58
		ISWTObservableValue value = SWTObservables.observeEnabled(shell);
59
				SWTProperties.ENABLED);
60
		shell.setEnabled(false);
59
		shell.setEnabled(false);
61
		assertEquals(Boolean.FALSE, value.getValue());
60
		assertEquals(Boolean.FALSE, value.getValue());
62
	}
61
	}
63
62
64
	public void testGetValueTypeEnabled() throws Exception {
63
	public void testGetValueTypeEnabled() throws Exception {
65
		ControlObservableValue value = new ControlObservableValue(shell,
64
		ISWTObservableValue value = SWTObservables.observeEnabled(shell);
66
				SWTProperties.ENABLED);
67
		assertEquals(boolean.class, value.getValueType());
65
		assertEquals(boolean.class, value.getValueType());
68
	}
66
	}
69
67
70
	public void testSetValueVisible() throws Exception {
68
	public void testSetValueVisible() throws Exception {
71
		ControlObservableValue value = new ControlObservableValue(shell,
69
		ISWTObservableValue value = SWTObservables.observeVisible(shell);
72
				SWTProperties.VISIBLE);
73
		value.setValue(Boolean.FALSE);
70
		value.setValue(Boolean.FALSE);
74
		assertFalse(shell.isVisible());
71
		assertFalse(shell.isVisible());
75
	}
72
	}
76
73
77
	public void testGetValueVisible() throws Exception {
74
	public void testGetValueVisible() throws Exception {
78
		ControlObservableValue value = new ControlObservableValue(shell,
75
		ISWTObservableValue value = SWTObservables.observeVisible(shell);
79
				SWTProperties.VISIBLE);
80
		shell.setVisible(false);
76
		shell.setVisible(false);
81
		assertEquals(Boolean.FALSE, value.getValue());
77
		assertEquals(Boolean.FALSE, value.getValue());
82
	}
78
	}
83
79
84
	public void testGetValueTypeVisible() throws Exception {
80
	public void testGetValueTypeVisible() throws Exception {
85
		ControlObservableValue value = new ControlObservableValue(shell,
81
		ISWTObservableValue value = SWTObservables.observeVisible(shell);
86
				SWTProperties.VISIBLE);
87
		assertEquals(Boolean.TYPE, value.getValueType());
82
		assertEquals(Boolean.TYPE, value.getValueType());
88
	}
83
	}
89
84
90
	public void testSetValueForeground() throws Exception {
85
	public void testSetValueForeground() throws Exception {
91
		ControlObservableValue value = new ControlObservableValue(shell,
86
		ISWTObservableValue value = SWTObservables.observeForeground(shell);
92
				SWTProperties.FOREGROUND);
93
87
94
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
88
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
95
89
Lines 98-105 Link Here
98
	}
92
	}
99
93
100
	public void testGetValueForeground() throws Exception {
94
	public void testGetValueForeground() throws Exception {
101
		ControlObservableValue value = new ControlObservableValue(shell,
95
		ISWTObservableValue value = SWTObservables.observeForeground(shell);
102
				SWTProperties.FOREGROUND);
103
96
104
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
97
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
105
		shell.setForeground(color);
98
		shell.setForeground(color);
Lines 107-120 Link Here
107
	}
100
	}
108
101
109
	public void testGetValueTypeForgroundColor() throws Exception {
102
	public void testGetValueTypeForgroundColor() throws Exception {
110
		ControlObservableValue value = new ControlObservableValue(shell,
103
		ISWTObservableValue value = SWTObservables.observeForeground(shell);
111
				SWTProperties.FOREGROUND);
112
		assertEquals(Color.class, value.getValueType());
104
		assertEquals(Color.class, value.getValueType());
113
	}
105
	}
114
106
115
	public void testGetValueBackground() throws Exception {
107
	public void testGetValueBackground() throws Exception {
116
		ControlObservableValue value = new ControlObservableValue(shell,
108
		ISWTObservableValue value = SWTObservables.observeBackground(shell);
117
				SWTProperties.BACKGROUND);
118
109
119
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
110
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
120
		shell.setBackground(color);
111
		shell.setBackground(color);
Lines 122-129 Link Here
122
	}
113
	}
123
114
124
	public void testSetValueBackground() throws Exception {
115
	public void testSetValueBackground() throws Exception {
125
		ControlObservableValue value = new ControlObservableValue(shell,
116
		ISWTObservableValue value = SWTObservables.observeBackground(shell);
126
				SWTProperties.BACKGROUND);
127
117
128
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
118
		Color color = shell.getDisplay().getSystemColor(SWT.COLOR_BLACK);
129
119
Lines 132-151 Link Here
132
	}
122
	}
133
123
134
	public void testGetValueTypeBackgroundColor() throws Exception {
124
	public void testGetValueTypeBackgroundColor() throws Exception {
135
		ControlObservableValue value = new ControlObservableValue(shell,
125
		ISWTObservableValue value = SWTObservables.observeBackground(shell);
136
				SWTProperties.BACKGROUND);
137
		assertEquals(Color.class, value.getValueType());
126
		assertEquals(Color.class, value.getValueType());
138
	}
127
	}
139
128
140
	public void testGetValueTypeTooltip() throws Exception {
129
	public void testGetValueTypeTooltip() throws Exception {
141
		ControlObservableValue value = new ControlObservableValue(shell,
130
		ISWTObservableValue value = SWTObservables.observeTooltipText(shell);
142
				SWTProperties.TOOLTIP_TEXT);
143
		assertEquals(String.class, value.getValueType());
131
		assertEquals(String.class, value.getValueType());
144
	}
132
	}
145
133
146
	public void testSetValueFont() throws Exception {
134
	public void testSetValueFont() throws Exception {
147
		ControlObservableValue value = new ControlObservableValue(shell,
135
		ISWTObservableValue value = SWTObservables.observeFont(shell);
148
				SWTProperties.FONT);
149
136
150
		Font font = JFaceResources.getDialogFont();
137
		Font font = JFaceResources.getDialogFont();
151
138
Lines 154-161 Link Here
154
	}
141
	}
155
142
156
	public void testGetValueFont() throws Exception {
143
	public void testGetValueFont() throws Exception {
157
		ControlObservableValue value = new ControlObservableValue(shell,
144
		ISWTObservableValue value = SWTObservables.observeFont(shell);
158
				SWTProperties.FONT);
159
145
160
		Font font = JFaceResources.getDialogFont();
146
		Font font = JFaceResources.getDialogFont();
161
		shell.setFont(font);
147
		shell.setFont(font);
Lines 163-192 Link Here
163
	}
149
	}
164
150
165
	public void testGetValueTypeFont() throws Exception {
151
	public void testGetValueTypeFont() throws Exception {
166
		ControlObservableValue value = new ControlObservableValue(shell,
152
		ISWTObservableValue value = SWTObservables.observeFont(shell);
167
				SWTProperties.FONT);
168
		assertEquals(Font.class, value.getValueType());
153
		assertEquals(Font.class, value.getValueType());
169
	}
154
	}
170
155
171
	public void testSetValueTooltipText() throws Exception {
156
	public void testSetValueTooltipText() throws Exception {
172
		ControlObservableValue value = new ControlObservableValue(shell,
157
		ISWTObservableValue value = SWTObservables.observeTooltipText(shell);
173
				SWTProperties.TOOLTIP_TEXT);
174
		String text = "text";
158
		String text = "text";
175
		value.setValue(text);
159
		value.setValue(text);
176
		assertEquals(text, shell.getToolTipText());
160
		assertEquals(text, shell.getToolTipText());
177
	}
161
	}
178
162
179
	public void testGetValueTooltipText() throws Exception {
163
	public void testGetValueTooltipText() throws Exception {
180
		ControlObservableValue value = new ControlObservableValue(shell,
164
		ISWTObservableValue value = SWTObservables.observeTooltipText(shell);
181
				SWTProperties.TOOLTIP_TEXT);
182
		String text = "text";
165
		String text = "text";
183
		shell.setToolTipText(text);
166
		shell.setToolTipText(text);
184
		assertEquals(text, value.getValue());
167
		assertEquals(text, value.getValue());
185
	}
168
	}
186
169
187
	public void testGetValueTypeTooltipText() throws Exception {
170
	public void testGetValueTypeTooltipText() throws Exception {
188
		ControlObservableValue value = new ControlObservableValue(shell,
171
		ISWTObservableValue value = SWTObservables.observeTooltipText(shell);
189
				SWTProperties.TOOLTIP_TEXT);
190
		assertEquals(String.class, value.getValueType());
172
		assertEquals(String.class, value.getValueType());
191
	}
173
	}
192
}
174
}
(-)src/org/eclipse/jface/tests/internal/databinding/swt/ComboObservableValueTest.java (-16 / +21 lines)
Lines 12-20 Link Here
12
12
13
package org.eclipse.jface.tests.internal.databinding.swt;
13
package org.eclipse.jface.tests.internal.databinding.swt;
14
14
15
import org.eclipse.core.databinding.observable.value.IObservableValue;
16
import org.eclipse.core.databinding.property.IValueProperty;
17
import org.eclipse.core.databinding.property.PropertyObservables;
15
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
18
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
16
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
19
import org.eclipse.jface.databinding.swt.ComboProperties;
17
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
20
import org.eclipse.jface.databinding.swt.SWTObservables;
21
import org.eclipse.jface.internal.databinding.swt.ComboSelectionProperty;
22
import org.eclipse.jface.internal.databinding.swt.ComboTextProperty;
18
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
23
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
19
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.widgets.Combo;
25
import org.eclipse.swt.widgets.Combo;
Lines 26-33 Link Here
26
public class ComboObservableValueTest extends AbstractSWTTestCase {
31
public class ComboObservableValueTest extends AbstractSWTTestCase {
27
	public void testDispose() throws Exception {
32
	public void testDispose() throws Exception {
28
		Combo combo = new Combo(getShell(), SWT.NONE);
33
		Combo combo = new Combo(getShell(), SWT.NONE);
29
		ComboObservableValue observableValue = new ComboObservableValue(combo,
34
		IObservableValue observableValue = SWTObservables.observeText(combo);
30
				SWTProperties.TEXT);
31
		ValueChangeEventTracker testCounterValueChangeListener = new ValueChangeEventTracker();
35
		ValueChangeEventTracker testCounterValueChangeListener = new ValueChangeEventTracker();
32
		observableValue.addValueChangeListener(testCounterValueChangeListener);
36
		observableValue.addValueChangeListener(testCounterValueChangeListener);
33
37
Lines 51-75 Link Here
51
	}
55
	}
52
56
53
	public void testSetValueWithNull() {
57
	public void testSetValueWithNull() {
54
		testSetValueWithNull(SWTProperties.TEXT);
58
		testSetValueWithNull(ComboProperties.textProperty());
55
		testSetValueWithNull(SWTProperties.SELECTION);
59
		testSetValueWithNull(ComboProperties.selectionProperty());
56
	}
60
	}
57
61
58
	protected void testSetValueWithNull(String observableMode) {
62
	protected void testSetValueWithNull(IValueProperty property) {
59
		Combo combo = new Combo(getShell(), SWT.NONE);
63
		Combo combo = new Combo(getShell(), SWT.NONE);
60
		combo.setItems(new String[] {"one", "two", "three"});
64
		combo.setItems(new String[] { "one", "two", "three" });
61
		ComboObservableValue observable = new ComboObservableValue(
65
		IObservableValue observable = PropertyObservables.observeValue(combo,
62
				combo, observableMode);
66
				property);
63
67
64
		observable.doSetValue("two");
68
		observable.setValue("two");
65
		assertEquals("two", combo.getText());
69
		assertEquals("two", combo.getText());
66
		if (observableMode.equals(SWTProperties.SELECTION)) {
70
		if (property instanceof ComboSelectionProperty) {
67
			assertEquals("expect selection at index 1 in mode " + observableMode, 1, combo.getSelectionIndex());
71
			assertEquals("expect selection at index 1 in selection mode", 1,
72
					combo.getSelectionIndex());
68
		}
73
		}
69
74
70
		if (observableMode.equals(SWTProperties.TEXT)) {
75
		if (property instanceof ComboTextProperty) {
71
			observable.doSetValue(null);
76
			observable.setValue(null);
72
			assertEquals("expect empty text in mode " + observableMode, "", combo.getText());
77
			assertEquals("expect empty text in text mode", "", combo.getText());
73
		}
78
		}
74
	}
79
	}
75
}
80
}
(-)src/org/eclipse/jface/tests/internal/databinding/swt/CComboObservableValueSelectionTest.java (-11 / +14 lines)
Lines 19-31 Link Here
19
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.databinding.property.PropertyObservables;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
26
import org.eclipse.jface.databinding.swt.CComboProperties;
25
import org.eclipse.jface.databinding.swt.ISWTObservable;
27
import org.eclipse.jface.databinding.swt.ISWTObservable;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
28
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
29
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
28
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.custom.CCombo;
31
import org.eclipse.swt.custom.CCombo;
31
import org.eclipse.swt.widgets.Display;
32
import org.eclipse.swt.widgets.Display;
Lines 57-72 Link Here
57
		IObservableValue observable = (IObservableValue) delegate
58
		IObservableValue observable = (IObservableValue) delegate
58
				.createObservable(SWTObservables.getRealm(Display.getDefault()));
59
				.createObservable(SWTObservables.getRealm(Display.getDefault()));
59
60
60
		ValueChangeEventTracker listener = ValueChangeEventTracker.observe(observable);
61
		ValueChangeEventTracker listener = ValueChangeEventTracker
62
				.observe(observable);
61
		combo.select(0);
63
		combo.select(0);
62
64
63
		assertEquals("Observable was not notified.", 1, listener.count);
65
		assertEquals("Observable was not notified.", 1, listener.count);
64
	}
66
	}
65
67
66
	public static Test suite() {
68
	public static Test suite() {
67
		TestSuite suite = new TestSuite(CComboObservableValueSelectionTest.class.getName());
69
		TestSuite suite = new TestSuite(
70
				CComboObservableValueSelectionTest.class.getName());
68
		suite.addTestSuite(CComboObservableValueSelectionTest.class);
71
		suite.addTestSuite(CComboObservableValueSelectionTest.class);
69
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
72
		suite.addTest(SWTMutableObservableValueContractTest
73
				.suite(new Delegate()));
70
		return suite;
74
		return suite;
71
	}
75
	}
72
76
Lines 88-102 Link Here
88
		}
92
		}
89
93
90
		public IObservableValue createObservableValue(Realm realm) {
94
		public IObservableValue createObservableValue(Realm realm) {
91
			return new CComboObservableValue(realm, combo,
95
			return new SWTObservableValueDecorator(PropertyObservables
92
					SWTProperties.SELECTION);
96
					.observeValue(realm, combo, CComboProperties
97
							.selectionProperty()), combo);
93
		}
98
		}
94
99
95
		public void change(IObservable observable) {
100
		public void change(IObservable observable) {
96
			int index = combo
101
			IObservableValue ov = (IObservableValue) observable;
97
					.indexOf((String) createValue((IObservableValue) observable));
102
			ov.setValue(createValue(ov));
98
99
			combo.select(index);
100
		}
103
		}
101
104
102
		public Object getValueType(IObservableValue observable) {
105
		public Object getValueType(IObservableValue observable) {
(-)src/org/eclipse/jface/tests/internal/databinding/swt/CComboObservableValueTest.java (-12 / +15 lines)
Lines 13-21 Link Here
13
13
14
package org.eclipse.jface.tests.internal.databinding.swt;
14
package org.eclipse.jface.tests.internal.databinding.swt;
15
15
16
import org.eclipse.core.databinding.observable.value.IObservableValue;
17
import org.eclipse.core.databinding.property.IValueProperty;
18
import org.eclipse.core.databinding.property.PropertyObservables;
16
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
19
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
17
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
20
import org.eclipse.jface.databinding.swt.CComboProperties;
18
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
21
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
22
import org.eclipse.jface.databinding.swt.SWTObservables;
19
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
23
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
20
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.SWT;
21
import org.eclipse.swt.custom.CCombo;
25
import org.eclipse.swt.custom.CCombo;
Lines 26-33 Link Here
26
public class CComboObservableValueTest extends AbstractSWTTestCase {
30
public class CComboObservableValueTest extends AbstractSWTTestCase {
27
	public void testDispose() throws Exception {
31
	public void testDispose() throws Exception {
28
		CCombo combo = new CCombo(getShell(), SWT.NONE);
32
		CCombo combo = new CCombo(getShell(), SWT.NONE);
29
		CComboObservableValue observableValue = new CComboObservableValue(
33
		ISWTObservableValue observableValue = SWTObservables.observeText(combo);
30
				combo, SWTProperties.TEXT);
31
34
32
		ValueChangeEventTracker testCounterValueChangeListener = new ValueChangeEventTracker();
35
		ValueChangeEventTracker testCounterValueChangeListener = new ValueChangeEventTracker();
33
		observableValue.addValueChangeListener(testCounterValueChangeListener);
36
		observableValue.addValueChangeListener(testCounterValueChangeListener);
Lines 52-72 Link Here
52
	}
55
	}
53
56
54
	public void testSetValueWithNull() {
57
	public void testSetValueWithNull() {
55
		testSetValueWithNull(SWTProperties.TEXT);
58
		testSetValueWithNull(CComboProperties.textProperty());
56
		testSetValueWithNull(SWTProperties.SELECTION);
59
		testSetValueWithNull(CComboProperties.selectionProperty());
57
	}
60
	}
58
61
59
	protected void testSetValueWithNull(String observableMode) {
62
	protected void testSetValueWithNull(IValueProperty property) {
60
		CCombo combo = new CCombo(getShell(), SWT.NONE);
63
		CCombo combo = new CCombo(getShell(), SWT.NONE);
61
		combo.setItems(new String[] {"one", "two", "three"});
64
		combo.setItems(new String[] { "one", "two", "three" });
62
		CComboObservableValue observable = new CComboObservableValue(
65
		IObservableValue observable = PropertyObservables.observeValue(
63
				combo, observableMode);
66
				combo, property);
64
67
65
		observable.doSetValue("two");
68
		observable.setValue("two");
66
		assertEquals("two", combo.getText());
69
		assertEquals("two", combo.getText());
67
		assertEquals(1, combo.getSelectionIndex());
70
		assertEquals(1, combo.getSelectionIndex());
68
71
69
		observable.doSetValue(null);
72
		observable.setValue(null);
70
		assertEquals("", combo.getText());
73
		assertEquals("", combo.getText());
71
		assertEquals(-1, combo.getSelectionIndex());
74
		assertEquals(-1, combo.getSelectionIndex());
72
	}
75
	}
(-)src/org/eclipse/jface/tests/internal/databinding/swt/ComboObservableValueSelectionTest.java (-9 / +12 lines)
Lines 19-31 Link Here
19
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.databinding.property.PropertyObservables;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
26
import org.eclipse.jface.databinding.swt.ComboProperties;
25
import org.eclipse.jface.databinding.swt.ISWTObservable;
27
import org.eclipse.jface.databinding.swt.ISWTObservable;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
28
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
29
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
28
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.widgets.Combo;
31
import org.eclipse.swt.widgets.Combo;
31
import org.eclipse.swt.widgets.Display;
32
import org.eclipse.swt.widgets.Display;
Lines 33-39 Link Here
33
34
34
/**
35
/**
35
 * @since 3.2
36
 * @since 3.2
36
 *
37
 * 
37
 */
38
 */
38
public class ComboObservableValueSelectionTest extends TestCase {
39
public class ComboObservableValueSelectionTest extends TestCase {
39
	private Delegate delegate;
40
	private Delegate delegate;
Lines 67-75 Link Here
67
	}
68
	}
68
69
69
	public static Test suite() {
70
	public static Test suite() {
70
		TestSuite suite = new TestSuite(ComboObservableValueSelectionTest.class.toString());
71
		TestSuite suite = new TestSuite(ComboObservableValueSelectionTest.class
72
				.toString());
71
		suite.addTestSuite(ComboObservableValueSelectionTest.class);
73
		suite.addTestSuite(ComboObservableValueSelectionTest.class);
72
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
74
		suite.addTest(SWTMutableObservableValueContractTest
75
				.suite(new Delegate()));
73
		return suite;
76
		return suite;
74
	}
77
	}
75
78
Lines 91-106 Link Here
91
		}
94
		}
92
95
93
		public IObservableValue createObservableValue(Realm realm) {
96
		public IObservableValue createObservableValue(Realm realm) {
94
			return new ComboObservableValue(realm, combo,
97
			return new SWTObservableValueDecorator(PropertyObservables
95
					SWTProperties.SELECTION);
98
					.observeValue(realm, combo, ComboProperties
99
							.selectionProperty()), combo);
96
		}
100
		}
97
101
98
		public void change(IObservable observable) {
102
		public void change(IObservable observable) {
99
			int index = combo
103
			int index = combo
100
					.indexOf((String) createValue((IObservableValue) observable));
104
					.indexOf((String) createValue((IObservableValue) observable));
101
105
102
			combo.select(index);
106
			((IObservableValue) observable).setValue(combo.getItem(index));
103
			combo.notifyListeners(SWT.Selection, null);
104
		}
107
		}
105
108
106
		public Object getValueType(IObservableValue observable) {
109
		public Object getValueType(IObservableValue observable) {
(-)src/org/eclipse/jface/tests/internal/databinding/swt/ButtonObservableValueTest.java (-23 / +27 lines)
Lines 19-28 Link Here
19
import org.eclipse.core.databinding.observable.IObservable;
19
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.databinding.property.PropertyObservables;
22
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.delegate.AbstractObservableValueContractDelegate;
23
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.swt.SWTMutableObservableValueContractTest;
24
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ValueChangeEventTracker;
25
import org.eclipse.jface.internal.databinding.swt.ButtonObservableValue;
26
import org.eclipse.jface.databinding.swt.ButtonProperties;
27
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
28
import org.eclipse.jface.databinding.swt.SWTObservables;
26
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
29
import org.eclipse.jface.tests.databinding.AbstractSWTTestCase;
27
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.widgets.Button;
31
import org.eclipse.swt.widgets.Button;
Lines 33-54 Link Here
33
 */
36
 */
34
public class ButtonObservableValueTest extends AbstractSWTTestCase {
37
public class ButtonObservableValueTest extends AbstractSWTTestCase {
35
	private Button button;
38
	private Button button;
36
	private ButtonObservableValue observableValue;
39
	private ISWTObservableValue observableValue;
37
	private ValueChangeEventTracker listener;
40
	private ValueChangeEventTracker listener;
38
	
41
39
	/* (non-Javadoc)
40
	 * @see junit.framework.TestCase#setUp()
41
	 */
42
	protected void setUp() throws Exception {
42
	protected void setUp() throws Exception {
43
		super.setUp();
43
		super.setUp();
44
		
44
45
		Shell shell = getShell();
45
		Shell shell = getShell();
46
		button = new Button(shell, SWT.CHECK);
46
		button = new Button(shell, SWT.CHECK);
47
		observableValue = new ButtonObservableValue(
47
		observableValue = SWTObservables.observeSelection(button);
48
				button);
49
		listener = new ValueChangeEventTracker();
48
		listener = new ValueChangeEventTracker();
50
	}
49
	}
51
	
50
52
	public void testSelection_ChangeNotifiesObservable() throws Exception {
51
	public void testSelection_ChangeNotifiesObservable() throws Exception {
53
		observableValue.addValueChangeListener(listener);
52
		observableValue.addValueChangeListener(listener);
54
		button.setSelection(true);
53
		button.setSelection(true);
Lines 60-78 Link Here
60
		assertEquals("Selection event should notify observable.", 1,
59
		assertEquals("Selection event should notify observable.", 1,
61
				listener.count);
60
				listener.count);
62
	}
61
	}
63
	
62
64
	public void testSelection_NoChange() throws Exception {
63
	public void testSelection_NoChange() throws Exception {
65
		button.setSelection(true);
64
		button.setSelection(true);
66
		button.notifyListeners(SWT.Selection, null);
65
		button.notifyListeners(SWT.Selection, null);
67
		observableValue.addValueChangeListener(listener);
66
		observableValue.addValueChangeListener(listener);
68
		
67
69
		//precondition
68
		// precondition
70
		assertEquals(0, listener.count);
69
		assertEquals(0, listener.count);
71
		
70
72
		button.notifyListeners(SWT.Selection, null);
71
		button.notifyListeners(SWT.Selection, null);
73
		assertEquals("Value did not change.  Listeners should not have been notified.", 0, listener.count);
72
		assertEquals(
73
				"Value did not change.  Listeners should not have been notified.",
74
				0, listener.count);
74
	}
75
	}
75
	
76
76
	public void testSetValue_NullConvertedToFalse() {
77
	public void testSetValue_NullConvertedToFalse() {
77
		button.setSelection(true);
78
		button.setSelection(true);
78
		assertEquals(Boolean.TRUE, observableValue.getValue());
79
		assertEquals(Boolean.TRUE, observableValue.getValue());
Lines 104-112 Link Here
104
	}
105
	}
105
106
106
	public static Test suite() {
107
	public static Test suite() {
107
		TestSuite suite = new TestSuite(ButtonObservableValueTest.class.getName());
108
		TestSuite suite = new TestSuite(ButtonObservableValueTest.class
109
				.getName());
108
		suite.addTestSuite(ButtonObservableValueTest.class);
110
		suite.addTestSuite(ButtonObservableValueTest.class);
109
		suite.addTest(SWTMutableObservableValueContractTest.suite(new Delegate()));
111
		suite.addTest(SWTMutableObservableValueContractTest
112
				.suite(new Delegate()));
110
		return suite;
113
		return suite;
111
	}
114
	}
112
115
Lines 130-136 Link Here
130
		}
133
		}
131
134
132
		public IObservableValue createObservableValue(Realm realm) {
135
		public IObservableValue createObservableValue(Realm realm) {
133
			return new ButtonObservableValue(realm, button);
136
			return PropertyObservables.observeValue(realm, button,
137
					ButtonProperties.selectionProperty());
134
		}
138
		}
135
139
136
		public Object getValueType(IObservableValue observable) {
140
		public Object getValueType(IObservableValue observable) {
Lines 138-151 Link Here
138
		}
142
		}
139
143
140
		public void change(IObservable observable) {
144
		public void change(IObservable observable) {
141
			button.setSelection(changeValue(button));
145
			((IObservableValue) observable).setValue(Boolean
142
			button.notifyListeners(SWT.Selection, null);
146
					.valueOf(changeValue(button)));
143
		}
147
		}
144
		
148
145
		public Object createValue(IObservableValue observable) {
149
		public Object createValue(IObservableValue observable) {
146
			return Boolean.valueOf(changeValue(button));
150
			return Boolean.valueOf(changeValue(button));
147
		}
151
		}
148
		
152
149
		private boolean changeValue(Button button) {
153
		private boolean changeValue(Button button) {
150
			return !button.getSelection();
154
			return !button.getSelection();
151
		}
155
		}
(-)src/org/eclipse/core/tests/databinding/beans/PojoObservablesTest.java (-18 / +16 lines)
Lines 7-16 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Matthew Hall - bug 194734
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
12
package org.eclipse.core.tests.databinding.beans;
13
package org.eclipse.core.tests.databinding.beans;
13
14
15
import org.eclipse.core.databinding.beans.IBeanObservable;
14
import org.eclipse.core.databinding.beans.PojoObservables;
16
import org.eclipse.core.databinding.beans.PojoObservables;
15
import org.eclipse.core.databinding.observable.Realm;
17
import org.eclipse.core.databinding.observable.Realm;
16
import org.eclipse.core.databinding.observable.list.IObservableList;
18
import org.eclipse.core.databinding.observable.list.IObservableList;
Lines 19-28 Link Here
19
import org.eclipse.core.databinding.observable.set.IObservableSet;
21
import org.eclipse.core.databinding.observable.set.IObservableSet;
20
import org.eclipse.core.databinding.observable.set.WritableSet;
22
import org.eclipse.core.databinding.observable.set.WritableSet;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
23
import org.eclipse.core.databinding.observable.value.IObservableValue;
22
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
23
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableMap;
24
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
25
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableValue;
26
import org.eclipse.core.tests.internal.databinding.beans.Bean;
24
import org.eclipse.core.tests.internal.databinding.beans.Bean;
27
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
25
import org.eclipse.jface.databinding.conformance.util.ChangeEventTracker;
28
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
26
import org.eclipse.jface.databinding.conformance.util.CurrentRealm;
Lines 47-58 Link Here
47
		propertyName = "value";
45
		propertyName = "value";
48
	}
46
	}
49
47
50
	public void testObserveValue_ReturnsJavaBeanObservableValue()
48
	public void testObserveValue_ReturnsIBeanObservable()
51
			throws Exception {
49
			throws Exception {
52
		IObservableValue value = PojoObservables.observeValue(pojo, propertyName);
50
		IObservableValue value = PojoObservables.observeValue(pojo, propertyName);
53
51
54
		assertNotNull(value);
52
		assertNotNull(value);
55
		assertTrue(value instanceof JavaBeanObservableValue);
53
		assertTrue(value instanceof IBeanObservable);
56
	}
54
	}
57
55
58
	public void testObserveValue_DoesNotAttachListeners() throws Exception {
56
	public void testObserveValue_DoesNotAttachListeners() throws Exception {
Lines 62-78 Link Here
62
		assertFalse(pojo.hasListeners(propertyName));
60
		assertFalse(pojo.hasListeners(propertyName));
63
	}
61
	}
64
62
65
	public void testObservableValueWithRealm_ReturnsJavaBeanObservable()
63
	public void testObservableValueWithRealm_ReturnsIBeanObservable()
66
			throws Exception {
64
			throws Exception {
67
		CurrentRealm realm = new CurrentRealm(true);
65
		CurrentRealm realm = new CurrentRealm(true);
68
		IObservableValue value = PojoObservables.observeValue(realm, pojo,
66
		IObservableValue value = PojoObservables.observeValue(realm, pojo,
69
				propertyName);
67
				propertyName);
70
68
71
		assertNotNull(value);
69
		assertNotNull(value);
72
		assertTrue(value instanceof JavaBeanObservableValue);
70
		assertTrue(value instanceof IBeanObservable);
73
	}
71
	}
74
72
75
	public void testObservableMap_ReturnsJavaBeanObservableMap()
73
	public void testObservableMap_ReturnsIBeanObservable()
76
			throws Exception {
74
			throws Exception {
77
		IObservableSet set = new WritableSet();
75
		IObservableSet set = new WritableSet();
78
		set.add(new Bean());
76
		set.add(new Bean());
Lines 80-86 Link Here
80
		IObservableMap map = PojoObservables.observeMap(set, Bean.class,
78
		IObservableMap map = PojoObservables.observeMap(set, Bean.class,
81
				propertyName);
79
				propertyName);
82
		assertNotNull(map);
80
		assertNotNull(map);
83
		assertTrue(map instanceof JavaBeanObservableMap);
81
		assertTrue(map instanceof IBeanObservable);
84
	}
82
	}
85
	
83
	
86
	public void testObservableMap_DoesNotAttachListeners() throws Exception {
84
	public void testObservableMap_DoesNotAttachListeners() throws Exception {
Lines 101-109 Link Here
101
		assertEquals(2, maps.length);
99
		assertEquals(2, maps.length);
102
	}
100
	}
103
	
101
	
104
	public void testObserveListWithElementType_ReturnsJavaBeanObservableList() throws Exception {
102
	public void testObserveListWithElementType_ReturnsIBeanObservable() throws Exception {
105
		IObservableList list = PojoObservables.observeList(Realm.getDefault(), pojo, "list", String.class);
103
		IObservableList list = PojoObservables.observeList(Realm.getDefault(), pojo, "list", String.class);
106
		assertTrue(list instanceof JavaBeanObservableList);
104
		assertTrue(list instanceof IBeanObservable);
107
	}
105
	}
108
	
106
	
109
	public void testObserveListWithElementType_DoesNotAttachListeners() throws Exception {
107
	public void testObserveListWithElementType_DoesNotAttachListeners() throws Exception {
Lines 113-121 Link Here
113
		assertFalse(pojo.hasListeners("list"));
111
		assertFalse(pojo.hasListeners("list"));
114
	}
112
	}
115
	
113
	
116
	public void testObserveList_ReturnsJavaBeanObservableList() throws Exception {
114
	public void testObserveList_ReturnsIBeanObservable() throws Exception {
117
		IObservableList observable = PojoObservables.observeList(Realm.getDefault(), pojo, "list");
115
		IObservableList observable = PojoObservables.observeList(Realm.getDefault(), pojo, "list");
118
		assertTrue(observable instanceof JavaBeanObservableList);
116
		assertTrue(observable instanceof IBeanObservable);
119
	}
117
	}
120
	
118
	
121
	public void testObserveList_DoesNotAttachListeners() throws Exception {
119
	public void testObserveList_DoesNotAttachListeners() throws Exception {
Lines 125-133 Link Here
125
		assertFalse(pojo.hasListeners("list"));
123
		assertFalse(pojo.hasListeners("list"));
126
	}
124
	}
127
	
125
	
128
	public void testObserveSetWithElementType_ReturnsJavaBeanObservableList() throws Exception {
126
	public void testObserveSetWithElementType_ReturnsIBeanObservable() throws Exception {
129
		IObservableSet list = PojoObservables.observeSet(Realm.getDefault(), pojo, "set", String.class);
127
		IObservableSet list = PojoObservables.observeSet(Realm.getDefault(), pojo, "set", String.class);
130
		assertTrue(list instanceof JavaBeanObservableSet);
128
		assertTrue(list instanceof IBeanObservable);
131
	}
129
	}
132
	
130
	
133
	public void testObserveSetWithElementType_DoesNotAttachListeners() throws Exception {
131
	public void testObserveSetWithElementType_DoesNotAttachListeners() throws Exception {
Lines 137-145 Link Here
137
		assertFalse(pojo.hasListeners("set"));
135
		assertFalse(pojo.hasListeners("set"));
138
	}
136
	}
139
	
137
	
140
	public void testObserveSet_ReturnsJavaBeanObservableList() throws Exception {
138
	public void testObserveSet_ReturnsIBeanObservable() throws Exception {
141
		IObservableSet list = PojoObservables.observeSet(Realm.getDefault(), pojo, "set");
139
		IObservableSet list = PojoObservables.observeSet(Realm.getDefault(), pojo, "set");
142
		assertTrue(list instanceof JavaBeanObservableSet);
140
		assertTrue(list instanceof IBeanObservable);
143
	}
141
	}
144
	
142
	
145
	public void testObserveSet_DoesNotAttachListeners() throws Exception {
143
	public void testObserveSet_DoesNotAttachListeners() throws Exception {
(-)src/org/eclipse/core/tests/databinding/beans/BeansObservablesTest.java (-6 / +6 lines)
Lines 9-15 Link Here
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brad Reynolds - bug 164268, 171616
10
 *     Brad Reynolds - bug 164268, 171616
11
 *     Mike Evans - bug 217558
11
 *     Mike Evans - bug 217558
12
 *     Matthew Hall - bug 221351
12
 *     Matthew Hall - bugs 221351, 194734
13
 *******************************************************************************/
13
 *******************************************************************************/
14
14
15
package org.eclipse.core.tests.databinding.beans;
15
package org.eclipse.core.tests.databinding.beans;
Lines 95-101 Link Here
95
		assertEquals("property descriptor", Bean.class.getMethod("getValue",
95
		assertEquals("property descriptor", Bean.class.getMethod("getValue",
96
				null), beanObservable.getPropertyDescriptor().getReadMethod());
96
				null), beanObservable.getPropertyDescriptor().getReadMethod());
97
		assertEquals("observed", parent.getValue(), beanObservable.getObserved());
97
		assertEquals("observed", parent.getValue(), beanObservable.getObserved());
98
		assertTrue("delegate", beanObservable.getDelegate().getClass()
98
		assertTrue("delegate", beanObservable.getDecorated().getClass()
99
				.getName().endsWith("DetailObservableValue"));
99
				.getName().endsWith("DetailObservableValue"));
100
	}
100
	}
101
101
Lines 121-131 Link Here
121
		BeanObservableListDecorator beanObservable = (BeanObservableListDecorator) detailList;
121
		BeanObservableListDecorator beanObservable = (BeanObservableListDecorator) detailList;
122
		assertEquals("property descriptor", Bean.class.getMethod("getList",
122
		assertEquals("property descriptor", Bean.class.getMethod("getList",
123
				null), beanObservable.getPropertyDescriptor().getReadMethod());
123
				null), beanObservable.getPropertyDescriptor().getReadMethod());
124
		assertEquals("observed", parent, beanObservable.getObserved());
124
		assertEquals("observed", parent.getValue(), beanObservable.getObserved());
125
125
126
		// DetailObservableList is package level we can do a straight instanceof
126
		// DetailObservableList is package level we can do a straight instanceof
127
		// check
127
		// check
128
		assertTrue("delegate is the observed", beanObservable.getDelegate()
128
		assertTrue("delegate is the observed", beanObservable.getDecorated()
129
				.equals(detailList));
129
				.equals(detailList));
130
	}
130
	}
131
131
Lines 152-162 Link Here
152
		assertEquals("property descriptor", Bean.class
152
		assertEquals("property descriptor", Bean.class
153
				.getMethod("getSet", null), beanObservable
153
				.getMethod("getSet", null), beanObservable
154
				.getPropertyDescriptor().getReadMethod());
154
				.getPropertyDescriptor().getReadMethod());
155
		assertEquals("observed", parent, beanObservable.getObserved());
155
		assertEquals("observed", parent.getValue(), beanObservable.getObserved());
156
156
157
		// DetailObservableSet is package level we can't do a straight
157
		// DetailObservableSet is package level we can't do a straight
158
		// instanceof check
158
		// instanceof check
159
		assertTrue("delegate is the observed", beanObservable.getDelegate()
159
		assertTrue("delegate is the observed", beanObservable.getDecorated()
160
				.equals(detailSet));
160
				.equals(detailSet));
161
	}
161
	}
162
162
(-)src/org/eclipse/jface/tests/databinding/scenarios/ButtonControlScenario.java (-1 lines)
Lines 66-72 Link Here
66
        adventure.setPetsAllowed(finalNewBoolean);
66
        adventure.setPetsAllowed(finalNewBoolean);
67
        spinEventLoop(0);
67
        spinEventLoop(0);
68
        assertEquals(newBoolean, button.getSelection());
68
        assertEquals(newBoolean, button.getSelection());
69
70
    }
69
    }
71
70
72
    public void testScenario02() {
71
    public void testScenario02() {
(-)src/org/eclipse/jface/internal/databinding/swt/ListObservableValue.java (-109 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *     Ashley Cambrell - bug 198904
12
 *******************************************************************************/
13
package org.eclipse.jface.internal.databinding.swt;
14
15
import org.eclipse.core.databinding.observable.Diffs;
16
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.List;
20
import org.eclipse.swt.widgets.Listener;
21
22
/**
23
 * @since 3.2
24
 * 
25
 */
26
public class ListObservableValue extends AbstractSWTObservableValue {
27
28
	private final List list;
29
30
	private boolean updating = false;
31
32
	private String currentValue;
33
34
	private Listener listener;
35
36
	/**
37
	 * @param list
38
	 */
39
	public ListObservableValue(List list) {
40
		super(list);
41
		this.list = list;
42
		this.currentValue = (String) doGetValue();
43
44
		if ((list.getStyle() & SWT.MULTI) > 0)
45
			throw new IllegalArgumentException(
46
					"SWT.SINGLE support only for a List selection"); //$NON-NLS-1$
47
48
		listener = new Listener() {
49
50
			public void handleEvent(Event event) {
51
				if (!updating) {
52
					Object oldValue = currentValue;
53
					currentValue = (String) doGetValue();
54
					fireValueChange(Diffs.createValueDiff(oldValue,
55
							currentValue));
56
				}
57
			}
58
59
		};
60
		list.addListener(SWT.Selection, listener);
61
	}
62
63
	public void doSetValue(Object value) {
64
		String oldValue = null;
65
		if (list.getSelection() != null && list.getSelection().length > 0)
66
			oldValue = list.getSelection()[0];
67
		try {
68
			updating = true;
69
			String items[] = list.getItems();
70
			int index = -1;
71
			if (items != null && value != null) {
72
				for (int i = 0; i < items.length; i++) {
73
					if (value.equals(items[i])) {
74
						index = i;
75
						break;
76
					}
77
				}
78
				list.select(index); // -1 will not "unselect"
79
			}
80
			currentValue = (String) value;
81
		} finally {
82
			updating = false;
83
		}
84
		fireValueChange(Diffs.createValueDiff(oldValue, value));
85
	}
86
87
	public Object doGetValue() {
88
		int index = list.getSelectionIndex();
89
		if (index >= 0)
90
			return list.getItem(index);
91
		return null;
92
	}
93
94
	public Object getValueType() {
95
		return String.class;
96
	}
97
98
	/*
99
	 * (non-Javadoc)
100
	 *
101
	 * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#dispose()
102
	 */
103
	public synchronized void dispose() {
104
		super.dispose();
105
		if (listener != null && !list.isDisposed()) {
106
			list.removeListener(SWT.Selection, listener);
107
		}
108
	}
109
}
(-)src/org/eclipse/jface/internal/databinding/swt/SWTProperties.java (-26 / +1 lines)
Lines 21-38 Link Here
21
public interface SWTProperties {
21
public interface SWTProperties {
22
22
23
	/**
23
	/**
24
	 * Applies to Control
25
	 */
26
	public static final String ENABLED = "enabled"; //$NON-NLS-1$
27
	/**
28
	 * Applies to Control
29
	 */
30
	public static final String VISIBLE = "visible"; //$NON-NLS-1$
31
	/**
32
	 * Applies to Control
33
	 */
34
	public static final String TOOLTIP_TEXT = "tooltip"; //$NON-NLS-1$	
35
	/**
36
	 * Applies to
24
	 * Applies to
37
	 */
25
	 */
38
	public static final String ITEMS = "items"; //$NON-NLS-1$
26
	public static final String ITEMS = "items"; //$NON-NLS-1$
Lines 56-77 Link Here
56
	 * Applies to Text, Label, Combo
44
	 * Applies to Text, Label, Combo
57
	 */
45
	 */
58
	public static final String TEXT = "text"; //$NON-NLS-1$
46
	public static final String TEXT = "text"; //$NON-NLS-1$
59
	
47
60
	/**
48
	/**
61
	 * Applies to Label, CLabel.
49
	 * Applies to Label, CLabel.
62
	 */
50
	 */
63
	public static final String IMAGE = "image"; //$NON-NLS-1$
51
	public static final String IMAGE = "image"; //$NON-NLS-1$
64
	/**
65
	 * Applies to Control
66
	 */
67
	public static final String FOREGROUND = "foreground"; //$NON-NLS-1$
68
	/**
69
	 * Applies to Control
70
	 */
71
	public static final String BACKGROUND = "background"; //$NON-NLS-1$
72
	/**
73
	 * Applies to Control
74
	 */
75
	public static final String FONT = "font"; //$NON-NLS-1$
76
77
}
52
}
(-)src/org/eclipse/jface/internal/databinding/swt/ButtonObservableValue.java (-110 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *     Ashley Cambrell - bug 198904
12
 *******************************************************************************/
13
package org.eclipse.jface.internal.databinding.swt;
14
15
import org.eclipse.core.databinding.observable.Diffs;
16
import org.eclipse.core.databinding.observable.Realm;
17
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.widgets.Button;
20
import org.eclipse.swt.widgets.Event;
21
import org.eclipse.swt.widgets.Listener;
22
23
/**
24
 * @since 1.0
25
 * 
26
 */
27
public class ButtonObservableValue extends AbstractSWTObservableValue {
28
29
	private final Button button;
30
31
	private boolean selectionValue;
32
33
	private Listener updateListener = new Listener() {
34
		public void handleEvent(Event event) {
35
			boolean oldSelectionValue = selectionValue;
36
			selectionValue = button.getSelection();
37
						
38
			notifyIfChanged(oldSelectionValue, selectionValue);
39
		}
40
	};
41
42
	/**
43
	 * @param button
44
	 */
45
	public ButtonObservableValue(Button button) {
46
		super(button);
47
		this.button = button;
48
		init();
49
	}
50
	
51
	/**
52
	 * @param realm
53
	 * @param button
54
	 */
55
	public ButtonObservableValue(Realm realm, Button button) {
56
		super(realm, button);
57
		this.button = button;
58
		init();
59
	}
60
	
61
	private void init() {
62
		button.addListener(SWT.Selection, updateListener);
63
		button.addListener(SWT.DefaultSelection, updateListener);
64
		this.selectionValue = button.getSelection();
65
	}
66
67
	public void doSetValue(final Object value) {
68
		boolean oldSelectionValue = selectionValue;
69
		selectionValue = value == null ? false : ((Boolean) value)
70
				.booleanValue();
71
		
72
		button.setSelection(selectionValue);
73
		notifyIfChanged(oldSelectionValue, selectionValue);
74
	}
75
76
	public Object doGetValue() {
77
		return button.getSelection() ? Boolean.TRUE : Boolean.FALSE;
78
	}
79
80
	public Object getValueType() {
81
		return Boolean.TYPE;
82
	}
83
	
84
	/*
85
	 * (non-Javadoc)
86
	 *
87
	 * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#dispose()
88
	 */
89
	public synchronized void dispose() {
90
		super.dispose();
91
92
		if (!button.isDisposed()) {
93
			button.removeListener(SWT.Selection, updateListener);
94
			button.removeListener(SWT.DefaultSelection, updateListener);
95
		}
96
	}
97
98
	/**
99
	 * Notifies consumers with a value change event only if a change occurred.
100
	 * 
101
	 * @param oldValue
102
	 * @param newValue
103
	 */
104
	private void notifyIfChanged(boolean oldValue, boolean newValue) {
105
		if (oldValue != newValue) {
106
			fireValueChange(Diffs.createValueDiff(oldValue ? Boolean.TRUE : Boolean.FALSE,
107
					newValue ? Boolean.TRUE : Boolean.FALSE));
108
		}		
109
	}
110
}
(-)src/org/eclipse/jface/internal/databinding/swt/ComboObservableValue.java (-155 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *     Ashley Cambrell - bug 198904
12
 *     Matthew Hall - bug 118516
13
 *******************************************************************************/
14
package org.eclipse.jface.internal.databinding.swt;
15
16
import org.eclipse.core.databinding.observable.Diffs;
17
import org.eclipse.core.databinding.observable.Realm;
18
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
20
import org.eclipse.swt.events.ModifyEvent;
21
import org.eclipse.swt.events.ModifyListener;
22
import org.eclipse.swt.widgets.Combo;
23
24
/**
25
 * @since 3.2
26
 * 
27
 */
28
public class ComboObservableValue extends AbstractSWTObservableValue {
29
30
	private final Combo combo;
31
	private final String attribute;
32
	private boolean updating = false;
33
	private String currentValue;
34
	private ModifyListener modifyListener;
35
36
	/**
37
	 * @param combo
38
	 * @param attribute
39
	 */
40
	public ComboObservableValue(Combo combo, String attribute) {
41
		super(combo);
42
		this.combo = combo;
43
		this.attribute = attribute;
44
		init();
45
	}
46
		
47
	/**
48
	 * @param realm
49
	 * @param combo
50
	 * @param attribute
51
	 */
52
	public ComboObservableValue(Realm realm, Combo combo, String attribute) {
53
		super(realm, combo);
54
		this.combo = combo;
55
		this.attribute = attribute;
56
		init();
57
	}
58
	
59
	private void init() {		
60
		if (attribute.equals(SWTProperties.SELECTION)
61
				|| attribute.equals(SWTProperties.TEXT)) {
62
			this.currentValue = combo.getText();
63
			modifyListener = new ModifyListener() {
64
65
				public void modifyText(ModifyEvent e) {
66
					if (!updating) {
67
						String oldValue = currentValue;
68
						currentValue = ComboObservableValue.this.combo
69
								.getText();
70
						
71
						notifyIfChanged(oldValue, currentValue);
72
					}
73
				}
74
			};
75
			combo.addModifyListener(modifyListener);
76
		} else
77
			throw new IllegalArgumentException();
78
	}
79
80
	public void doSetValue(final Object value) {
81
		String oldValue = combo.getText();
82
		try {
83
			updating = true;
84
			if (attribute.equals(SWTProperties.TEXT)) {
85
				String stringValue = value != null ? value.toString() : ""; //$NON-NLS-1$
86
				combo.setText(stringValue);
87
			} else if (attribute.equals(SWTProperties.SELECTION)) {
88
				String items[] = combo.getItems();
89
				int index = -1;
90
				if (items != null && value != null) {
91
					for (int i = 0; i < items.length; i++) {
92
						if (value.equals(items[i])) {
93
							index = i;
94
							break;
95
						}
96
					}
97
					if (index == -1) {
98
						combo.setText((String) value);
99
					} else {
100
						combo.select(index); // -1 will not "unselect"
101
					}
102
				}
103
			}
104
		} finally {
105
			updating = false;
106
			currentValue = combo.getText();
107
		}
108
		
109
		notifyIfChanged(oldValue, currentValue);
110
	}
111
112
	public Object doGetValue() {
113
		if (attribute.equals(SWTProperties.TEXT))
114
			return combo.getText();
115
116
		Assert.isTrue(attribute.equals(SWTProperties.SELECTION),
117
				"unexpected attribute: " + attribute); //$NON-NLS-1$
118
		// The problem with a ccombo, is that it changes the text and
119
		// fires before it update its selection index
120
		return combo.getText();
121
	}
122
123
	public Object getValueType() {
124
		Assert.isTrue(attribute.equals(SWTProperties.TEXT)
125
				|| attribute.equals(SWTProperties.SELECTION),
126
				"unexpected attribute: " + attribute); //$NON-NLS-1$
127
		return String.class;
128
	}
129
130
	/**
131
	 * @return attribute being observed
132
	 */
133
	public String getAttribute() {
134
		return attribute;
135
	}
136
137
	/*
138
	 * (non-Javadoc)
139
	 *
140
	 * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#dispose()
141
	 */
142
	public synchronized void dispose() {
143
		super.dispose();
144
145
		if (modifyListener != null && !combo.isDisposed()) {
146
			combo.removeModifyListener(modifyListener);
147
		}
148
	}
149
	
150
	private void notifyIfChanged(String oldValue, String newValue) {
151
		if (!oldValue.equals(newValue)) {
152
			fireValueChange(Diffs.createValueDiff(oldValue, newValue));
153
		}
154
	}
155
}
(-)src/org/eclipse/jface/internal/databinding/swt/CComboObservableList.java (-51 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *******************************************************************************/
11
package org.eclipse.jface.internal.databinding.swt;
12
13
import org.eclipse.jface.databinding.swt.SWTObservables;
14
import org.eclipse.swt.custom.CCombo;
15
16
/**
17
 * @since 3.2
18
 * 
19
 */
20
public class CComboObservableList extends SWTObservableList {
21
22
	private final CCombo ccombo;
23
24
	/**
25
	 * @param ccombo
26
	 */
27
	public CComboObservableList(CCombo ccombo) {
28
		super(SWTObservables.getRealm(ccombo.getDisplay()));
29
		this.ccombo = ccombo;
30
	}
31
32
	protected int getItemCount() {
33
		return ccombo.getItemCount();
34
	}
35
36
	protected void setItems(String[] newItems) {
37
		ccombo.setItems(newItems);
38
	}
39
40
	protected String[] getItems() {
41
		return ccombo.getItems();
42
	}
43
44
	protected String getItem(int index) {
45
		return ccombo.getItem(index);
46
	}
47
48
	protected void setItem(int index, String string) {
49
		ccombo.setItem(index, string);
50
	}
51
}
(-)src/org/eclipse/jface/internal/databinding/swt/ComboObservableList.java (-51 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *******************************************************************************/
11
package org.eclipse.jface.internal.databinding.swt;
12
13
import org.eclipse.jface.databinding.swt.SWTObservables;
14
import org.eclipse.swt.widgets.Combo;
15
16
/**
17
 * @since 3.2
18
 * 
19
 */
20
public class ComboObservableList extends SWTObservableList {
21
22
	private final Combo combo;
23
24
	/**
25
	 * @param combo
26
	 */
27
	public ComboObservableList(Combo combo) {
28
		super(SWTObservables.getRealm(combo.getDisplay()));
29
		this.combo = combo;
30
	}
31
32
	protected int getItemCount() {
33
		return combo.getItemCount();
34
	}
35
36
	protected void setItems(String[] newItems) {
37
		combo.setItems(newItems);
38
	}
39
40
	protected String[] getItems() {
41
		return combo.getItems();
42
	}
43
44
	protected String getItem(int index) {
45
		return combo.getItem(index);
46
	}
47
48
	protected void setItem(int index, String string) {
49
		combo.setItem(index, string);
50
	}
51
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlObservableValue.java (-106 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *     Matt Carter - bug 170668
12
 *     Brad Reynolds - bug 170848
13
 *******************************************************************************/
14
package org.eclipse.jface.internal.databinding.swt;
15
16
import java.util.HashMap;
17
import java.util.Map;
18
19
import org.eclipse.core.databinding.observable.Diffs;
20
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
21
import org.eclipse.swt.graphics.Color;
22
import org.eclipse.swt.graphics.Font;
23
import org.eclipse.swt.widgets.Control;
24
25
/**
26
 * @since 1.0
27
 * 
28
 */
29
public class ControlObservableValue extends AbstractSWTObservableValue {
30
31
	private final Control control;
32
33
	private final String attribute;
34
35
	private Object valueType;
36
	
37
	private static final Map SUPPORTED_ATTRIBUTES = new HashMap();
38
	static {
39
		SUPPORTED_ATTRIBUTES.put(SWTProperties.ENABLED, Boolean.TYPE);
40
		SUPPORTED_ATTRIBUTES.put(SWTProperties.VISIBLE, Boolean.TYPE);
41
		SUPPORTED_ATTRIBUTES.put(SWTProperties.TOOLTIP_TEXT, String.class);
42
		SUPPORTED_ATTRIBUTES.put(SWTProperties.FOREGROUND, Color.class);
43
		SUPPORTED_ATTRIBUTES.put(SWTProperties.BACKGROUND, Color.class);
44
		SUPPORTED_ATTRIBUTES.put(SWTProperties.FONT, Font.class);
45
	}
46
	
47
	/**
48
	 * @param control
49
	 * @param attribute
50
	 */
51
	public ControlObservableValue(Control control, String attribute) {
52
		super(control);
53
		this.control = control;
54
		this.attribute = attribute;
55
		if (SUPPORTED_ATTRIBUTES.keySet().contains(attribute)) {
56
			this.valueType = SUPPORTED_ATTRIBUTES.get(attribute); 
57
		} else {
58
			throw new IllegalArgumentException();
59
		}
60
	}
61
62
	public void doSetValue(Object value) {
63
		Object oldValue = doGetValue();
64
		if (attribute.equals(SWTProperties.ENABLED)) {
65
			control.setEnabled(((Boolean) value).booleanValue());
66
		} else if (attribute.equals(SWTProperties.VISIBLE)) {
67
			control.setVisible(((Boolean) value).booleanValue());
68
		} else if (attribute.equals(SWTProperties.TOOLTIP_TEXT)) {
69
			control.setToolTipText((String) value);
70
		} else if (attribute.equals(SWTProperties.FOREGROUND)) {
71
			control.setForeground((Color) value);
72
		} else if (attribute.equals(SWTProperties.BACKGROUND)) {
73
			control.setBackground((Color) value);
74
		} else if (attribute.equals(SWTProperties.FONT)) {
75
			control.setFont((Font) value);
76
		}
77
		fireValueChange(Diffs.createValueDiff(oldValue, value));
78
	}
79
80
	public Object doGetValue() {
81
		if (attribute.equals(SWTProperties.ENABLED)) {
82
			return control.getEnabled() ? Boolean.TRUE : Boolean.FALSE;
83
		}
84
		if (attribute.equals(SWTProperties.VISIBLE)) {
85
			return control.getVisible() ? Boolean.TRUE : Boolean.FALSE;
86
		}
87
		if (attribute.equals(SWTProperties.TOOLTIP_TEXT)) {
88
			return control.getToolTipText();			
89
		}
90
		if (attribute.equals(SWTProperties.FOREGROUND))	 {
91
			return control.getForeground();
92
		}
93
		if (attribute.equals(SWTProperties.BACKGROUND)) {
94
			return control.getBackground();
95
		}
96
		if (attribute.equals(SWTProperties.FONT)) {
97
			return control.getFont();
98
		}
99
		
100
		return null;
101
	}
102
103
	public Object getValueType() {
104
		return valueType;
105
	}
106
}
(-)src/org/eclipse/jface/internal/databinding/swt/DelayedObservableValue.java (-57 / +40 lines)
Lines 16-32 Link Here
16
package org.eclipse.jface.internal.databinding.swt;
16
package org.eclipse.jface.internal.databinding.swt;
17
17
18
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.Diffs;
19
import org.eclipse.core.databinding.observable.IStaleListener;
20
import org.eclipse.core.databinding.observable.ObservableTracker;
21
import org.eclipse.core.databinding.observable.StaleEvent;
19
import org.eclipse.core.databinding.observable.StaleEvent;
22
import org.eclipse.core.databinding.observable.value.IObservableValue;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
23
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
24
import org.eclipse.core.databinding.observable.value.IVetoableValue;
21
import org.eclipse.core.databinding.observable.value.IVetoableValue;
25
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
22
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
26
import org.eclipse.core.databinding.observable.value.ValueChangingEvent;
23
import org.eclipse.core.databinding.observable.value.ValueChangingEvent;
27
import org.eclipse.core.databinding.observable.value.ValueDiff;
24
import org.eclipse.core.databinding.observable.value.ValueDiff;
28
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
25
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
29
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
30
import org.eclipse.jface.util.Util;
26
import org.eclipse.jface.util.Util;
31
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.SWT;
32
import org.eclipse.swt.widgets.Control;
28
import org.eclipse.swt.widgets.Control;
Lines 49-55 Link Here
49
 * 
45
 * 
50
 * @since 1.2
46
 * @since 1.2
51
 */
47
 */
52
public class DelayedObservableValue extends AbstractSWTObservableValue {
48
public class DelayedObservableValue extends SWTObservableValueDecorator {
53
	class ValueUpdater implements Runnable {
49
	class ValueUpdater implements Runnable {
54
		private final Object oldValue;
50
		private final Object oldValue;
55
51
Lines 75-94 Link Here
75
		}
71
		}
76
	}
72
	}
77
73
78
	private IStaleListener staleListener = new IStaleListener() {
79
		public void handleStale(StaleEvent staleEvent) {
80
			if (!updating)
81
				fireStale();
82
		}
83
	};
84
85
	private IValueChangeListener valueChangeListener = new IValueChangeListener() {
86
		public void handleValueChange(ValueChangeEvent event) {
87
			if (!updating)
88
				makeDirty();
89
		}
90
	};
91
92
	private Listener focusOutListener = new Listener() {
74
	private Listener focusOutListener = new Listener() {
93
		public void handleEvent(Event event) {
75
		public void handleEvent(Event event) {
94
			// Force update on focus out
76
			// Force update on focus out
Lines 98-105 Link Here
98
	};
80
	};
99
81
100
	private final int delay;
82
	private final int delay;
101
	private ISWTObservableValue observable;
83
	private Widget widget;
102
	private Control control;
103
84
104
	private boolean dirty = true;
85
	private boolean dirty = true;
105
	private Object cachedValue = null;
86
	private Object cachedValue = null;
Lines 121-144 Link Here
121
	 */
102
	 */
122
	public DelayedObservableValue(int delayMillis,
103
	public DelayedObservableValue(int delayMillis,
123
			ISWTObservableValue observable) {
104
			ISWTObservableValue observable) {
124
		super(observable.getRealm(), observable.getWidget());
105
		super(observable, observable.getWidget());
125
		this.delay = delayMillis;
106
		this.delay = delayMillis;
126
		this.observable = observable;
127
107
128
		observable.addValueChangeListener(valueChangeListener);
108
		widget = observable.getWidget();
129
		observable.addStaleListener(staleListener);
130
		Widget widget = observable.getWidget();
131
		if (widget instanceof Control) {
109
		if (widget instanceof Control) {
132
			control = (Control) widget;
110
			widget.addListener(SWT.FocusOut, focusOutListener);
133
			control.addListener(SWT.FocusOut, focusOutListener);
134
		}
111
		}
135
112
136
		cachedValue = doGetValue();
113
		cachedValue = observable.getValue();
114
	}
115
116
	protected void handleValueChange(ValueChangeEvent event) {
117
		if (!updating)
118
			makeDirty();
119
	}
120
121
	protected void handleStaleEvent(StaleEvent event) {
122
		if (!updating)
123
			super.handleStaleEvent(event);
137
	}
124
	}
138
125
139
	protected Object doGetValue() {
126
	public Object getValue() {
127
		getterCalled();
128
129
		if (!hasListeners())
130
			return super.getValue();
131
140
		if (dirty) {
132
		if (dirty) {
141
			cachedValue = observable.getValue();
133
			cachedValue = super.getValue();
142
			dirty = false;
134
			dirty = false;
143
135
144
			if (updater != null && !updater.running) {
136
			if (updater != null && !updater.running) {
Lines 147-156 Link Here
147
				cancelScheduledUpdate();
139
				cancelScheduledUpdate();
148
			}
140
			}
149
		}
141
		}
142
150
		return cachedValue;
143
		return cachedValue;
151
	}
144
	}
152
145
153
	protected void doSetValue(Object value) {
146
	public void setValue(Object value) {
147
		checkRealm();
148
154
		updating = true;
149
		updating = true;
155
		try {
150
		try {
156
			// Principle of least surprise: setValue overrides any pending
151
			// Principle of least surprise: setValue overrides any pending
Lines 159-202 Link Here
159
			cancelScheduledUpdate();
154
			cancelScheduledUpdate();
160
155
161
			Object oldValue = cachedValue;
156
			Object oldValue = cachedValue;
162
			observable.setValue(value);
157
			super.setValue(value);
163
			// Bug 215297 - target observable could veto or override value
158
			// Bug 215297 - target observable could veto or override value
164
			// passed to setValue(). Make sure we cache whatever is set.
159
			// passed to setValue(). Make sure we cache whatever is set.
165
			cachedValue = observable.getValue();
160
			Object newValue = cachedValue = super.getValue();
166
161
167
			if (!Util.equals(oldValue, cachedValue))
162
			if (hasListeners() && !Util.equals(oldValue, newValue))
168
				fireValueChange(Diffs.createValueDiff(oldValue, cachedValue));
163
				fireValueChange(Diffs.createValueDiff(oldValue, newValue));
169
		} finally {
164
		} finally {
170
			updating = false;
165
			updating = false;
171
		}
166
		}
172
	}
167
	}
173
168
174
	public boolean isStale() {
169
	protected boolean hasListeners() {
175
		ObservableTracker.getterCalled(this);
170
		return super.hasListeners();
176
		return (dirty && updater != null) || observable.isStale();
177
	}
171
	}
178
172
179
	/**
173
	public boolean isStale() {
180
	 * Returns the type of the value from {@link #doGetValue()}, i.e.
174
		getterCalled();
181
	 * String.class
175
		return (dirty && updater != null) || super.isStale();
182
	 * 
183
	 * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType()
184
	 */
185
	public Object getValueType() {
186
		return observable.getValueType();
187
	}
176
	}
188
177
189
	public void dispose() {
178
	public void dispose() {
190
		cancelScheduledUpdate();
179
		cancelScheduledUpdate();
191
		if (observable != null) {
180
		if (widget instanceof Control) {
192
			observable.dispose();
181
			widget.removeListener(SWT.FocusOut, focusOutListener);
193
			observable.removeValueChangeListener(valueChangeListener);
182
			widget = null;
194
			observable.removeStaleListener(staleListener);
195
			observable = null;
196
		}
197
		if (control != null) {
198
			control.removeListener(SWT.FocusOut, focusOutListener);
199
			control = null;
200
		}
183
		}
201
		super.dispose();
184
		super.dispose();
202
	}
185
	}
Lines 219-225 Link Here
219
202
220
	private void scheduleUpdate() {
203
	private void scheduleUpdate() {
221
		updater = new ValueUpdater(cachedValue);
204
		updater = new ValueUpdater(cachedValue);
222
		observable.getWidget().getDisplay().timerExec(delay, updater);
205
		widget.getDisplay().timerExec(delay, updater);
223
	}
206
	}
224
207
225
	private void internalFireValueChange(final Object oldValue) {
208
	private void internalFireValueChange(final Object oldValue) {
(-)src/org/eclipse/jface/internal/databinding/swt/CComboObservableValue.java (-166 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *     Ashley Cambrell - bug 198904
12
 *     Matthew Hall - bug 118516
13
 *     Eric Rizzo - bug 134884
14
 *******************************************************************************/
15
package org.eclipse.jface.internal.databinding.swt;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.Realm;
19
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTObservableValue;
21
import org.eclipse.swt.custom.CCombo;
22
import org.eclipse.swt.events.ModifyEvent;
23
import org.eclipse.swt.events.ModifyListener;
24
25
/**
26
 * @since 3.2
27
 * 
28
 */
29
public class CComboObservableValue extends AbstractSWTObservableValue {
30
31
	/**
32
	 * 
33
	 */
34
35
	private final CCombo ccombo;
36
37
	private final String attribute;
38
39
	private boolean updating = false;
40
41
	private String currentValue;
42
43
	private ModifyListener modifyListener;
44
45
	/**
46
	 * @param ccombo
47
	 * @param attribute
48
	 */
49
	public CComboObservableValue(CCombo ccombo, String attribute) {
50
		super(ccombo);
51
		this.ccombo = ccombo;
52
		this.attribute = attribute;
53
		init();
54
	}
55
56
	/**
57
	 * @param realm
58
	 * @param ccombo
59
	 * @param attribute
60
	 */
61
	public CComboObservableValue(Realm realm, CCombo ccombo, String attribute) {
62
		super(realm, ccombo);
63
		this.ccombo = ccombo;
64
		this.attribute = attribute;
65
		init();
66
	}
67
	
68
	private void init() {		
69
		if (attribute.equals(SWTProperties.SELECTION)
70
				|| attribute.equals(SWTProperties.TEXT)) {
71
			this.currentValue = ccombo.getText();
72
			modifyListener = new ModifyListener() {
73
74
				public void modifyText(ModifyEvent e) {
75
					if (!updating) {
76
						String oldValue = currentValue;
77
						currentValue = CComboObservableValue.this.ccombo
78
								.getText();
79
						
80
						notifyIfChanged(oldValue, currentValue);
81
					}
82
				}
83
			};
84
			ccombo.addModifyListener(modifyListener);
85
		} else
86
			throw new IllegalArgumentException();
87
	}
88
89
	public void doSetValue(final Object value) {
90
		String oldValue = ccombo.getText();
91
		try {
92
			updating = true;
93
			if (attribute.equals(SWTProperties.TEXT)) {
94
				String stringValue = value != null ? value.toString() : ""; //$NON-NLS-1$
95
				ccombo.setText(stringValue);
96
			} else if (attribute.equals(SWTProperties.SELECTION)) {
97
				String items[] = ccombo.getItems();
98
				int index = -1;
99
				if (value == null) {
100
					ccombo.select(-1);
101
				} else if (items != null) {
102
					for (int i = 0; i < items.length; i++) {
103
						if (value.equals(items[i])) {
104
							index = i;
105
							break;
106
						}
107
					}
108
					if (index == -1) {
109
						ccombo.setText((String) value);
110
					} else {
111
						ccombo.select(index); // -1 will not "unselect"
112
					}
113
				}
114
			}
115
		} finally {
116
			updating = false;
117
			currentValue = ccombo.getText();
118
		}
119
		
120
		notifyIfChanged(oldValue, currentValue);
121
	}
122
123
	public Object doGetValue() {
124
		if (attribute.equals(SWTProperties.TEXT))
125
			return ccombo.getText();
126
127
		Assert.isTrue(attribute.equals(SWTProperties.SELECTION),
128
				"unexpected attribute: " + attribute); //$NON-NLS-1$
129
		// The problem with a ccombo, is that it changes the text and
130
		// fires before it update its selection index
131
		return ccombo.getText();
132
	}
133
134
	public Object getValueType() {
135
		Assert.isTrue(attribute.equals(SWTProperties.TEXT)
136
				|| attribute.equals(SWTProperties.SELECTION),
137
				"unexpected attribute: " + attribute); //$NON-NLS-1$
138
		return String.class;
139
	}
140
141
	/**
142
	 * @return attribute being observed
143
	 */
144
	public String getAttribute() {
145
		return attribute;
146
	}
147
148
	/*
149
	 * (non-Javadoc)
150
	 *
151
	 * @see org.eclipse.core.databinding.observable.value.AbstractObservableValue#dispose()
152
	 */
153
	public synchronized void dispose() {
154
		super.dispose();
155
156
		if (modifyListener != null && !ccombo.isDisposed()) {
157
			ccombo.removeModifyListener(modifyListener);
158
		}
159
	}
160
	
161
	private void notifyIfChanged(String oldValue, String newValue) {
162
		if (!oldValue.equals(newValue)) {
163
			fireValueChange(Diffs.createValueDiff(oldValue, ccombo.getText()));			
164
		}
165
	}
166
}
(-)src/org/eclipse/jface/internal/databinding/swt/ListObservableList.java (-51 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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
 *******************************************************************************/
11
package org.eclipse.jface.internal.databinding.swt;
12
13
import org.eclipse.jface.databinding.swt.SWTObservables;
14
import org.eclipse.swt.widgets.List;
15
16
/**
17
 * @since 3.2
18
 * 
19
 */
20
public class ListObservableList extends SWTObservableList {
21
22
	private final List list;
23
24
	/**
25
	 * @param list
26
	 */
27
	public ListObservableList(List list) {
28
		super(SWTObservables.getRealm(list.getDisplay()));
29
		this.list = list;
30
	}
31
32
	protected int getItemCount() {
33
		return list.getItemCount();
34
	}
35
36
	protected void setItems(String[] newItems) {
37
		list.setItems(newItems);
38
	}
39
40
	protected String[] getItems() {
41
		return list.getItems();
42
	}
43
44
	protected String getItem(int index) {
45
		return list.getItem(index);
46
	}
47
48
	protected void setItem(int index, String string) {
49
		list.setItem(index, string);
50
	}
51
}
(-)src/org/eclipse/jface/databinding/swt/SWTObservables.java (-47 / +68 lines)
Lines 19-39 Link Here
19
19
20
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.list.IObservableList;
21
import org.eclipse.core.databinding.observable.list.IObservableList;
22
import org.eclipse.jface.internal.databinding.swt.ButtonObservableValue;
22
import org.eclipse.core.databinding.property.IListProperty;
23
import org.eclipse.jface.internal.databinding.swt.CComboObservableList;
23
import org.eclipse.core.databinding.property.IValueProperty;
24
import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
24
import org.eclipse.core.databinding.property.PropertyObservables;
25
import org.eclipse.jface.internal.databinding.internal.swt.LinkObservableValue;
25
import org.eclipse.jface.internal.databinding.swt.CComboSingleSelectionObservableValue;
26
import org.eclipse.jface.internal.databinding.swt.CComboSingleSelectionObservableValue;
26
import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
27
import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
27
import org.eclipse.jface.internal.databinding.swt.ComboObservableList;
28
import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
29
import org.eclipse.jface.internal.databinding.internal.swt.LinkObservableValue;
30
import org.eclipse.jface.internal.databinding.swt.ComboSingleSelectionObservableValue;
28
import org.eclipse.jface.internal.databinding.swt.ComboSingleSelectionObservableValue;
31
import org.eclipse.jface.internal.databinding.swt.ControlObservableValue;
32
import org.eclipse.jface.internal.databinding.swt.DelayedObservableValue;
29
import org.eclipse.jface.internal.databinding.swt.DelayedObservableValue;
33
import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
30
import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
34
import org.eclipse.jface.internal.databinding.swt.ListObservableList;
35
import org.eclipse.jface.internal.databinding.swt.ListObservableValue;
36
import org.eclipse.jface.internal.databinding.swt.ListSingleSelectionObservableValue;
31
import org.eclipse.jface.internal.databinding.swt.ListSingleSelectionObservableValue;
32
import org.eclipse.jface.internal.databinding.swt.SWTObservableListDecorator;
33
import org.eclipse.jface.internal.databinding.swt.SWTObservableValueDecorator;
37
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
34
import org.eclipse.jface.internal.databinding.swt.SWTProperties;
38
import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
35
import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
39
import org.eclipse.jface.internal.databinding.swt.ShellObservableValue;
36
import org.eclipse.jface.internal.databinding.swt.ShellObservableValue;
Lines 88-100 Link Here
88
85
89
	/**
86
	/**
90
	 * Returns an observable which delays notification of value change events
87
	 * Returns an observable which delays notification of value change events
91
	 * from <code>observable</code> until <code>delay</code> milliseconds
88
	 * from <code>observable</code> until <code>delay</code> milliseconds have
92
	 * have passed since the last change event, or until a FocusOut event is
89
	 * passed since the last change event, or until a FocusOut event is received
93
	 * received from the underlying widget (whichever happens earlier). This
90
	 * from the underlying widget (whichever happens earlier). This class helps
94
	 * class helps to delay validation until the user stops typing. To notify
91
	 * to delay validation until the user stops typing. To notify about pending
95
	 * about pending changes, the returned observable value will fire a stale
92
	 * changes, the returned observable value will fire a stale event when the
96
	 * event when the wrapped observable value fires a change event, but this
93
	 * wrapped observable value fires a change event, but this change is being
97
	 * change is being delayed.
94
	 * delayed.
98
	 * 
95
	 * 
99
	 * @param delay
96
	 * @param delay
100
	 * @param observable
97
	 * @param observable
Lines 104-111 Link Here
104
	 * 
101
	 * 
105
	 * @since 1.2
102
	 * @since 1.2
106
	 */
103
	 */
107
	public static ISWTObservableValue observeDelayedValue(int delay, ISWTObservableValue observable) {
104
	public static ISWTObservableValue observeDelayedValue(int delay,
108
	  return new DelayedObservableValue(delay, observable);
105
			ISWTObservableValue observable) {
106
		return new DelayedObservableValue(delay, observable);
107
	}
108
109
	private static ISWTObservableValue observeControlValueProperty(
110
			Control control, IValueProperty property) {
111
		return new SWTObservableValueDecorator(
112
				PropertyObservables.observeValue(
113
						getRealm(control.getDisplay()), control, property),
114
				control);
109
	}
115
	}
110
116
111
	/**
117
	/**
Lines 114-120 Link Here
114
	 *         control
120
	 *         control
115
	 */
121
	 */
116
	public static ISWTObservableValue observeEnabled(Control control) {
122
	public static ISWTObservableValue observeEnabled(Control control) {
117
		return new ControlObservableValue(control, SWTProperties.ENABLED);
123
		return observeControlValueProperty(control, ControlProperties
124
				.enabledProperty());
118
	}
125
	}
119
126
120
	/**
127
	/**
Lines 123-129 Link Here
123
	 *         control
130
	 *         control
124
	 */
131
	 */
125
	public static ISWTObservableValue observeVisible(Control control) {
132
	public static ISWTObservableValue observeVisible(Control control) {
126
		return new ControlObservableValue(control, SWTProperties.VISIBLE);
133
		return observeControlValueProperty(control, ControlProperties
134
				.visibleProperty());
127
	}
135
	}
128
136
129
	/**
137
	/**
Lines 132-138 Link Here
132
	 *         control
140
	 *         control
133
	 */
141
	 */
134
	public static ISWTObservableValue observeTooltipText(Control control) {
142
	public static ISWTObservableValue observeTooltipText(Control control) {
135
		return new ControlObservableValue(control, SWTProperties.TOOLTIP_TEXT);
143
		return observeControlValueProperty(control, ControlProperties
144
				.toolTipTextProperty());
136
	}
145
	}
137
146
138
	/**
147
	/**
Lines 153-178 Link Here
153
	 *             if <code>control</code> type is unsupported
162
	 *             if <code>control</code> type is unsupported
154
	 */
163
	 */
155
	public static ISWTObservableValue observeSelection(Control control) {
164
	public static ISWTObservableValue observeSelection(Control control) {
165
		IValueProperty property;
156
		if (control instanceof Spinner) {
166
		if (control instanceof Spinner) {
157
			return new SpinnerObservableValue((Spinner) control,
167
			return new SpinnerObservableValue((Spinner) control,
158
					SWTProperties.SELECTION);
168
					SWTProperties.SELECTION);
159
		} else if (control instanceof Button) {
169
		} else if (control instanceof Button) {
160
			return new ButtonObservableValue((Button) control);
170
			property = ButtonProperties.selectionProperty();
161
		} else if (control instanceof Combo) {
171
		} else if (control instanceof Combo) {
162
			return new ComboObservableValue((Combo) control,
172
			property = ComboProperties.selectionProperty();
163
					SWTProperties.SELECTION);
164
		} else if (control instanceof CCombo) {
173
		} else if (control instanceof CCombo) {
165
			return new CComboObservableValue((CCombo) control,
174
			property = CComboProperties.selectionProperty();
166
					SWTProperties.SELECTION);
167
		} else if (control instanceof List) {
175
		} else if (control instanceof List) {
168
			return new ListObservableValue((List) control);
176
			property = ListProperties.selectionProperty();
169
		} else if (control instanceof Scale) {
177
		} else if (control instanceof Scale) {
170
			return new ScaleObservableValue((Scale) control,
178
			return new ScaleObservableValue((Scale) control,
171
					SWTProperties.SELECTION);
179
					SWTProperties.SELECTION);
180
		} else {
181
			throw new IllegalArgumentException(
182
					"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
172
		}
183
		}
173
184
174
		throw new IllegalArgumentException(
185
		return observeControlValueProperty(control, property);
175
				"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
176
	}
186
	}
177
187
178
	/**
188
	/**
Lines 233-240 Link Here
233
	 * </ul>
243
	 * </ul>
234
	 * 
244
	 * 
235
	 * <li>org.eclipse.swt.widgets.Label</li>
245
	 * <li>org.eclipse.swt.widgets.Label</li>
246
	 * 
236
	 * @param control
247
	 * @param control
237
	 * @param event event type to register for change events
248
	 * @param event
249
	 *            event type to register for change events
238
	 * @return observable value
250
	 * @return observable value
239
	 * @throws IllegalArgumentException
251
	 * @throws IllegalArgumentException
240
	 *             if <code>control</code> type is unsupported
252
	 *             if <code>control</code> type is unsupported
Lines 266-271 Link Here
266
	 *             if <code>control</code> type is unsupported
278
	 *             if <code>control</code> type is unsupported
267
	 */
279
	 */
268
	public static ISWTObservableValue observeText(Control control) {
280
	public static ISWTObservableValue observeText(Control control) {
281
		IValueProperty property;
269
		if (control instanceof Label) {
282
		if (control instanceof Label) {
270
			return new LabelObservableValue((Label) control);
283
			return new LabelObservableValue((Label) control);
271
		} else if (control instanceof Link) {
284
		} else if (control instanceof Link) {
Lines 273-288 Link Here
273
		} else if (control instanceof CLabel) {
286
		} else if (control instanceof CLabel) {
274
			return new CLabelObservableValue((CLabel) control);
287
			return new CLabelObservableValue((CLabel) control);
275
		} else if (control instanceof Combo) {
288
		} else if (control instanceof Combo) {
276
			return new ComboObservableValue((Combo) control, SWTProperties.TEXT);
289
			property = ComboProperties.textProperty();
277
		} else if (control instanceof CCombo) {
290
		} else if (control instanceof CCombo) {
278
			return new CComboObservableValue((CCombo) control,
291
			property = CComboProperties.textProperty();
279
					SWTProperties.TEXT);
280
		} else if (control instanceof Shell) {
292
		} else if (control instanceof Shell) {
281
			return new ShellObservableValue((Shell) control);
293
			return new ShellObservableValue((Shell) control);
294
		} else {
295
			throw new IllegalArgumentException(
296
					"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
282
		}
297
		}
283
298
284
		throw new IllegalArgumentException(
299
		return observeControlValueProperty(control, property);
285
				"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
286
	}
300
	}
287
301
288
	/**
302
	/**
Lines 300-315 Link Here
300
	 *             if <code>control</code> type is unsupported
314
	 *             if <code>control</code> type is unsupported
301
	 */
315
	 */
302
	public static IObservableList observeItems(Control control) {
316
	public static IObservableList observeItems(Control control) {
317
		IListProperty property;
303
		if (control instanceof Combo) {
318
		if (control instanceof Combo) {
304
			return new ComboObservableList((Combo) control);
319
			property = ComboProperties.itemsProperty();
305
		} else if (control instanceof CCombo) {
320
		} else if (control instanceof CCombo) {
306
			return new CComboObservableList((CCombo) control);
321
			property = CComboProperties.itemsProperty();
307
		} else if (control instanceof List) {
322
		} else if (control instanceof List) {
308
			return new ListObservableList((List) control);
323
			property = ListProperties.itemsProperty();
324
		} else {
325
			throw new IllegalArgumentException(
326
					"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
309
		}
327
		}
310
328
311
		throw new IllegalArgumentException(
329
		return new SWTObservableListDecorator(PropertyObservables.observeList(
312
				"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
330
				control, property), control);
313
	}
331
	}
314
332
315
	/**
333
	/**
Lines 349-355 Link Here
349
	 *         control
367
	 *         control
350
	 */
368
	 */
351
	public static ISWTObservableValue observeForeground(Control control) {
369
	public static ISWTObservableValue observeForeground(Control control) {
352
		return new ControlObservableValue(control, SWTProperties.FOREGROUND);
370
		return observeControlValueProperty(control, ControlProperties
371
				.foregroundProperty());
353
	}
372
	}
354
373
355
	/**
374
	/**
Lines 358-364 Link Here
358
	 *         control
377
	 *         control
359
	 */
378
	 */
360
	public static ISWTObservableValue observeBackground(Control control) {
379
	public static ISWTObservableValue observeBackground(Control control) {
361
		return new ControlObservableValue(control, SWTProperties.BACKGROUND);
380
		return observeControlValueProperty(control, ControlProperties
381
				.backgroundProperty());
362
	}
382
	}
363
383
364
	/**
384
	/**
Lines 366-377 Link Here
366
	 * @return an observable value tracking the font of the given control
386
	 * @return an observable value tracking the font of the given control
367
	 */
387
	 */
368
	public static ISWTObservableValue observeFont(Control control) {
388
	public static ISWTObservableValue observeFont(Control control) {
369
		return new ControlObservableValue(control, SWTProperties.FONT);
389
		return observeControlValueProperty(control, ControlProperties
390
				.fontProperty());
370
	}
391
	}
371
	
392
372
	/**
393
	/**
373
	 * Returns an observable observing the editable attribute of
394
	 * Returns an observable observing the editable attribute of the provided
374
	 * the provided <code>control</code>. The supported types are:
395
	 * <code>control</code>. The supported types are:
375
	 * <ul>
396
	 * <ul>
376
	 * <li>org.eclipse.swt.widgets.Text</li>
397
	 * <li>org.eclipse.swt.widgets.Text</li>
377
	 * </ul>
398
	 * </ul>
Lines 385-391 Link Here
385
		if (control instanceof Text) {
406
		if (control instanceof Text) {
386
			return new TextEditableObservableValue((Text) control);
407
			return new TextEditableObservableValue((Text) control);
387
		}
408
		}
388
		
409
389
		throw new IllegalArgumentException(
410
		throw new IllegalArgumentException(
390
				"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
411
				"Widget [" + control.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
391
	}
412
	}
(-)src/org/eclipse/jface/internal/databinding/swt/SWTObservableListDecorator.java (+57 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 The Pampered Chef, Inc. 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
 *     The Pampered Chef, Inc. - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.core.databinding.observable.list.DecoratingObservableList;
15
import org.eclipse.core.databinding.observable.list.IObservableList;
16
import org.eclipse.jface.databinding.swt.ISWTObservable;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Listener;
20
import org.eclipse.swt.widgets.Widget;
21
22
/**
23
 * @since 3.3
24
 * 
25
 */
26
public class SWTObservableListDecorator extends DecoratingObservableList
27
		implements ISWTObservable {
28
	private Widget widget;
29
30
	/**
31
	 * @param decorated
32
	 * @param widget
33
	 */
34
	public SWTObservableListDecorator(IObservableList decorated, Widget widget) {
35
		super(decorated, true);
36
		this.widget = widget;
37
		widget.addListener(SWT.Dispose, disposeListener);
38
	}
39
40
	private Listener disposeListener = new Listener() {
41
		public void handleEvent(Event event) {
42
			SWTObservableListDecorator.this.dispose();
43
		}
44
	};
45
46
	public void dispose() {
47
		this.widget = null;
48
		super.dispose();
49
	}
50
51
	/**
52
	 * @return Returns the widget.
53
	 */
54
	public Widget getWidget() {
55
		return widget;
56
	}
57
}
(-)src/org/eclipse/jface/internal/databinding/swt/SWTObservableValueDecorator.java (+57 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 The Pampered Chef, Inc. 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
 *     The Pampered Chef, Inc. - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.core.databinding.observable.value.DecoratingObservableValue;
15
import org.eclipse.core.databinding.observable.value.IObservableValue;
16
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Listener;
20
import org.eclipse.swt.widgets.Widget;
21
22
/**
23
 * @since 3.3
24
 * 
25
 */
26
public class SWTObservableValueDecorator extends DecoratingObservableValue
27
		implements ISWTObservableValue {
28
	private Widget widget;
29
30
	/**
31
	 * @param decorated
32
	 * @param widget
33
	 */
34
	public SWTObservableValueDecorator(IObservableValue decorated, Widget widget) {
35
		super(decorated, true);
36
		this.widget = widget;
37
		widget.addListener(SWT.Dispose, disposeListener);
38
	}
39
40
	private Listener disposeListener = new Listener() {
41
		public void handleEvent(Event event) {
42
			SWTObservableValueDecorator.this.dispose();
43
		}
44
	};
45
46
	public void dispose() {
47
		this.widget = null;
48
		super.dispose();
49
	}
50
51
	/**
52
	 * @return Returns the widget.
53
	 */
54
	public Widget getWidget() {
55
		return widget;
56
	}
57
}
(-)src/org/eclipse/jface/databinding/swt/ButtonProperties.java (+28 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.databinding.swt;
13
14
import org.eclipse.core.databinding.property.IValueProperty;
15
import org.eclipse.jface.internal.databinding.swt.ButtonSelectionProperty;
16
17
/**
18
 * @since 1.3
19
 *
20
 */
21
public class ButtonProperties {
22
	/**
23
	 * @return blah
24
	 */
25
	public static IValueProperty selectionProperty() {
26
		return new ButtonSelectionProperty();
27
	}
28
}
(-)src/org/eclipse/jface/internal/databinding/swt/ListItemsProperty.java (+35 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import java.util.Arrays;
15
16
import org.eclipse.swt.widgets.List;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class ListItemsProperty extends ControlListProperty {
23
	public Object getElementType() {
24
		return String.class;
25
	}
26
27
	protected void doSetList(Object source, java.util.List list) {
28
		String[] items = (String[]) list.toArray(new String[list.size()]);
29
		((List) source).setItems(items);
30
	}
31
32
	public java.util.List getList(Object source) {
33
		return Arrays.asList(((List) source).getItems());
34
	}
35
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlValueProperty.java (+66 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.property.ValueProperty;
19
import org.eclipse.jface.util.Util;
20
import org.eclipse.swt.widgets.Control;
21
import org.eclipse.swt.widgets.Event;
22
import org.eclipse.swt.widgets.Listener;
23
24
abstract class ControlValueProperty extends ValueProperty implements Listener {
25
	protected Map controlToValue = new HashMap();
26
27
	protected void addListenerTo(Object source) {
28
		controlToValue.put(source, getValue(source));
29
	}
30
31
	protected void removeListenerFrom(Object source) {
32
		controlToValue.remove(source);
33
	}
34
35
	public void handleEvent(Event event) {
36
		Object source = event.widget;
37
		Object oldValue = controlToValue.get(source);
38
		Object newValue = getValue(source);
39
		controlToValue.put(source, newValue);
40
		if (!Util.equals(oldValue, newValue))
41
			fireValueChange(source, Diffs.createValueDiff(oldValue, newValue));
42
	}
43
44
	public Object getValue(Object source) {
45
		return doGetValue((Control) source);
46
	}
47
48
	public void setValue(Object source, Object value) {
49
		Object oldValue = getValue(source);
50
51
		doSetValue((Control) source, value);
52
53
		if (hasListeners(source)) {
54
			Object newValue = getValue(source);
55
			if (!Util.equals(oldValue, newValue)) {
56
				controlToValue.put(source, newValue);
57
				fireValueChange(source, Diffs.createValueDiff(oldValue,
58
						newValue));
59
			}
60
		}
61
	}
62
63
	abstract Object doGetValue(Control control);
64
65
	abstract void doSetValue(Control control, Object value);
66
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlForegroundProperty.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.graphics.Color;
15
import org.eclipse.swt.widgets.Control;
16
17
/**
18
 * @since 3.3
19
 *
20
 */
21
public class ControlForegroundProperty extends ControlValueProperty {
22
	public Object getValueType() {
23
		return Color.class;
24
	}
25
26
	public Object doGetValue(Control control) {
27
		return control.getForeground();
28
	}
29
30
	public void doSetValue(Control control, Object value) {
31
		control.setForeground((Color) value);
32
	}
33
}
(-)src/org/eclipse/jface/internal/databinding/swt/CComboItemsProperty.java (+36 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import java.util.Arrays;
15
import java.util.List;
16
17
import org.eclipse.swt.custom.CCombo;
18
19
/**
20
 * @since 3.3
21
 * 
22
 */
23
public class CComboItemsProperty extends ControlListProperty {
24
	public Object getElementType() {
25
		return String.class;
26
	}
27
28
	protected void doSetList(Object source, List list) {
29
		String[] items = (String[]) list.toArray(new String[list.size()]);
30
		((CCombo) source).setItems(items);
31
	}
32
33
	public List getList(Object source) {
34
		return Arrays.asList(((CCombo) source).getItems());
35
	}
36
}
(-)src/org/eclipse/jface/databinding/swt/ComboProperties.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.databinding.swt;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IValueProperty;
16
import org.eclipse.jface.internal.databinding.swt.ComboItemsProperty;
17
import org.eclipse.jface.internal.databinding.swt.ComboSelectionProperty;
18
import org.eclipse.jface.internal.databinding.swt.ComboTextProperty;
19
20
/**
21
 * @since 1.3
22
 * 
23
 */
24
public class ComboProperties {
25
	/**
26
	 * @return blah
27
	 */
28
	public static IValueProperty selectionProperty() {
29
		return new ComboSelectionProperty();
30
	}
31
32
	/**
33
	 * @return blah
34
	 */
35
	public static IValueProperty textProperty() {
36
		return new ComboTextProperty();
37
	}
38
39
	/**
40
	 * @return blah
41
	 */
42
	public static IListProperty itemsProperty() {
43
		return new ComboItemsProperty();
44
	}
45
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlEnabledProperty.java (+32 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.widgets.Control;
15
16
/**
17
 * @since 3.3
18
 *
19
 */
20
public class ControlEnabledProperty extends ControlValueProperty {
21
	public Object getValueType() {
22
		return Boolean.TYPE;
23
	}
24
25
	public Object doGetValue(Control control) {
26
		return Boolean.valueOf(control.getEnabled());
27
	}
28
29
	public void doSetValue(Control control, Object value) {
30
		control.setEnabled(((Boolean) value).booleanValue());
31
	}
32
}
(-)src/org/eclipse/jface/internal/databinding/swt/ComboTextProperty.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.widgets.Combo;
16
import org.eclipse.swt.widgets.Control;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class ComboTextProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return String.class;
25
	}
26
27
	Object doGetValue(Control control) {
28
		return ((Combo) control).getText();
29
	}
30
31
	void doSetValue(Control control, Object value) {
32
		((Combo) control).setText(value != null ? (String) value : ""); //$NON-NLS-1$
33
	}
34
35
	protected void addListenerTo(Object source) {
36
		Combo combo = (Combo) source;
37
		combo.addListener(SWT.Modify, this);
38
		super.addListenerTo(source);
39
	}
40
41
	protected void removeListenerFrom(Object source) {
42
		Combo combo = (Combo) source;
43
		if (!combo.isDisposed())
44
			combo.removeListener(SWT.Modify, this);
45
		super.removeListenerFrom(combo);
46
	}
47
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlToolTipTextProperty.java (+32 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.widgets.Control;
15
16
/**
17
 * @since 3.3
18
 *
19
 */
20
public class ControlToolTipTextProperty extends ControlValueProperty {
21
	public Object getValueType() {
22
		return String.class;
23
	}
24
25
	public Object doGetValue(Control control) {
26
		return control.getToolTipText();
27
	}
28
29
	public void doSetValue(Control control, Object value) {
30
		control.setToolTipText((String) value);
31
	}
32
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlListProperty.java (+24 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.core.databinding.property.BasicListProperty;
15
16
abstract class ControlListProperty extends BasicListProperty {
17
	protected void addListenerTo(Object source) {
18
		// no-op
19
	}
20
21
	protected void removeListenerFrom(Object source) {
22
		// no-op
23
	}
24
}
(-)src/org/eclipse/jface/internal/databinding/swt/ButtonSelectionProperty.java (+49 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.widgets.Button;
16
import org.eclipse.swt.widgets.Control;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class ButtonSelectionProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return Boolean.TYPE;
25
	}
26
27
	Object doGetValue(Control control) {
28
		return Boolean.valueOf(((Button) control).getSelection());
29
	}
30
31
	void doSetValue(Control control, Object value) {
32
		if (value == null)
33
			value = Boolean.FALSE;
34
		((Button) control).setSelection(((Boolean) value).booleanValue());
35
	}
36
37
	protected void addListenerTo(Object source) {
38
		Button button = (Button) source;
39
		button.addListener(SWT.Selection, this);
40
		super.addListenerTo(source);
41
	}
42
43
	protected void removeListenerFrom(Object source) {
44
		Button button = (Button) source;
45
		if (!button.isDisposed())
46
			button.removeListener(SWT.Selection, this);
47
		super.removeListenerFrom(button);
48
	}
49
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlFontProperty.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.graphics.Font;
15
import org.eclipse.swt.widgets.Control;
16
17
/**
18
 * @since 3.3
19
 *
20
 */
21
public class ControlFontProperty extends ControlValueProperty {
22
	public Object getValueType() {
23
		return Font.class;
24
	}
25
26
	public Object doGetValue(Control control) {
27
		return control.getFont();
28
	}
29
30
	public void doSetValue(Control control, Object value) {
31
		control.setFont((Font) value);
32
	}
33
}
(-)src/org/eclipse/jface/databinding/swt/CComboProperties.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.databinding.swt;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IValueProperty;
16
import org.eclipse.jface.internal.databinding.swt.CComboItemsProperty;
17
import org.eclipse.jface.internal.databinding.swt.CComboSelectionProperty;
18
import org.eclipse.jface.internal.databinding.swt.CComboTextProperty;
19
20
/**
21
 * @since 1.3
22
 * 
23
 */
24
public class CComboProperties {
25
	/**
26
	 * @return blah
27
	 */
28
	public static IValueProperty selectionProperty() {
29
		return new CComboSelectionProperty();
30
	}
31
32
	/**
33
	 * @return blah
34
	 */
35
	public static IValueProperty textProperty() {
36
		return new CComboTextProperty();
37
	}
38
39
	/**
40
	 * @return blah
41
	 */
42
	public static IListProperty itemsProperty() {
43
		return new CComboItemsProperty();
44
	}
45
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlVisibleProperty.java (+32 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.widgets.Control;
15
16
/**
17
 * @since 3.3
18
 *
19
 */
20
public class ControlVisibleProperty extends ControlValueProperty {
21
	public Object getValueType() {
22
		return Boolean.TYPE;
23
	}
24
25
	public Object doGetValue(Control control) {
26
		return Boolean.valueOf(control.getVisible());
27
	}
28
29
	public void doSetValue(Control control, Object value) {
30
		control.setVisible(((Boolean) value).booleanValue());
31
	}
32
}
(-)src/org/eclipse/jface/internal/databinding/swt/ListSelectionProperty.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.widgets.Control;
16
import org.eclipse.swt.widgets.List;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class ListSelectionProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return String.class;
25
	}
26
27
	Object doGetValue(Control control) {
28
		List list = (List) control;
29
		int index = list.getSelectionIndex();
30
		if (index >= 0)
31
			return list.getItem(index);
32
		return null;
33
	}
34
35
	void doSetValue(Control control, Object value) {
36
		List list = (List) control;
37
		String items[] = list.getItems();
38
		int index = -1;
39
		if (items != null && value != null) {
40
			for (int i = 0; i < items.length; i++) {
41
				if (value.equals(items[i])) {
42
					index = i;
43
					break;
44
				}
45
			}
46
			list.select(index);
47
		}
48
	}
49
50
	protected void addListenerTo(Object source) {
51
		List list = (List) source;
52
		list.addListener(SWT.Selection, this);
53
		super.addListenerTo(source);
54
	}
55
56
	protected void removeListenerFrom(Object source) {
57
		List list = (List) source;
58
		if (!list.isDisposed())
59
			list.removeListener(SWT.Selection, this);
60
		super.removeListenerFrom(list);
61
	}
62
}
(-)src/org/eclipse/jface/databinding/swt/ListProperties.java (+37 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.databinding.swt;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IValueProperty;
16
import org.eclipse.jface.internal.databinding.swt.ListItemsProperty;
17
import org.eclipse.jface.internal.databinding.swt.ListSelectionProperty;
18
19
/**
20
 * @since 1.3
21
 * 
22
 */
23
public class ListProperties {
24
	/**
25
	 * @return blah
26
	 */
27
	public static IValueProperty selectionProperty() {
28
		return new ListSelectionProperty();
29
	}
30
	
31
	/**
32
	 * @return blah
33
	 */
34
	public static IListProperty itemsProperty() {
35
		return new ListItemsProperty();
36
	}
37
}
(-)src/org/eclipse/jface/databinding/swt/ControlProperties.java (+68 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.databinding.swt;
13
14
import org.eclipse.core.databinding.property.IValueProperty;
15
import org.eclipse.jface.internal.databinding.swt.ControlBackgroundProperty;
16
import org.eclipse.jface.internal.databinding.swt.ControlEnabledProperty;
17
import org.eclipse.jface.internal.databinding.swt.ControlFontProperty;
18
import org.eclipse.jface.internal.databinding.swt.ControlForegroundProperty;
19
import org.eclipse.jface.internal.databinding.swt.ControlVisibleProperty;
20
import org.eclipse.jface.internal.databinding.swt.ControlToolTipTextProperty;
21
 
22
/**
23
 * @since 1.3
24
 * 
25
 */
26
public class ControlProperties {
27
	/**
28
	 * @return blah
29
	 */
30
	public static IValueProperty enabledProperty() {
31
		return new ControlEnabledProperty();
32
	}
33
34
	/**
35
	 * @return blah
36
	 */
37
	public static IValueProperty visibleProperty() {
38
		return new ControlVisibleProperty();
39
	}
40
41
	/**
42
	 * @return blah
43
	 */
44
	public static IValueProperty toolTipTextProperty() {
45
		return new ControlToolTipTextProperty();
46
	}
47
48
	/**
49
	 * @return blah
50
	 */
51
	public static IValueProperty foregroundProperty() {
52
		return new ControlForegroundProperty();
53
	}
54
55
	/**
56
	 * @return blah
57
	 */
58
	public static IValueProperty backgroundProperty() {
59
		return new ControlBackgroundProperty();
60
	}
61
62
	/**
63
	 * @return blah
64
	 */
65
	public static IValueProperty fontProperty() {
66
		return new ControlFontProperty();
67
	}
68
}
(-)src/org/eclipse/jface/internal/databinding/swt/ComboSelectionProperty.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.widgets.Combo;
16
import org.eclipse.swt.widgets.Control;
17
18
/**
19
 * @since 3.3
20
 *
21
 */
22
public class ComboSelectionProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return String.class;
25
	}
26
27
	Object doGetValue(Control control) {
28
		return ((Combo)control).getText();
29
	}
30
31
	void doSetValue(Control control, Object value) {
32
		Combo combo = (Combo) control;
33
		String items[] = combo.getItems();
34
		int index = -1;
35
		if (items != null && value != null) {
36
			for (int i = 0; i < items.length; i++) {
37
				if (value.equals(items[i])) {
38
					index = i;
39
					break;
40
				}
41
			}
42
			if (index == -1) {
43
				combo.setText((String) value);
44
			} else {
45
				combo.select(index); // -1 will not "unselect"
46
			}
47
		}
48
	}
49
50
	protected void addListenerTo(Object source) {
51
		Combo combo = (Combo) source;
52
		combo.addListener(SWT.Modify, this);
53
		super.addListenerTo(source);
54
	}
55
56
	protected void removeListenerFrom(Object source) {
57
		Combo combo = (Combo) source;
58
		if (!combo.isDisposed())
59
			combo.removeListener(SWT.Modify, this);
60
		super.removeListenerFrom(combo);
61
	}
62
}
(-)src/org/eclipse/jface/internal/databinding/swt/ControlBackgroundProperty.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.graphics.Color;
15
import org.eclipse.swt.widgets.Control;
16
17
/**
18
 * @since 3.3
19
 *
20
 */
21
public class ControlBackgroundProperty extends ControlValueProperty {
22
	public Object getValueType() {
23
		return Color.class;
24
	}
25
26
	public Object doGetValue(Control control) {
27
		return control.getBackground();
28
	}
29
30
	public void doSetValue(Control control, Object value) {
31
		control.setBackground((Color) value);
32
	}
33
}
(-)src/org/eclipse/jface/internal/databinding/swt/ComboItemsProperty.java (+36 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import java.util.Arrays;
15
import java.util.List;
16
17
import org.eclipse.swt.widgets.Combo;
18
19
/**
20
 * @since 3.3
21
 * 
22
 */
23
public class ComboItemsProperty extends ControlListProperty {
24
	public Object getElementType() {
25
		return String.class;
26
	}
27
28
	protected void doSetList(Object source, List list) {
29
		String[] items = (String[]) list.toArray(new String[list.size()]);
30
		((Combo) source).setItems(items);
31
	}
32
33
	public List getList(Object source) {
34
		return Arrays.asList(((Combo) source).getItems());
35
	}
36
}
(-)src/org/eclipse/jface/internal/databinding/swt/CComboTextProperty.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.custom.CCombo;
16
import org.eclipse.swt.widgets.Control;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class CComboTextProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return String.class;
25
	}
26
27
	Object doGetValue(Control control) {
28
		return ((CCombo) control).getText();
29
	}
30
31
	void doSetValue(Control control, Object value) {
32
		((CCombo) control).setText(value != null ? (String) value : ""); //$NON-NLS-1$
33
	}
34
35
	protected void addListenerTo(Object source) {
36
		CCombo combo = (CCombo) source;
37
		combo.addListener(SWT.Modify, this);
38
		super.addListenerTo(source);
39
	}
40
41
	protected void removeListenerFrom(Object source) {
42
		CCombo combo = (CCombo) source;
43
		if (!combo.isDisposed())
44
			combo.removeListener(SWT.Modify, this);
45
		super.removeListenerFrom(combo);
46
	}
47
}
(-)src/org/eclipse/jface/internal/databinding/swt/CComboSelectionProperty.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.jface.internal.databinding.swt;
13
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.custom.CCombo;
16
import org.eclipse.swt.widgets.Control;
17
18
/**
19
 * @since 3.3
20
 * 
21
 */
22
public class CComboSelectionProperty extends ControlValueProperty {
23
	public Object getValueType() {
24
		return String.class;
25
	}
26
27
	Object doGetValue(Control control) {
28
		return ((CCombo) control).getText();
29
	}
30
31
	void doSetValue(Control control, Object value) {
32
		CCombo ccombo = (CCombo) control;
33
		String items[] = ccombo.getItems();
34
		int index = -1;
35
		if (value == null) {
36
			ccombo.select(-1);
37
		} else if (items != null) {
38
			for (int i = 0; i < items.length; i++) {
39
				if (value.equals(items[i])) {
40
					index = i;
41
					break;
42
				}
43
			}
44
			if (index == -1) {
45
				ccombo.setText((String) value);
46
			} else {
47
				ccombo.select(index); // -1 will not "unselect"
48
			}
49
		}
50
	}
51
52
	protected void addListenerTo(Object source) {
53
		CCombo ccombo = (CCombo) source;
54
		ccombo.addListener(SWT.Modify, this);
55
		super.addListenerTo(source);
56
	}
57
58
	protected void removeListenerFrom(Object source) {
59
		CCombo ccombo = (CCombo) source;
60
		if (!ccombo.isDisposed())
61
			ccombo.removeListener(SWT.Modify, this);
62
		super.removeListenerFrom(ccombo);
63
	}
64
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanObservableSetDecorator.java (-132 / +15 lines)
Lines 7-174 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 194734
10
 ******************************************************************************/
11
 ******************************************************************************/
11
12
12
package org.eclipse.core.internal.databinding.beans;
13
package org.eclipse.core.internal.databinding.beans;
13
14
14
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
15
import java.util.Collection;
16
import java.util.Iterator;
17
16
18
import org.eclipse.core.databinding.beans.IBeanObservable;
17
import org.eclipse.core.databinding.beans.IBeanObservable;
19
import org.eclipse.core.databinding.observable.IChangeListener;
18
import org.eclipse.core.databinding.observable.IObservable;
20
import org.eclipse.core.databinding.observable.IStaleListener;
19
import org.eclipse.core.databinding.observable.IObserving;
21
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.set.DecoratingObservableSet;
22
import org.eclipse.core.databinding.observable.set.IObservableSet;
21
import org.eclipse.core.databinding.observable.set.IObservableSet;
23
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
24
import org.eclipse.core.internal.databinding.Util;
25
22
26
/**
23
/**
27
 * {@link IBeanObservable} decorator for an {@link IObservableSet}.
24
 * {@link IBeanObservable} decorator for an {@link IObservableSet}.
28
 * 
25
 * 
29
 * @since 3.3
26
 * @since 3.3
30
 */
27
 */
31
public class BeanObservableSetDecorator implements IObservableSet, IBeanObservable {
28
public class BeanObservableSetDecorator extends DecoratingObservableSet
32
	private IObservableSet delegate;
29
		implements IBeanObservable {
33
	private Object observed;
34
	private PropertyDescriptor propertyDescriptor;
30
	private PropertyDescriptor propertyDescriptor;
35
31
36
	/**
32
	/**
37
	 * @param delegate 
33
	 * @param decorated
38
	 * @param observed 
39
	 * @param propertyDescriptor
34
	 * @param propertyDescriptor
40
	 */
35
	 */
41
	public BeanObservableSetDecorator(IObservableSet delegate,
36
	public BeanObservableSetDecorator(IObservableSet decorated,
42
			Object observed,
43
			PropertyDescriptor propertyDescriptor) {
37
			PropertyDescriptor propertyDescriptor) {
44
		
38
		super(decorated, true);
45
		this.delegate = delegate;
46
		this.observed = observed;
47
		this.propertyDescriptor = propertyDescriptor;
39
		this.propertyDescriptor = propertyDescriptor;
48
	}
40
	}
49
41
50
	public boolean add(Object o) {
51
		return delegate.add(o);
52
	}
53
54
	public boolean addAll(Collection c) {
55
		return delegate.addAll(c);
56
	}
57
58
	public void addChangeListener(IChangeListener listener) {
59
		delegate.addChangeListener(listener);
60
	}
61
62
	public void addSetChangeListener(ISetChangeListener listener) {
63
		delegate.addSetChangeListener(listener);
64
	}
65
66
	public void addStaleListener(IStaleListener listener) {
67
		delegate.addStaleListener(listener);
68
	}
69
70
	public void clear() {
71
		delegate.clear();
72
	}
73
74
	public boolean contains(Object o) {
75
		return delegate.contains(o);
76
	}
77
78
	public boolean containsAll(Collection c) {
79
		return delegate.containsAll(c);
80
	}
81
82
	public void dispose() {
42
	public void dispose() {
83
		delegate.dispose();
43
		this.propertyDescriptor = null;
84
	}
44
		super.dispose();
85
86
	public boolean equals(Object obj) {
87
		if (obj instanceof BeanObservableSetDecorator) {
88
			BeanObservableSetDecorator other = (BeanObservableSetDecorator) obj;
89
			return Util.equals(other.delegate, delegate);
90
		}
91
		return Util.equals(delegate, obj);
92
	}
45
	}
93
46
94
	public Object getElementType() {
95
		return delegate.getElementType();
96
	}
97
98
	public Realm getRealm() {
99
		return delegate.getRealm();
100
	}
101
102
	public int hashCode() {
103
		return delegate.hashCode();
104
	}
105
106
	public boolean isEmpty() {
107
		return delegate.isEmpty();
108
	}
109
110
	public boolean isStale() {
111
		return delegate.isStale();
112
	}
113
114
	public Iterator iterator() {
115
		return delegate.iterator();
116
	}
117
118
	public boolean remove(Object o) {
119
		return delegate.remove(o);
120
	}
121
122
	public boolean removeAll(Collection c) {
123
		return delegate.removeAll(c);
124
	}
125
126
	public void removeChangeListener(IChangeListener listener) {
127
		delegate.removeChangeListener(listener);
128
	}
129
130
	public void removeSetChangeListener(ISetChangeListener listener) {
131
		delegate.removeSetChangeListener(listener);
132
	}
133
134
	public void removeStaleListener(IStaleListener listener) {
135
		delegate.removeStaleListener(listener);
136
	}
137
138
	public boolean retainAll(Collection c) {
139
		return delegate.retainAll(c);
140
	}
141
142
	public int size() {
143
		return delegate.size();
144
	}
145
146
	public Object[] toArray() {
147
		return delegate.toArray();
148
	}
149
150
	public Object[] toArray(Object[] a) {
151
		return delegate.toArray(a);
152
	}
153
154
	/* (non-Javadoc)
155
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getObserved()
156
	 */
157
	public Object getObserved() {
47
	public Object getObserved() {
158
		return observed;
48
		IObservable decorated = getDecorated();
49
		if (decorated instanceof IObserving)
50
			return ((IObserving) decorated).getObserved();
51
		return null;
159
	}
52
	}
160
53
161
	/* (non-Javadoc)
162
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getPropertyDescriptor()
163
	 */
164
	public PropertyDescriptor getPropertyDescriptor() {
54
	public PropertyDescriptor getPropertyDescriptor() {
165
		return propertyDescriptor;
55
		return propertyDescriptor;
166
	}
56
	}
167
168
	/**
169
	 * @return the wrapped set
170
	 */
171
	public IObservableSet getDelegate() {
172
		return delegate;
173
	}	
174
}
57
}
(-)src/org/eclipse/core/internal/databinding/beans/JavaBeanObservableMap.java (-142 lines)
Removed Link Here
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 171616
11
 *     Matthew hall - bugs 223164, 241585
12
 *******************************************************************************/
13
14
package org.eclipse.core.internal.databinding.beans;
15
16
import java.beans.PropertyChangeListener;
17
import java.beans.PropertyDescriptor;
18
import java.lang.reflect.Method;
19
20
import org.eclipse.core.databinding.beans.IBeanObservable;
21
import org.eclipse.core.databinding.observable.Diffs;
22
import org.eclipse.core.databinding.observable.map.ComputedObservableMap;
23
import org.eclipse.core.databinding.observable.set.IObservableSet;
24
import org.eclipse.core.databinding.util.Policy;
25
import org.eclipse.core.runtime.IStatus;
26
import org.eclipse.core.runtime.Status;
27
28
/**
29
 * @since 1.0
30
 * 
31
 */
32
public class JavaBeanObservableMap extends ComputedObservableMap implements
33
		IBeanObservable {
34
35
	private PropertyDescriptor propertyDescriptor;
36
	
37
	private PropertyChangeListener elementListener = new PropertyChangeListener() {
38
		public void propertyChange(final java.beans.PropertyChangeEvent event) {
39
			if (!updating) {
40
				getRealm().exec(new Runnable() {
41
					public void run() {
42
						fireMapChange(Diffs.createMapDiffSingleChange(
43
								event.getSource(), event.getOldValue(), event
44
								.getNewValue()));
45
					}
46
				});
47
			}
48
		}
49
	};
50
51
	private ListenerSupport listenerSupport;
52
53
	private boolean updating = false;
54
55
	private boolean attachListeners;
56
57
	/**
58
	 * @param domain
59
	 * @param propertyDescriptor
60
	 */
61
	public JavaBeanObservableMap(IObservableSet domain,
62
			PropertyDescriptor propertyDescriptor) {
63
		this(domain, propertyDescriptor, true);
64
	}
65
66
	/**
67
	 * @param domain
68
	 * @param propertyDescriptor
69
	 * @param attachListeners
70
	 */
71
	public JavaBeanObservableMap(IObservableSet domain,
72
			PropertyDescriptor propertyDescriptor, boolean attachListeners) {
73
		super(domain);
74
75
		this.propertyDescriptor = propertyDescriptor;
76
		this.attachListeners = attachListeners;
77
		if (attachListeners) {
78
			this.listenerSupport = new ListenerSupport(elementListener,
79
					propertyDescriptor.getName());
80
		}
81
		init();
82
	}
83
84
	protected void hookListener(Object domainElement) {
85
		if (attachListeners && domainElement != null) {
86
			listenerSupport.hookListener(domainElement);
87
		}
88
	}
89
90
	protected void unhookListener(Object domainElement) {
91
		if (attachListeners && domainElement != null) {
92
			listenerSupport.unhookListener(domainElement);
93
		}
94
	}
95
96
	protected Object doGet(Object key) {
97
		if (key == null) {
98
			return null;
99
		}
100
		try {
101
			Method readMethod = propertyDescriptor.getReadMethod();
102
			if (!readMethod.isAccessible()) {
103
				readMethod.setAccessible(true);
104
			}
105
			return readMethod.invoke(key, new Object[0]);
106
		} catch (Exception e) {
107
			Policy.getLog().log(
108
					new Status(IStatus.ERROR, Policy.JFACE_DATABINDING,
109
							IStatus.ERROR, "cannot get value", e)); //$NON-NLS-1$
110
			throw new RuntimeException(e);
111
		}
112
	}
113
114
	protected Object doPut(Object key, Object value) {
115
		try {
116
			Object oldValue = get(key);
117
			propertyDescriptor.getWriteMethod().invoke(key,
118
					new Object[] { value });
119
			keySet().add(key);
120
			return oldValue;
121
		} catch (Exception e) {
122
			Policy.getLog().log(
123
					new Status(IStatus.ERROR, Policy.JFACE_DATABINDING,
124
							IStatus.ERROR, "cannot set value", e)); //$NON-NLS-1$
125
			throw new RuntimeException(e);
126
		}
127
	}
128
129
	/* (non-Javadoc)
130
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getObserved()
131
	 */
132
	public Object getObserved() {
133
		return keySet();
134
	}
135
136
	/* (non-Javadoc)
137
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getPropertyDescriptor()
138
	 */
139
	public PropertyDescriptor getPropertyDescriptor() {
140
		return propertyDescriptor;
141
	}
142
}
(-)src/org/eclipse/core/internal/databinding/beans/JavaBeanObservableList.java (-410 lines)
Removed Link Here
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 171616
11
 *     Matthew Hall - bugs 208858, 221351, 213145, 223164
12
 *     Mike Evans - bug 217558
13
 *******************************************************************************/
14
15
package org.eclipse.core.internal.databinding.beans;
16
17
import java.beans.PropertyChangeListener;
18
import java.beans.PropertyDescriptor;
19
import java.lang.reflect.Array;
20
import java.lang.reflect.InvocationTargetException;
21
import java.lang.reflect.Method;
22
import java.util.ArrayList;
23
import java.util.Arrays;
24
import java.util.Collection;
25
import java.util.Iterator;
26
import java.util.List;
27
28
import org.eclipse.core.databinding.BindingException;
29
import org.eclipse.core.databinding.beans.IBeanObservable;
30
import org.eclipse.core.databinding.observable.Diffs;
31
import org.eclipse.core.databinding.observable.Realm;
32
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
33
import org.eclipse.core.databinding.observable.list.ObservableList;
34
35
/**
36
 * @since 1.0
37
 * 
38
 */
39
public class JavaBeanObservableList extends ObservableList implements
40
		IBeanObservable {
41
42
	private final Object object;
43
44
	private PropertyChangeListener collectionListener = new PropertyChangeListener() {
45
		public void propertyChange(java.beans.PropertyChangeEvent event) {
46
			if (!updating) {
47
				getRealm().exec(new Runnable() {
48
					public void run() {
49
						updateWrappedList( new ArrayList( Arrays.asList(getValues() ) ) );
50
					}
51
				});
52
			}
53
		}
54
	};
55
56
	private boolean updating = false;
57
58
	private PropertyDescriptor descriptor;
59
60
	private ListenerSupport collectionListenSupport;
61
62
	private boolean attachListeners;
63
64
	/**
65
	 * @param realm
66
	 * @param object
67
	 * @param descriptor
68
	 * @param elementType
69
	 */
70
	public JavaBeanObservableList(Realm realm, Object object,
71
			PropertyDescriptor descriptor, Class elementType) {
72
		this(realm, object, descriptor, elementType, true);
73
	}
74
75
	/**
76
	 * @param realm
77
	 * @param object
78
	 * @param descriptor
79
	 * @param elementType
80
	 * @param attachListeners
81
	 */
82
	public JavaBeanObservableList(Realm realm, Object object,
83
			PropertyDescriptor descriptor, Class elementType,
84
			boolean attachListeners) {
85
86
		super(realm, new ArrayList(), elementType);
87
		this.object = object;
88
		this.descriptor = descriptor;
89
		this.attachListeners = attachListeners;
90
91
		if (attachListeners) {
92
			this.collectionListenSupport = new ListenerSupport(
93
					collectionListener, descriptor.getName());
94
		}
95
96
		// initialize list without firing events
97
		wrappedList.addAll(Arrays.asList(getValues()));
98
	}
99
100
	protected void firstListenerAdded() {
101
		if (attachListeners) {
102
			collectionListenSupport.hookListener(this.object);
103
		}
104
	}
105
106
	protected void lastListenerRemoved() {
107
		if (collectionListenSupport != null) {
108
			collectionListenSupport.dispose();
109
		}
110
	}
111
112
	public void dispose() {
113
		super.dispose();
114
		lastListenerRemoved();
115
	}
116
117
	private Object primGetValues() {
118
		Exception ex = null;
119
		try {
120
			Method readMethod = descriptor.getReadMethod();
121
			if (!readMethod.isAccessible()) {
122
				readMethod.setAccessible(true);
123
			}
124
			return readMethod.invoke(object, new Object[0]);
125
		} catch (IllegalArgumentException e) {
126
			ex = e;
127
		} catch (IllegalAccessException e) {
128
			ex = e;
129
		} catch (InvocationTargetException e) {
130
			ex = e;
131
		}
132
		throw new BindingException("Could not read collection values", ex); //$NON-NLS-1$
133
	}
134
135
	private Object[] getValues() {
136
		Object[] values = null;
137
138
		Object result = primGetValues();
139
		if (descriptor.getPropertyType().isArray())
140
			values = (Object[]) result;
141
		else {
142
			// TODO add jUnit for POJO (var. SettableValue) collections
143
			Collection list = (Collection) result;
144
			if (list != null) {
145
				values = list.toArray();
146
			}
147
		}
148
		if (values == null)
149
			values = new Object[0];
150
		return values;
151
	}
152
153
	public Object getObserved() {
154
		return object;
155
	}
156
157
	public PropertyDescriptor getPropertyDescriptor() {
158
		return descriptor;
159
	}
160
161
	private void setValues() {
162
		if (descriptor.getPropertyType().isArray()) {
163
			Class componentType = descriptor.getPropertyType()
164
					.getComponentType();
165
			Object[] newArray = (Object[]) Array.newInstance(componentType,
166
					wrappedList.size());
167
			wrappedList.toArray(newArray);
168
			primSetValues(newArray);
169
		} else {
170
			// assume that it is a java.util.List
171
			primSetValues(new ArrayList(wrappedList));
172
		}
173
	}
174
175
	private void primSetValues(Object newValue) {
176
		Exception ex = null;
177
		try {
178
			Method writeMethod = descriptor.getWriteMethod();
179
			if (!writeMethod.isAccessible()) {
180
				writeMethod.setAccessible(true);
181
			}
182
			writeMethod.invoke(object, new Object[] { newValue });
183
			return;
184
		} catch (IllegalArgumentException e) {
185
			ex = e;
186
		} catch (IllegalAccessException e) {
187
			ex = e;
188
		} catch (InvocationTargetException e) {
189
			ex = e;
190
		}
191
		throw new BindingException("Could not write collection values", ex); //$NON-NLS-1$
192
	}
193
194
	public Object set(int index, Object element) {
195
		getterCalled();
196
		updating = true;
197
		try {
198
			Object oldElement = wrappedList.set(index, element);
199
			setValues();
200
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
201
					index, false, oldElement), Diffs.createListDiffEntry(index,
202
					true, element)));
203
			return oldElement;
204
		} finally {
205
			updating = false;
206
		}
207
	}
208
209
	public Object move(int oldIndex, int newIndex) {
210
		getterCalled();
211
		updating = true;
212
		try {
213
			int size = wrappedList.size();
214
			if (oldIndex < 0 || oldIndex >= size)
215
				throw new IndexOutOfBoundsException(
216
						"oldIndex: " + oldIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
217
			if (newIndex < 0 || newIndex >= size)
218
				throw new IndexOutOfBoundsException(
219
						"newIndex: " + newIndex + ", size:" + size); //$NON-NLS-1$ //$NON-NLS-2$
220
			if (oldIndex == newIndex)
221
				return wrappedList.get(oldIndex);
222
			Object element = wrappedList.remove(oldIndex);
223
			wrappedList.add(newIndex, element);
224
			setValues();
225
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
226
					oldIndex, false, element), Diffs.createListDiffEntry(
227
					newIndex, true, element)));
228
			return element;
229
		} finally {
230
			updating = false;
231
		}
232
	}
233
234
	public Object remove(int index) {
235
		getterCalled();
236
		updating = true;
237
		try {
238
			Object oldElement = wrappedList.remove(index);
239
			setValues();
240
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
241
					index, false, oldElement)));
242
			return oldElement;
243
		} finally {
244
			updating = false;
245
		}
246
	}
247
248
	public boolean add(Object element) {
249
		updating = true;
250
		try {
251
			int index = wrappedList.size();
252
			boolean result = wrappedList.add(element);
253
			setValues();
254
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
255
					index, true, element)));
256
			return result;
257
		} finally {
258
			updating = false;
259
		}
260
	}
261
262
	public void add(int index, Object element) {
263
		updating = true;
264
		try {
265
			wrappedList.add(index, element);
266
			setValues();
267
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
268
					index, true, element)));
269
		} finally {
270
			updating = false;
271
		}
272
	}
273
274
	public boolean addAll(Collection c) {
275
		if (c.isEmpty()) {
276
			return false;
277
		}
278
		updating = true;
279
		try {
280
			int index = wrappedList.size();
281
			boolean result = wrappedList.addAll(c);
282
			setValues();
283
			ListDiffEntry[] entries = new ListDiffEntry[c.size()];
284
			int i = 0;
285
			for (Iterator it = c.iterator(); it.hasNext();) {
286
				Object o = it.next();
287
				entries[i++] = Diffs.createListDiffEntry(index++, true, o);
288
			}
289
			fireListChange(Diffs.createListDiff(entries));
290
			return result;
291
		} finally {
292
			updating = false;
293
		}
294
	}
295
296
	public boolean addAll(int index, Collection c) {
297
		if (c.isEmpty()) {
298
			return false;
299
		}
300
		updating = true;
301
		try {
302
			boolean result = wrappedList.addAll(index, c);
303
			setValues();
304
			ListDiffEntry[] entries = new ListDiffEntry[c.size()];
305
			int i = 0;
306
			for (Iterator it = c.iterator(); it.hasNext();) {
307
				Object o = it.next();
308
				entries[i++] = Diffs.createListDiffEntry(index++, true, o);
309
			}
310
			fireListChange(Diffs.createListDiff(entries));
311
			return result;
312
		} finally {
313
			updating = false;
314
		}
315
	}
316
317
	public boolean remove(Object o) {
318
		getterCalled();
319
		int index = wrappedList.indexOf(o);
320
		if (index == -1) {
321
			return false;
322
		}
323
		updating = true;
324
		try {
325
			Object oldElement = wrappedList.remove(index);
326
			setValues();
327
			fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(
328
					index, false, oldElement)));
329
			return true;
330
		} finally {
331
			updating = false;
332
		}
333
	}
334
335
	public boolean removeAll(Collection c) {
336
		getterCalled();
337
		boolean changed = false;
338
		updating = true;
339
		try {
340
			List diffEntries = new ArrayList();
341
			for (Iterator it = c.iterator(); it.hasNext();) {
342
				Object o = it.next();
343
				int index = wrappedList.indexOf(o);
344
				if (index != -1) {
345
					changed = true;
346
					Object oldElement = wrappedList.remove(index);
347
					diffEntries.add(Diffs.createListDiffEntry(index, false,
348
							oldElement));
349
				}
350
			}
351
			if (changed) {
352
				setValues();
353
				fireListChange(Diffs
354
						.createListDiff((ListDiffEntry[]) diffEntries
355
								.toArray(new ListDiffEntry[diffEntries.size()])));
356
			}
357
			return changed;
358
		} finally {
359
			updating = false;
360
		}
361
	}
362
363
	public boolean retainAll(Collection c) {
364
		getterCalled();
365
		boolean changed = false;
366
		updating = true;
367
		try {
368
			List diffEntries = new ArrayList();
369
			int index = 0;
370
			for (Iterator it = wrappedList.iterator(); it.hasNext();) {
371
				Object o = it.next();
372
				boolean retain = c.contains(o);
373
				if (retain) {
374
					index++;
375
				} else {
376
					changed = true;
377
					it.remove();
378
					diffEntries.add(Diffs.createListDiffEntry(index, false, o));
379
				}
380
			}
381
			if (changed) {
382
				setValues();
383
				fireListChange(Diffs
384
						.createListDiff((ListDiffEntry[]) diffEntries
385
								.toArray(new ListDiffEntry[diffEntries.size()])));
386
			}
387
			return changed;
388
		} finally {
389
			updating = false;
390
		}
391
	}
392
393
	public void clear() {
394
		updating = true;
395
		try {
396
			List diffEntries = new ArrayList();
397
			for (Iterator it = wrappedList.iterator(); it.hasNext();) {
398
				Object o = it.next();
399
				diffEntries.add(Diffs.createListDiffEntry(0, false, o));
400
			}
401
			wrappedList.clear();
402
			setValues();
403
			fireListChange(Diffs.createListDiff((ListDiffEntry[]) diffEntries
404
					.toArray(new ListDiffEntry[diffEntries.size()])));
405
		} finally {
406
			updating = false;
407
		}
408
	}
409
410
}
(-)src/org/eclipse/core/internal/databinding/beans/JavaBeanPropertyObservableMap.java (-241 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 221704)
10
 *     Matthew Hall - bug 223164
11
 *******************************************************************************/
12
13
package org.eclipse.core.internal.databinding.beans;
14
15
import java.beans.PropertyChangeEvent;
16
import java.beans.PropertyChangeListener;
17
import java.beans.PropertyDescriptor;
18
import java.lang.reflect.InvocationTargetException;
19
import java.lang.reflect.Method;
20
import java.util.Collections;
21
import java.util.HashMap;
22
import java.util.HashSet;
23
import java.util.Iterator;
24
import java.util.Map;
25
import java.util.Set;
26
27
import org.eclipse.core.databinding.BindingException;
28
import org.eclipse.core.databinding.beans.IBeanObservable;
29
import org.eclipse.core.databinding.observable.Diffs;
30
import org.eclipse.core.databinding.observable.Realm;
31
import org.eclipse.core.databinding.observable.map.ObservableMap;
32
import org.eclipse.core.internal.databinding.Util;
33
import org.eclipse.core.runtime.Assert;
34
35
/**
36
 * @since 1.0
37
 * 
38
 */
39
public class JavaBeanPropertyObservableMap extends ObservableMap implements
40
		IBeanObservable {
41
42
	private final Object object;
43
44
	private PropertyChangeListener mapListener = new PropertyChangeListener() {
45
		public void propertyChange(final PropertyChangeEvent event) {
46
			if (!updating) {
47
				getRealm().exec(new Runnable() {
48
					public void run() {
49
						Map oldValue = wrappedMap;
50
						Map newValue = (Map) event.getNewValue();
51
						wrappedMap = new HashMap(newValue);
52
						
53
						fireMapChange(Diffs.computeMapDiff(oldValue, newValue));
54
					}
55
				});
56
			}
57
		}
58
	};
59
60
	private boolean updating = false;
61
62
	private PropertyDescriptor descriptor;
63
64
	private ListenerSupport collectionListenSupport;
65
66
	private boolean attachListeners;
67
68
	/**
69
	 * @param realm
70
	 * @param object
71
	 * @param descriptor
72
	 */
73
	public JavaBeanPropertyObservableMap(Realm realm, Object object,
74
			PropertyDescriptor descriptor) {
75
		this(realm, object, descriptor, true);
76
	}
77
78
	/**
79
	 * @param realm
80
	 * @param object
81
	 * @param descriptor
82
	 * @param attachListeners
83
	 */
84
	public JavaBeanPropertyObservableMap(Realm realm, Object object,
85
			PropertyDescriptor descriptor, boolean attachListeners) {
86
		super(realm, new HashMap());
87
		this.object = object;
88
		this.descriptor = descriptor;
89
		this.attachListeners = attachListeners;
90
		if (attachListeners) {
91
			this.collectionListenSupport = new ListenerSupport(mapListener,
92
					descriptor.getName());
93
		}
94
95
		wrappedMap.putAll(getMap());
96
	}
97
98
	protected void firstListenerAdded() {
99
		if (attachListeners) {
100
			collectionListenSupport.hookListener(this.object);
101
		}
102
	}
103
104
	protected void lastListenerRemoved() {
105
		if (collectionListenSupport != null) {
106
			collectionListenSupport.dispose();
107
		}
108
	}
109
110
	private Object primGetMap() {
111
		try {
112
			Method readMethod = descriptor.getReadMethod();
113
			if (!readMethod.isAccessible()) {
114
				readMethod.setAccessible(true);
115
			}
116
			return readMethod.invoke(object, new Object[0]);
117
		} catch (IllegalArgumentException e) {
118
		} catch (IllegalAccessException e) {
119
		} catch (InvocationTargetException e) {
120
		}
121
		Assert.isTrue(false, "Could not read collection values"); //$NON-NLS-1$
122
		return null;
123
	}
124
125
	private void primSetMap(Object newValue) {
126
		Exception ex = null;
127
		try {
128
			Method writeMethod = descriptor.getWriteMethod();
129
			if (!writeMethod.isAccessible()) {
130
				writeMethod.setAccessible(true);
131
			}
132
			writeMethod.invoke(object, new Object[] { newValue });
133
			return;
134
		} catch (IllegalArgumentException e) {
135
			ex = e;
136
		} catch (IllegalAccessException e) {
137
			ex = e;
138
		} catch (InvocationTargetException e) {
139
			ex = e;
140
		}
141
		throw new BindingException("Could not write collection values", ex); //$NON-NLS-1$
142
	}
143
144
	private Map getMap() {
145
		Map result = (Map) primGetMap();
146
147
		if (result == null)
148
			result = new HashMap();
149
		return result;
150
	}
151
152
	private void setMap() {
153
		primSetMap(new HashMap(wrappedMap));
154
	}
155
156
	public Object put(Object key, Object value) {
157
		checkRealm();
158
		updating = true;
159
		try {
160
			Object result = wrappedMap.put(key, value);
161
			if (!Util.equals(result, value)) {
162
				setMap();
163
				if (result == null) {
164
					fireMapChange(Diffs.createMapDiffSingleAdd(key, value));
165
				} else {
166
					fireMapChange(Diffs.createMapDiffSingleChange(key, result,
167
							value));
168
				}
169
			}
170
			return result;
171
		} finally {
172
			updating = false;
173
		}
174
	}
175
176
	public void putAll(Map map) {
177
		checkRealm();
178
		updating = true;
179
		try {
180
			Set addedKeys = new HashSet(map.size());
181
			Map changes = new HashMap(map.size());
182
			for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
183
				Map.Entry entry = (Entry) it.next();
184
				Object key = entry.getKey();
185
				Object newValue = entry.getValue();
186
				Object oldValue = wrappedMap.put(key, newValue);
187
				if (oldValue == null) {
188
					addedKeys.add(key);
189
				} else if (!Util.equals(oldValue, newValue)) {
190
					changes.put(key, oldValue);
191
				}
192
			}
193
			if (!addedKeys.isEmpty() || !changes.isEmpty()) {
194
				setMap();
195
				fireMapChange(Diffs.createMapDiff(addedKeys,
196
						Collections.EMPTY_SET, changes.keySet(), changes,
197
						wrappedMap));
198
			}
199
		} finally {
200
			updating = false;
201
		}
202
	}
203
204
	public Object remove(Object key) {
205
		checkRealm();
206
		updating = true;
207
		try {
208
			Object result = wrappedMap.remove(key);
209
			if (result!=null) {
210
				setMap();
211
				fireMapChange(Diffs.createMapDiffSingleRemove(key, result));
212
			}
213
			return result;
214
		} finally {
215
			updating = false;
216
		}
217
	}
218
219
	public void clear() {
220
		checkRealm();
221
		if (wrappedMap.isEmpty())
222
			return;
223
		updating = true;
224
		try {
225
			Map oldMap = wrappedMap;
226
			wrappedMap = new HashMap();
227
			setMap();
228
			fireMapChange(Diffs.computeMapDiff(oldMap, Collections.EMPTY_MAP));
229
		} finally {
230
			updating = false;
231
		}
232
	}
233
234
	public Object getObserved() {
235
		return object;
236
	}
237
238
	public PropertyDescriptor getPropertyDescriptor() {
239
		return descriptor;
240
	}
241
}
(-)src/org/eclipse/core/internal/databinding/beans/JavaBeanObservableSet.java (-306 lines)
Removed Link Here
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 171616
11
 *     Matthew Hall - bug 221351, 223164
12
 *******************************************************************************/
13
14
package org.eclipse.core.internal.databinding.beans;
15
16
import java.beans.PropertyChangeListener;
17
import java.beans.PropertyDescriptor;
18
import java.lang.reflect.Array;
19
import java.lang.reflect.InvocationTargetException;
20
import java.lang.reflect.Method;
21
import java.util.Arrays;
22
import java.util.Collection;
23
import java.util.Collections;
24
import java.util.HashSet;
25
import java.util.Iterator;
26
import java.util.Set;
27
28
import org.eclipse.core.databinding.BindingException;
29
import org.eclipse.core.databinding.beans.IBeanObservable;
30
import org.eclipse.core.databinding.observable.Diffs;
31
import org.eclipse.core.databinding.observable.Realm;
32
import org.eclipse.core.databinding.observable.set.ObservableSet;
33
import org.eclipse.core.runtime.Assert;
34
35
/**
36
 * @since 1.0
37
 * 
38
 */
39
public class JavaBeanObservableSet extends ObservableSet implements IBeanObservable {
40
41
	private final Object object;
42
43
	private PropertyChangeListener collectionListener = new PropertyChangeListener() {
44
		public void propertyChange(java.beans.PropertyChangeEvent event) {
45
			if (!updating) {
46
				getRealm().exec(new Runnable() {
47
					public void run() {
48
						Set newElements = new HashSet(Arrays
49
								.asList(getValues()));
50
						Set addedElements = new HashSet(newElements);
51
						Set removedElements = new HashSet(wrappedSet);
52
						// remove all new elements from old elements to compute
53
						// the removed elements
54
						removedElements.removeAll(newElements);
55
						addedElements.removeAll(wrappedSet);
56
						wrappedSet = newElements;
57
						fireSetChange(Diffs.createSetDiff(addedElements,
58
								removedElements));
59
					}
60
				});
61
			}
62
		}
63
	};
64
65
	private boolean updating = false;
66
67
	private PropertyDescriptor descriptor;
68
69
	private ListenerSupport collectionListenSupport;
70
71
	private boolean attachListeners;
72
73
	/**
74
	 * @param realm
75
	 * @param object
76
	 * @param descriptor
77
	 * @param elementType
78
	 */
79
	public JavaBeanObservableSet(Realm realm, Object object,
80
			PropertyDescriptor descriptor, Class elementType) {
81
		this(realm, object, descriptor, elementType, true);
82
	}
83
84
	/**
85
	 * @param realm
86
	 * @param object
87
	 * @param descriptor
88
	 * @param elementType
89
	 * @param attachListeners
90
	 */
91
	public JavaBeanObservableSet(Realm realm, Object object,
92
			PropertyDescriptor descriptor, Class elementType,
93
			boolean attachListeners) {
94
		super(realm, new HashSet(), elementType);
95
		this.object = object;
96
		this.descriptor = descriptor;
97
		this.attachListeners = attachListeners;
98
		if (attachListeners) {
99
			this.collectionListenSupport = new ListenerSupport(
100
					collectionListener, descriptor.getName());
101
		}
102
103
		wrappedSet.addAll(Arrays.asList(getValues()));
104
	}
105
106
	protected void firstListenerAdded() {
107
		if (attachListeners) {
108
			collectionListenSupport.hookListener(this.object);
109
		}
110
	}
111
112
	protected void lastListenerRemoved() {
113
		if (collectionListenSupport != null) {
114
			collectionListenSupport.dispose();
115
		}
116
	}
117
118
	private Object primGetValues() {
119
		try {
120
			Method readMethod = descriptor.getReadMethod();
121
			if (!readMethod.isAccessible()) {
122
				readMethod.setAccessible(true);
123
			}
124
			return readMethod.invoke(object, new Object[0]);
125
		} catch (IllegalArgumentException e) {
126
		} catch (IllegalAccessException e) {
127
		} catch (InvocationTargetException e) {
128
		}
129
		Assert.isTrue(false, "Could not read collection values"); //$NON-NLS-1$
130
		return null;
131
	}
132
133
	private Object[] getValues() {
134
		Object[] values = null;
135
136
		Object result = primGetValues();
137
		if (descriptor.getPropertyType().isArray())
138
			values = (Object[]) result;
139
		else {
140
			// TODO add jUnit for POJO (var. SettableValue) collections
141
			Collection list = (Collection) result;
142
			if (list != null)
143
				values = list.toArray();
144
		}
145
		if (values == null)
146
			values = new Object[0];
147
		return values;
148
	}
149
150
	private void setValues() {
151
		if (descriptor.getPropertyType().isArray()) {
152
			Class componentType = descriptor.getPropertyType()
153
					.getComponentType();
154
			Object[] newArray = (Object[]) Array.newInstance(componentType,
155
					wrappedSet.size());
156
			wrappedSet.toArray(newArray);
157
			primSetValues(newArray);
158
		} else {
159
			// assume that it is a java.util.Set
160
			primSetValues(new HashSet(wrappedSet));
161
		}
162
	}
163
164
	public boolean add(Object o) {
165
		getterCalled();
166
		updating = true;
167
		try {
168
			boolean added = wrappedSet.add(o);
169
			if (added) {
170
				setValues();
171
				fireSetChange(Diffs.createSetDiff(Collections.singleton(o),
172
						Collections.EMPTY_SET));
173
			}
174
			return added;
175
		} finally {
176
			updating = false;
177
		}
178
	}
179
180
	public boolean remove(Object o) {
181
		getterCalled();
182
		updating = true;
183
		try {
184
			boolean removed = wrappedSet.remove(o);
185
			if (removed) {
186
				setValues();
187
				fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
188
						Collections.singleton(o)));
189
			}
190
			return removed;
191
		} finally {
192
			updating = false;
193
		}
194
	}
195
196
	public boolean addAll(Collection c) {
197
		getterCalled();
198
		updating = true;
199
		try {
200
			Set additions = new HashSet();
201
			for (Iterator iterator = c.iterator(); iterator.hasNext();) {
202
				Object element = iterator.next();
203
				if (wrappedSet.add(element))
204
					additions.add(element);
205
			}
206
			boolean changed = !additions.isEmpty();
207
			if (changed) {
208
				setValues();
209
				fireSetChange(Diffs.createSetDiff(additions,
210
						Collections.EMPTY_SET));
211
			}
212
			return changed;
213
		} finally {
214
			updating = false;
215
		}
216
	}
217
218
	public boolean removeAll(Collection c) {
219
		getterCalled();
220
		updating = true;
221
		try {
222
			Set removals = new HashSet();
223
			for (Iterator iterator = c.iterator(); iterator.hasNext();) {
224
				Object element = iterator.next();
225
				if (wrappedSet.remove(element))
226
					removals.add(element);
227
			}
228
			boolean changed = !removals.isEmpty();
229
			if (changed) {
230
				setValues();
231
				fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
232
						removals));
233
			}
234
			return changed;
235
		} finally {
236
			updating = false;
237
		}
238
	}
239
240
	public boolean retainAll(Collection c) {
241
		getterCalled();
242
		updating = true;
243
		try {
244
			Set removals = new HashSet();
245
			for (Iterator iterator = wrappedSet.iterator(); iterator.hasNext();) {
246
				Object element = iterator.next();
247
				if (!c.contains(element)) {
248
					iterator.remove();
249
					removals.add(element);
250
				}
251
			}
252
			boolean changed = !removals.isEmpty();
253
			if (changed) {
254
				setValues();
255
				fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
256
						removals));
257
			}
258
			return changed;
259
		} finally {
260
			updating = false;
261
		}
262
	}
263
264
	public void clear() {
265
		getterCalled();
266
		if (wrappedSet.isEmpty())
267
			return;
268
269
		updating = true;
270
		try {
271
			Set removals = new HashSet(wrappedSet);
272
			wrappedSet.clear();
273
			setValues();
274
			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
275
		} finally {
276
			updating = false;
277
		}
278
	}
279
280
	private void primSetValues(Object newValue) {
281
		Exception ex = null;
282
		try {
283
			Method writeMethod = descriptor.getWriteMethod();
284
			if (!writeMethod.isAccessible()) {
285
				writeMethod.setAccessible(true);
286
			}
287
			writeMethod.invoke(object, new Object[] { newValue });
288
			return;
289
		} catch (IllegalArgumentException e) {
290
			ex = e;
291
		} catch (IllegalAccessException e) {
292
			ex = e;
293
		} catch (InvocationTargetException e) {
294
			ex = e;
295
		}
296
		throw new BindingException("Could not write collection values", ex); //$NON-NLS-1$
297
	}
298
299
	public Object getObserved() {
300
		return object;
301
	}
302
303
	public PropertyDescriptor getPropertyDescriptor() {
304
		return descriptor;
305
	}
306
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanObservableMapDecorator.java (-119 / +16 lines)
Lines 7-160 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Matthew Hall - initial API and implementation (bug 221704)
9
 *     Matthew Hall - initial API and implementation (bug 221704)
10
 *     Matthew Hall - bug 194734
10
 ******************************************************************************/
11
 ******************************************************************************/
11
12
12
package org.eclipse.core.internal.databinding.beans;
13
package org.eclipse.core.internal.databinding.beans;
13
14
14
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
15
import java.util.Collection;
16
import java.util.Map;
17
import java.util.Set;
18
16
19
import org.eclipse.core.databinding.beans.IBeanObservable;
17
import org.eclipse.core.databinding.beans.IBeanObservable;
20
import org.eclipse.core.databinding.observable.IChangeListener;
18
import org.eclipse.core.databinding.observable.IObservable;
21
import org.eclipse.core.databinding.observable.IStaleListener;
19
import org.eclipse.core.databinding.observable.IObserving;
22
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.map.DecoratingObservableMap;
23
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
24
import org.eclipse.core.databinding.observable.map.IObservableMap;
21
import org.eclipse.core.databinding.observable.map.IObservableMap;
25
import org.eclipse.core.internal.databinding.Util;
26
22
27
/**
23
/**
28
 * {@link IBeanObservable} decorator for an {@link IObservableMap}.
24
 * {@link IBeanObservable} decorator for an {@link IObservableMap}.
29
 * 
25
 * 
30
 * @since 3.3
26
 * @since 3.3
31
 */
27
 */
32
public class BeanObservableMapDecorator implements IObservableMap, IBeanObservable {
28
public class BeanObservableMapDecorator extends DecoratingObservableMap
33
	private IObservableMap delegate;
29
		implements IBeanObservable {
34
	private Object observed;
35
	private PropertyDescriptor propertyDescriptor;
30
	private PropertyDescriptor propertyDescriptor;
36
31
37
	/**
32
	/**
38
	 * @param delegate 
33
	 * @param decorated
39
	 * @param observed 
40
	 * @param propertyDescriptor
34
	 * @param propertyDescriptor
41
	 */
35
	 */
42
	public BeanObservableMapDecorator(IObservableMap delegate,
36
	public BeanObservableMapDecorator(IObservableMap decorated,
43
			Object observed,
44
			PropertyDescriptor propertyDescriptor) {
37
			PropertyDescriptor propertyDescriptor) {
45
		
38
		super(decorated, true);
46
		this.delegate = delegate;
47
		this.observed = observed;
48
		this.propertyDescriptor = propertyDescriptor;
39
		this.propertyDescriptor = propertyDescriptor;
49
	}
40
	}
50
41
51
	public Realm getRealm() {
42
	public void dispose() {
52
		return delegate.getRealm();
43
		this.propertyDescriptor = null;
53
	}
44
		super.dispose();
54
55
	public boolean isStale() {
56
		return delegate.isStale();
57
	}
58
59
	public boolean containsKey(Object key) {
60
		return delegate.containsKey(key);
61
	}
62
63
	public boolean containsValue(Object value) {
64
		return delegate.containsValue(value);
65
	}
66
67
	public Set entrySet() {
68
		return delegate.entrySet();
69
	}
70
71
	public Object get(Object key) {
72
		return delegate.get(key);
73
	}
74
75
	public Set keySet() {
76
		return delegate.keySet();
77
	}
78
79
	public Object put(Object key, Object value) {
80
		return delegate.put(key, value);
81
	}
82
83
	public Object remove(Object key) {
84
		return delegate.remove(key);
85
	}
86
87
	public Collection values() {
88
		return delegate.values();
89
	}
90
91
	public void putAll(Map map) {
92
		delegate.putAll(map);
93
	}
94
95
	public void clear() {
96
		delegate.clear();
97
	}
98
99
	public boolean isEmpty() {
100
		return delegate.isEmpty();
101
	}
102
103
	public int size() {
104
		return delegate.size();
105
	}
45
	}
106
46
107
	public Object getObserved() {
47
	public Object getObserved() {
108
		return observed;
48
		IObservable decorated = getDecorated();
49
		if (decorated instanceof IObserving)
50
			return ((IObserving) decorated).getObserved();
51
		return null;
109
	}
52
	}
110
53
111
	public PropertyDescriptor getPropertyDescriptor() {
54
	public PropertyDescriptor getPropertyDescriptor() {
112
		return propertyDescriptor;
55
		return propertyDescriptor;
113
	}
56
	}
114
115
	/**
116
	 * @return the wrapped map
117
	 */
118
	public IObservableMap getDelegate() {
119
		return delegate;
120
	}	
121
	public void dispose() {
122
		delegate.dispose();
123
	}
124
125
	public void addChangeListener(IChangeListener listener) {
126
		delegate.addChangeListener(listener);
127
	}
128
129
	public void removeChangeListener(IChangeListener listener) {
130
		delegate.removeChangeListener(listener);
131
	}
132
133
	public void addMapChangeListener(IMapChangeListener listener) {
134
		delegate.addMapChangeListener(listener);
135
	}
136
137
	public void removeMapChangeListener(IMapChangeListener listener) {
138
		delegate.removeMapChangeListener(listener);
139
	}
140
141
	public void addStaleListener(IStaleListener listener) {
142
		delegate.addStaleListener(listener);
143
	}
144
145
	public void removeStaleListener(IStaleListener listener) {
146
		delegate.removeStaleListener(listener);
147
	}
148
149
	public boolean equals(Object obj) {
150
		if (obj instanceof BeanObservableMapDecorator) {
151
			BeanObservableMapDecorator other = (BeanObservableMapDecorator) obj;
152
			return Util.equals(other.delegate, delegate);
153
		}
154
		return Util.equals(delegate, obj);
155
	}
156
157
	public int hashCode() {
158
		return delegate.hashCode();
159
	}
160
}
57
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanObservableValueDecorator.java (-94 / +20 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 194734
10
 ******************************************************************************/
11
 ******************************************************************************/
11
12
12
package org.eclipse.core.internal.databinding.beans;
13
package org.eclipse.core.internal.databinding.beans;
Lines 14-131 Link Here
14
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
15
16
16
import org.eclipse.core.databinding.beans.IBeanObservable;
17
import org.eclipse.core.databinding.beans.IBeanObservable;
17
import org.eclipse.core.databinding.observable.IChangeListener;
18
import org.eclipse.core.databinding.observable.IObservable;
18
import org.eclipse.core.databinding.observable.IStaleListener;
19
import org.eclipse.core.databinding.observable.IObserving;
19
import org.eclipse.core.databinding.observable.Realm;
20
import org.eclipse.core.databinding.observable.value.DecoratingObservableValue;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
22
import org.eclipse.core.internal.databinding.Util;
23
22
24
/**
23
/**
25
 * {@link IBeanObservable} decorator for an {@link IObservableValue}.
24
 * {@link IBeanObservable} decorator for an {@link IObservableValue}.
26
 * 
25
 * 
27
 * @since 3.3
26
 * @since 3.3
28
 */
27
 */
29
public class BeanObservableValueDecorator implements IObservableValue,
28
public class BeanObservableValueDecorator extends DecoratingObservableValue
30
		IBeanObservable {
29
		implements IBeanObservable {
31
	private final IObservableValue delegate;
30
	private PropertyDescriptor propertyDescriptor;
32
	private final PropertyDescriptor descriptor;
33
	private final IObservableValue observed;
34
31
35
	/**
32
	/**
36
	 * @param delegate
33
	 * @param decorated
37
	 * @param observed 
34
	 * @param propertyDescriptor
38
	 * @param descriptor
39
	 */
35
	 */
40
	public BeanObservableValueDecorator(IObservableValue delegate, IObservableValue observed,
36
	public BeanObservableValueDecorator(IObservableValue decorated,
41
			PropertyDescriptor descriptor) {
37
			PropertyDescriptor propertyDescriptor) {
42
		this.delegate = delegate;
38
		super(decorated, true);
43
		this.observed = observed;
39
		this.propertyDescriptor = propertyDescriptor;
44
		this.descriptor = descriptor;
45
	}
46
47
	public void addChangeListener(IChangeListener listener) {
48
		delegate.addChangeListener(listener);
49
	}
50
51
	public void addStaleListener(IStaleListener listener) {
52
		delegate.addStaleListener(listener);
53
	}
54
55
	public void addValueChangeListener(IValueChangeListener listener) {
56
		delegate.addValueChangeListener(listener);
57
	}
40
	}
58
41
59
	public void dispose() {
42
	public void dispose() {
60
		delegate.dispose();
43
		this.propertyDescriptor = null;
61
	}
44
		super.dispose();
62
	
63
	public boolean equals(Object obj) {
64
		if (obj instanceof BeanObservableValueDecorator) {
65
			BeanObservableValueDecorator other = (BeanObservableValueDecorator) obj;
66
			return Util.equals(other.delegate, delegate);
67
		}
68
		return Util.equals(delegate, obj);
69
	}
45
	}
70
46
71
	public Realm getRealm() {
72
		return delegate.getRealm();
73
	}
74
75
	public Object getValue() {
76
		return delegate.getValue();
77
	}
78
79
	public Object getValueType() {
80
		return delegate.getValueType();
81
	}
82
	
83
	public int hashCode() {
84
		return delegate.hashCode();
85
	}
86
87
	public boolean isStale() {
88
		return delegate.isStale();
89
	}
90
91
	public void removeChangeListener(IChangeListener listener) {
92
		delegate.removeChangeListener(listener);
93
	}
94
95
	public void removeStaleListener(IStaleListener listener) {
96
		delegate.removeStaleListener(listener);
97
	}
98
99
	public void removeValueChangeListener(IValueChangeListener listener) {
100
		delegate.removeValueChangeListener(listener);
101
	}
102
103
	public void setValue(Object value) {
104
		delegate.setValue(value);
105
	}
106
107
	/*
108
	 * (non-Javadoc)
109
	 * 
110
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getObserved()
111
	 */
112
	public Object getObserved() {
47
	public Object getObserved() {
113
		return observed.getValue();
48
		IObservable decorated = getDecorated();
49
		if (decorated instanceof IObserving)
50
			return ((IObserving) decorated).getObserved();
51
		return null;
114
	}
52
	}
115
53
116
	/*
117
	 * (non-Javadoc)
118
	 * 
119
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getPropertyDescriptor()
120
	 */
121
	public PropertyDescriptor getPropertyDescriptor() {
54
	public PropertyDescriptor getPropertyDescriptor() {
122
		return descriptor;
55
		return propertyDescriptor;
123
	}
124
	
125
	/**
126
	 * @return observable value delegate
127
	 */
128
	public IObservableValue getDelegate() {
129
		return delegate;
130
	}
56
	}
131
}
57
}
(-)src/org/eclipse/core/internal/databinding/beans/JavaBeanObservableValue.java (-190 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 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 164134, 171616
12
 *******************************************************************************/
13
package org.eclipse.core.internal.databinding.beans;
14
15
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyDescriptor;
17
import java.lang.reflect.InvocationTargetException;
18
import java.lang.reflect.Method;
19
20
import org.eclipse.core.databinding.BindingException;
21
import org.eclipse.core.databinding.beans.BeansObservables;
22
import org.eclipse.core.databinding.beans.IBeanObservable;
23
import org.eclipse.core.databinding.observable.Diffs;
24
import org.eclipse.core.databinding.observable.Realm;
25
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
26
import org.eclipse.core.databinding.observable.value.ValueDiff;
27
import org.eclipse.core.databinding.util.Policy;
28
import org.eclipse.core.internal.databinding.Util;
29
import org.eclipse.core.runtime.IStatus;
30
import org.eclipse.core.runtime.Status;
31
32
/**
33
 * @since 1.0
34
 * 
35
 */
36
public class JavaBeanObservableValue extends AbstractObservableValue implements IBeanObservable {
37
	private final Object object;
38
	private boolean updating = false;
39
40
	private final PropertyDescriptor propertyDescriptor;
41
	private ListenerSupport listenerSupport;
42
43
	private boolean attachListeners;
44
45
	/**
46
	 * @param realm
47
	 * @param object
48
	 * @param descriptor
49
	 */
50
	public JavaBeanObservableValue(Realm realm, Object object,
51
			PropertyDescriptor descriptor) {
52
		this(realm, object, descriptor, true);
53
	}
54
55
	/**
56
	 * @param realm
57
	 * @param object
58
	 * @param descriptor
59
	 * @param attachListeners
60
	 */
61
	public JavaBeanObservableValue(Realm realm, Object object,
62
			PropertyDescriptor descriptor, boolean attachListeners) {
63
		super(realm);
64
		this.object = object;
65
		this.propertyDescriptor = descriptor;
66
		this.attachListeners = attachListeners;
67
	}
68
69
	protected void firstListenerAdded() {
70
		if (!attachListeners) {
71
			return;
72
		}
73
			
74
		PropertyChangeListener listener = new PropertyChangeListener() {
75
			public void propertyChange(java.beans.PropertyChangeEvent event) {
76
				if (!updating) {
77
					final ValueDiff diff = Diffs.createValueDiff(event.getOldValue(),
78
											event.getNewValue());
79
					getRealm().exec(new Runnable(){
80
						public void run() {
81
							fireValueChange(diff);
82
						}});
83
				}
84
			}
85
		};
86
		
87
		if (listenerSupport == null) {
88
			listenerSupport = new ListenerSupport(listener, propertyDescriptor.getName());
89
		}
90
		
91
		listenerSupport.hookListener(object);
92
	}
93
94
	public void doSetValue(Object value) {
95
		updating = true;
96
		try {
97
			Object oldValue = doGetValue();
98
			
99
			if (Util.equals(oldValue, value)) {
100
				return;
101
			}
102
			
103
			Method writeMethod = propertyDescriptor.getWriteMethod();
104
			if (!writeMethod.isAccessible()) {
105
				writeMethod.setAccessible(true);
106
			}
107
			writeMethod.invoke(object, new Object[] { value });
108
			fireValueChange(Diffs.createValueDiff(oldValue, doGetValue()));
109
		} catch (InvocationTargetException e) {
110
			/*
111
			 * InvocationTargetException wraps any exception thrown by the
112
			 * invoked method.
113
			 */
114
			throw new RuntimeException(e.getCause());
115
		} catch (Exception e) {
116
			if (BeansObservables.DEBUG) {
117
				Policy
118
						.getLog()
119
						.log(
120
								new Status(
121
										IStatus.WARNING,
122
										Policy.JFACE_DATABINDING,
123
										IStatus.OK,
124
										"Could not change value of " + object + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
125
			}
126
		} finally {
127
			updating = false;
128
		}
129
	}
130
131
	public Object doGetValue() {
132
		try {
133
			Method readMethod = propertyDescriptor.getReadMethod();
134
			if (readMethod == null) {
135
				throw new BindingException(propertyDescriptor.getName()
136
						+ " property does not have a read method."); //$NON-NLS-1$
137
			}
138
			if (!readMethod.isAccessible()) {
139
				readMethod.setAccessible(true);
140
			}
141
			return readMethod.invoke(object, null);
142
		} catch (InvocationTargetException e) {
143
			/*
144
			 * InvocationTargetException wraps any exception thrown by the
145
			 * invoked method.
146
			 */
147
			throw new RuntimeException(e.getCause());
148
		} catch (Exception e) {
149
			if (BeansObservables.DEBUG) {
150
				Policy
151
						.getLog()
152
						.log(
153
								new Status(
154
										IStatus.WARNING,
155
										Policy.JFACE_DATABINDING,
156
										IStatus.OK,
157
										"Could not read value of " + object + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
158
			}
159
			return null;
160
		}
161
	}
162
163
	protected void lastListenerRemoved() {
164
		unhookListener();
165
	}
166
167
	private void unhookListener() {
168
		if (listenerSupport != null) {
169
			listenerSupport.dispose();
170
			listenerSupport = null;
171
		}
172
	}
173
174
	public Object getValueType() {
175
		return propertyDescriptor.getPropertyType();
176
	}
177
178
	public Object getObserved() {
179
		return object;
180
	}
181
182
	public PropertyDescriptor getPropertyDescriptor() {
183
		return propertyDescriptor;
184
	}
185
186
	public synchronized void dispose() {
187
		unhookListener();
188
		super.dispose();
189
	}
190
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanObservableListDecorator.java (-182 / +14 lines)
Lines 7-224 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     Brad Reynolds - initial API and implementation
9
 *     Brad Reynolds - initial API and implementation
10
 *     Matthew Hall - bug 208858
10
 *     Matthew Hall - bugs 208858, 194734
11
 ******************************************************************************/
11
 ******************************************************************************/
12
12
13
package org.eclipse.core.internal.databinding.beans;
13
package org.eclipse.core.internal.databinding.beans;
14
14
15
import java.beans.PropertyDescriptor;
15
import java.beans.PropertyDescriptor;
16
import java.util.Collection;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.ListIterator;
20
16
21
import org.eclipse.core.databinding.beans.IBeanObservable;
17
import org.eclipse.core.databinding.beans.IBeanObservable;
22
import org.eclipse.core.databinding.observable.IStaleListener;
18
import org.eclipse.core.databinding.observable.IObservable;
23
import org.eclipse.core.databinding.observable.ObservableTracker;
19
import org.eclipse.core.databinding.observable.IObserving;
24
import org.eclipse.core.databinding.observable.StaleEvent;
20
import org.eclipse.core.databinding.observable.list.DecoratingObservableList;
25
import org.eclipse.core.databinding.observable.list.AbstractObservableList;
26
import org.eclipse.core.databinding.observable.list.IListChangeListener;
27
import org.eclipse.core.databinding.observable.list.IObservableList;
21
import org.eclipse.core.databinding.observable.list.IObservableList;
28
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
29
import org.eclipse.core.internal.databinding.Util;
30
22
31
/**
23
/**
32
 * {@link IBeanObservable} decorator for an {@link IObservableList}.
24
 * {@link IBeanObservable} decorator for an {@link IObservableList}.
33
 * 
25
 * 
34
 * @since 3.3
26
 * @since 3.3
35
 */
27
 */
36
public class BeanObservableListDecorator extends AbstractObservableList
28
public class BeanObservableListDecorator extends DecoratingObservableList
37
		implements IBeanObservable {
29
		implements IBeanObservable {
38
	private IObservableList delegate;
39
	private IStaleListener delegateStaleListener;
40
	private IListChangeListener delegateListChangeListener;
41
42
	private Object observed;
43
	private PropertyDescriptor propertyDescriptor;
30
	private PropertyDescriptor propertyDescriptor;
44
31
45
	/**
32
	/**
46
	 * @param delegate
33
	 * @param decorated
47
	 * @param observed
48
	 * @param propertyDescriptor
34
	 * @param propertyDescriptor
49
	 */
35
	 */
50
	public BeanObservableListDecorator(IObservableList delegate,
36
	public BeanObservableListDecorator(IObservableList decorated,
51
			Object observed, PropertyDescriptor propertyDescriptor) {
37
			PropertyDescriptor propertyDescriptor) {
52
		super(delegate.getRealm());
38
		super(decorated, true);
53
		this.delegate = delegate;
54
		this.observed = observed;
55
		this.propertyDescriptor = propertyDescriptor;
39
		this.propertyDescriptor = propertyDescriptor;
56
	}
40
	}
57
41
58
	public void add(int index, Object element) {
59
		delegate.add(index, element);
60
	}
61
62
	public boolean add(Object o) {
63
		return delegate.add(o);
64
	}
65
66
	public boolean addAll(Collection c) {
67
		return delegate.addAll(c);
68
	}
69
70
	public boolean addAll(int index, Collection c) {
71
		return delegate.addAll(index, c);
72
	}
73
74
	public void clear() {
75
		delegate.clear();
76
	}
77
78
	public void dispose() {
42
	public void dispose() {
79
		delegate.dispose();
43
		this.propertyDescriptor = null;
80
		super.dispose();
44
		super.dispose();
81
	}
45
	}
82
46
83
	public boolean equals(Object o) {
84
		getterCalled();
85
		if (o instanceof BeanObservableListDecorator) {
86
			BeanObservableListDecorator other = (BeanObservableListDecorator) o;
87
			return Util.equals(other.delegate, delegate);
88
		}
89
		return Util.equals(delegate, o);
90
	}
91
92
	public Object get(int index) {
93
		getterCalled();
94
		return delegate.get(index);
95
	}
96
97
	public Object getElementType() {
98
		return delegate.getElementType();
99
	}
100
101
	public int hashCode() {
102
		getterCalled();
103
		return delegate.hashCode();
104
	}
105
106
	public int indexOf(Object o) {
107
		getterCalled();
108
		return delegate.indexOf(o);
109
	}
110
111
	public Iterator iterator() {
112
		getterCalled();
113
		return delegate.iterator();
114
	}
115
116
	public int lastIndexOf(Object o) {
117
		getterCalled();
118
		return delegate.lastIndexOf(o);
119
	}
120
121
	public ListIterator listIterator() {
122
		getterCalled();
123
		return delegate.listIterator();
124
	}
125
126
	public ListIterator listIterator(int index) {
127
		getterCalled();
128
		return delegate.listIterator(index);
129
	}
130
131
	public Object move(int oldIndex, int newIndex) {
132
		return delegate.move(oldIndex, newIndex);
133
	}
134
135
	public Object remove(int index) {
136
		return delegate.remove(index);
137
	}
138
139
	public boolean remove(Object o) {
140
		return delegate.remove(o);
141
	}
142
143
	public boolean removeAll(Collection c) {
144
		return delegate.removeAll(c);
145
	}
146
147
	public boolean retainAll(Collection c) {
148
		return delegate.retainAll(c);
149
	}
150
151
	public Object set(int index, Object element) {
152
		return delegate.set(index, element);
153
	}
154
155
	protected int doGetSize() {
156
		return delegate.size();
157
	}
158
159
	public List subList(int fromIndex, int toIndex) {
160
		getterCalled();
161
		return delegate.subList(fromIndex, toIndex);
162
	}
163
164
	public Object[] toArray() {
165
		getterCalled();
166
		return delegate.toArray();
167
	}
168
169
	public Object[] toArray(Object[] a) {
170
		return delegate.toArray(a);
171
	}
172
173
	protected void firstListenerAdded() {
174
		delegateStaleListener = new IStaleListener() {
175
			public void handleStale(StaleEvent staleEvent) {
176
				fireStale();
177
			}
178
		};
179
		delegate.addStaleListener(delegateStaleListener);
180
181
		delegateListChangeListener = new IListChangeListener() {
182
			public void handleListChange(ListChangeEvent event) {
183
				fireListChange(event.diff);
184
			}
185
		};
186
		delegate.addListChangeListener(delegateListChangeListener);
187
	}
188
189
	protected void lastListenerRemoved() {
190
		delegate.removeStaleListener(delegateStaleListener);
191
		delegateStaleListener = null;
192
193
		delegate.removeListChangeListener(delegateListChangeListener);
194
		delegateListChangeListener = null;
195
	}
196
197
	private void getterCalled() {
198
		ObservableTracker.getterCalled(this);
199
	}
200
201
	/**
202
	 * @return list being delegated to
203
	 */
204
	public IObservableList getDelegate() {
205
		return delegate;
206
	}
207
208
	/*
209
	 * (non-Javadoc)
210
	 * 
211
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getObserved()
212
	 */
213
	public Object getObserved() {
47
	public Object getObserved() {
214
		return observed;
48
		IObservable decorated = getDecorated();
49
		if (decorated instanceof IObserving)
50
			return ((IObserving) decorated).getObserved();
51
		return null;
215
	}
52
	}
216
53
217
	/*
218
	 * (non-Javadoc)
219
	 * 
220
	 * @see org.eclipse.core.databinding.beans.IBeanObservable#getPropertyDescriptor()
221
	 */
222
	public PropertyDescriptor getPropertyDescriptor() {
54
	public PropertyDescriptor getPropertyDescriptor() {
223
		return propertyDescriptor;
55
		return propertyDescriptor;
224
	}
56
	}
(-)src/org/eclipse/core/databinding/beans/BeansObservables.java (-99 / +46 lines)
Lines 8-24 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brad Reynolds - bugs 164268, 171616, 147515
10
 *     Brad Reynolds - bugs 164268, 171616, 147515
11
 *     Matthew Hall - bug 221704, 234686
11
 *     Matthew Hall - bugs 221704, 234686, 194734
12
 *     Thomas Kratz - bug 213787
12
 *     Thomas Kratz - bug 213787
13
 *******************************************************************************/
13
 *******************************************************************************/
14
package org.eclipse.core.databinding.beans;
14
package org.eclipse.core.databinding.beans;
15
15
16
import java.beans.BeanInfo;
17
import java.beans.IntrospectionException;
18
import java.beans.Introspector;
19
import java.beans.PropertyDescriptor;
16
import java.beans.PropertyDescriptor;
20
17
21
import org.eclipse.core.databinding.BindingException;
22
import org.eclipse.core.databinding.observable.IObservable;
18
import org.eclipse.core.databinding.observable.IObservable;
23
import org.eclipse.core.databinding.observable.Realm;
19
import org.eclipse.core.databinding.observable.Realm;
24
import org.eclipse.core.databinding.observable.list.IObservableList;
20
import org.eclipse.core.databinding.observable.list.IObservableList;
Lines 27-41 Link Here
27
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
23
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
28
import org.eclipse.core.databinding.observable.set.IObservableSet;
24
import org.eclipse.core.databinding.observable.set.IObservableSet;
29
import org.eclipse.core.databinding.observable.value.IObservableValue;
25
import org.eclipse.core.databinding.observable.value.IObservableValue;
26
import org.eclipse.core.databinding.property.IListProperty;
27
import org.eclipse.core.databinding.property.IMapProperty;
28
import org.eclipse.core.databinding.property.ISetProperty;
29
import org.eclipse.core.databinding.property.IValueProperty;
30
import org.eclipse.core.databinding.property.PropertyObservables;
30
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
31
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
31
import org.eclipse.core.internal.databinding.beans.BeanObservableMapDecorator;
32
import org.eclipse.core.internal.databinding.beans.BeanObservableMapDecorator;
32
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
33
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
33
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
34
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
34
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
35
import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
35
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableMap;
36
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
37
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableValue;
38
import org.eclipse.core.internal.databinding.beans.JavaBeanPropertyObservableMap;
39
import org.eclipse.core.runtime.Assert;
36
import org.eclipse.core.runtime.Assert;
40
37
41
/**
38
/**
Lines 83-91 Link Here
83
	 */
80
	 */
84
	public static IObservableValue observeValue(Realm realm, Object bean,
81
	public static IObservableValue observeValue(Realm realm, Object bean,
85
			String propertyName) {
82
			String propertyName) {
86
		PropertyDescriptor descriptor = getPropertyDescriptor(bean.getClass(),
83
		IValueProperty property = BeanProperties.valueProperty(bean.getClass(),
87
				propertyName);
84
				propertyName);
88
		return new JavaBeanObservableValue(realm, bean, descriptor);
85
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
86
				.getPropertyDescriptor();
87
		return new BeanObservableValueDecorator(PropertyObservables
88
				.observeValue(realm, bean, property), propertyDescriptor);
89
	}
89
	}
90
90
91
	/**
91
	/**
Lines 103-111 Link Here
103
	 */
103
	 */
104
	public static IObservableMap observeMap(IObservableSet domain,
104
	public static IObservableMap observeMap(IObservableSet domain,
105
			Class beanClass, String propertyName) {
105
			Class beanClass, String propertyName) {
106
		PropertyDescriptor descriptor = getPropertyDescriptor(beanClass,
106
		IValueProperty property = BeanProperties.valueProperty(beanClass,
107
				propertyName);
107
				propertyName);
108
		return new JavaBeanObservableMap(domain, descriptor);
108
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
109
				.getPropertyDescriptor();
110
		return new BeanObservableMapDecorator(PropertyObservables.observeMap(
111
				domain, property), propertyDescriptor);
109
	}
112
	}
110
113
111
	/**
114
	/**
Lines 124-132 Link Here
124
	 */
127
	 */
125
	public static IObservableMap observeMap(Realm realm, Object bean,
128
	public static IObservableMap observeMap(Realm realm, Object bean,
126
			String propertyName) {
129
			String propertyName) {
127
		PropertyDescriptor descriptor = getPropertyDescriptor(bean.getClass(),
130
		IMapProperty property = BeanProperties.mapProperty(bean.getClass(),
128
				propertyName);
131
				propertyName);
129
		return new JavaBeanPropertyObservableMap(realm, bean, descriptor);
132
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
133
				.getPropertyDescriptor();
134
		return new BeanObservableMapDecorator(PropertyObservables.observeMap(
135
				realm, bean, property), propertyDescriptor);
130
	}
136
	}
131
137
132
	/**
138
	/**
Lines 145-171 Link Here
145
		return observeMap(Realm.getDefault(), bean, propertyName);
151
		return observeMap(Realm.getDefault(), bean, propertyName);
146
	}
152
	}
147
153
148
	/*package*/ static PropertyDescriptor getPropertyDescriptor(Class beanClass,
149
			String propertyName) {
150
		BeanInfo beanInfo;
151
		try {
152
			beanInfo = Introspector.getBeanInfo(beanClass);
153
		} catch (IntrospectionException e) {
154
			// cannot introspect, give up
155
			return null;
156
		}
157
		PropertyDescriptor[] propertyDescriptors = beanInfo
158
				.getPropertyDescriptors();
159
		for (int i = 0; i < propertyDescriptors.length; i++) {
160
			PropertyDescriptor descriptor = propertyDescriptors[i];
161
			if (descriptor.getName().equals(propertyName)) {
162
				return descriptor;
163
			}
164
		}
165
		throw new BindingException(
166
				"Could not find property with name " + propertyName + " in class " + beanClass); //$NON-NLS-1$ //$NON-NLS-2$
167
	}
168
169
	/**
154
	/**
170
	 * Returns an array of observable maps in the default realm tracking the
155
	 * Returns an array of observable maps in the default realm tracking the
171
	 * current values of the named propertys for the beans in the given set.
156
	 * current values of the named propertys for the beans in the given set.
Lines 251-262 Link Here
251
	 */
236
	 */
252
	public static IObservableList observeList(Realm realm, Object bean,
237
	public static IObservableList observeList(Realm realm, Object bean,
253
			String propertyName, Class elementType) {
238
			String propertyName, Class elementType) {
254
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(bean
239
		IListProperty property = BeanProperties.listProperty(bean.getClass(),
255
				.getClass(), propertyName);
240
				propertyName, elementType);
256
		elementType = getCollectionElementType(elementType, propertyDescriptor);
241
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
242
				.getPropertyDescriptor();
257
243
258
		return new JavaBeanObservableList(realm, bean, propertyDescriptor,
244
		return new BeanObservableListDecorator(PropertyObservables.observeList(
259
				elementType);
245
				realm, bean, property), propertyDescriptor);
260
	}
246
	}
261
247
262
	/**
248
	/**
Lines 439-449 Link Here
439
425
440
		IObservableValue value = MasterDetailObservables.detailValue(master,
426
		IObservableValue value = MasterDetailObservables.detailValue(master,
441
				valueFactory(realm, propertyName), propertyType);
427
				valueFactory(realm, propertyName), propertyType);
442
		BeanObservableValueDecorator decorator = new BeanObservableValueDecorator(
428
		return new BeanObservableValueDecorator(value, BeanPropertyHelper
443
				value, master, getValueTypePropertyDescriptor(master,
429
				.getValueTypePropertyDescriptor(master, propertyName));
444
						propertyName));
445
446
		return decorator;
447
	}
430
	}
448
431
449
	/**
432
	/**
Lines 492-506 Link Here
492
	 * @since 1.1
475
	 * @since 1.1
493
	 */
476
	 */
494
	public static IObservableValue observeDetailValue(Realm realm,
477
	public static IObservableValue observeDetailValue(Realm realm,
495
			IObservableValue master, Class masterType, String propertyName, Class propertyType) {
478
			IObservableValue master, Class masterType, String propertyName,
479
			Class propertyType) {
496
		Assert.isNotNull(masterType, "masterType cannot be null"); //$NON-NLS-1$
480
		Assert.isNotNull(masterType, "masterType cannot be null"); //$NON-NLS-1$
497
		IObservableValue value = MasterDetailObservables.detailValue(master,
481
		IObservableValue value = MasterDetailObservables.detailValue(master,
498
				valueFactory(realm, propertyName), propertyType);
482
				valueFactory(realm, propertyName), propertyType);
499
		BeanObservableValueDecorator decorator = new BeanObservableValueDecorator(
483
		return new BeanObservableValueDecorator(value, BeanPropertyHelper
500
				value, master, getPropertyDescriptor(masterType,
484
				.getPropertyDescriptor(masterType, propertyName));
501
						propertyName));
502
503
		return decorator;
504
	}
485
	}
505
486
506
	/**
487
	/**
Lines 551-561 Link Here
551
		IObservableList observableList = MasterDetailObservables.detailList(
532
		IObservableList observableList = MasterDetailObservables.detailList(
552
				master, listFactory(realm, propertyName, propertyType),
533
				master, listFactory(realm, propertyName, propertyType),
553
				propertyType);
534
				propertyType);
554
		BeanObservableListDecorator decorator = new BeanObservableListDecorator(
535
		return new BeanObservableListDecorator(observableList,
555
				observableList, master, getValueTypePropertyDescriptor(master,
536
				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
556
						propertyName));
537
						propertyName));
557
558
		return decorator;
559
	}
538
	}
560
539
561
	/**
540
	/**
Lines 599-609 Link Here
599
		IObservableSet observableSet = MasterDetailObservables.detailSet(
578
		IObservableSet observableSet = MasterDetailObservables.detailSet(
600
				master, setFactory(realm, propertyName, propertyType),
579
				master, setFactory(realm, propertyName, propertyType),
601
				propertyType);
580
				propertyType);
602
		BeanObservableSetDecorator decorator = new BeanObservableSetDecorator(
581
		return new BeanObservableSetDecorator(observableSet, BeanPropertyHelper
603
				observableSet, master, getValueTypePropertyDescriptor(master,
582
				.getValueTypePropertyDescriptor(master, propertyName));
604
						propertyName));
605
606
		return decorator;
607
	}
583
	}
608
584
609
	/**
585
	/**
Lines 642-651 Link Here
642
			IObservableValue master, String propertyName) {
618
			IObservableValue master, String propertyName) {
643
		IObservableMap observableMap = MasterDetailObservables.detailMap(
619
		IObservableMap observableMap = MasterDetailObservables.detailMap(
644
				master, mapPropertyFactory(realm, propertyName));
620
				master, mapPropertyFactory(realm, propertyName));
645
		BeanObservableMapDecorator decorator = new BeanObservableMapDecorator(
621
		return new BeanObservableMapDecorator(observableMap, BeanPropertyHelper
646
				observableMap, master, getValueTypePropertyDescriptor(master,
622
				.getValueTypePropertyDescriptor(master, propertyName));
647
						propertyName));
648
		return decorator;
649
	}
623
	}
650
624
651
	/**
625
	/**
Lines 688-699 Link Here
688
	 */
662
	 */
689
	public static IObservableSet observeSet(Realm realm, Object bean,
663
	public static IObservableSet observeSet(Realm realm, Object bean,
690
			String propertyName, Class elementType) {
664
			String propertyName, Class elementType) {
691
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(bean
665
		ISetProperty property = BeanProperties.setProperty(bean.getClass(),
692
				.getClass(), propertyName);
666
				propertyName, elementType);
693
		elementType = getCollectionElementType(elementType, propertyDescriptor);
667
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
668
				.getPropertyDescriptor();
694
669
695
		return new JavaBeanObservableSet(realm, bean, propertyDescriptor,
670
		return new BeanObservableSetDecorator(PropertyObservables.observeSet(
696
				elementType);
671
				realm, bean, property), propertyDescriptor);
697
	}
672
	}
698
673
699
	/**
674
	/**
Lines 828-859 Link Here
828
	public static IObservableFactory mapPropertyFactory(String propertyName) {
803
	public static IObservableFactory mapPropertyFactory(String propertyName) {
829
		return mapPropertyFactory(Realm.getDefault(), propertyName);
804
		return mapPropertyFactory(Realm.getDefault(), propertyName);
830
	}
805
	}
831
832
	/**
833
	 * @param elementType
834
	 *            can be <code>null</code>
835
	 * @param propertyDescriptor
836
	 * @return type of the items in a collection/array property
837
	 */
838
	/*package*/ static Class getCollectionElementType(Class elementType,
839
			PropertyDescriptor propertyDescriptor) {
840
		if (elementType == null) {
841
			Class propertyType = propertyDescriptor.getPropertyType();
842
			elementType = propertyType.isArray() ? propertyType
843
					.getComponentType() : Object.class;
844
		}
845
846
		return elementType;
847
	}
848
849
	/**
850
	 * @param observable
851
	 * @param propertyName
852
	 * @return property descriptor or <code>null</code>
853
	 */
854
	/* package*/ static PropertyDescriptor getValueTypePropertyDescriptor(
855
			IObservableValue observable, String propertyName) {
856
		return (observable.getValueType() != null) ? getPropertyDescriptor(
857
				(Class) observable.getValueType(), propertyName) : null;
858
	}
859
}
806
}
(-)src/org/eclipse/core/databinding/beans/PojoObservables.java (-49 / +46 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Matthew Hall - bugs 221704, 234686
10
 *     Matthew Hall - bugs 221704, 234686, 194734
11
 *******************************************************************************/
11
 *******************************************************************************/
12
12
13
package org.eclipse.core.databinding.beans;
13
package org.eclipse.core.databinding.beans;
Lines 23-37 Link Here
23
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
23
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
24
import org.eclipse.core.databinding.observable.set.IObservableSet;
24
import org.eclipse.core.databinding.observable.set.IObservableSet;
25
import org.eclipse.core.databinding.observable.value.IObservableValue;
25
import org.eclipse.core.databinding.observable.value.IObservableValue;
26
import org.eclipse.core.databinding.property.IListProperty;
27
import org.eclipse.core.databinding.property.IMapProperty;
28
import org.eclipse.core.databinding.property.ISetProperty;
29
import org.eclipse.core.databinding.property.IValueProperty;
30
import org.eclipse.core.databinding.property.PropertyObservables;
26
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
31
import org.eclipse.core.internal.databinding.beans.BeanObservableListDecorator;
27
import org.eclipse.core.internal.databinding.beans.BeanObservableMapDecorator;
32
import org.eclipse.core.internal.databinding.beans.BeanObservableMapDecorator;
28
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
33
import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
29
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
34
import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
30
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableList;
35
import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
31
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableMap;
32
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableSet;
33
import org.eclipse.core.internal.databinding.beans.JavaBeanObservableValue;
34
import org.eclipse.core.internal.databinding.beans.JavaBeanPropertyObservableMap;
35
36
36
/**
37
/**
37
 * A factory for creating observable objects for POJOs (plain old java objects)
38
 * A factory for creating observable objects for POJOs (plain old java objects)
Lines 73-82 Link Here
73
	 */
74
	 */
74
	public static IObservableValue observeValue(Realm realm, Object pojo,
75
	public static IObservableValue observeValue(Realm realm, Object pojo,
75
			String propertyName) {
76
			String propertyName) {
76
77
		IValueProperty property = PojoProperties.valueProperty(pojo.getClass(),
77
		PropertyDescriptor descriptor = BeansObservables.getPropertyDescriptor(
78
				propertyName);
78
				pojo.getClass(), propertyName);
79
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
79
		return new JavaBeanObservableValue(realm, pojo, descriptor, false);
80
				.getPropertyDescriptor();
81
		return new BeanObservableValueDecorator(PropertyObservables
82
				.observeValue(realm, pojo, property), propertyDescriptor);
80
	}
83
	}
81
84
82
	/**
85
	/**
Lines 94-102 Link Here
94
	 */
97
	 */
95
	public static IObservableMap observeMap(IObservableSet domain,
98
	public static IObservableMap observeMap(IObservableSet domain,
96
			Class pojoClass, String propertyName) {
99
			Class pojoClass, String propertyName) {
97
		PropertyDescriptor descriptor = BeansObservables.getPropertyDescriptor(
100
		IValueProperty property = PojoProperties.valueProperty(pojoClass,
98
				pojoClass, propertyName);
101
				propertyName);
99
		return new JavaBeanObservableMap(domain, descriptor, false);
102
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
103
				.getPropertyDescriptor();
104
		return new BeanObservableMapDecorator(PropertyObservables.observeMap(
105
				domain, property), propertyDescriptor);
100
	}
106
	}
101
107
102
	/**
108
	/**
Lines 136-144 Link Here
136
	 */
142
	 */
137
	public static IObservableMap observeMap(Realm realm, Object pojo,
143
	public static IObservableMap observeMap(Realm realm, Object pojo,
138
			String propertyName) {
144
			String propertyName) {
139
		PropertyDescriptor descriptor = BeansObservables.getPropertyDescriptor(
145
		IMapProperty property = PojoProperties.mapProperty(pojo.getClass(),
140
				pojo.getClass(), propertyName);
146
				propertyName);
141
		return new JavaBeanPropertyObservableMap(realm, pojo, descriptor, false);
147
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
148
				.getPropertyDescriptor();
149
		return new BeanObservableMapDecorator(PropertyObservables.observeMap(
150
				realm, pojo, property), propertyDescriptor);
142
	}
151
	}
143
152
144
	/**
153
	/**
Lines 220-232 Link Here
220
	 */
229
	 */
221
	public static IObservableList observeList(Realm realm, Object pojo,
230
	public static IObservableList observeList(Realm realm, Object pojo,
222
			String propertyName, Class elementType) {
231
			String propertyName, Class elementType) {
223
		PropertyDescriptor propertyDescriptor = BeansObservables
232
		IListProperty property = PojoProperties.listProperty(pojo.getClass(),
224
				.getPropertyDescriptor(pojo.getClass(), propertyName);
233
				propertyName, elementType);
225
		elementType = BeansObservables.getCollectionElementType(elementType,
234
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
226
				propertyDescriptor);
235
				.getPropertyDescriptor();
227
236
		return new BeanObservableListDecorator(PropertyObservables.observeList(
228
		return new JavaBeanObservableList(realm, pojo, propertyDescriptor,
237
				realm, pojo, property), propertyDescriptor);
229
				elementType, false);
230
	}
238
	}
231
239
232
	/**
240
	/**
Lines 310-322 Link Here
310
	 */
318
	 */
311
	public static IObservableSet observeSet(Realm realm, Object pojo,
319
	public static IObservableSet observeSet(Realm realm, Object pojo,
312
			String propertyName, Class elementType) {
320
			String propertyName, Class elementType) {
313
		PropertyDescriptor propertyDescriptor = BeansObservables
321
		ISetProperty property = PojoProperties.setProperty(pojo.getClass(),
314
				.getPropertyDescriptor(pojo.getClass(), propertyName);
322
				propertyName, elementType);
315
		elementType = BeansObservables.getCollectionElementType(elementType,
323
		PropertyDescriptor propertyDescriptor = ((IBeanProperty) property)
316
				propertyDescriptor);
324
				.getPropertyDescriptor();
317
325
		return new BeanObservableSetDecorator(PropertyObservables.observeSet(
318
		return new JavaBeanObservableSet(realm, pojo, propertyDescriptor,
326
				realm, pojo, property), propertyDescriptor);
319
				elementType, false);
320
	}
327
	}
321
328
322
	/**
329
	/**
Lines 540-550 Link Here
540
547
541
		IObservableValue value = MasterDetailObservables.detailValue(master,
548
		IObservableValue value = MasterDetailObservables.detailValue(master,
542
				valueFactory(realm, propertyName), propertyType);
549
				valueFactory(realm, propertyName), propertyType);
543
		BeanObservableValueDecorator decorator = new BeanObservableValueDecorator(
550
		return new BeanObservableValueDecorator(value, BeanPropertyHelper
544
				value, master, BeansObservables.getValueTypePropertyDescriptor(
551
				.getValueTypePropertyDescriptor(master, propertyName));
545
						master, propertyName));
546
547
		return decorator;
548
	}
552
	}
549
553
550
	/**
554
	/**
Lines 587-597 Link Here
587
		IObservableList observableList = MasterDetailObservables.detailList(
591
		IObservableList observableList = MasterDetailObservables.detailList(
588
				master, listFactory(realm, propertyName, propertyType),
592
				master, listFactory(realm, propertyName, propertyType),
589
				propertyType);
593
				propertyType);
590
		BeanObservableListDecorator decorator = new BeanObservableListDecorator(
594
		return new BeanObservableListDecorator(observableList,
591
				observableList, master, BeansObservables
595
				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
592
						.getValueTypePropertyDescriptor(master, propertyName));
596
						propertyName));
593
594
		return decorator;
595
	}
597
	}
596
598
597
	/**
599
	/**
Lines 635-645 Link Here
635
		IObservableSet observableSet = MasterDetailObservables.detailSet(
637
		IObservableSet observableSet = MasterDetailObservables.detailSet(
636
				master, setFactory(realm, propertyName, propertyType),
638
				master, setFactory(realm, propertyName, propertyType),
637
				propertyType);
639
				propertyType);
638
		BeanObservableSetDecorator decorator = new BeanObservableSetDecorator(
640
		return new BeanObservableSetDecorator(observableSet, BeanPropertyHelper
639
				observableSet, master, BeansObservables
641
				.getValueTypePropertyDescriptor(master, propertyName));
640
						.getValueTypePropertyDescriptor(master, propertyName));
641
642
		return decorator;
643
	}
642
	}
644
643
645
	/**
644
	/**
Lines 676-685 Link Here
676
			IObservableValue master, String propertyName) {
675
			IObservableValue master, String propertyName) {
677
		IObservableMap observableMap = MasterDetailObservables.detailMap(
676
		IObservableMap observableMap = MasterDetailObservables.detailMap(
678
				master, mapPropertyFactory(realm, propertyName));
677
				master, mapPropertyFactory(realm, propertyName));
679
		BeanObservableMapDecorator decorator = new BeanObservableMapDecorator(
678
		return new BeanObservableMapDecorator(observableMap, BeanPropertyHelper
680
				observableMap, master, BeansObservables
679
				.getValueTypePropertyDescriptor(master, propertyName));
681
						.getValueTypePropertyDescriptor(master, propertyName));
682
		return decorator;
683
	}
680
	}
684
681
685
	/**
682
	/**
(-)src/org/eclipse/core/databinding/beans/IBeanProperty.java (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.beans;
13
14
import java.beans.PropertyDescriptor;
15
16
import org.eclipse.core.databinding.property.IProperty;
17
18
/**
19
 * @since 1.2
20
 * 
21
 */
22
public interface IBeanProperty extends IProperty {
23
	/**
24
	 * @return property descriptor for the bean property
25
	 */
26
	public PropertyDescriptor getPropertyDescriptor();
27
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanMapProperty.java (+138 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.beans;
13
14
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyDescriptor;
17
import java.util.Collections;
18
import java.util.HashMap;
19
import java.util.Map;
20
21
import org.eclipse.core.databinding.beans.IBeanProperty;
22
import org.eclipse.core.databinding.observable.Diffs;
23
import org.eclipse.core.databinding.observable.map.MapDiff;
24
import org.eclipse.core.databinding.property.BasicMapProperty;
25
26
/**
27
 * @since 3.3
28
 * 
29
 */
30
public class BeanMapProperty extends BasicMapProperty implements IBeanProperty {
31
	private PropertyDescriptor propertyDescriptor;
32
	private boolean attachListener;
33
34
	private ListenerSupport listenerSupport;
35
36
	private Map sourceToCachedMap = Collections.synchronizedMap(new HashMap());
37
38
	/**
39
	 * @param propertyDescriptor
40
	 * @param attachListener
41
	 */
42
	public BeanMapProperty(PropertyDescriptor propertyDescriptor,
43
			boolean attachListener) {
44
		this.propertyDescriptor = propertyDescriptor;
45
		this.attachListener = attachListener;
46
	}
47
48
	private void initListenerSupport() {
49
		if (listenerSupport == null) {
50
			synchronized (this) {
51
				if (listenerSupport == null) {
52
					PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
53
						public void propertyChange(PropertyChangeEvent evt) {
54
							Object source = evt.getSource();
55
							if (!isUpdating(source)) {
56
								Object oldValue = evt.getOldValue();
57
								Object newValue = evt.getNewValue();
58
								if (oldValue == null && newValue == null) {
59
									// Obscure condition indicating new and old
60
									// values are unknown
61
									oldValue = sourceToCachedMap.get(source);
62
									newValue = BeanPropertyHelper.getProperty(
63
											source, propertyDescriptor);
64
								}
65
								sourceToCachedMap.put(source, newValue);
66
								fireMapChange(source, Diffs.computeMapDiff(
67
										asMap(oldValue), asMap(newValue)));
68
							}
69
						}
70
					};
71
					listenerSupport = new ListenerSupport(
72
							propertyChangeListener, propertyDescriptor
73
									.getName());
74
				}
75
			}
76
		}
77
	}
78
79
	protected void addListenerTo(Object source) {
80
		if (source != null && attachListener) {
81
			initListenerSupport();
82
			listenerSupport.hookListener(source);
83
			sourceToCachedMap.put(source, BeanPropertyHelper.getProperty(
84
					source, propertyDescriptor));
85
		}
86
	}
87
88
	protected void removeListenerFrom(Object source) {
89
		if (source != null && attachListener && listenerSupport != null) {
90
			listenerSupport.unhookListener(source);
91
			sourceToCachedMap.remove(source);
92
		}
93
	}
94
95
	public Map getMap(Object source) {
96
		if (source == null)
97
			return Collections.EMPTY_MAP;
98
		Object propertyValue = BeanPropertyHelper.getProperty(source,
99
				propertyDescriptor);
100
		return asMap(propertyValue);
101
	}
102
103
	private Map asMap(Object propertyValue) {
104
		if (propertyValue == null)
105
			return new HashMap();
106
		return (Map) propertyValue;
107
	}
108
109
	protected void setMap(Object source, Map map, MapDiff diff) {
110
		if (source == null)
111
			return;
112
113
		super.setMap(source, map, diff);
114
		sourceToCachedMap.put(source, map);
115
	}
116
117
	protected void doSetMap(Object source, Map map) {
118
		BeanPropertyHelper.setProperty(source, propertyDescriptor, map);
119
	}
120
121
	public synchronized void dispose() {
122
		propertyDescriptor = null;
123
		attachListener = false;
124
		if (listenerSupport != null) {
125
			listenerSupport.dispose();
126
			listenerSupport = null;
127
		}
128
		if (sourceToCachedMap != null) {
129
			sourceToCachedMap.clear();
130
			sourceToCachedMap = null;
131
		}
132
		super.dispose();
133
	}
134
135
	public PropertyDescriptor getPropertyDescriptor() {
136
		return propertyDescriptor;
137
	}
138
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanValueProperty.java (+137 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.beans;
13
14
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyDescriptor;
17
import java.util.Collections;
18
import java.util.HashMap;
19
import java.util.Map;
20
21
import org.eclipse.core.databinding.beans.IBeanProperty;
22
import org.eclipse.core.databinding.observable.Diffs;
23
import org.eclipse.core.databinding.property.BasicValueProperty;
24
25
/**
26
 * @since 3.3
27
 * 
28
 */
29
public class BeanValueProperty extends BasicValueProperty implements
30
		IBeanProperty {
31
	private PropertyDescriptor propertyDescriptor;
32
	private Class valueType;
33
	private boolean attachListener;
34
35
	private ListenerSupport listenerSupport;
36
37
	private Map sourceToCachedValue = Collections
38
			.synchronizedMap(new HashMap());
39
40
	/**
41
	 * @param propertyDescriptor
42
	 * @param valueType
43
	 * @param attachListener
44
	 */
45
	public BeanValueProperty(PropertyDescriptor propertyDescriptor,
46
			Class valueType, boolean attachListener) {
47
		this.propertyDescriptor = propertyDescriptor;
48
		this.valueType = valueType == null ? propertyDescriptor
49
				.getPropertyType() : valueType;
50
		this.attachListener = attachListener;
51
	}
52
53
	private void initListenerSupport() {
54
		if (listenerSupport == null) {
55
			synchronized (this) {
56
				if (listenerSupport == null) {
57
					PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
58
						public void propertyChange(PropertyChangeEvent evt) {
59
							Object source = evt.getSource();
60
							if (!isUpdating(source)) {
61
								Object oldValue = evt.getOldValue();
62
								Object newValue = evt.getNewValue();
63
								if (oldValue == null && newValue == null) {
64
									// Obscure condition indicating new and old
65
									// values are unknown
66
									oldValue = sourceToCachedValue.get(source);
67
									newValue = getValue(source);
68
								}
69
								sourceToCachedValue.put(source, newValue);
70
								fireValueChange(source, Diffs.createValueDiff(
71
										oldValue, newValue));
72
							}
73
						}
74
					};
75
					listenerSupport = new ListenerSupport(
76
							propertyChangeListener, propertyDescriptor
77
									.getName());
78
				}
79
			}
80
		}
81
	}
82
83
	protected void addListenerTo(Object source) {
84
		if (source != null && attachListener) {
85
			initListenerSupport();
86
			listenerSupport.hookListener(source);
87
			sourceToCachedValue.put(source, getValue(source));
88
		}
89
	}
90
91
	protected void removeListenerFrom(Object source) {
92
		if (source != null && attachListener && listenerSupport != null) {
93
			listenerSupport.unhookListener(source);
94
			sourceToCachedValue.remove(source);
95
		}
96
	}
97
98
	public Object getValue(Object source) {
99
		if (source == null)
100
			return null;
101
		return BeanPropertyHelper.getProperty(source, propertyDescriptor);
102
	}
103
104
	public void setValue(Object source, Object value) {
105
		if (source == null)
106
			return;
107
		super.setValue(source, value);
108
		sourceToCachedValue.put(source, getValue(source));
109
	}
110
111
	protected void doSetValue(Object source, Object value) {
112
		BeanPropertyHelper.setProperty(source, propertyDescriptor, value);
113
	}
114
115
	public Object getValueType() {
116
		return valueType;
117
	}
118
119
	public PropertyDescriptor getPropertyDescriptor() {
120
		return propertyDescriptor;
121
	}
122
123
	public synchronized void dispose() {
124
		propertyDescriptor = null;
125
		valueType = null;
126
		attachListener = false;
127
		if (listenerSupport != null) {
128
			listenerSupport.dispose();
129
			listenerSupport = null;
130
		}
131
		if (sourceToCachedValue != null) {
132
			sourceToCachedValue.clear();
133
			sourceToCachedValue = null;
134
		}
135
		super.dispose();
136
	}
137
}
(-)src/org/eclipse/core/databinding/beans/PojoProperties.java (+109 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.beans;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IMapProperty;
16
import org.eclipse.core.databinding.property.ISetProperty;
17
import org.eclipse.core.databinding.property.IValueProperty;
18
import org.eclipse.core.internal.databinding.beans.BeanListProperty;
19
import org.eclipse.core.internal.databinding.beans.BeanMapProperty;
20
import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
21
import org.eclipse.core.internal.databinding.beans.BeanSetProperty;
22
import org.eclipse.core.internal.databinding.beans.BeanValueProperty;
23
24
/**
25
 * @since 1.2
26
 */
27
public class PojoProperties {
28
	/**
29
	 * @param beanClass
30
	 * @param propertyName
31
	 * @return a value property for the given property name of the given bean
32
	 *         class.
33
	 */
34
	public static IValueProperty valueProperty(Class beanClass,
35
			String propertyName) {
36
		return valueProperty(beanClass, propertyName, null);
37
	}
38
39
	/**
40
	 * @param beanClass
41
	 * @param propertyName
42
	 * @param valueType
43
	 * @return a value property for the given property name of the given bean
44
	 *         class.
45
	 */
46
	public static IValueProperty valueProperty(Class beanClass,
47
			String propertyName, Class valueType) {
48
		return new BeanValueProperty(BeanPropertyHelper.getPropertyDescriptor(
49
				beanClass, propertyName), valueType, false);
50
	}
51
52
	/**
53
	 * @param beanClass
54
	 * @param propertyName
55
	 * @return a list property for the given property name of the given bean
56
	 *         class.
57
	 */
58
	public static ISetProperty setProperty(Class beanClass, String propertyName) {
59
		return setProperty(beanClass, propertyName, null);
60
	}
61
62
	/**
63
	 * @param beanClass
64
	 * @param propertyName
65
	 * @param elementType
66
	 * @return a list property for the given property name of the given bean
67
	 *         class.
68
	 */
69
	public static ISetProperty setProperty(Class beanClass,
70
			String propertyName, Class elementType) {
71
		return new BeanSetProperty(BeanPropertyHelper.getPropertyDescriptor(
72
				beanClass, propertyName), elementType, false);
73
	}
74
75
	/**
76
	 * @param beanClass
77
	 * @param propertyName
78
	 * @return a list property for the given property name of the given bean
79
	 *         class.
80
	 */
81
	public static IListProperty listProperty(Class beanClass,
82
			String propertyName) {
83
		return listProperty(beanClass, propertyName, null);
84
	}
85
86
	/**
87
	 * @param beanClass
88
	 * @param propertyName
89
	 * @param elementType
90
	 * @return a list property for the given property name of the given bean
91
	 *         class.
92
	 */
93
	public static IListProperty listProperty(Class beanClass,
94
			String propertyName, Class elementType) {
95
		return new BeanListProperty(BeanPropertyHelper.getPropertyDescriptor(
96
				beanClass, propertyName), elementType, false);
97
	}
98
99
	/**
100
	 * @param beanClass
101
	 * @param propertyName
102
	 * @return a map property for the given property name of the given bean
103
	 *         class.
104
	 */
105
	public static IMapProperty mapProperty(Class beanClass, String propertyName) {
106
		return new BeanMapProperty(BeanPropertyHelper.getPropertyDescriptor(
107
				beanClass, propertyName), false);
108
	}
109
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanListProperty.java (+169 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.beans;
13
14
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyDescriptor;
17
import java.lang.reflect.Array;
18
import java.util.ArrayList;
19
import java.util.Arrays;
20
import java.util.Collections;
21
import java.util.HashMap;
22
import java.util.List;
23
import java.util.Map;
24
25
import org.eclipse.core.databinding.beans.IBeanProperty;
26
import org.eclipse.core.databinding.observable.Diffs;
27
import org.eclipse.core.databinding.observable.list.ListDiff;
28
import org.eclipse.core.databinding.property.BasicListProperty;
29
30
/**
31
 * @since 3.3
32
 * 
33
 */
34
public class BeanListProperty extends BasicListProperty implements
35
		IBeanProperty {
36
	private PropertyDescriptor propertyDescriptor;
37
	private Class elementType;
38
	private boolean attachListener;
39
40
	private ListenerSupport listenerSupport;
41
42
	private Map sourceToCachedList = Collections.synchronizedMap(new HashMap());
43
44
	/**
45
	 * @param propertyDescriptor
46
	 * @param elementType
47
	 * @param attachListener
48
	 */
49
	public BeanListProperty(PropertyDescriptor propertyDescriptor,
50
			Class elementType, boolean attachListener) {
51
		this.propertyDescriptor = propertyDescriptor;
52
		this.elementType = elementType == null ? BeanPropertyHelper
53
				.getCollectionPropertyElementType(propertyDescriptor)
54
				: elementType;
55
		this.attachListener = attachListener;
56
	}
57
58
	private void initListenerSupport() {
59
		if (listenerSupport == null) {
60
			synchronized (this) {
61
				if (listenerSupport == null) {
62
					PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
63
						public void propertyChange(PropertyChangeEvent evt) {
64
							Object source = evt.getSource();
65
							if (!isUpdating(source)) {
66
								Object oldValue = evt.getOldValue();
67
								Object newValue = evt.getNewValue();
68
								if (oldValue == null && newValue == null) {
69
									// Obscure condition indicating new and old
70
									// values are unknown
71
									oldValue = sourceToCachedList.get(source);
72
									newValue = BeanPropertyHelper.getProperty(
73
											source, propertyDescriptor);
74
								}
75
								sourceToCachedList.put(source, newValue);
76
								fireListChange(source, Diffs.computeListDiff(
77
										asList(oldValue), asList(newValue)));
78
							}
79
						}
80
					};
81
					listenerSupport = new ListenerSupport(
82
							propertyChangeListener, propertyDescriptor
83
									.getName());
84
				}
85
			}
86
		}
87
	}
88
89
	protected void addListenerTo(Object source) {
90
		if (source != null && attachListener) {
91
			initListenerSupport();
92
			listenerSupport.hookListener(source);
93
			sourceToCachedList.put(source, BeanPropertyHelper.getProperty(
94
					source, propertyDescriptor));
95
		}
96
	}
97
98
	protected void removeListenerFrom(Object source) {
99
		if (source != null && attachListener && listenerSupport != null) {
100
			listenerSupport.unhookListener(source);
101
			sourceToCachedList.remove(source);
102
		}
103
	}
104
105
	public List getList(Object source) {
106
		if (source == null)
107
			return Collections.EMPTY_LIST;
108
		Object propertyValue = BeanPropertyHelper.getProperty(source,
109
				propertyDescriptor);
110
		return asList(propertyValue);
111
	}
112
113
	private List asList(Object propertyValue) {
114
		if (propertyValue == null)
115
			return new ArrayList();
116
		if (propertyDescriptor.getPropertyType().isArray())
117
			return new ArrayList(Arrays.asList((Object[]) propertyValue));
118
		return (List) propertyValue;
119
	}
120
121
	protected void setList(Object source, List list, ListDiff diff) {
122
		if (source == null)
123
			return;
124
125
		super.setList(source, list, diff);
126
		sourceToCachedList.put(source, list);
127
	}
128
129
	protected void doSetList(Object source, List list) {
130
		BeanPropertyHelper.setProperty(source, propertyDescriptor,
131
				convertListToBeanPropertyType(list));
132
	}
133
134
	private Object convertListToBeanPropertyType(List list) {
135
		Object propertyValue = list;
136
		if (propertyDescriptor.getPropertyType().isArray()) {
137
			Class componentType = propertyDescriptor.getPropertyType()
138
					.getComponentType();
139
			Object[] array = (Object[]) Array.newInstance(componentType, list
140
					.size());
141
			list.toArray(array);
142
			propertyValue = array;
143
		}
144
		return propertyValue;
145
	}
146
147
	public Object getElementType() {
148
		return elementType;
149
	}
150
151
	public PropertyDescriptor getPropertyDescriptor() {
152
		return propertyDescriptor;
153
	}
154
155
	public synchronized void dispose() {
156
		propertyDescriptor = null;
157
		elementType = null;
158
		attachListener = false;
159
		if (listenerSupport != null) {
160
			listenerSupport.dispose();
161
			listenerSupport = null;
162
		}
163
		if (sourceToCachedList != null) {
164
			sourceToCachedList.clear();
165
			sourceToCachedList = null;
166
		}
167
		super.dispose();
168
	}
169
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanSetProperty.java (+167 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.beans;
13
14
import java.beans.PropertyChangeEvent;
15
import java.beans.PropertyChangeListener;
16
import java.beans.PropertyDescriptor;
17
import java.lang.reflect.Array;
18
import java.util.Arrays;
19
import java.util.Collections;
20
import java.util.HashMap;
21
import java.util.HashSet;
22
import java.util.Map;
23
import java.util.Set;
24
25
import org.eclipse.core.databinding.beans.IBeanProperty;
26
import org.eclipse.core.databinding.observable.Diffs;
27
import org.eclipse.core.databinding.observable.set.SetDiff;
28
import org.eclipse.core.databinding.property.BasicSetProperty;
29
30
/**
31
 * @since 3.3
32
 * 
33
 */
34
public class BeanSetProperty extends BasicSetProperty implements IBeanProperty {
35
	private PropertyDescriptor propertyDescriptor;
36
	private Class elementType;
37
	private boolean attachListener;
38
39
	private ListenerSupport listenerSupport;
40
41
	private Map sourceToCachedSet = Collections.synchronizedMap(new HashMap());
42
43
	/**
44
	 * @param propertyDescriptor
45
	 * @param elementType
46
	 * @param attachListener
47
	 */
48
	public BeanSetProperty(PropertyDescriptor propertyDescriptor,
49
			Class elementType, boolean attachListener) {
50
		this.propertyDescriptor = propertyDescriptor;
51
		this.elementType = elementType == null ? BeanPropertyHelper
52
				.getCollectionPropertyElementType(propertyDescriptor)
53
				: elementType;
54
		this.attachListener = attachListener;
55
	}
56
57
	private void initListenerSupport() {
58
		if (listenerSupport == null) {
59
			synchronized (this) {
60
				if (listenerSupport == null) {
61
					PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
62
						public void propertyChange(PropertyChangeEvent evt) {
63
							Object source = evt.getSource();
64
							if (!isUpdating(source)) {
65
								Object oldValue = evt.getOldValue();
66
								Object newValue = evt.getNewValue();
67
								if (oldValue == null && newValue == null) {
68
									// Obscure condition indicating new and old
69
									// values are unknown
70
									oldValue = sourceToCachedSet.get(source);
71
									newValue = BeanPropertyHelper.getProperty(
72
											source, propertyDescriptor);
73
								}
74
								sourceToCachedSet.put(source, newValue);
75
								fireSetChange(source, Diffs.computeSetDiff(
76
										asSet(oldValue), asSet(newValue)));
77
							}
78
						}
79
					};
80
					listenerSupport = new ListenerSupport(
81
							propertyChangeListener, propertyDescriptor
82
									.getName());
83
				}
84
			}
85
		}
86
	}
87
88
	protected void addListenerTo(Object source) {
89
		if (source != null && attachListener) {
90
			initListenerSupport();
91
			listenerSupport.hookListener(source);
92
			sourceToCachedSet.put(source, BeanPropertyHelper.getProperty(
93
					source, propertyDescriptor));
94
		}
95
	}
96
97
	protected void removeListenerFrom(Object source) {
98
		if (source != null && attachListener && listenerSupport != null) {
99
			listenerSupport.unhookListener(source);
100
			sourceToCachedSet.remove(source);
101
		}
102
	}
103
104
	public Set getSet(Object source) {
105
		if (source == null)
106
			return Collections.EMPTY_SET;
107
		Object propertyValue = BeanPropertyHelper.getProperty(source,
108
				propertyDescriptor);
109
		return asSet(propertyValue);
110
	}
111
112
	private Set asSet(Object propertyValue) {
113
		if (propertyValue == null)
114
			return Collections.EMPTY_SET;
115
		if (propertyDescriptor.getPropertyType().isArray())
116
			return new HashSet(Arrays.asList((Object[]) propertyValue));
117
		return (Set) propertyValue;
118
	}
119
120
	protected void setSet(Object source, Set set, SetDiff diff) {
121
		if (source == null)
122
			return;
123
		super.setSet(source, set, diff);
124
		sourceToCachedSet.put(source, set);
125
	}
126
127
	protected void doSetSet(Object source, Set set) {
128
		BeanPropertyHelper.setProperty(source, propertyDescriptor,
129
				convertSetToBeanPropertyType(set));
130
	}
131
132
	private Object convertSetToBeanPropertyType(Set set) {
133
		Object propertyValue = set;
134
		if (propertyDescriptor.getPropertyType().isArray()) {
135
			Class componentType = propertyDescriptor.getPropertyType()
136
					.getComponentType();
137
			Object[] array = (Object[]) Array.newInstance(componentType, set
138
					.size());
139
			set.toArray(array);
140
			propertyValue = array;
141
		}
142
		return propertyValue;
143
	}
144
145
	public Object getElementType() {
146
		return elementType;
147
	}
148
149
	public PropertyDescriptor getPropertyDescriptor() {
150
		return propertyDescriptor;
151
	}
152
153
	public synchronized void dispose() {
154
		propertyDescriptor = null;
155
		elementType = null;
156
		attachListener = false;
157
		if (listenerSupport != null) {
158
			listenerSupport.dispose();
159
			listenerSupport = null;
160
		}
161
		if (sourceToCachedSet != null) {
162
			sourceToCachedSet.clear();
163
			sourceToCachedSet = null;
164
		}
165
		super.dispose();
166
	}
167
}
(-)src/org/eclipse/core/databinding/beans/BeanProperties.java (+110 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.beans;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IMapProperty;
16
import org.eclipse.core.databinding.property.ISetProperty;
17
import org.eclipse.core.databinding.property.IValueProperty;
18
import org.eclipse.core.internal.databinding.beans.BeanListProperty;
19
import org.eclipse.core.internal.databinding.beans.BeanMapProperty;
20
import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
21
import org.eclipse.core.internal.databinding.beans.BeanSetProperty;
22
import org.eclipse.core.internal.databinding.beans.BeanValueProperty;
23
24
/**
25
 * @since 1.2
26
 * 
27
 */
28
public class BeanProperties {
29
	/**
30
	 * @param beanClass
31
	 * @param propertyName
32
	 * @return a value property for the given property name of the given bean
33
	 *         class.
34
	 */
35
	public static IValueProperty valueProperty(Class beanClass,
36
			String propertyName) {
37
		return valueProperty(beanClass, propertyName, null);
38
	}
39
40
	/**
41
	 * @param beanClass
42
	 * @param propertyName
43
	 * @param valueType
44
	 * @return a value property for the given property name of the given bean
45
	 *         class.
46
	 */
47
	public static IValueProperty valueProperty(Class beanClass,
48
			String propertyName, Class valueType) {
49
		return new BeanValueProperty(BeanPropertyHelper.getPropertyDescriptor(
50
				beanClass, propertyName), valueType, true);
51
	}
52
53
	/**
54
	 * @param beanClass
55
	 * @param propertyName
56
	 * @return a list property for the given property name of the given bean
57
	 *         class.
58
	 */
59
	public static ISetProperty setProperty(Class beanClass, String propertyName) {
60
		return setProperty(beanClass, propertyName, null);
61
	}
62
63
	/**
64
	 * @param beanClass
65
	 * @param propertyName
66
	 * @param elementType
67
	 * @return a list property for the given property name of the given bean
68
	 *         class.
69
	 */
70
	public static ISetProperty setProperty(Class beanClass,
71
			String propertyName, Class elementType) {
72
		return new BeanSetProperty(BeanPropertyHelper.getPropertyDescriptor(
73
				beanClass, propertyName), elementType, true);
74
	}
75
76
	/**
77
	 * @param beanClass
78
	 * @param propertyName
79
	 * @return a list property for the given property name of the given bean
80
	 *         class.
81
	 */
82
	public static IListProperty listProperty(Class beanClass,
83
			String propertyName) {
84
		return listProperty(beanClass, propertyName, null);
85
	}
86
87
	/**
88
	 * @param beanClass
89
	 * @param propertyName
90
	 * @param elementType
91
	 * @return a list property for the given property name of the given bean
92
	 *         class.
93
	 */
94
	public static IListProperty listProperty(Class beanClass,
95
			String propertyName, Class elementType) {
96
		return new BeanListProperty(BeanPropertyHelper.getPropertyDescriptor(
97
				beanClass, propertyName), elementType, true);
98
	}
99
100
	/**
101
	 * @param beanClass
102
	 * @param propertyName
103
	 * @return a map property for the given property name of the given bean
104
	 *         class.
105
	 */
106
	public static IMapProperty mapProperty(Class beanClass, String propertyName) {
107
		return new BeanMapProperty(BeanPropertyHelper.getPropertyDescriptor(
108
				beanClass, propertyName), true);
109
	}
110
}
(-)src/org/eclipse/core/internal/databinding/beans/BeanPropertyHelper.java (+169 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.beans;
13
14
import java.beans.BeanInfo;
15
import java.beans.IntrospectionException;
16
import java.beans.Introspector;
17
import java.beans.PropertyDescriptor;
18
import java.lang.reflect.InvocationTargetException;
19
import java.lang.reflect.Method;
20
21
import org.eclipse.core.databinding.BindingException;
22
import org.eclipse.core.databinding.beans.BeansObservables;
23
import org.eclipse.core.databinding.observable.value.IObservableValue;
24
import org.eclipse.core.databinding.util.Policy;
25
import org.eclipse.core.runtime.IStatus;
26
import org.eclipse.core.runtime.Status;
27
28
/**
29
 * @since 1.2
30
 * 
31
 */
32
public class BeanPropertyHelper {
33
	/**
34
	 * Sets the contents of the given property on the given source object to the
35
	 * given value.
36
	 * 
37
	 * @param source
38
	 *            the source object which has the property being updated
39
	 * @param propertyDescriptor
40
	 *            the property being changed
41
	 * @param value
42
	 *            the new value of the property
43
	 */
44
	public static void setProperty(Object source,
45
			PropertyDescriptor propertyDescriptor, Object value) {
46
		try {
47
			Method writeMethod = propertyDescriptor.getWriteMethod();
48
			if (!writeMethod.isAccessible()) {
49
				writeMethod.setAccessible(true);
50
			}
51
			writeMethod.invoke(source, new Object[] { value });
52
		} catch (InvocationTargetException e) {
53
			/*
54
			 * InvocationTargetException wraps any exception thrown by the
55
			 * invoked method.
56
			 */
57
			throw new RuntimeException(e.getCause());
58
		} catch (Exception e) {
59
			if (BeansObservables.DEBUG) {
60
				Policy
61
						.getLog()
62
						.log(
63
								new Status(
64
										IStatus.WARNING,
65
										Policy.JFACE_DATABINDING,
66
										IStatus.OK,
67
										"Could not change value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
68
			}
69
		}
70
	}
71
72
	/**
73
	 * Returns the contents of the given property for the given bean.
74
	 * 
75
	 * @param source
76
	 *            the source bean
77
	 * @param propertyDescriptor
78
	 *            the property to retrieve
79
	 * @return the contents of the given property for the given bean.
80
	 */
81
	public static Object getProperty(Object source,
82
			PropertyDescriptor propertyDescriptor) {
83
		try {
84
			Method readMethod = propertyDescriptor.getReadMethod();
85
			if (readMethod == null) {
86
				throw new BindingException(propertyDescriptor.getName()
87
						+ " property does not have a read method."); //$NON-NLS-1$
88
			}
89
			if (!readMethod.isAccessible()) {
90
				readMethod.setAccessible(true);
91
			}
92
			return readMethod.invoke(source, null);
93
		} catch (InvocationTargetException e) {
94
			/*
95
			 * InvocationTargetException wraps any exception thrown by the
96
			 * invoked method.
97
			 */
98
			throw new RuntimeException(e.getCause());
99
		} catch (Exception e) {
100
			if (BeansObservables.DEBUG) {
101
				Policy
102
						.getLog()
103
						.log(
104
								new Status(
105
										IStatus.WARNING,
106
										Policy.JFACE_DATABINDING,
107
										IStatus.OK,
108
										"Could not read value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
109
			}
110
			return null;
111
		}
112
	}
113
114
	/**
115
	 * Returns the element type of the given collection-typed property for the
116
	 * given bean.
117
	 * 
118
	 * @param descriptor
119
	 *            the property being inspected
120
	 * @return the element type of the given collection-typed property if it is
121
	 *         an array property, or Object.class otherwise.
122
	 */
123
	public static Class getCollectionPropertyElementType(
124
			PropertyDescriptor descriptor) {
125
		Class propertyType = descriptor.getPropertyType();
126
		return propertyType.isArray() ? propertyType.getComponentType()
127
				: Object.class;
128
	}
129
130
	/**
131
	 * @param beanClass
132
	 * @param propertyName
133
	 * @return the PropertyDescriptor for the named property on the given bean
134
	 *         class
135
	 */
136
	public static PropertyDescriptor getPropertyDescriptor(Class beanClass,
137
			String propertyName) {
138
		BeanInfo beanInfo;
139
		try {
140
			beanInfo = Introspector.getBeanInfo(beanClass);
141
		} catch (IntrospectionException e) {
142
			// cannot introspect, give up
143
			return null;
144
		}
145
		PropertyDescriptor[] propertyDescriptors = beanInfo
146
				.getPropertyDescriptors();
147
		for (int i = 0; i < propertyDescriptors.length; i++) {
148
			PropertyDescriptor descriptor = propertyDescriptors[i];
149
			if (descriptor.getName().equals(propertyName)) {
150
				return descriptor;
151
			}
152
		}
153
		throw new BindingException(
154
				"Could not find property with name " + propertyName + " in class " + beanClass); //$NON-NLS-1$ //$NON-NLS-2$
155
	}
156
157
	/**
158
	 * @param observable
159
	 * @param propertyName
160
	 * @return property descriptor or <code>null</code>
161
	 */
162
	/* package */public static PropertyDescriptor getValueTypePropertyDescriptor(
163
			IObservableValue observable, String propertyName) {
164
		if (observable.getValueType() != null)
165
			return getPropertyDescriptor((Class) observable.getValueType(),
166
					propertyName);
167
		return null;
168
	}
169
}
(-)src/org/eclipse/core/databinding/observable/map/ComputedObservableMap.java (-5 / +37 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Matthew Hall - bug 241585
10
 *     Matthew Hall - bugs 241585, 194734
11
 *******************************************************************************/
11
 *******************************************************************************/
12
12
13
package org.eclipse.core.databinding.observable.map;
13
package org.eclipse.core.databinding.observable.map;
Lines 31-37 Link Here
31
 */
31
 */
32
public abstract class ComputedObservableMap extends AbstractObservableMap {
32
public abstract class ComputedObservableMap extends AbstractObservableMap {
33
33
34
	private final IObservableSet keySet;
34
	private IObservableSet keySet;
35
35
36
	private ISetChangeListener setChangeListener = new ISetChangeListener() {
36
	private ISetChangeListener setChangeListener = new ISetChangeListener() {
37
		public void handleSetChange(SetChangeEvent event) {
37
		public void handleSetChange(SetChangeEvent event) {
Lines 109-118 Link Here
109
		this.keySet.addSetChangeListener(setChangeListener);
109
		this.keySet.addSetChangeListener(setChangeListener);
110
	}
110
	}
111
111
112
	/**
113
     * @deprecated Subclasses are no longer required to call this method.
114
     */
112
	protected void init() {
115
	protected void init() {
113
		for (Iterator it = this.keySet.iterator(); it.hasNext();) {
116
	}
114
			Object key = it.next();
117
115
			hookListener(key);
118
	protected void firstListenerAdded() {
119
		hookListeners();
120
	}
121
122
	protected void lastListenerRemoved() {
123
		unhookListeners();
124
	}
125
126
	private void hookListeners() {
127
		if (keySet != null) {
128
			for (Iterator it = this.keySet.iterator(); it.hasNext();) {
129
				Object key = it.next();
130
				hookListener(key);
131
			}
132
		}
133
	}
134
135
	private void unhookListeners() {
136
		if (keySet != null) {
137
			Object[] keys = keySet.toArray();
138
			for (int i = 0; i < keys.length; i++) {
139
				unhookListener(keys[i]);
140
			}
141
			keySet = null;
116
		}
142
		}
117
	}
143
	}
118
144
Lines 163-166 Link Here
163
	 * @return the old value for the given key
189
	 * @return the old value for the given key
164
	 */
190
	 */
165
	protected abstract Object doPut(Object key, Object value);
191
	protected abstract Object doPut(Object key, Object value);
192
193
	public void dispose() {
194
		unhookListeners();
195
		entrySet = null;
196
		super.dispose();
197
	}
166
}
198
}
(-)src/org/eclipse/core/databinding/observable/list/AbstractObservableList.java (-11 / +20 lines)
Lines 7-17 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Brad Reynolds - bug 164653
10
 *     Brad Reynolds - bugs 164653, 167204
11
 *     Brad Reynolds - bug 167204
11
 *     Matthew Hall - bugs 118516, 208858, 208332, 194734
12
 *     Matthew Hall - bug 118516
13
 *     Matthew Hall - bug 208858
14
 *     Matthew Hall - bug 208332
15
 *******************************************************************************/
12
 *******************************************************************************/
16
13
17
package org.eclipse.core.databinding.observable.list;
14
package org.eclipse.core.databinding.observable.list;
Lines 76-86 Link Here
76
	}
73
	}
77
74
78
	public synchronized void addListChangeListener(IListChangeListener listener) {
75
	public synchronized void addListChangeListener(IListChangeListener listener) {
79
		changeSupport.addListener(ListChangeEvent.TYPE, listener);
76
		if (changeSupport != null) {
77
			changeSupport.addListener(ListChangeEvent.TYPE, listener);
78
		}
80
	}
79
	}
81
80
82
	public synchronized void removeListChangeListener(IListChangeListener listener) {
81
	public synchronized void removeListChangeListener(IListChangeListener listener) {
83
		changeSupport.removeListener(ListChangeEvent.TYPE, listener);
82
		if (changeSupport != null) {
83
			changeSupport.removeListener(ListChangeEvent.TYPE, listener);
84
		}
84
	}
85
	}
85
86
86
	protected void fireListChange(ListDiff diff) {
87
	protected void fireListChange(ListDiff diff) {
Lines 90-108 Link Here
90
	}
91
	}
91
92
92
	public synchronized void addChangeListener(IChangeListener listener) {
93
	public synchronized void addChangeListener(IChangeListener listener) {
93
		changeSupport.addChangeListener(listener);
94
		if (changeSupport != null) {
95
			changeSupport.addChangeListener(listener);
96
		}
94
	}
97
	}
95
98
96
	public synchronized void removeChangeListener(IChangeListener listener) {
99
	public synchronized void removeChangeListener(IChangeListener listener) {
97
		changeSupport.removeChangeListener(listener);
100
		if (changeSupport != null) {
101
			changeSupport.removeChangeListener(listener);
102
		}
98
	}
103
	}
99
104
100
	public synchronized void addStaleListener(IStaleListener listener) {
105
	public synchronized void addStaleListener(IStaleListener listener) {
101
		changeSupport.addStaleListener(listener);
106
		if (changeSupport != null) {
107
			changeSupport.addStaleListener(listener);
108
		}
102
	}
109
	}
103
110
104
	public synchronized void removeStaleListener(IStaleListener listener) {
111
	public synchronized void removeStaleListener(IStaleListener listener) {
105
		changeSupport.removeStaleListener(listener);
112
		if (changeSupport != null) {
113
			changeSupport.removeStaleListener(listener);
114
		}
106
	}
115
	}
107
116
108
	/**
117
	/**
(-)META-INF/MANIFEST.MF (+4 lines)
Lines 14-19 Link Here
14
 org.eclipse.core.databinding.observable.masterdetail,
14
 org.eclipse.core.databinding.observable.masterdetail,
15
 org.eclipse.core.databinding.observable.set;x-internal:=false,
15
 org.eclipse.core.databinding.observable.set;x-internal:=false,
16
 org.eclipse.core.databinding.observable.value;x-internal:=false,
16
 org.eclipse.core.databinding.observable.value;x-internal:=false,
17
 org.eclipse.core.databinding.property,
18
 org.eclipse.core.databinding.property.masterdetail,
17
 org.eclipse.core.databinding.util,
19
 org.eclipse.core.databinding.util,
18
 org.eclipse.core.databinding.validation;x-internal:=false,
20
 org.eclipse.core.databinding.validation;x-internal:=false,
19
 org.eclipse.core.internal.databinding;x-friends:="org.eclipse.core.databinding.beans",
21
 org.eclipse.core.internal.databinding;x-friends:="org.eclipse.core.databinding.beans",
Lines 21-26 Link Here
21
 org.eclipse.core.internal.databinding.observable;x-internal:=true,
23
 org.eclipse.core.internal.databinding.observable;x-internal:=true,
22
 org.eclipse.core.internal.databinding.observable.masterdetail;x-friends:="org.eclipse.jface.tests.databinding",
24
 org.eclipse.core.internal.databinding.observable.masterdetail;x-friends:="org.eclipse.jface.tests.databinding",
23
 org.eclipse.core.internal.databinding.observable.tree;x-friends:="org.eclipse.jface.databinding,org.eclipse.jface.tests.databinding",
25
 org.eclipse.core.internal.databinding.observable.tree;x-friends:="org.eclipse.jface.databinding,org.eclipse.jface.tests.databinding",
26
 org.eclipse.core.internal.databinding.property;x-friends:="org.eclipse.jface.databinding,org.eclipse.jface.tests.databinding",
27
 org.eclipse.core.internal.databinding.property.masterdetail;x-friends:="org.eclipse.jface.databinding,org.eclipse.jface.tests.databinding",
24
 org.eclipse.core.internal.databinding.validation;x-friends:="org.eclipse.jface.tests.databinding"
28
 org.eclipse.core.internal.databinding.validation;x-friends:="org.eclipse.jface.tests.databinding"
25
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.2.0,4.0.0)"
29
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.2.0,4.0.0)"
26
Import-Package-Comment: see http://wiki.eclipse.org/
30
Import-Package-Comment: see http://wiki.eclipse.org/
(-)src/org/eclipse/core/databinding/property/IListProperty.java (+105 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
import java.util.List;
16
17
/**
18
 * @since 1.2
19
 * 
20
 */
21
public interface IListProperty extends ICollectionProperty {
22
	/**
23
	 * @param source
24
	 * @return a List with the current contents of the source's list property
25
	 */
26
	List getList(Object source);
27
28
	/**
29
	 * @param source
30
	 * @param index
31
	 * @param c
32
	 * @return whether the source's list property was changed
33
	 */
34
	boolean addAll(Object source, int index, Collection c);
35
36
	/**
37
	 * @param source
38
	 * @param index
39
	 * @return the element at the given location in the source's list property
40
	 */
41
	Object get(Object source, int index);
42
43
	/**
44
	 * @param source
45
	 * @param index
46
	 * @param element
47
	 * @return the element previous at the given location in the source's list
48
	 *         property
49
	 */
50
	Object set(Object source, int index, Object element);
51
52
	/**
53
	 * @param source
54
	 * @param oldIndex
55
	 * @param newIndex
56
	 * @return the element that was moved
57
	 */
58
	Object move(Object source, int oldIndex, int newIndex);
59
60
	/**
61
	 * @param source
62
	 * @param index
63
	 * @param element
64
	 */
65
	void add(Object source, int index, Object element);
66
67
	/**
68
	 * @param source
69
	 * @param index
70
	 * @return the element that was removed from the source's list property
71
	 */
72
	Object remove(Object source, int index);
73
74
	/**
75
	 * @param source
76
	 * @param o
77
	 * @return the index of the first location of the given element in the
78
	 *         source's list property, or -1 if the list does not contain the
79
	 *         element
80
	 */
81
	int indexOf(Object source, Object o);
82
83
	/**
84
	 * @param source
85
	 * @param o
86
	 * @return the index of the last location of the given element in the
87
	 *         source's list property, or -1 if the list does not contain the
88
	 *         element
89
	 */
90
	int lastIndexOf(Object source, Object o);
91
92
	/**
93
	 * @param source
94
	 * @param listener
95
	 */
96
	public void addListChangeListener(Object source,
97
			IListPropertyChangeListener listener);
98
99
	/**
100
	 * @param source
101
	 * @param listener
102
	 */
103
	public void removeListChangeListener(Object source,
104
			IListPropertyChangeListener listener);
105
}
(-)src/org/eclipse/core/databinding/property/BasicMapProperty.java (+119 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collections;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.Map;
19
import java.util.Set;
20
21
import org.eclipse.core.databinding.observable.Diffs;
22
import org.eclipse.core.databinding.observable.map.MapDiff;
23
import org.eclipse.core.internal.databinding.property.PropertyUpdateHelper;
24
25
/**
26
 * @since 1.2
27
 */
28
public abstract class BasicMapProperty extends MapProperty {
29
	private PropertyUpdateHelper updateHelper = new PropertyUpdateHelper();
30
31
	protected boolean isUpdating(Object source) {
32
		return updateHelper.isUpdating(source);
33
	}
34
35
	protected void setMap(Object source, Map map, MapDiff diff) {
36
		if (diff == null) {
37
			diff = Diffs.computeMapDiff(getMap(source), map);
38
		}
39
40
		updateHelper.setUpdating(source, true);
41
		try {
42
			doSetMap(source, map);
43
		} finally {
44
			updateHelper.setUpdating(source, false);
45
		}
46
47
		if (hasListeners(source)) {
48
			fireMapChange(source, diff);
49
		}
50
	}
51
52
	public void clear(Object source) {
53
		setMap(source, new HashMap(), Diffs.createMapDiffRemoveAll(new HashMap(
54
				getMap(source))));
55
	}
56
57
	public Object put(Object source, Object key, Object value) {
58
		Map map = new HashMap(getMap(source));
59
		boolean addition = !map.containsKey(key);
60
		Object result = map.put(key, value);
61
		MapDiff diff;
62
		if (addition) {
63
			diff = Diffs.createMapDiffSingleAdd(key, value);
64
		} else {
65
			diff = Diffs.createMapDiffSingleChange(key, result, value);
66
		}
67
		setMap(source, map, diff);
68
		return result;
69
	}
70
71
	public void putAll(Object source, Map t) {
72
		Map map = new HashMap(getMap(source));
73
		Set addedKeys = new HashSet();
74
		Set changedKeys = new HashSet();
75
		Map oldValues = new HashMap();
76
		Map newValues = new HashMap();
77
		for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
78
			Map.Entry entry = (Map.Entry) it.next();
79
			Object key = entry.getKey();
80
			Object newValue = entry.getValue();
81
			boolean addition = !map.containsKey(key);
82
			Object oldValue = map.put(key, newValue);
83
			if (addition) {
84
				addedKeys.add(key);
85
			} else {
86
				changedKeys.add(key);
87
				oldValues.put(key, oldValue);
88
			}
89
			newValues.put(key, newValue);
90
		}
91
		setMap(source, map, Diffs.createMapDiff(addedKeys,
92
				Collections.EMPTY_SET, changedKeys, oldValues, newValues));
93
	}
94
95
	public Object remove(Object source, Object key) {
96
		Map map = getMap(source);
97
		if (map.containsKey(key)) {
98
			map = new HashMap(map);
99
			Object result = map.remove(key);
100
			setMap(source, map, Diffs.createMapDiffSingleRemove(key, result));
101
			return result;
102
		}
103
		return null;
104
	}
105
106
	public int size(Object source) {
107
		return getMap(source).size();
108
	}
109
110
	protected abstract void doSetMap(Object source, Map map);
111
112
	public synchronized void dispose() {
113
		if (updateHelper != null) {
114
			updateHelper.dispose();
115
			updateHelper = null;
116
		}
117
		super.dispose();
118
	}
119
}
(-)src/org/eclipse/core/databinding/property/ISetProperty.java (+39 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Set;
15
16
/**
17
 * @since 1.2
18
 */
19
public interface ISetProperty extends ICollectionProperty {
20
	/**
21
	 * @param source
22
	 * @return a Set with the current contents of the source's set property
23
	 */
24
	public Set getSet(Object source);
25
26
	/**
27
	 * @param source
28
	 * @param listener
29
	 */
30
	public void addSetChangeListener(Object source,
31
			ISetPropertyChangeListener listener);
32
33
	/**
34
	 * @param source
35
	 * @param listener
36
	 */
37
	public void removeSetChangeListener(Object source,
38
			ISetPropertyChangeListener listener);
39
}
(-)src/org/eclipse/core/databinding/property/ObservableProperties.java (+55 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.list.IObservableList;
15
import org.eclipse.core.databinding.observable.map.IObservableMap;
16
import org.eclipse.core.databinding.observable.set.IObservableSet;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
19
/**
20
 * @since 1.2
21
 * 
22
 */
23
public class ObservableProperties {
24
	/**
25
	 * @param observable
26
	 * @return blah
27
	 */
28
	public static IValueProperty detailValue(IObservableValue observable) {
29
		return null;
30
	}
31
32
	/**
33
	 * @param observable
34
	 * @return blah
35
	 */
36
	public static ISetProperty detailSet(IObservableSet observable) {
37
		return null;
38
	}
39
40
	/**
41
	 * @param observable
42
	 * @return blah
43
	 */
44
	public static IListProperty detailList(IObservableList observable) {
45
		return null;
46
	}
47
48
	/**
49
	 * @param observable
50
	 * @return blah
51
	 */
52
	public static IMapProperty detailMap(IObservableMap observable) {
53
		return null;
54
	}
55
}
(-)src/org/eclipse/core/databinding/property/ValuePropertyChangeEvent.java (+52 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.value.ValueDiff;
15
import org.eclipse.core.runtime.Assert;
16
17
/**
18
 * @since 1.2
19
 * 
20
 */
21
public class ValuePropertyChangeEvent extends PropertyChangeEvent {
22
	private static final long serialVersionUID = 1L;
23
24
	/**
25
	 * 
26
	 */
27
	public final IValueProperty property;
28
29
	/**
30
	 * ValueDiff with the old and new values of the property. May be null to
31
	 * indicate that the details of the value change are unknown.
32
	 */
33
	public final ValueDiff diff;
34
35
	/**
36
	 * @param source
37
	 * @param property
38
	 * @param diff
39
	 */
40
	public ValuePropertyChangeEvent(Object source, IValueProperty property,
41
			ValueDiff diff) {
42
		super(source);
43
		this.property = property;
44
		Assert.isNotNull(diff, "diff cannot be null"); //$NON-NLS-1$
45
		this.diff = diff;
46
	}
47
48
	void dispatch(IPropertyChangeListener listener) {
49
		((IValuePropertyChangeListener) listener)
50
				.handleValuePropertyChange(this);
51
	}
52
}
(-)src/org/eclipse/core/databinding/property/MapProperty.java (+62 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.map.MapDiff;
15
16
/**
17
 * @since 1.2
18
 */
19
public abstract class MapProperty extends Property implements IMapProperty {
20
	public boolean containsKey(Object source, Object key) {
21
		return getMap(source).containsKey(key);
22
	}
23
24
	public boolean containsValue(Object source, Object value) {
25
		return getMap(source).containsValue(value);
26
	}
27
28
	public boolean equals(Object source, Object o) {
29
		return getMap(source).equals(o);
30
	}
31
32
	public Object get(Object source, Object key) {
33
		return getMap(source).get(key);
34
	}
35
36
	public int hashCode(Object source) {
37
		return getMap(source).hashCode();
38
	}
39
40
	public boolean isEmpty(Object source) {
41
		return getMap(source).isEmpty();
42
	}
43
44
	public int size(Object source) {
45
		return getMap(source).size();
46
	}
47
48
	public final void addMapChangeListener(Object source,
49
			IMapPropertyChangeListener listener) {
50
		getChangeSupport().addListener(source, listener);
51
	}
52
53
	public final void removeMapChangeListener(Object source,
54
			IMapPropertyChangeListener listener) {
55
		getChangeSupport().removeListener(source, listener);
56
	}
57
58
	protected final void fireMapChange(Object source, MapDiff diff) {
59
		getChangeSupport().firePropertyChange(
60
				new MapPropertyChangeEvent(source, this, diff));
61
	}
62
}
(-)src/org/eclipse/core/databinding/property/ListProperty.java (+53 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
16
import org.eclipse.core.databinding.observable.list.ListDiff;
17
18
/**
19
 * @since 1.2
20
 */
21
public abstract class ListProperty extends CollectionProperty implements
22
		IListProperty {
23
	Collection getCollection(Object source) {
24
		return getList(source);
25
	}
26
27
	public Object get(Object source, int index) {
28
		return getList(source).get(index);
29
	}
30
31
	public int indexOf(Object source, Object o) {
32
		return getList(source).indexOf(o);
33
	}
34
35
	public int lastIndexOf(Object source, Object o) {
36
		return getList(source).lastIndexOf(o);
37
	}
38
39
	public final void addListChangeListener(Object source,
40
			IListPropertyChangeListener listener) {
41
		getChangeSupport().addListener(source, listener);
42
	}
43
44
	public final void removeListChangeListener(Object source,
45
			IListPropertyChangeListener listener) {
46
		getChangeSupport().removeListener(source, listener);
47
	}
48
49
	protected final void fireListChange(Object source, ListDiff diff) {
50
		getChangeSupport().firePropertyChange(
51
				new ListPropertyChangeEvent(source, this, diff));
52
	}
53
}
(-)src/org/eclipse/core/internal/databinding/property/PropertyObservableMap.java (+177 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.Map;
17
import java.util.Set;
18
19
import org.eclipse.core.databinding.observable.ObservableTracker;
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.map.AbstractObservableMap;
22
import org.eclipse.core.databinding.property.IMapProperty;
23
import org.eclipse.core.databinding.property.IMapPropertyChangeListener;
24
import org.eclipse.core.databinding.property.IProperty;
25
import org.eclipse.core.databinding.property.IPropertyObservable;
26
import org.eclipse.core.databinding.property.MapPropertyChangeEvent;
27
28
/**
29
 * @since 3.3
30
 * 
31
 */
32
public class PropertyObservableMap extends AbstractObservableMap implements
33
		IPropertyObservable {
34
	private Object source;
35
	private IMapProperty property;
36
37
	private volatile boolean updating = false;
38
39
	private boolean disposed = false;
40
41
	private transient volatile int modCount = 0;
42
43
	private IMapPropertyChangeListener listener = new IMapPropertyChangeListener() {
44
		public void handleMapPropertyChange(final MapPropertyChangeEvent event) {
45
			if (!disposed && !updating) {
46
				getRealm().exec(new Runnable() {
47
					public void run() {
48
						getRealm().exec(new Runnable() {
49
							public void run() {
50
								modCount++;
51
								fireMapChange(event.diff);
52
							}
53
						});
54
					}
55
				});
56
			}
57
		}
58
	};
59
60
	/**
61
	 * @param realm
62
	 * @param source
63
	 * @param property
64
	 */
65
	public PropertyObservableMap(Realm realm, Object source,
66
			IMapProperty property) {
67
		super(realm);
68
		this.source = source;
69
		this.property = property;
70
	}
71
72
	private void getterCalled() {
73
		ObservableTracker.getterCalled(this);
74
	}
75
76
	protected void firstListenerAdded() {
77
		if (!disposed) {
78
			property.addMapChangeListener(source, listener);
79
		}
80
	}
81
82
	protected void lastListenerRemoved() {
83
		if (!disposed) {
84
			property.removeMapChangeListener(source, listener);
85
		}
86
	}
87
88
	public boolean containsKey(Object key) {
89
		getterCalled();
90
		return property.containsKey(source, key);
91
	}
92
93
	public boolean containsValue(Object value) {
94
		getterCalled();
95
		return property.containsValue(source, value);
96
	}
97
98
	public Set entrySet() {
99
		getterCalled();
100
		// unmodifiable for now
101
		return Collections.unmodifiableSet(property.getMap(source).entrySet());
102
	}
103
104
	public Object get(Object key) {
105
		getterCalled();
106
		return property.get(source, key);
107
	}
108
109
	public boolean isEmpty() {
110
		getterCalled();
111
		return property.isEmpty(source);
112
	}
113
114
	public Set keySet() {
115
		getterCalled();
116
		return Collections.unmodifiableSet(property.getMap(source).keySet());
117
	}
118
119
	public Object put(Object key, Object value) {
120
		checkRealm();
121
		return property.put(source, key, value);
122
	}
123
124
	public void putAll(Map m) {
125
		checkRealm();
126
		property.putAll(source, m);
127
	}
128
129
	public Object remove(Object key) {
130
		checkRealm();
131
		return property.remove(source, key);
132
	}
133
134
	public int size() {
135
		getterCalled();
136
		return property.size(source);
137
	}
138
139
	public Collection values() {
140
		getterCalled();
141
		return Collections.unmodifiableCollection(property.getMap(source)
142
				.values());
143
	}
144
145
	public void clear() {
146
		getterCalled();
147
		property.clear(source);
148
	}
149
150
	public boolean equals(Object o) {
151
		getterCalled();
152
		return property.equals(source, o);
153
	}
154
155
	public int hashCode() {
156
		getterCalled();
157
		return property.hashCode(source);
158
	}
159
160
	public Object getObserved() {
161
		return source;
162
	}
163
164
	public IProperty getProperty() {
165
		return property;
166
	}
167
168
	public synchronized void dispose() {
169
		if (!disposed) {
170
			disposed = true;
171
			property.removeMapChangeListener(source, listener);
172
			property = null;
173
			source = null;
174
		}
175
		super.dispose();
176
	}
177
}
(-)src/org/eclipse/core/databinding/property/SetPropertyChangeEvent.java (+50 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.set.SetDiff;
15
import org.eclipse.core.runtime.Assert;
16
17
/**
18
 * @since 1.2
19
 */
20
public class SetPropertyChangeEvent extends PropertyChangeEvent {
21
	private static final long serialVersionUID = 1L;
22
23
	/**
24
	 * 
25
	 */
26
	public final ISetProperty property;
27
28
	/**
29
	 * SetDiff enumerating the added and removed elements in the set. May be
30
	 * null to indicate that the details of the set change are unknown.
31
	 */
32
	public final SetDiff diff;
33
34
	/**
35
	 * @param source
36
	 * @param property
37
	 * @param diff
38
	 */
39
	public SetPropertyChangeEvent(Object source, ISetProperty property,
40
			SetDiff diff) {
41
		super(source);
42
		this.property = property;
43
		Assert.isNotNull(diff, "diff cannot be null"); //$NON-NLS-1$
44
		this.diff = diff;
45
	}
46
47
	void dispatch(IPropertyChangeListener listener) {
48
		((ISetPropertyChangeListener) listener).handleSetPropertyChange(this);
49
	}
50
}
(-)src/org/eclipse/core/databinding/property/IValueProperty.java (+49 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 * 
17
 */
18
public interface IValueProperty extends IProperty {
19
	/**
20
	 * @param source
21
	 * @return the property value
22
	 */
23
	public Object getValue(Object source);
24
25
	/**
26
	 * @param source
27
	 * @param value
28
	 */
29
	public void setValue(Object source, Object value);
30
31
	/**
32
	 * @return the value type of the property, or <code>null</code> if untyped.
33
	 */
34
	public Object getValueType();
35
36
	/**
37
	 * @param source
38
	 * @param listener
39
	 */
40
	public void addValueChangeListener(Object source,
41
			IValuePropertyChangeListener listener);
42
43
	/**
44
	 * @param source
45
	 * @param listener
46
	 */
47
	public void removeValueChangeListener(Object source,
48
			IValuePropertyChangeListener listener);
49
}
(-)src/org/eclipse/core/databinding/property/IMapProperty.java (+116 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Map;
15
16
/**
17
 * @since 1.2
18
 */
19
public interface IMapProperty extends IProperty {
20
	/**
21
	 * @param source
22
	 * @return a Map with the current contents of the source's map property
23
	 */
24
	Map getMap(Object source);
25
26
	/**
27
	 * @param source
28
	 * @return the size of the source's map property
29
	 */
30
	int size(Object source);
31
32
	/**
33
	 * @param source
34
	 * @return whether the source's map property is empty
35
	 */
36
	boolean isEmpty(Object source);
37
38
	/**
39
	 * @param source
40
	 * @param key
41
	 * @return whether the given key is contained in the key set of the source's
42
	 *         map property
43
	 */
44
	boolean containsKey(Object source, Object key);
45
46
	/**
47
	 * @param source
48
	 * @param value
49
	 * @return whether the given value is contains in the values collection of
50
	 *         the source's map property
51
	 */
52
	boolean containsValue(Object source, Object value);
53
54
	/**
55
	 * @param source
56
	 * @param key
57
	 * @return the value associated with the given key in the source's map
58
	 *         property
59
	 */
60
	Object get(Object source, Object key);
61
62
	/**
63
	 * @param source
64
	 * @param key
65
	 * @param value
66
	 * @return the value that was previously associated with the given key in
67
	 *         the source's map property
68
	 */
69
	Object put(Object source, Object key, Object value);
70
71
	/**
72
	 * @param source
73
	 * @param key
74
	 * @return the value that was previously associated with the given key in
75
	 *         the source's map property
76
	 */
77
	Object remove(Object source, Object key);
78
79
	/**
80
	 * @param source
81
	 * @param t
82
	 */
83
	void putAll(Object source, Map t);
84
85
	/**
86
	 * @param source
87
	 */
88
	void clear(Object source);
89
90
	/**
91
	 * @param source
92
	 * @param o
93
	 * @return whether the source's map property is equal to the argument
94
	 */
95
	boolean equals(Object source, Object o);
96
97
	/**
98
	 * @param source
99
	 * @return the hash code of the source's map property
100
	 */
101
	int hashCode(Object source);
102
103
	/**
104
	 * @param source
105
	 * @param listener
106
	 */
107
	public void addMapChangeListener(Object source,
108
			IMapPropertyChangeListener listener);
109
110
	/**
111
	 * @param source
112
	 * @param listener
113
	 */
114
	public void removeMapChangeListener(Object source,
115
			IMapPropertyChangeListener listener);
116
}
(-)src/org/eclipse/core/databinding/property/IMapPropertyChangeListener.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 */
17
public interface IMapPropertyChangeListener extends IPropertyChangeListener {
18
	/**
19
	 * @param event
20
	 */
21
	public void handleMapPropertyChange(MapPropertyChangeEvent event);
22
}
(-)src/org/eclipse/core/databinding/property/ValueProperty.java (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.value.ValueDiff;
15
16
/**
17
 * @since 1.2
18
 */
19
public abstract class ValueProperty extends Property implements IValueProperty {
20
	public final void addValueChangeListener(Object source,
21
			IValuePropertyChangeListener listener) {
22
		getChangeSupport().addListener(source, listener);
23
	}
24
25
	public final void removeValueChangeListener(Object source,
26
			IValuePropertyChangeListener listener) {
27
		getChangeSupport().removeListener(source, listener);
28
	}
29
30
	protected final void fireValueChange(Object source, ValueDiff diff) {
31
		getChangeSupport().firePropertyChange(
32
				new ValuePropertyChangeEvent(source, this, diff));
33
	}
34
}
(-)src/org/eclipse/core/databinding/property/IValuePropertyChangeListener.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 */
17
public interface IValuePropertyChangeListener extends IPropertyChangeListener {
18
	/**
19
	 * @param event
20
	 */
21
	public void handleValuePropertyChange(ValuePropertyChangeEvent event);
22
}
(-)src/org/eclipse/core/databinding/property/BasicListProperty.java (+205 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.ListIterator;
19
20
import org.eclipse.core.databinding.observable.Diffs;
21
import org.eclipse.core.databinding.observable.list.ListDiff;
22
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
23
import org.eclipse.core.internal.databinding.property.PropertyUpdateHelper;
24
25
/**
26
 * @since 1.2
27
 * 
28
 */
29
public abstract class BasicListProperty extends ListProperty {
30
	private PropertyUpdateHelper updateHelper = new PropertyUpdateHelper();
31
32
	protected boolean isUpdating(Object source) {
33
		return updateHelper.isUpdating(source);
34
	}
35
36
	protected void setList(Object source, List list, ListDiff diff) {
37
		if (diff == null) {
38
			diff = Diffs.computeListDiff(getList(source), list);
39
		}
40
41
		updateHelper.setUpdating(source, true);
42
		try {
43
			doSetList(source, list);
44
		} finally {
45
			updateHelper.setUpdating(source, false);
46
		}
47
48
		if (hasListeners(source)) {
49
			fireListChange(source, diff);
50
		}
51
	}
52
53
	protected abstract void doSetList(Object source, List list);
54
55
	public boolean add(Object source, Object o) {
56
		add(source, size(source), o);
57
		return true;
58
	}
59
60
	public void add(Object source, int index, Object element) {
61
		List list = new ArrayList(getList(source));
62
		list.add(index, element);
63
		setList(source, list, Diffs.createListDiff(Diffs.createListDiffEntry(
64
				index, true, element)));
65
	}
66
67
	public boolean addAll(Object source, Collection c) {
68
		if (c.isEmpty())
69
			return false;
70
		addAll(source, size(source), c);
71
		return true;
72
	}
73
74
	public boolean addAll(Object source, int index, Collection c) {
75
		if (c.isEmpty()) {
76
			return false;
77
		}
78
79
		List list = new ArrayList(getList(source));
80
		List entries = new ArrayList();
81
		int i = index;
82
		for (Iterator it = c.iterator(); it.hasNext(); i++) {
83
			Object o = it.next();
84
			list.add(i, o);
85
			entries.add(Diffs.createListDiffEntry(i, true, o));
86
		}
87
		boolean changed = !entries.isEmpty();
88
		if (changed) {
89
			ListDiffEntry[] ea = (ListDiffEntry[]) entries
90
					.toArray(new ListDiffEntry[entries.size()]);
91
			setList(source, list, Diffs.createListDiff(ea));
92
		}
93
		return changed;
94
	}
95
96
	public void clear(Object source) {
97
		if (isEmpty(source))
98
			return;
99
		List list = getList(source);
100
		ListDiffEntry[] entries = new ListDiffEntry[list.size()];
101
		int i = 0;
102
		for (Iterator it = getList(source).iterator(); it.hasNext(); i++) {
103
			entries[i] = Diffs.createListDiffEntry(0, false, it.next());
104
		}
105
		setList(source, new ArrayList(), Diffs.createListDiff(entries));
106
	}
107
108
	public Object move(Object source, int oldIndex, int newIndex) {
109
		if (oldIndex == newIndex)
110
			return get(source, oldIndex);
111
		List list = new ArrayList(getList(source));
112
		Object result = list.remove(oldIndex);
113
		list.add(newIndex, result);
114
		setList(source, list, Diffs.createListDiff(Diffs.createListDiffEntry(
115
				oldIndex, false, result), Diffs.createListDiffEntry(newIndex,
116
				true, result)));
117
		return result;
118
	}
119
120
	public boolean remove(Object source, Object o) {
121
		int i = indexOf(source, o);
122
		if (i == -1)
123
			return false;
124
		remove(source, i);
125
		return true;
126
	}
127
128
	public Object remove(Object source, int index) {
129
		List list = new ArrayList(getList(source));
130
		Object result = list.remove(index);
131
		setList(source, list, Diffs.createListDiff(Diffs.createListDiffEntry(
132
				index, false, result)));
133
		return result;
134
	}
135
136
	public boolean removeAll(Object source, Collection c) {
137
		if (isEmpty(source)) {
138
			return false;
139
		}
140
		if (c.isEmpty()) {
141
			return false;
142
		}
143
		List list = new ArrayList(getList(source));
144
		List entries = new ArrayList();
145
		for (ListIterator it = list.listIterator(); it.hasNext();) {
146
			Object o = it.next();
147
			if (c.contains(o)) {
148
				entries.add(Diffs.createListDiffEntry(it.previousIndex(),
149
						false, o));
150
				it.remove();
151
			}
152
		}
153
		boolean changed = !entries.isEmpty();
154
		if (changed) {
155
			ListDiffEntry[] ea = (ListDiffEntry[]) entries
156
					.toArray(new ListDiffEntry[entries.size()]);
157
			setList(source, list, Diffs.createListDiff(ea));
158
		}
159
		return changed;
160
	}
161
162
	public boolean retainAll(Object source, Collection c) {
163
		if (isEmpty(source)) {
164
			return false;
165
		}
166
		if (c.isEmpty()) {
167
			clear(source);
168
			return true;
169
		}
170
		List list = new ArrayList(getList(source));
171
		List entries = new ArrayList();
172
		for (ListIterator it = list.listIterator(); it.hasNext();) {
173
			Object o = it.next();
174
			if (!c.contains(o)) {
175
				entries.add(Diffs.createListDiffEntry(it.previousIndex(),
176
						false, o));
177
				it.remove();
178
			}
179
		}
180
		boolean changed = !entries.isEmpty();
181
		if (changed) {
182
			ListDiffEntry[] ea = (ListDiffEntry[]) entries
183
					.toArray(new ListDiffEntry[entries.size()]);
184
			setList(source, list, Diffs.createListDiff(ea));
185
		}
186
		return changed;
187
	}
188
189
	public Object set(Object source, int index, Object element) {
190
		List list = new ArrayList(getList(source));
191
		Object result = list.set(index, element);
192
		setList(source, list, Diffs.createListDiff(Diffs.createListDiffEntry(
193
				index, false, result), Diffs.createListDiffEntry(index, true,
194
				element)));
195
		return result;
196
	}
197
198
	public synchronized void dispose() {
199
		if (updateHelper != null) {
200
			updateHelper.dispose();
201
			updateHelper = null;
202
		}
203
		super.dispose();
204
	}
205
}
(-)src/org/eclipse/core/databinding/property/masterdetail/MasterDetailProperties.java (+107 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property.masterdetail;
13
14
import org.eclipse.core.databinding.property.IListProperty;
15
import org.eclipse.core.databinding.property.IMapProperty;
16
import org.eclipse.core.databinding.property.ISetProperty;
17
import org.eclipse.core.databinding.property.IValueProperty;
18
import org.eclipse.core.internal.databinding.property.masterdetail.ListPropertyDetailValueList;
19
import org.eclipse.core.internal.databinding.property.masterdetail.MapPropertyDetailValueMap;
20
import org.eclipse.core.internal.databinding.property.masterdetail.SetPropertyDetailValueMap;
21
import org.eclipse.core.internal.databinding.property.masterdetail.ValuePropertyDetailList;
22
import org.eclipse.core.internal.databinding.property.masterdetail.ValuePropertyDetailMap;
23
import org.eclipse.core.internal.databinding.property.masterdetail.ValuePropertyDetailSet;
24
import org.eclipse.core.internal.databinding.property.masterdetail.ValuePropertyDetailValue;
25
26
/**
27
 * @since 1.2
28
 */
29
public class MasterDetailProperties {
30
	// Properties of IValueProperty master properties
31
32
	/**
33
	 * @param masterValue
34
	 * @param detailValue
35
	 * @return blah
36
	 */
37
	public static IValueProperty detailValue(IValueProperty masterValue,
38
			IValueProperty detailValue) {
39
		return new ValuePropertyDetailValue(masterValue, detailValue);
40
	}
41
42
	/**
43
	 * @param masterValue
44
	 * @param detailList
45
	 * @return blah
46
	 */
47
	public static IListProperty detailList(IValueProperty masterValue,
48
			IListProperty detailList) {
49
		return new ValuePropertyDetailList(masterValue, detailList);
50
	}
51
52
	/**
53
	 * @param masterValue
54
	 * @param detailSet
55
	 * @return blah
56
	 */
57
	public static ISetProperty detailSet(IValueProperty masterValue,
58
			ISetProperty detailSet) {
59
		return new ValuePropertyDetailSet(masterValue, detailSet);
60
	}
61
62
	/**
63
	 * @param masterValue
64
	 * @param detailMap
65
	 * @return blah
66
	 */
67
	public static IMapProperty detailMap(IValueProperty masterValue,
68
			IMapProperty detailMap) {
69
		return new ValuePropertyDetailMap(masterValue, detailMap);
70
	}
71
72
	// Properties of IListProperty master properties
73
74
	/**
75
	 * @param masterList
76
	 * @param detailValue
77
	 * @return blah
78
	 */
79
	public static IListProperty detailList(IListProperty masterList,
80
			IValueProperty detailValue) {
81
		return new ListPropertyDetailValueList(masterList, detailValue);
82
	}
83
84
	// Properties of ISetProperty master properties
85
86
	/**
87
	 * @param masterKeySet
88
	 * @param detailValues
89
	 * @return blah
90
	 */
91
	public static IMapProperty detailMap(ISetProperty masterKeySet,
92
			IValueProperty detailValues) {
93
		return new SetPropertyDetailValueMap(masterKeySet, detailValues);
94
	}
95
96
	// Properties of IMapProperty master properties
97
98
	/**
99
	 * @param masterMap
100
	 * @param detailValues
101
	 * @return blah
102
	 */
103
	public static IMapProperty detailMap(IMapProperty masterMap,
104
			IValueProperty detailValues) {
105
		return new MapPropertyDetailValueMap(masterMap, detailValues);
106
	}
107
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/ValuePropertyDetailValue.java (+123 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.value.ValueDiff;
19
import org.eclipse.core.databinding.property.IValueProperty;
20
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
21
import org.eclipse.core.databinding.property.ValueProperty;
22
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
23
24
/**
25
 * @since 1.2
26
 * 
27
 */
28
public class ValuePropertyDetailValue extends ValueProperty implements
29
		IValueProperty {
30
	private IValueProperty masterProperty;
31
	private IValueProperty detailProperty;
32
33
	private Map sourceToDetailListener = new HashMap();
34
35
	private IValuePropertyChangeListener masterListener = new MasterPropertyListener();
36
37
	private class MasterPropertyListener implements
38
			IValuePropertyChangeListener {
39
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
40
			Object oldSource = event.diff.getOldValue();
41
			Object newSource = event.diff.getNewValue();
42
43
			Object oldValue = detailProperty.getValue(oldSource);
44
			Object newValue = detailProperty.getValue(newSource);
45
46
			ValueDiff diff = Diffs.createValueDiff(oldValue, newValue);
47
48
			Object source = event.getSource();
49
50
			removeDetailPropertyListener(source);
51
			addDetailPropertyListener(source);
52
53
			fireValueChange(source, diff);
54
		}
55
	}
56
57
	private class DetailPropertyListener implements
58
			IValuePropertyChangeListener {
59
		private Object source;
60
		private Object masterValue;
61
62
		DetailPropertyListener(Object source, Object masterValue) {
63
			this.source = source;
64
			this.masterValue = masterValue;
65
		}
66
67
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
68
			fireValueChange(source, event.diff);
69
		}
70
	}
71
72
	/**
73
	 * @param masterProperty
74
	 * @param detailProperty
75
	 */
76
	public ValuePropertyDetailValue(IValueProperty masterProperty,
77
			IValueProperty detailProperty) {
78
		this.masterProperty = masterProperty;
79
		this.detailProperty = detailProperty;
80
	}
81
82
	protected void addListenerTo(Object source) {
83
		masterProperty.addValueChangeListener(source, masterListener);
84
		addDetailPropertyListener(source);
85
	}
86
87
	protected void removeListenerFrom(Object source) {
88
		masterProperty.removeValueChangeListener(source, masterListener);
89
		removeDetailPropertyListener(source);
90
	}
91
92
	private void addDetailPropertyListener(Object source) {
93
		Object masterValue = masterProperty.getValue(source);
94
		DetailPropertyListener detailListener = new DetailPropertyListener(
95
				source, masterValue);
96
		detailProperty.addValueChangeListener(masterValue, detailListener);
97
		sourceToDetailListener.put(source, detailListener);
98
	}
99
100
	private void removeDetailPropertyListener(Object source) {
101
		DetailPropertyListener detailListener = (DetailPropertyListener) sourceToDetailListener
102
				.remove(source);
103
		if (detailListener != null) {
104
			detailProperty.removeValueChangeListener(
105
					detailListener.masterValue, detailListener);
106
		}
107
		sourceToDetailListener.remove(source);
108
	}
109
110
	public Object getValue(Object source) {
111
		Object masterValue = masterProperty.getValue(source);
112
		return detailProperty.getValue(masterValue);
113
	}
114
115
	public Object getValueType() {
116
		return detailProperty.getValueType();
117
	}
118
119
	public void setValue(Object source, Object value) {
120
		Object masterValue = masterProperty.getValue(source);
121
		detailProperty.setValue(masterValue, value);
122
	}
123
}
(-)src/org/eclipse/core/internal/databinding/property/MapValuePropertyObservableMap.java (+323 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import java.util.AbstractSet;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.IdentityHashMap;
18
import java.util.Iterator;
19
import java.util.Map;
20
import java.util.Set;
21
22
import org.eclipse.core.databinding.observable.Diffs;
23
import org.eclipse.core.databinding.observable.IObserving;
24
import org.eclipse.core.databinding.observable.IStaleListener;
25
import org.eclipse.core.databinding.observable.ObservableTracker;
26
import org.eclipse.core.databinding.observable.StaleEvent;
27
import org.eclipse.core.databinding.observable.map.AbstractObservableMap;
28
import org.eclipse.core.databinding.observable.map.IMapChangeListener;
29
import org.eclipse.core.databinding.observable.map.IObservableMap;
30
import org.eclipse.core.databinding.observable.map.MapChangeEvent;
31
import org.eclipse.core.databinding.property.IValueProperty;
32
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
33
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
34
import org.eclipse.core.internal.databinding.Util;
35
36
/**
37
 * @since 3.3
38
 * 
39
 */
40
public class MapValuePropertyObservableMap extends AbstractObservableMap
41
		implements IObserving {
42
	private IObservableMap map;
43
	private IValueProperty property;
44
45
	private Map keyToMasterValueListener;
46
47
	private boolean updating = false;
48
	private boolean disposed = false;
49
50
	private IMapChangeListener mapListener = new IMapChangeListener() {
51
		public void handleMapChange(final MapChangeEvent event) {
52
			if (!updating && !disposed) {
53
				getRealm().exec(new Runnable() {
54
					public void run() {
55
						Map oldValues = new HashMap();
56
						Map newValues = new HashMap();
57
58
						Set addedKeys = event.diff.getAddedKeys();
59
						for (Iterator it = addedKeys.iterator(); it.hasNext();) {
60
							Object key = it.next();
61
							Object newSource = event.diff.getNewValue(key);
62
							Object newValue = property.getValue(newSource);
63
							newValues.put(key, newValue);
64
							addPropertySourceListener(key, newSource);
65
						}
66
67
						Set removedKeys = event.diff.getRemovedKeys();
68
						for (Iterator it = removedKeys.iterator(); it.hasNext();) {
69
							Object key = it.next();
70
							Object oldSource = event.diff.getOldValue(key);
71
							Object oldValue = property.getValue(oldSource);
72
							oldValues.put(key, oldValue);
73
							removePropertySourceListener(key, oldSource);
74
						}
75
76
						Set changedKeys = new HashSet(event.diff
77
								.getChangedKeys());
78
						for (Iterator it = changedKeys.iterator(); it.hasNext();) {
79
							Object key = it.next();
80
81
							Object oldSource = event.diff.getOldValue(key);
82
							Object newSource = event.diff.getNewValue(key);
83
84
							Object oldValue = property.getValue(oldSource);
85
							Object newValue = property.getValue(newSource);
86
87
							if (Util.equals(oldValue, newValue)) {
88
								it.remove();
89
							} else {
90
								oldValues.put(key, oldValue);
91
								newValues.put(key, newValue);
92
							}
93
94
							removePropertySourceListener(key, oldSource);
95
							addPropertySourceListener(key, newSource);
96
						}
97
98
						fireMapChange(Diffs.createMapDiff(addedKeys,
99
								removedKeys, changedKeys, oldValues, newValues));
100
					}
101
				});
102
			}
103
		}
104
	};
105
106
	private IStaleListener staleListener = new IStaleListener() {
107
		public void handleStale(StaleEvent staleEvent) {
108
			fireStale();
109
		}
110
	};
111
112
	/**
113
	 * @param map
114
	 * @param valueProperty
115
	 */
116
	public MapValuePropertyObservableMap(IObservableMap map,
117
			IValueProperty valueProperty) {
118
		super(map.getRealm());
119
		this.map = map;
120
		this.property = valueProperty;
121
122
		this.keyToMasterValueListener = new IdentityHashMap();
123
	}
124
125
	private class ValuePropertySourceChangeListener implements
126
			IValuePropertyChangeListener {
127
		private final Object key;
128
129
		public ValuePropertySourceChangeListener(Object key) {
130
			this.key = key;
131
		}
132
133
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
134
			Object oldSource = event.diff.getOldValue();
135
			Object oldValue = property.getValue(oldSource);
136
			property.removeValueChangeListener(oldSource, this);
137
138
			Object newSource = event.diff.getNewValue();
139
			Object newValue = property.getValue(newSource);
140
			property.addValueChangeListener(newSource, this);
141
142
			if (!Util.equals(oldValue, newValue))
143
				fireMapChange(Diffs.createMapDiffSingleChange(key, oldValue,
144
						newValue));
145
		}
146
	}
147
148
	protected void firstListenerAdded() {
149
		if (!disposed) {
150
			map.addMapChangeListener(mapListener);
151
			map.addStaleListener(staleListener);
152
			for (Iterator iterator = map.entrySet().iterator(); iterator
153
					.hasNext();) {
154
				Map.Entry entry = (Map.Entry) iterator.next();
155
				Object key = entry.getKey();
156
				Object masterValue = entry.getValue();
157
158
				addPropertySourceListener(key, masterValue);
159
			}
160
		}
161
	}
162
163
	protected void lastListenerRemoved() {
164
		if (!disposed) {
165
			map.removeMapChangeListener(mapListener);
166
			map.removeStaleListener(staleListener);
167
			for (Iterator iterator = map.entrySet().iterator(); iterator
168
					.hasNext();) {
169
				Map.Entry entry = (Map.Entry) iterator.next();
170
				Object key = entry.getKey();
171
				Object propertySource = entry.getValue();
172
173
				removePropertySourceListener(key, propertySource);
174
			}
175
		}
176
	}
177
178
	private void addPropertySourceListener(Object key, Object propertySource) {
179
		IValuePropertyChangeListener propertyListener = new ValuePropertySourceChangeListener(
180
				key);
181
		property.addValueChangeListener(propertySource, propertyListener);
182
		keyToMasterValueListener.put(key, propertyListener);
183
	}
184
185
	private void removePropertySourceListener(Object key, Object propertySource) {
186
		IValuePropertyChangeListener propertyListener = (IValuePropertyChangeListener) keyToMasterValueListener
187
				.remove(key);
188
		if (propertyListener != null) {
189
			property
190
					.removeValueChangeListener(propertySource, propertyListener);
191
		}
192
	}
193
194
	protected Object doGet(Object key) {
195
		if (!map.containsKey(key))
196
			return null;
197
		return property.getValue(map.get(key));
198
	}
199
200
	protected Object doPut(Object key, Object value) {
201
		if (!map.containsKey(key))
202
			return null;
203
		Object source = map.get(key);
204
205
		Object oldValue = property.getValue(source);
206
207
		updating = true;
208
		try {
209
			property.setValue(source, value);
210
		} finally {
211
			updating = false;
212
		}
213
214
		Object newValue = property.getValue(source);
215
216
		if (!Util.equals(oldValue, newValue)) {
217
			fireMapChange(Diffs.createMapDiffSingleChange(key, oldValue,
218
					newValue));
219
		}
220
221
		return oldValue;
222
	}
223
224
	private Set entrySet;
225
226
	public Set entrySet() {
227
		getterCalled();
228
		if (entrySet == null)
229
			entrySet = new EntrySet();
230
		return entrySet;
231
	}
232
233
	class EntrySet extends AbstractSet {
234
		public Iterator iterator() {
235
			return new Iterator() {
236
				Iterator it = map.entrySet().iterator();
237
238
				public boolean hasNext() {
239
					getterCalled();
240
					return it.hasNext();
241
				}
242
243
				public Object next() {
244
					getterCalled();
245
					Map.Entry next = (Map.Entry) it.next();
246
					return new MapEntry(next.getKey());
247
				}
248
249
				public void remove() {
250
					it.remove();
251
				}
252
			};
253
		}
254
255
		public int size() {
256
			return map.size();
257
		}
258
	}
259
260
	class MapEntry implements Map.Entry {
261
		private Object key;
262
263
		MapEntry(Object key) {
264
			this.key = key;
265
		}
266
267
		public Object getKey() {
268
			getterCalled();
269
			return key;
270
		}
271
272
		public Object getValue() {
273
			getterCalled();
274
			return get(key);
275
		}
276
277
		public Object setValue(Object value) {
278
			return put(key, value);
279
		}
280
281
		public boolean equals(Object o) {
282
			getterCalled();
283
			if (o == this)
284
				return true;
285
			if (o == null)
286
				return false;
287
			if (!(o instanceof Map.Entry))
288
				return false;
289
			Map.Entry that = (Map.Entry) o;
290
			return Util.equals(this.getKey(), that.getKey())
291
					&& Util.equals(this.getValue(), that.getValue());
292
		}
293
294
		public int hashCode() {
295
			getterCalled();
296
			Object value = getValue();
297
			return (key == null ? 0 : key.hashCode())
298
					^ (value == null ? 0 : value.hashCode());
299
		}
300
	}
301
302
	public boolean isStale() {
303
		getterCalled();
304
		return map.isStale();
305
	}
306
307
	private void getterCalled() {
308
		ObservableTracker.getterCalled(this);
309
	}
310
311
	public Object getObserved() {
312
		return map;
313
	}
314
315
	public synchronized void dispose() {
316
		if (!disposed) {
317
			disposed = true;
318
			property = null;
319
		}
320
321
		super.dispose();
322
	}
323
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/SetPropertyDetailValueMap.java (+217 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.Collections;
15
import java.util.HashMap;
16
import java.util.Iterator;
17
import java.util.Map;
18
import java.util.Set;
19
20
import org.eclipse.core.databinding.observable.Diffs;
21
import org.eclipse.core.databinding.observable.map.MapDiff;
22
import org.eclipse.core.databinding.property.ISetProperty;
23
import org.eclipse.core.databinding.property.ISetPropertyChangeListener;
24
import org.eclipse.core.databinding.property.IValueProperty;
25
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
26
import org.eclipse.core.databinding.property.MapProperty;
27
import org.eclipse.core.databinding.property.SetPropertyChangeEvent;
28
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
29
30
/**
31
 * @since 3.3
32
 * 
33
 */
34
public class SetPropertyDetailValueMap extends MapProperty {
35
	private final ISetProperty masterProperty;
36
	private final IValueProperty detailProperty;
37
38
	private Map sourceToMasterElementToDetailListener = new HashMap();
39
40
	private ISetPropertyChangeListener masterListener = new MasterPropertyListener();
41
42
	private class MasterPropertyListener implements ISetPropertyChangeListener {
43
		public void handleSetPropertyChange(final SetPropertyChangeEvent event) {
44
			Object source = event.getSource();
45
46
			MapDiff diff;
47
			if (event.diff == null) {
48
				diff = null;
49
			} else {
50
				final Set removals = event.diff.getRemovals();
51
				final Set additions = event.diff.getAdditions();
52
53
				diff = new MapDiff() {
54
					public Set getAddedKeys() {
55
						return additions;
56
					}
57
58
					public Set getChangedKeys() {
59
						return Collections.EMPTY_SET;
60
					}
61
62
					public Object getNewValue(Object key) {
63
						return getValue(key);
64
					}
65
66
					public Object getOldValue(Object key) {
67
						return getValue(key);
68
					}
69
70
					private Object getValue(Object key) {
71
						return detailProperty.getValue(key);
72
					}
73
74
					public Set getRemovedKeys() {
75
						return removals;
76
					}
77
				};
78
79
				for (Iterator it = removals.iterator(); it.hasNext();) {
80
					removeElementPropertyListener(source, it.next());
81
				}
82
				for (Iterator it = additions.iterator(); it.hasNext();) {
83
					addElementPropertyListener(source, it.next());
84
				}
85
			}
86
87
			fireMapChange(source, diff);
88
		}
89
90
		private void addElementPropertyListener(Object source, Object element) {
91
			Map elementToDetailListener = (Map) sourceToMasterElementToDetailListener
92
					.get(source);
93
			if (elementToDetailListener == null) {
94
				sourceToMasterElementToDetailListener.put(source,
95
						elementToDetailListener = new HashMap());
96
			}
97
			if (!elementToDetailListener.containsKey(element)) {
98
				DetailPropertyListener detailListener = new DetailPropertyListener(
99
						source, element);
100
				detailProperty.addValueChangeListener(element, detailListener);
101
				elementToDetailListener.put(element, detailListener);
102
			}
103
		}
104
105
		private void removeElementPropertyListener(Object source, Object element) {
106
			Map elementToDetailListener = (Map) sourceToMasterElementToDetailListener
107
					.get(source);
108
			if (elementToDetailListener != null
109
					&& elementToDetailListener.containsKey(element)) {
110
				DetailPropertyListener detailListener = (DetailPropertyListener) elementToDetailListener
111
						.remove(element);
112
				detailProperty.removeValueChangeListener(element,
113
						detailListener);
114
			}
115
		}
116
	}
117
118
	private class DetailPropertyListener implements
119
			IValuePropertyChangeListener {
120
		private Object source;
121
		private Object masterValue;
122
123
		DetailPropertyListener(Object source, Object masterValue) {
124
			this.source = source;
125
			this.masterValue = masterValue;
126
		}
127
128
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
129
			MapDiff diff;
130
			if (event.diff == null) {
131
				diff = null;
132
			} else {
133
				diff = Diffs.createMapDiffSingleChange(masterValue, event.diff
134
						.getOldValue(), event.diff.getNewValue());
135
			}
136
			fireMapChange(source, diff);
137
		}
138
	}
139
140
	/**
141
	 * @param masterProperty
142
	 * @param detailProperty
143
	 */
144
	public SetPropertyDetailValueMap(ISetProperty masterProperty,
145
			IValueProperty detailProperty) {
146
		this.masterProperty = masterProperty;
147
		this.detailProperty = detailProperty;
148
	}
149
150
	protected void addListenerTo(Object source) {
151
		masterProperty.addSetChangeListener(source, masterListener);
152
153
		Map masterElementToDetailListener = new HashMap();
154
		for (Iterator it = masterProperty.getSet(source).iterator(); it
155
				.hasNext();) {
156
			Object masterElement = it.next();
157
			DetailPropertyListener detailListener = new DetailPropertyListener(
158
					source, masterElement);
159
			detailProperty
160
					.addValueChangeListener(masterElement, detailListener);
161
			masterElementToDetailListener.put(masterElement, detailListener);
162
		}
163
164
		sourceToMasterElementToDetailListener.put(source,
165
				masterElementToDetailListener);
166
	}
167
168
	protected void removeListenerFrom(Object source) {
169
		masterProperty.removeSetChangeListener(source, masterListener);
170
		Map masterElementToDetailListener = (Map) sourceToMasterElementToDetailListener
171
				.remove(source);
172
		if (masterElementToDetailListener != null) {
173
			for (Iterator it = masterElementToDetailListener.entrySet()
174
					.iterator(); it.hasNext();) {
175
				Map.Entry entry = (Map.Entry) it.next();
176
				detailProperty.removeValueChangeListener(entry.getKey(),
177
						(DetailPropertyListener) entry.getValue());
178
			}
179
		}
180
	}
181
182
	public Map getMap(Object source) {
183
		Map result = new HashMap();
184
		for (Iterator it = masterProperty.getSet(source).iterator(); it
185
				.hasNext();) {
186
			Object element = it.next();
187
			result.put(element, detailProperty.getValue(element));
188
		}
189
		return result;
190
	}
191
192
	public void clear(Object source) {
193
		throw new UnsupportedOperationException();
194
	}
195
196
	public Object put(Object source, Object key, Object value) {
197
		if (!masterProperty.contains(source, key))
198
			return null;
199
		Object result = detailProperty.getValue(key);
200
		detailProperty.setValue(key, value);
201
		return result;
202
	}
203
204
	public void putAll(Object source, Map t) {
205
		Set masterSet = masterProperty.getSet(source);
206
		for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
207
			Map.Entry entry = (Map.Entry) it.next();
208
			if (masterSet.contains(entry.getKey())) {
209
				detailProperty.setValue(entry.getKey(), entry.getValue());
210
			}
211
		}
212
	}
213
214
	public Object remove(Object source, Object key) {
215
		throw new UnsupportedOperationException();
216
	}
217
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/ValuePropertyDetailList.java (+173 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.List;
17
import java.util.Map;
18
19
import org.eclipse.core.databinding.observable.Diffs;
20
import org.eclipse.core.databinding.property.IListProperty;
21
import org.eclipse.core.databinding.property.IListPropertyChangeListener;
22
import org.eclipse.core.databinding.property.IValueProperty;
23
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
24
import org.eclipse.core.databinding.property.ListProperty;
25
import org.eclipse.core.databinding.property.ListPropertyChangeEvent;
26
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
27
28
/**
29
 * @since 3.3
30
 * 
31
 */
32
public class ValuePropertyDetailList extends ListProperty {
33
	private final IValueProperty masterProperty;
34
	private final IListProperty detailProperty;
35
36
	private Map sourceToDetailListener = new HashMap();
37
38
	private IValuePropertyChangeListener masterListener = new MasterPropertyListener();
39
40
	private class MasterPropertyListener implements
41
			IValuePropertyChangeListener {
42
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
43
			Object oldSource = event.diff.getOldValue();
44
			Object newSource = event.diff.getNewValue();
45
46
			List oldList = detailProperty.getList(oldSource);
47
			List newList = detailProperty.getList(newSource);
48
49
			Object source = event.getSource();
50
51
			removeDetailPropertyListener(source);
52
			addDetailPropertyListener(source);
53
54
			fireListChange(source, Diffs.computeListDiff(oldList, newList));
55
		}
56
	}
57
58
	private class DetailPropertyListener implements IListPropertyChangeListener {
59
		private Object source;
60
		private Object masterValue;
61
62
		DetailPropertyListener(Object source, Object masterValue) {
63
			this.source = source;
64
			this.masterValue = masterValue;
65
		}
66
67
		public void handleListPropertyChange(ListPropertyChangeEvent event) {
68
			fireListChange(source, event.diff);
69
		}
70
	}
71
72
	/**
73
	 * @param masterProperty
74
	 * @param detailProperty
75
	 */
76
	public ValuePropertyDetailList(IValueProperty masterProperty,
77
			IListProperty detailProperty) {
78
		this.masterProperty = masterProperty;
79
		this.detailProperty = detailProperty;
80
	}
81
82
	protected void addListenerTo(Object source) {
83
		masterProperty.addValueChangeListener(source, masterListener);
84
		addDetailPropertyListener(source);
85
	}
86
87
	protected void removeListenerFrom(Object source) {
88
		masterProperty.removeValueChangeListener(source, masterListener);
89
		removeDetailPropertyListener(source);
90
	}
91
92
	private void addDetailPropertyListener(Object source) {
93
		Object masterValue = masterProperty.getValue(source);
94
		DetailPropertyListener detailListener = new DetailPropertyListener(
95
				source, masterValue);
96
		detailProperty.addListChangeListener(masterValue, detailListener);
97
		sourceToDetailListener.put(source, detailListener);
98
	}
99
100
	private void removeDetailPropertyListener(Object source) {
101
		DetailPropertyListener detailListener = (DetailPropertyListener) sourceToDetailListener
102
				.remove(source);
103
		if (detailListener != null) {
104
			detailProperty.removeListChangeListener(detailListener.masterValue,
105
					detailListener);
106
		}
107
		sourceToDetailListener.remove(source);
108
	}
109
110
	public List getList(Object source) {
111
		Object masterValue = masterProperty.getValue(source);
112
		return detailProperty.getList(masterValue);
113
	}
114
115
	public boolean add(Object source, Object o) {
116
		Object masterValue = masterProperty.getValue(source);
117
		return detailProperty.add(masterValue, o);
118
	}
119
120
	public boolean addAll(Object source, Collection c) {
121
		Object masterValue = masterProperty.getValue(source);
122
		return detailProperty.addAll(masterValue, c);
123
	}
124
125
	public void clear(Object source) {
126
		Object masterValue = masterProperty.getValue(source);
127
		detailProperty.clear(masterValue);
128
	}
129
130
	public Object getElementType() {
131
		return detailProperty.getElementType();
132
	}
133
134
	public boolean remove(Object source, Object o) {
135
		Object masterValue = masterProperty.getValue(source);
136
		return detailProperty.remove(masterValue, o);
137
	}
138
139
	public boolean removeAll(Object source, Collection c) {
140
		Object masterValue = masterProperty.getValue(source);
141
		return detailProperty.removeAll(masterValue, c);
142
	}
143
144
	public boolean retainAll(Object source, Collection c) {
145
		Object masterValue = masterProperty.getValue(source);
146
		return detailProperty.retainAll(masterValue, c);
147
	}
148
149
	public void add(Object source, int index, Object element) {
150
		Object masterValue = masterProperty.getValue(source);
151
		detailProperty.add(masterValue, index, element);
152
	}
153
154
	public boolean addAll(Object source, int index, Collection c) {
155
		Object masterValue = masterProperty.getValue(source);
156
		return detailProperty.addAll(masterValue, index, c);
157
	}
158
159
	public Object move(Object source, int oldIndex, int newIndex) {
160
		Object masterValue = masterProperty.getValue(source);
161
		return detailProperty.move(masterValue, oldIndex, newIndex);
162
	}
163
164
	public Object remove(Object source, int index) {
165
		Object masterValue = masterProperty.getValue(source);
166
		return detailProperty.remove(masterValue, index);
167
	}
168
169
	public Object set(Object source, int index, Object element) {
170
		Object masterValue = masterProperty.getValue(source);
171
		return detailProperty.set(masterValue, index, element);
172
	}
173
}
(-)src/org/eclipse/core/databinding/property/SetProperty.java (+41 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
16
import org.eclipse.core.databinding.observable.set.SetDiff;
17
18
/**
19
 * @since 1.2
20
 */
21
public abstract class SetProperty extends CollectionProperty implements
22
		ISetProperty {
23
	Collection getCollection(Object source) {
24
		return getSet(source);
25
	}
26
27
	public final void addSetChangeListener(Object source,
28
			ISetPropertyChangeListener listener) {
29
		getChangeSupport().addListener(source, listener);
30
	}
31
32
	public final void removeSetChangeListener(Object source,
33
			ISetPropertyChangeListener listener) {
34
		getChangeSupport().removeListener(source, listener);
35
	}
36
37
	protected final void fireSetChange(Object source, SetDiff diff) {
38
		getChangeSupport().firePropertyChange(
39
				new SetPropertyChangeEvent(source, this, diff));
40
	}
41
}
(-)src/org/eclipse/core/databinding/property/IProperty.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * Interface for observing a property of a source object.
16
 * 
17
 * @noimplement
18
 * @since 1.2
19
 */
20
public interface IProperty {
21
	/**
22
	 * Disposes the property, removing all property listeners on source objects.
23
	 */
24
	public void dispose();
25
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/ListPropertyDetailValueList.java (+259 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.ListIterator;
21
import java.util.Map;
22
import java.util.Set;
23
24
import org.eclipse.core.databinding.observable.Diffs;
25
import org.eclipse.core.databinding.observable.list.ListDiff;
26
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
27
import org.eclipse.core.databinding.property.IListProperty;
28
import org.eclipse.core.databinding.property.IListPropertyChangeListener;
29
import org.eclipse.core.databinding.property.IValueProperty;
30
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
31
import org.eclipse.core.databinding.property.ListProperty;
32
import org.eclipse.core.databinding.property.ListPropertyChangeEvent;
33
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
34
import org.eclipse.core.internal.databinding.Util;
35
36
/**
37
 * @since 3.3
38
 * 
39
 */
40
public class ListPropertyDetailValueList extends ListProperty {
41
	private final IListProperty masterProperty;
42
	private final IValueProperty detailProperty;
43
44
	private Map sourceToMasterElementToDetailListener = new HashMap();
45
46
	private IListPropertyChangeListener masterListener = new MasterPropertyListener();
47
48
	private class MasterPropertyListener implements IListPropertyChangeListener {
49
		public void handleListPropertyChange(ListPropertyChangeEvent event) {
50
			Object source = event.getSource();
51
			ListDiffEntry[] masterEntries = event.diff.getDifferences();
52
			ListDiffEntry[] detailEntries = new ListDiffEntry[masterEntries.length];
53
			Set masterElementsAdded = new HashSet();
54
			Set masterElementsRemoved = new HashSet();
55
			for (int i = 0; i < masterEntries.length; i++) {
56
				ListDiffEntry masterDifference = masterEntries[i];
57
				int index = masterDifference.getPosition();
58
				boolean addition = masterDifference.isAddition();
59
				Object masterElement = masterDifference.getElement();
60
				Object elementDetailValue = detailProperty
61
						.getValue(masterElement);
62
				detailEntries[i] = Diffs.createListDiffEntry(index, addition,
63
						elementDetailValue);
64
				if (addition)
65
					masterElementsAdded.add(masterElement);
66
				else
67
					masterElementsRemoved.add(masterElement);
68
			}
69
70
			ListDiff diff = Diffs.createListDiff(detailEntries);
71
72
			for (Iterator it = masterElementsRemoved.iterator(); it.hasNext();) {
73
				Object element = it.next();
74
				if (!masterProperty.contains(source, element))
75
					removeElementPropertyListener(source, element);
76
			}
77
			for (Iterator it = masterElementsAdded.iterator(); it.hasNext();) {
78
				Object element = it.next();
79
				if (masterProperty.contains(source, element))
80
					addElementPropertyListener(source, element);
81
			}
82
83
			fireListChange(source, diff);
84
		}
85
86
		private void addElementPropertyListener(Object source, Object element) {
87
			Map elementToDetailListener = (Map) sourceToMasterElementToDetailListener
88
					.get(source);
89
			if (elementToDetailListener == null) {
90
				sourceToMasterElementToDetailListener.put(source,
91
						elementToDetailListener = new HashMap());
92
			}
93
			if (!elementToDetailListener.containsKey(element)) {
94
				DetailPropertyListener detailListener = new DetailPropertyListener(
95
						source, element);
96
				detailProperty.addValueChangeListener(element, detailListener);
97
				elementToDetailListener.put(element, detailListener);
98
			}
99
		}
100
101
		private void removeElementPropertyListener(Object source, Object element) {
102
			Map elementToDetailListener = (Map) sourceToMasterElementToDetailListener
103
					.get(source);
104
			if (elementToDetailListener != null
105
					&& elementToDetailListener.containsKey(element)) {
106
				DetailPropertyListener detailListener = (DetailPropertyListener) elementToDetailListener
107
						.remove(element);
108
				detailProperty.removeValueChangeListener(element,
109
						detailListener);
110
			}
111
		}
112
	}
113
114
	private class DetailPropertyListener implements
115
			IValuePropertyChangeListener {
116
		private Object source;
117
		private Object masterElement;
118
119
		DetailPropertyListener(Object source, Object masterElement) {
120
			this.source = source;
121
			this.masterElement = masterElement;
122
		}
123
124
		private int[] findIndices() {
125
			List indices = new ArrayList();
126
127
			List list = masterProperty.getList(source);
128
			for (ListIterator it = list.listIterator(); it.hasNext();) {
129
				if (Util.equals(masterElement, it.next()))
130
					indices.add(Integer.valueOf(it.previousIndex()));
131
			}
132
133
			int[] result = new int[indices.size()];
134
			for (int i = 0; i < result.length; i++) {
135
				result[i] = ((Integer) indices.get(i)).intValue();
136
			}
137
			return result;
138
		}
139
140
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
141
			int[] indices = findIndices();
142
			Object oldValue = event.diff.getOldValue();
143
			Object newValue = event.diff.getNewValue();
144
			ListDiffEntry[] entries = new ListDiffEntry[indices.length * 2];
145
			for (int i = 0; i < indices.length; i++) {
146
				int index = indices[i];
147
				entries[i * 2] = Diffs.createListDiffEntry(index, false,
148
						oldValue);
149
				entries[i * 2 + 1] = Diffs.createListDiffEntry(index, true,
150
						newValue);
151
			}
152
153
			ListDiff diff = Diffs.createListDiff(entries);
154
			fireListChange(source, diff);
155
		}
156
	}
157
158
	/**
159
	 * @param masterProperty
160
	 * @param detailProperty
161
	 */
162
	public ListPropertyDetailValueList(IListProperty masterProperty,
163
			IValueProperty detailProperty) {
164
		this.masterProperty = masterProperty;
165
		this.detailProperty = detailProperty;
166
	}
167
168
	protected void addListenerTo(Object source) {
169
		masterProperty.addListChangeListener(source, masterListener);
170
171
		Map masterElementToDetailListener = new HashMap();
172
		for (Iterator it = masterProperty.getList(source).iterator(); it
173
				.hasNext();) {
174
			Object masterElement = it.next();
175
			DetailPropertyListener detailListener = new DetailPropertyListener(
176
					source, masterElement);
177
			detailProperty
178
					.addValueChangeListener(masterElement, detailListener);
179
			masterElementToDetailListener.put(masterElement, detailListener);
180
		}
181
182
		sourceToMasterElementToDetailListener.put(source,
183
				masterElementToDetailListener);
184
	}
185
186
	protected void removeListenerFrom(Object source) {
187
		masterProperty.removeListChangeListener(source, masterListener);
188
		Map masterElementToDetailListener = (Map) sourceToMasterElementToDetailListener
189
				.remove(source);
190
		if (masterElementToDetailListener != null) {
191
			for (Iterator it = masterElementToDetailListener.entrySet()
192
					.iterator(); it.hasNext();) {
193
				Map.Entry entry = (Map.Entry) it.next();
194
				detailProperty.removeValueChangeListener(entry.getKey(),
195
						(DetailPropertyListener) entry.getValue());
196
			}
197
		}
198
	}
199
200
	public List getList(Object source) {
201
		List result = new ArrayList();
202
		for (Iterator it = masterProperty.getList(source).iterator(); it
203
				.hasNext();) {
204
			result.add(detailProperty.getValue(it.next()));
205
		}
206
		return result;
207
	}
208
209
	public boolean add(Object source, Object o) {
210
		throw new UnsupportedOperationException();
211
	}
212
213
	public boolean addAll(Object source, Collection c) {
214
		throw new UnsupportedOperationException();
215
	}
216
217
	public void clear(Object source) {
218
		throw new UnsupportedOperationException();
219
	}
220
221
	public Object getElementType() {
222
		return detailProperty.getValueType();
223
	}
224
225
	public boolean remove(Object source, Object o) {
226
		throw new UnsupportedOperationException();
227
	}
228
229
	public boolean removeAll(Object source, Collection c) {
230
		throw new UnsupportedOperationException();
231
	}
232
233
	public boolean retainAll(Object source, Collection c) {
234
		throw new UnsupportedOperationException();
235
	}
236
237
	public void add(Object source, int index, Object element) {
238
		throw new UnsupportedOperationException();
239
	}
240
241
	public boolean addAll(Object source, int index, Collection c) {
242
		throw new UnsupportedOperationException();
243
	}
244
245
	public Object move(Object source, int oldIndex, int newIndex) {
246
		throw new UnsupportedOperationException();
247
	}
248
249
	public Object remove(Object source, int index) {
250
		throw new UnsupportedOperationException();
251
	}
252
253
	public Object set(Object source, int index, Object element) {
254
		Object masterElement = masterProperty.get(source, index);
255
		Object result = detailProperty.getValue(masterElement);
256
		detailProperty.setValue(masterElement, element);
257
		return result;
258
	}
259
}
(-)src/org/eclipse/core/databinding/property/IPropertyObservable.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.IObserving;
15
16
/**
17
 * @since 1.2
18
 * 
19
 */
20
public interface IPropertyObservable extends IObserving {
21
	/**
22
	 * @return the property being observed
23
	 */
24
	IProperty getProperty();
25
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/ValuePropertyDetailMap.java (+133 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
17
import org.eclipse.core.databinding.observable.Diffs;
18
import org.eclipse.core.databinding.observable.map.MapDiff;
19
import org.eclipse.core.databinding.property.IMapProperty;
20
import org.eclipse.core.databinding.property.IMapPropertyChangeListener;
21
import org.eclipse.core.databinding.property.IValueProperty;
22
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
23
import org.eclipse.core.databinding.property.MapProperty;
24
import org.eclipse.core.databinding.property.MapPropertyChangeEvent;
25
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
26
27
/**
28
 * @since 3.3
29
 * 
30
 */
31
public class ValuePropertyDetailMap extends MapProperty {
32
	private final IValueProperty masterProperty;
33
	private final IMapProperty detailProperty;
34
35
	private Map sourceToDetailListener = new HashMap();
36
37
	private IValuePropertyChangeListener masterListener = new MasterValueListener();
38
39
	private class MasterValueListener implements IValuePropertyChangeListener {
40
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
41
			Object oldSource = event.diff.getOldValue();
42
			Object newSource = event.diff.getNewValue();
43
44
			Map oldMap = detailProperty.getMap(oldSource);
45
			Map newMap = detailProperty.getMap(newSource);
46
			MapDiff diff = Diffs.computeMapDiff(oldMap, newMap);
47
48
			Object source = event.getSource();
49
50
			removeDetailPropertyListener(source);
51
			addDetailPropertyListener(source);
52
53
			fireMapChange(source, diff);
54
		}
55
	}
56
57
	private class DetailPropertyListener implements IMapPropertyChangeListener {
58
		private Object source;
59
		private Object masterValue;
60
61
		DetailPropertyListener(Object source, Object masterValue) {
62
			this.source = source;
63
			this.masterValue = masterValue;
64
		}
65
66
		public void handleMapPropertyChange(MapPropertyChangeEvent event) {
67
			fireMapChange(source, event.diff);
68
		}
69
	}
70
71
	/**
72
	 * @param masterProperty
73
	 * @param detailProperty
74
	 */
75
	public ValuePropertyDetailMap(IValueProperty masterProperty,
76
			IMapProperty detailProperty) {
77
		this.masterProperty = masterProperty;
78
		this.detailProperty = detailProperty;
79
	}
80
81
	protected void addListenerTo(Object source) {
82
		masterProperty.addValueChangeListener(source, masterListener);
83
		addDetailPropertyListener(source);
84
	}
85
86
	protected void removeListenerFrom(Object source) {
87
		masterProperty.removeValueChangeListener(source, masterListener);
88
		removeDetailPropertyListener(source);
89
	}
90
91
	private void addDetailPropertyListener(Object source) {
92
		Object masterValue = masterProperty.getValue(source);
93
		DetailPropertyListener detailListener = new DetailPropertyListener(
94
				source, masterValue);
95
		detailProperty.addMapChangeListener(masterValue, detailListener);
96
		sourceToDetailListener.put(source, detailListener);
97
	}
98
99
	private void removeDetailPropertyListener(Object source) {
100
		DetailPropertyListener detailListener = (DetailPropertyListener) sourceToDetailListener
101
				.remove(source);
102
		if (detailListener != null) {
103
			detailProperty.removeMapChangeListener(detailListener.masterValue,
104
					detailListener);
105
		}
106
		sourceToDetailListener.remove(source);
107
	}
108
109
	public Map getMap(Object source) {
110
		Object masterValue = masterProperty.getValue(source);
111
		return detailProperty.getMap(masterValue);
112
	}
113
114
	public void clear(Object source) {
115
		Object masterValue = masterProperty.getValue(source);
116
		detailProperty.clear(masterValue);
117
	}
118
119
	public Object put(Object source, Object key, Object value) {
120
		Object masterValue = masterProperty.getValue(source);
121
		return detailProperty.put(masterValue, key, value);
122
	}
123
124
	public void putAll(Object source, Map t) {
125
		Object masterValue = masterProperty.getValue(source);
126
		detailProperty.putAll(masterValue, t);
127
	}
128
129
	public Object remove(Object source, Object key) {
130
		Object masterValue = masterProperty.getValue(source);
131
		return detailProperty.remove(masterValue, key);
132
	}
133
}
(-)src/org/eclipse/core/databinding/property/ISetPropertyChangeListener.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 */
17
public interface ISetPropertyChangeListener extends IPropertyChangeListener {
18
	/**
19
	 * @param event
20
	 */
21
	public void handleSetPropertyChange(SetPropertyChangeEvent event);
22
}
(-)src/org/eclipse/core/databinding/property/BasicSetProperty.java (+147 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.Set;
19
20
import org.eclipse.core.databinding.observable.Diffs;
21
import org.eclipse.core.databinding.observable.set.SetDiff;
22
import org.eclipse.core.internal.databinding.property.PropertyUpdateHelper;
23
24
/**
25
 * @since 1.2
26
 * 
27
 */
28
public abstract class BasicSetProperty extends SetProperty {
29
	private PropertyUpdateHelper updateHelper = new PropertyUpdateHelper();
30
31
	protected boolean isUpdating(Object source) {
32
		return updateHelper.isUpdating(source);
33
	}
34
35
	protected void setSet(Object source, Set set, SetDiff diff) {
36
		if (diff == null) {
37
			diff = Diffs.computeSetDiff(getSet(source), set);
38
		}
39
40
		updateHelper.setUpdating(source, true);
41
		try {
42
			doSetSet(source, set);
43
		} finally {
44
			updateHelper.setUpdating(source, false);
45
		}
46
47
		if (hasListeners(source)) {
48
			fireSetChange(source, diff);
49
		}
50
	}
51
52
	protected abstract void doSetSet(Object source, Set set);
53
54
	public boolean add(Object source, Object o) {
55
		Set set = getSet(source);
56
		if (!set.contains(o)) {
57
			set = new HashSet(set);
58
			boolean added = set.add(o);
59
			if (added)
60
				setSet(source, set, Diffs.createSetDiff(Collections
61
						.singleton(o), Collections.EMPTY_SET));
62
			return added;
63
		}
64
		return false;
65
	}
66
67
	public boolean addAll(Object source, Collection c) {
68
		Set set = getSet(source);
69
		Set additions = new HashSet();
70
		for (Iterator it = c.iterator(); it.hasNext();) {
71
			Object o = it.next();
72
			if (!set.contains(o)) {
73
				additions.add(o);
74
			}
75
		}
76
		boolean changed = !additions.isEmpty();
77
		if (changed) {
78
			set = new HashSet(set);
79
			set.addAll(additions);
80
			setSet(source, set, Diffs.createSetDiff(additions,
81
					Collections.EMPTY_SET));
82
		}
83
		return changed;
84
	}
85
86
	public void clear(Object source) {
87
		setSet(source, new HashSet(), Diffs.createSetDiff(
88
				Collections.EMPTY_SET, getSet(source)));
89
	}
90
91
	public boolean remove(Object source, Object o) {
92
		Set set = getSet(source);
93
		if (set.contains(o)) {
94
			set = new HashSet(set);
95
			boolean removed = set.remove(o);
96
			if (removed)
97
				setSet(source, set, Diffs.createSetDiff(Collections.EMPTY_SET,
98
						Collections.singleton(o)));
99
			return removed;
100
		}
101
		return false;
102
	}
103
104
	public boolean removeAll(Object source, Collection c) {
105
		Set set = new HashSet(getSet(source));
106
		Set removals = new HashSet();
107
		for (Iterator it = set.iterator(); it.hasNext();) {
108
			Object o = it.next();
109
			if (c.contains(o)) {
110
				removals.add(o);
111
				it.remove();
112
			}
113
		}
114
		boolean changed = !removals.isEmpty();
115
		if (changed) {
116
			setSet(source, set, Diffs.createSetDiff(Collections.EMPTY_SET,
117
					removals));
118
		}
119
		return changed;
120
	}
121
122
	public boolean retainAll(Object source, Collection c) {
123
		Set set = new HashSet(getSet(source));
124
		Set removals = new HashSet();
125
		for (Iterator it = set.iterator(); it.hasNext();) {
126
			Object o = it.next();
127
			if (!c.contains(o)) {
128
				removals.add(o);
129
				it.remove();
130
			}
131
		}
132
		boolean changed = !removals.isEmpty();
133
		if (changed) {
134
			setSet(source, set, Diffs.createSetDiff(Collections.EMPTY_SET,
135
					removals));
136
		}
137
		return changed;
138
	}
139
140
	public synchronized void dispose() {
141
		if (updateHelper != null) {
142
			updateHelper.dispose();
143
			updateHelper = null;
144
		}
145
		super.dispose();
146
	}
147
}
(-)src/org/eclipse/core/databinding/property/MapPropertyChangeEvent.java (+50 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.map.MapDiff;
15
import org.eclipse.core.runtime.Assert;
16
17
/**
18
 * @since 1.2
19
 */
20
public class MapPropertyChangeEvent extends PropertyChangeEvent {
21
	private static final long serialVersionUID = 1L;
22
23
	/**
24
	 * 
25
	 */
26
	public final IMapProperty property;
27
28
	/**
29
	 * MapDiff enumerating the added, changed, and removed entries in the map.
30
	 * May be null to indicate that the details of the map change are unknown.
31
	 */
32
	public final MapDiff diff;
33
34
	/**
35
	 * @param source
36
	 * @param property
37
	 * @param diff
38
	 */
39
	public MapPropertyChangeEvent(Object source, IMapProperty property,
40
			MapDiff diff) {
41
		super(source);
42
		this.property = property;
43
		Assert.isNotNull(diff, "diff cannot be null"); //$NON-NLS-1$
44
		this.diff = diff;
45
	}
46
47
	void dispatch(IPropertyChangeListener listener) {
48
		((IMapPropertyChangeListener) listener).handleMapPropertyChange(this);
49
	}
50
}
(-)src/org/eclipse/core/databinding/property/PropertyChangeEvent.java (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.EventObject;
15
16
/**
17
 * @since 1.2
18
 */
19
public abstract class PropertyChangeEvent extends EventObject {
20
	private static final long serialVersionUID = 1L;
21
22
	PropertyChangeEvent(Object source) {
23
		super(source);
24
	}
25
26
	abstract void dispatch(IPropertyChangeListener listener);
27
}
(-)src/org/eclipse/core/databinding/property/ListPropertyChangeEvent.java (+50 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.list.ListDiff;
15
import org.eclipse.core.runtime.Assert;
16
17
/**
18
 * @since 1.2
19
 */
20
public class ListPropertyChangeEvent extends PropertyChangeEvent {
21
	private static final long serialVersionUID = 1L;
22
23
	/**
24
	 * 
25
	 */
26
	public final IListProperty property;
27
28
	/**
29
	 * ListDiff enumerating the added and removed elements in the list. May be
30
	 * null to indicate that the details of the list change are unknown.
31
	 */
32
	public final ListDiff diff;
33
34
	/**
35
	 * @param source
36
	 * @param property
37
	 * @param diff
38
	 */
39
	public ListPropertyChangeEvent(Object source, IListProperty property,
40
			ListDiff diff) {
41
		super(source);
42
		this.property = property;
43
		Assert.isNotNull(diff, "diff cannot be null"); //$NON-NLS-1$
44
		this.diff = diff;
45
	}
46
47
	void dispatch(IPropertyChangeListener listener) {
48
		((IListPropertyChangeListener) listener).handleListPropertyChange(this);
49
	}
50
}
(-)src/org/eclipse/core/databinding/property/ICollectionProperty.java (+120 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
16
/**
17
 * @since 1.2
18
 * 
19
 */
20
public interface ICollectionProperty extends IProperty {
21
	/**
22
	 * @param source
23
	 * @return the size of the source's collection property
24
	 */
25
	int size(Object source);
26
27
	/**
28
	 * @param source
29
	 * @return whether the source's collection property is empty
30
	 */
31
	boolean isEmpty(Object source);
32
33
	/**
34
	 * @param source
35
	 * @param o
36
	 * @return whether the source's collection property contains the given
37
	 *         element
38
	 */
39
	boolean contains(Object source, Object o);
40
41
	/**
42
	 * @param source
43
	 * @return an array of all elements in the source's collection property
44
	 */
45
	Object[] toArray(Object source);
46
47
	/**
48
	 * @param source
49
	 * @param array
50
	 * @return an array of all elements in the source's collection property
51
	 */
52
	Object[] toArray(Object source, Object[] array);
53
54
	/**
55
	 * @param source
56
	 * @param o
57
	 * @return whether the element was added to the source's collection property
58
	 */
59
	boolean add(Object source, Object o);
60
61
	/**
62
	 * @param source
63
	 * @param o
64
	 * @return whether the element was removed from the source's collection
65
	 *         property
66
	 */
67
	boolean remove(Object source, Object o);
68
69
	/**
70
	 * @param source
71
	 * @param c
72
	 * @return whether the source's collection property contains all elements in
73
	 *         the given collection
74
	 */
75
	boolean containsAll(Object source, Collection c);
76
77
	/**
78
	 * @param source
79
	 * @param c
80
	 * @return whether the source's collection property was changed
81
	 */
82
	boolean addAll(Object source, Collection c);
83
84
	/**
85
	 * @param source
86
	 * @param c
87
	 * @return whether the source's collection property was changed
88
	 */
89
	boolean removeAll(Object source, Collection c);
90
91
	/**
92
	 * @param source
93
	 * @param c
94
	 * @return whether the source's collection property was changed
95
	 */
96
	boolean retainAll(Object source, Collection c);
97
98
	/**
99
	 * @param source
100
	 */
101
	void clear(Object source);
102
103
	/**
104
	 * @param source
105
	 * @param o
106
	 * @return whether the source's collection property is equal to the argument
107
	 */
108
	boolean equals(Object source, Object o);
109
110
	/**
111
	 * @param source
112
	 * @return the hash code of the source's collection property
113
	 */
114
	int hashCode(Object source);
115
116
	/**
117
	 * @return the type of the elements or <code>null</code> if untyped
118
	 */
119
	Object getElementType();
120
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/MapPropertyDetailValueMap.java (+223 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.Iterator;
17
import java.util.Map;
18
import java.util.Set;
19
20
import org.eclipse.core.databinding.observable.Diffs;
21
import org.eclipse.core.databinding.observable.map.MapDiff;
22
import org.eclipse.core.databinding.property.IMapProperty;
23
import org.eclipse.core.databinding.property.IMapPropertyChangeListener;
24
import org.eclipse.core.databinding.property.IValueProperty;
25
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
26
import org.eclipse.core.databinding.property.MapProperty;
27
import org.eclipse.core.databinding.property.MapPropertyChangeEvent;
28
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
29
import org.eclipse.core.internal.databinding.Util;
30
31
/**
32
 * @since 3.3
33
 * 
34
 */
35
public class MapPropertyDetailValueMap extends MapProperty {
36
	private final IMapProperty masterProperty;
37
	private final IValueProperty detailProperty;
38
39
	private Map sourceToKeyToDetailListener = new HashMap();
40
41
	private IMapPropertyChangeListener masterListener = new MasterPropertyListener();
42
43
	private class MasterPropertyListener implements IMapPropertyChangeListener {
44
		public void handleMapPropertyChange(final MapPropertyChangeEvent event) {
45
			Object source = event.getSource();
46
47
			Map oldValues = new HashMap();
48
			Map newValues = new HashMap();
49
50
			Set addedKeys = event.diff.getAddedKeys();
51
			for (Iterator it = addedKeys.iterator(); it.hasNext();) {
52
				Object key = it.next();
53
				Object newMasterValue = event.diff.getNewValue(key);
54
				Object newDetailValue = detailProperty.getValue(newMasterValue);
55
				newValues.put(key, newDetailValue);
56
				addPropertySourceListener(source, key, newMasterValue);
57
			}
58
59
			Set removedKeys = event.diff.getRemovedKeys();
60
			for (Iterator it = removedKeys.iterator(); it.hasNext();) {
61
				Object key = it.next();
62
				Object oldMasterValue = event.diff.getOldValue(key);
63
				Object oldDetailValue = detailProperty.getValue(oldMasterValue);
64
				oldValues.put(key, oldDetailValue);
65
				removePropertySourceListener(source, key, oldMasterValue);
66
			}
67
68
			Set changedKeys = new HashSet(event.diff.getChangedKeys());
69
			for (Iterator it = changedKeys.iterator(); it.hasNext();) {
70
				Object key = it.next();
71
72
				Object oldMasterValue = event.diff.getOldValue(key);
73
				Object newMasterValue = event.diff.getNewValue(key);
74
75
				Object oldDetailValue = detailProperty.getValue(oldMasterValue);
76
				Object newDetailValue = detailProperty.getValue(newMasterValue);
77
78
				if (Util.equals(oldDetailValue, newDetailValue)) {
79
					it.remove();
80
				} else {
81
					oldValues.put(key, oldDetailValue);
82
					newValues.put(key, newDetailValue);
83
				}
84
85
				removePropertySourceListener(source, key, oldMasterValue);
86
				addPropertySourceListener(source, key, newMasterValue);
87
			}
88
89
			MapDiff diff = Diffs.createMapDiff(addedKeys, removedKeys,
90
					changedKeys, oldValues, newValues);
91
92
			fireMapChange(source, diff);
93
		}
94
95
		private void addPropertySourceListener(Object source, Object key,
96
				Object masterValue) {
97
			Map keyToDetailListener = (Map) sourceToKeyToDetailListener
98
					.get(source);
99
			if (keyToDetailListener == null) {
100
				sourceToKeyToDetailListener.put(source,
101
						keyToDetailListener = new HashMap());
102
			}
103
			if (!keyToDetailListener.containsKey(key)) {
104
				DetailPropertyListener detailListener = new DetailPropertyListener(
105
						source, key);
106
				detailProperty.addValueChangeListener(masterValue,
107
						detailListener);
108
				keyToDetailListener.put(key, detailListener);
109
			}
110
		}
111
112
		private void removePropertySourceListener(Object source, Object key,
113
				Object masterValue) {
114
			Map keyToDetailListener = (Map) sourceToKeyToDetailListener
115
					.get(source);
116
			if (keyToDetailListener != null
117
					&& keyToDetailListener.containsKey(key)) {
118
				DetailPropertyListener detailListener = (DetailPropertyListener) keyToDetailListener
119
						.remove(key);
120
				detailProperty.removeValueChangeListener(masterValue,
121
						detailListener);
122
			}
123
		}
124
	}
125
126
	private class DetailPropertyListener implements
127
			IValuePropertyChangeListener {
128
		private Object source;
129
		private Object key;
130
131
		DetailPropertyListener(Object source, Object key) {
132
			this.source = source;
133
			this.key = key;
134
		}
135
136
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
137
			fireMapChange(source, Diffs.createMapDiffSingleChange(key,
138
					event.diff.getOldValue(), event.diff.getNewValue()));
139
		}
140
	}
141
142
	/**
143
	 * @param masterProperty
144
	 * @param detailProperty
145
	 */
146
	public MapPropertyDetailValueMap(IMapProperty masterProperty,
147
			IValueProperty detailProperty) {
148
		this.masterProperty = masterProperty;
149
		this.detailProperty = detailProperty;
150
	}
151
152
	protected void addListenerTo(Object source) {
153
		masterProperty.addMapChangeListener(source, masterListener);
154
155
		Map keyToDetailListener = new HashMap();
156
		for (Iterator it = masterProperty.getMap(source).entrySet().iterator(); it
157
				.hasNext();) {
158
			Map.Entry entry = (Map.Entry) it.next();
159
			Object key = entry.getKey();
160
			Object masterValue = entry.getValue();
161
			DetailPropertyListener detailListener = new DetailPropertyListener(
162
					source, key);
163
			detailProperty.addValueChangeListener(masterValue, detailListener);
164
			keyToDetailListener.put(masterValue, detailListener);
165
		}
166
167
		sourceToKeyToDetailListener.put(source, keyToDetailListener);
168
	}
169
170
	protected void removeListenerFrom(Object source) {
171
		masterProperty.removeMapChangeListener(source, masterListener);
172
		Map masterElementToDetailListener = (Map) sourceToKeyToDetailListener
173
				.remove(source);
174
		if (masterElementToDetailListener != null) {
175
			for (Iterator it = masterElementToDetailListener.entrySet()
176
					.iterator(); it.hasNext();) {
177
				Map.Entry entry = (Map.Entry) it.next();
178
				detailProperty.removeValueChangeListener(entry.getKey(),
179
						(DetailPropertyListener) entry.getValue());
180
			}
181
		}
182
	}
183
184
	public Map getMap(Object source) {
185
		Map result = new HashMap();
186
		for (Iterator it = masterProperty.getMap(source).entrySet().iterator(); it
187
				.hasNext();) {
188
			Map.Entry entry = (Map.Entry) it.next();
189
			result.put(entry.getKey(), detailProperty
190
					.getValue(entry.getValue()));
191
		}
192
		return result;
193
	}
194
195
	public void clear(Object source) {
196
		throw new UnsupportedOperationException();
197
	}
198
199
	public Object put(Object source, Object key, Object value) {
200
		if (!masterProperty.containsKey(source, key))
201
			return null;
202
		Object masterValue = masterProperty.get(source, key);
203
204
		Object result = detailProperty.getValue(masterValue);
205
		detailProperty.setValue(masterValue, value);
206
		return result;
207
	}
208
209
	public void putAll(Object source, Map t) {
210
		for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
211
			Map.Entry entry = (Map.Entry) it.next();
212
			Object masterKey = entry.getKey();
213
			Object detailValue = entry.getValue();
214
			if (masterProperty.getMap(source).containsKey(masterKey)) {
215
				detailProperty.setValue(masterKey, detailValue);
216
			}
217
		}
218
	}
219
220
	public Object remove(Object source, Object key) {
221
		throw new UnsupportedOperationException();
222
	}
223
}
(-)src/org/eclipse/core/databinding/property/PropertyChangeSupport.java (+121 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collections;
15
import java.util.IdentityHashMap;
16
import java.util.Iterator;
17
import java.util.Map;
18
19
import org.eclipse.core.runtime.ListenerList;
20
21
/**
22
 * @since 1.2
23
 */
24
public class PropertyChangeSupport {
25
	private Property property;
26
	private Map changeListeners;
27
28
	PropertyChangeSupport(Property property) {
29
		this.property = property;
30
		this.changeListeners = null;
31
	}
32
33
	protected final void addListener(Object source,
34
			IPropertyChangeListener listener) {
35
		boolean hadListeners = hasListeners(source);
36
37
		if (changeListeners == null) {
38
			synchronized (this) {
39
				if (changeListeners == null) {
40
					changeListeners = Collections
41
							.synchronizedMap(new IdentityHashMap());
42
				}
43
			}
44
		}
45
46
		ListenerList listeners;
47
		synchronized (changeListeners) {
48
			if (changeListeners.containsKey(source)) {
49
				listeners = (ListenerList) changeListeners.get(source);
50
			} else {
51
				changeListeners.put(source, listeners = new ListenerList());
52
			}
53
		}
54
55
		synchronized (listeners) {
56
			listeners.add(listener);
57
		}
58
59
		if (!hadListeners)
60
			property.addListenerTo(source);
61
	}
62
63
	/**
64
	 * Returns whether the change support has listeners registered for the given
65
	 * property source
66
	 * 
67
	 * @param source
68
	 *            the property source
69
	 * @return whether the change support has listeners registered for the given
70
	 *         property source
71
	 */
72
	public boolean hasListeners(Object source) {
73
		return changeListeners != null && changeListeners.containsKey(source);
74
	}
75
76
	protected final void removeListener(Object source,
77
			IPropertyChangeListener listener) {
78
		if (changeListeners != null) {
79
			ListenerList listeners = (ListenerList) changeListeners.get(source);
80
			if (listeners != null) {
81
				listeners.remove(listener);
82
				if (listeners.isEmpty()) {
83
					synchronized (listeners) {
84
						if (listeners.isEmpty()) {
85
							changeListeners.remove(source);
86
							property.removeListenerFrom(source);
87
						}
88
					}
89
				}
90
			}
91
		}
92
	}
93
94
	protected final void firePropertyChange(PropertyChangeEvent event) {
95
		ListenerList listenerList;
96
		synchronized (this) {
97
			if (changeListeners == null)
98
				return;
99
			listenerList = (ListenerList) changeListeners
100
					.get(event.getSource());
101
		}
102
		if (listenerList != null) {
103
			Object[] listeners = listenerList.getListeners();
104
			for (int i = 0; i < listeners.length; i++) {
105
				event.dispatch((IPropertyChangeListener) listeners[i]);
106
			}
107
		}
108
	}
109
110
	void dispose() {
111
		if (changeListeners != null) {
112
			for (Iterator iterator = changeListeners.keySet().iterator(); iterator
113
					.hasNext();) {
114
				Object source = iterator.next();
115
				property.removeListenerFrom(source);
116
				iterator.remove();
117
			}
118
			changeListeners = null;
119
		}
120
	}
121
}
(-)src/org/eclipse/core/databinding/property/PropertyObservables.java (+229 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.IObservable;
15
import org.eclipse.core.databinding.observable.Realm;
16
import org.eclipse.core.databinding.observable.list.IObservableList;
17
import org.eclipse.core.databinding.observable.map.IObservableMap;
18
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
19
import org.eclipse.core.databinding.observable.set.IObservableSet;
20
import org.eclipse.core.databinding.observable.value.IObservableValue;
21
import org.eclipse.core.internal.databinding.property.PropertyObservableList;
22
import org.eclipse.core.internal.databinding.property.PropertyObservableMap;
23
import org.eclipse.core.internal.databinding.property.PropertyObservableSet;
24
import org.eclipse.core.internal.databinding.property.PropertyObservableValue;
25
import org.eclipse.core.internal.databinding.property.SetValuePropertyObservableMap;
26
27
/**
28
 * @since 1.2
29
 * 
30
 */
31
public class PropertyObservables {
32
	/**
33
	 * @param source
34
	 * @param property
35
	 * @return an observable value that tracks the given property of the source
36
	 *         object.
37
	 * @since 1.2
38
	 */
39
	public static IObservableValue observeValue(Object source,
40
			IValueProperty property) {
41
		return observeValue(Realm.getDefault(), source, property);
42
	}
43
44
	/**
45
	 * @param realm
46
	 * @param source
47
	 * @param property
48
	 * @return an observable value that tracks the given property of the source
49
	 *         object
50
	 * @since 1.2
51
	 */
52
	public static IObservableValue observeValue(Realm realm, Object source,
53
			IValueProperty property) {
54
		return new PropertyObservableValue(realm, source, property);
55
	}
56
57
	/**
58
	 * @param source
59
	 * @param property
60
	 * @return an observable set that tracks the given property of the source
61
	 *         object
62
	 */
63
	public static IObservableSet observeSet(Object source, ISetProperty property) {
64
		return observeSet(Realm.getDefault(), source, property);
65
	}
66
67
	/**
68
	 * @param realm
69
	 * @param source
70
	 * @param property
71
	 * @return an observable set that tracks the given property of the source
72
	 *         object
73
	 */
74
	public static IObservableSet observeSet(Realm realm, Object source,
75
			ISetProperty property) {
76
		return new PropertyObservableSet(realm, source, property);
77
	}
78
79
	/**
80
	 * @param source
81
	 * @param property
82
	 * @return an observable list that tracks the given property of the source
83
	 *         object
84
	 */
85
	public static IObservableList observeList(Object source,
86
			IListProperty property) {
87
		return observeList(Realm.getDefault(), source, property);
88
	}
89
90
	/**
91
	 * @param realm
92
	 * @param source
93
	 * @param property
94
	 * @return an observable set that tracks the given property of the source
95
	 *         object
96
	 */
97
	public static IObservableList observeList(Realm realm, Object source,
98
			IListProperty property) {
99
		return new PropertyObservableList(realm, source, property);
100
	}
101
102
	/**
103
	 * @param source
104
	 * @param property
105
	 * @return an observable map that tracks the given property of the source
106
	 *         object
107
	 */
108
	public static IObservableMap observeMap(Object source, IMapProperty property) {
109
		return observeMap(Realm.getDefault(), source, property);
110
	}
111
112
	/**
113
	 * @param realm
114
	 * @param source
115
	 * @param property
116
	 * @return an observable set that tracks the given property of the source
117
	 *         object
118
	 */
119
	public static IObservableMap observeMap(Realm realm, Object source,
120
			IMapProperty property) {
121
		return new PropertyObservableMap(realm, source, property);
122
	}
123
124
	/**
125
	 * Returns an observable map in the default realm tracking the current
126
	 * values of the named property for the beans in the given set.
127
	 * 
128
	 * @param keySet
129
	 * @param valueProperty
130
	 * @return an observable map
131
	 */
132
	public static IObservableMap observeMap(IObservableSet keySet,
133
			IValueProperty valueProperty) {
134
		return new SetValuePropertyObservableMap(keySet, valueProperty);
135
	}
136
137
	/**
138
	 * Returns a factory for creating observable values tracking the given
139
	 * property of a particular source object
140
	 * 
141
	 * @param property
142
	 *            the property to be observed
143
	 * @return an observable value factory on
144
	 */
145
	public static IObservableFactory valueFactory(IValueProperty property) {
146
		return valueFactory(Realm.getDefault(), property);
147
	}
148
149
	/**
150
	 * Returns a factory for creating observable values tracking the given
151
	 * property of a particular source object
152
	 * 
153
	 * @param realm
154
	 *            the realm to use
155
	 * @param property
156
	 *            the property to be observed
157
	 * @return an observable value factory on
158
	 */
159
	public static IObservableFactory valueFactory(final Realm realm,
160
			final IValueProperty property) {
161
		return new IObservableFactory() {
162
			public IObservable createObservable(Object target) {
163
				return observeValue(realm, target, property);
164
			}
165
		};
166
	}
167
168
	/**
169
	 * Returns a factory for creating observable sets tracking the given
170
	 * property of a particular source object
171
	 * 
172
	 * @param property
173
	 *            the property to be observed
174
	 * @return an observable value factory on
175
	 */
176
	public static IObservableFactory setFactory(ISetProperty property) {
177
		return setFactory(Realm.getDefault(), property);
178
	}
179
180
	/**
181
	 * Returns a factory for creating obervable sets tracking the given property
182
	 * of a particular source object
183
	 * 
184
	 * @param realm
185
	 *            the realm to use
186
	 * @param property
187
	 *            the property to be observed
188
	 * @return an observable value factory on
189
	 */
190
	public static IObservableFactory setFactory(final Realm realm,
191
			final ISetProperty property) {
192
		return new IObservableFactory() {
193
			public IObservable createObservable(Object target) {
194
				return observeSet(realm, target, property);
195
			}
196
		};
197
	}
198
199
	/**
200
	 * Returns a factory for creating observable lists tracking the given
201
	 * property of a particular source object
202
	 * 
203
	 * @param property
204
	 *            the property to be observed
205
	 * @return an observable value factory on
206
	 */
207
	public static IObservableFactory listFactory(IListProperty property) {
208
		return listFactory(Realm.getDefault(), property);
209
	}
210
211
	/**
212
	 * Returns a factory for creating obervable lists tracking the given
213
	 * property of a particular source object
214
	 * 
215
	 * @param realm
216
	 *            the realm to use
217
	 * @param property
218
	 *            the property to be observed
219
	 * @return an observable value factory on
220
	 */
221
	public static IObservableFactory listFactory(final Realm realm,
222
			final IListProperty property) {
223
		return new IObservableFactory() {
224
			public IObservable createObservable(Object target) {
225
				return observeList(realm, target, property);
226
			}
227
		};
228
	}
229
}
(-)src/org/eclipse/core/internal/databinding/property/masterdetail/ValuePropertyDetailSet.java (+150 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property.masterdetail;
13
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.Map;
17
import java.util.Set;
18
19
import org.eclipse.core.databinding.observable.Diffs;
20
import org.eclipse.core.databinding.observable.set.SetDiff;
21
import org.eclipse.core.databinding.property.ISetProperty;
22
import org.eclipse.core.databinding.property.ISetPropertyChangeListener;
23
import org.eclipse.core.databinding.property.IValueProperty;
24
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
25
import org.eclipse.core.databinding.property.SetProperty;
26
import org.eclipse.core.databinding.property.SetPropertyChangeEvent;
27
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
28
29
/**
30
 * @since 3.3
31
 * 
32
 */
33
public class ValuePropertyDetailSet extends SetProperty {
34
	private final IValueProperty masterProperty;
35
	private final ISetProperty detailProperty;
36
37
	private Map sourceToDetailListener = new HashMap();
38
39
	private IValuePropertyChangeListener masterListener = new MasterPropertyListener();
40
41
	private class MasterPropertyListener implements
42
			IValuePropertyChangeListener {
43
		public void handleValuePropertyChange(ValuePropertyChangeEvent event) {
44
			Object oldSource = event.diff.getOldValue();
45
			Object newSource = event.diff.getNewValue();
46
47
			Set oldSet = detailProperty.getSet(oldSource);
48
			Set newSet = detailProperty.getSet(newSource);
49
			SetDiff diff = Diffs.computeSetDiff(oldSet, newSet);
50
51
			Object source = event.getSource();
52
53
			removeDetailPropertyListener(source);
54
			addDetailPropertyListener(source);
55
56
			fireSetChange(source, diff);
57
		}
58
	}
59
60
	private class DetailPropertyListener implements ISetPropertyChangeListener {
61
		private Object source;
62
		private Object masterValue;
63
64
		DetailPropertyListener(Object source, Object masterValue) {
65
			this.source = source;
66
			this.masterValue = masterValue;
67
		}
68
69
		public void handleSetPropertyChange(SetPropertyChangeEvent event) {
70
			fireSetChange(source, event.diff);
71
		}
72
	}
73
74
	/**
75
	 * @param masterProperty
76
	 * @param detailProperty
77
	 */
78
	public ValuePropertyDetailSet(IValueProperty masterProperty,
79
			ISetProperty detailProperty) {
80
		this.masterProperty = masterProperty;
81
		this.detailProperty = detailProperty;
82
	}
83
84
	protected void addListenerTo(Object source) {
85
		masterProperty.addValueChangeListener(source, masterListener);
86
		addDetailPropertyListener(source);
87
	}
88
89
	protected void removeListenerFrom(Object source) {
90
		masterProperty.removeValueChangeListener(source, masterListener);
91
		removeDetailPropertyListener(source);
92
	}
93
94
	private void addDetailPropertyListener(Object source) {
95
		Object masterValue = masterProperty.getValue(source);
96
		DetailPropertyListener detailListener = new DetailPropertyListener(
97
				source, masterValue);
98
		detailProperty.addSetChangeListener(masterValue, detailListener);
99
		sourceToDetailListener.put(source, detailListener);
100
	}
101
102
	private void removeDetailPropertyListener(Object source) {
103
		DetailPropertyListener detailListener = (DetailPropertyListener) sourceToDetailListener
104
				.remove(source);
105
		if (detailListener != null) {
106
			detailProperty.removeSetChangeListener(detailListener.masterValue,
107
					detailListener);
108
		}
109
		sourceToDetailListener.remove(source);
110
	}
111
112
	public Set getSet(Object source) {
113
		Object masterValue = masterProperty.getValue(source);
114
		return detailProperty.getSet(masterValue);
115
	}
116
117
	public boolean add(Object source, Object o) {
118
		Object masterValue = masterProperty.getValue(source);
119
		return detailProperty.add(masterValue, o);
120
	}
121
122
	public boolean addAll(Object source, Collection c) {
123
		Object masterValue = masterProperty.getValue(source);
124
		return detailProperty.addAll(masterValue, c);
125
	}
126
127
	public void clear(Object source) {
128
		Object masterValue = masterProperty.getValue(source);
129
		detailProperty.clear(masterValue);
130
	}
131
132
	public Object getElementType() {
133
		return detailProperty.getElementType();
134
	}
135
136
	public boolean remove(Object source, Object o) {
137
		Object masterValue = masterProperty.getValue(source);
138
		return detailProperty.remove(masterValue, o);
139
	}
140
141
	public boolean removeAll(Object source, Collection c) {
142
		Object masterValue = masterProperty.getValue(source);
143
		return detailProperty.removeAll(masterValue, c);
144
	}
145
146
	public boolean retainAll(Object source, Collection c) {
147
		Object masterValue = masterProperty.getValue(source);
148
		return detailProperty.retainAll(masterValue, c);
149
	}
150
}
(-)src/org/eclipse/core/internal/databinding/property/PropertyObservableList.java (+374 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.Collections;
17
import java.util.ConcurrentModificationException;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.ListIterator;
21
22
import org.eclipse.core.databinding.observable.ObservableTracker;
23
import org.eclipse.core.databinding.observable.Realm;
24
import org.eclipse.core.databinding.observable.list.AbstractObservableList;
25
import org.eclipse.core.databinding.property.IListProperty;
26
import org.eclipse.core.databinding.property.IListPropertyChangeListener;
27
import org.eclipse.core.databinding.property.IProperty;
28
import org.eclipse.core.databinding.property.IPropertyObservable;
29
import org.eclipse.core.databinding.property.ListPropertyChangeEvent;
30
31
/**
32
 * @since 3.3
33
 * 
34
 */
35
public class PropertyObservableList extends AbstractObservableList implements
36
		IPropertyObservable {
37
	private Object source;
38
	private IListProperty property;
39
40
	private volatile boolean updating = false;
41
42
	private boolean disposed = false;
43
44
	private transient volatile int modCount = 0;
45
46
	private IListPropertyChangeListener listener = new IListPropertyChangeListener() {
47
		public void handleListPropertyChange(final ListPropertyChangeEvent event) {
48
			if (!disposed && !updating) {
49
				getRealm().exec(new Runnable() {
50
					public void run() {
51
						getRealm().exec(new Runnable() {
52
							public void run() {
53
								modCount++;
54
								fireListChange(event.diff);
55
							}
56
						});
57
					}
58
				});
59
			}
60
		}
61
	};
62
63
	/**
64
	 * @param realm
65
	 * @param source
66
	 * @param property
67
	 */
68
	public PropertyObservableList(Realm realm, Object source,
69
			IListProperty property) {
70
		super(realm);
71
		this.source = source;
72
		this.property = property;
73
	}
74
75
	protected void firstListenerAdded() {
76
		if (!disposed) {
77
			property.addListChangeListener(source, listener);
78
		}
79
	}
80
81
	protected void lastListenerRemoved() {
82
		if (!disposed) {
83
			property.removeListChangeListener(source, listener);
84
		}
85
	}
86
87
	private void getterCalled() {
88
		ObservableTracker.getterCalled(this);
89
	}
90
91
	public Object getElementType() {
92
		return property.getElementType();
93
	}
94
95
	// Queries
96
97
	protected int doGetSize() {
98
		return property.size(source);
99
	}
100
101
	public boolean contains(Object o) {
102
		getterCalled();
103
		return property.contains(source, o);
104
	}
105
106
	public boolean containsAll(Collection c) {
107
		getterCalled();
108
		return property.containsAll(source, c);
109
	}
110
111
	public Object get(int index) {
112
		getterCalled();
113
		return property.get(source, index);
114
	}
115
116
	public int indexOf(Object o) {
117
		getterCalled();
118
		return property.indexOf(source, o);
119
	}
120
121
	public boolean isEmpty() {
122
		getterCalled();
123
		return property.isEmpty(source);
124
	}
125
126
	public int lastIndexOf(Object o) {
127
		getterCalled();
128
		return property.lastIndexOf(source, o);
129
	}
130
131
	public Object[] toArray() {
132
		getterCalled();
133
		return property.toArray(source);
134
	}
135
136
	public Object[] toArray(Object[] a) {
137
		getterCalled();
138
		return property.toArray(source, a);
139
	}
140
141
	// Single change operations
142
143
	public boolean add(Object o) {
144
		checkRealm();
145
		return property.add(source, o);
146
	}
147
148
	public Iterator iterator() {
149
		getterCalled();
150
		return new Iterator() {
151
			int lastReturned = -1;
152
			int expectedModCount = modCount;
153
			ListIterator delegate = new ArrayList(property.getList(source))
154
					.listIterator();
155
156
			public boolean hasNext() {
157
				getterCalled();
158
				checkForComodification();
159
				return delegate.hasNext();
160
			}
161
162
			public Object next() {
163
				getterCalled();
164
				checkForComodification();
165
				Object next = delegate.next();
166
				lastReturned = delegate.previousIndex();
167
				return next;
168
			}
169
170
			public void remove() {
171
				checkRealm();
172
				checkForComodification();
173
				if (lastReturned == -1)
174
					throw new IllegalStateException();
175
176
				delegate.remove(); // stay in sync
177
178
				property.remove(source, lastReturned);
179
180
				lastReturned = -1;
181
				expectedModCount = modCount;
182
			}
183
184
			private void checkForComodification() {
185
				if (expectedModCount != modCount)
186
					throw new ConcurrentModificationException();
187
			}
188
		};
189
	}
190
191
	public Object move(int oldIndex, int newIndex) {
192
		getterCalled();
193
		return property.move(source, oldIndex, newIndex);
194
	}
195
196
	public boolean remove(Object o) {
197
		getterCalled();
198
		return property.remove(source, o);
199
	}
200
201
	public void add(int index, Object o) {
202
		getterCalled();
203
		property.add(source, index, o);
204
	}
205
206
	public ListIterator listIterator() {
207
		return listIterator(0);
208
	}
209
210
	public ListIterator listIterator(final int index) {
211
		getterCalled();
212
		return new ListIterator() {
213
			int lastReturned = -1;
214
			int expectedModCount = modCount;
215
			ListIterator delegate = new ArrayList(property.getList(source))
216
					.listIterator(index);
217
218
			public boolean hasNext() {
219
				getterCalled();
220
				checkForComodification();
221
				return delegate.hasNext();
222
			}
223
224
			public int nextIndex() {
225
				getterCalled();
226
				checkForComodification();
227
				return delegate.nextIndex();
228
			}
229
230
			public Object next() {
231
				getterCalled();
232
				checkForComodification();
233
				Object next = delegate.next();
234
				lastReturned = delegate.previousIndex();
235
				return next;
236
			}
237
238
			public boolean hasPrevious() {
239
				getterCalled();
240
				checkForComodification();
241
				return delegate.hasPrevious();
242
			}
243
244
			public int previousIndex() {
245
				getterCalled();
246
				checkForComodification();
247
				return delegate.previousIndex();
248
			}
249
250
			public Object previous() {
251
				getterCalled();
252
				checkForComodification();
253
				Object previous = delegate.previous();
254
				lastReturned = delegate.nextIndex();
255
				return previous;
256
			}
257
258
			public void add(Object o) {
259
				checkRealm();
260
				checkForComodification();
261
				int index = delegate.nextIndex();
262
263
				delegate.add(o); // keep in sync
264
265
				property.add(source, index, o);
266
267
				lastReturned = -1;
268
				expectedModCount = modCount;
269
			}
270
271
			public void set(Object o) {
272
				checkRealm();
273
				checkForComodification();
274
275
				delegate.set(o);
276
277
				property.set(source, lastReturned, o);
278
279
				expectedModCount = modCount;
280
			}
281
282
			public void remove() {
283
				checkRealm();
284
				checkForComodification();
285
				if (lastReturned == -1)
286
					throw new IllegalStateException();
287
288
				delegate.remove(); // keep in sync
289
290
				property.remove(source, lastReturned);
291
292
				lastReturned = -1;
293
				expectedModCount = modCount;
294
			}
295
296
			private void checkForComodification() {
297
				if (expectedModCount != modCount)
298
					throw new ConcurrentModificationException();
299
			}
300
301
		};
302
	}
303
304
	public Object remove(int index) {
305
		getterCalled();
306
		return property.remove(source, index);
307
	}
308
309
	public Object set(int index, Object o) {
310
		getterCalled();
311
		return property.set(source, index, o);
312
	}
313
314
	public List subList(int fromIndex, int toIndex) {
315
		getterCalled();
316
		return Collections.unmodifiableList(property.getList(source).subList(
317
				fromIndex, toIndex));
318
	}
319
320
	// Bulk change operations
321
322
	public boolean addAll(Collection c) {
323
		getterCalled();
324
		return property.addAll(source, c);
325
	}
326
327
	public boolean addAll(int index, Collection c) {
328
		getterCalled();
329
		return property.addAll(source, index, c);
330
	}
331
332
	public boolean removeAll(Collection c) {
333
		getterCalled();
334
		return property.removeAll(source, c);
335
	}
336
337
	public boolean retainAll(Collection c) {
338
		getterCalled();
339
		return property.retainAll(source, c);
340
	}
341
342
	public void clear() {
343
		getterCalled();
344
		property.clear(source);
345
	}
346
347
	public boolean equals(Object o) {
348
		getterCalled();
349
		return property.equals(source, o);
350
	}
351
352
	public int hashCode() {
353
		getterCalled();
354
		return property.hashCode(source);
355
	}
356
357
	public Object getObserved() {
358
		return source;
359
	}
360
361
	public IProperty getProperty() {
362
		return property;
363
	}
364
365
	public synchronized void dispose() {
366
		if (!disposed) {
367
			disposed = true;
368
			property.removeListChangeListener(source, listener);
369
			property = null;
370
			source = null;
371
		}
372
		super.dispose();
373
	}
374
}
(-)src/org/eclipse/core/internal/databinding/property/PropertyUpdateHelper.java (+65 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import java.util.HashMap;
15
import java.util.Map;
16
17
/**
18
 * @since 3.3
19
 * 
20
 */
21
public class PropertyUpdateHelper {
22
	private ThreadLocal localMap = new ThreadLocal() {
23
		protected Object initialValue() {
24
			return new HashMap();
25
		}
26
	};
27
28
	/**
29
	 * @param source
30
	 * @return blah
31
	 */
32
	public boolean isUpdating(Object source) {
33
		Map map = (Map) localMap.get();
34
		return map.containsKey(source);
35
	}
36
37
	/**
38
	 * @param source
39
	 * @param state
40
	 */
41
	public void setUpdating(Object source, boolean state) {
42
		Map map = (Map) localMap.get();
43
		Integer count = (Integer) map.get(source);
44
		int newCount = (count == null ? 0 : count.intValue())
45
				+ (state ? 1 : -1);
46
		if (newCount > 0)
47
			map.put(source, new Integer(newCount));
48
		else
49
			map.remove(source);
50
	}
51
52
	/**
53
	 * 
54
	 */
55
	public void dispose() {
56
		if (localMap != null) {
57
			Map map = (Map) localMap.get();
58
			if (map != null) {
59
				map.clear();
60
				localMap.set(null);
61
			}
62
			localMap = null;
63
		}
64
	}
65
}
(-)src/org/eclipse/core/internal/databinding/property/PropertyObservableSet.java (+197 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import java.util.Collection;
15
import java.util.ConcurrentModificationException;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.Set;
19
20
import org.eclipse.core.databinding.observable.Realm;
21
import org.eclipse.core.databinding.observable.set.AbstractObservableSet;
22
import org.eclipse.core.databinding.property.IProperty;
23
import org.eclipse.core.databinding.property.IPropertyObservable;
24
import org.eclipse.core.databinding.property.ISetProperty;
25
import org.eclipse.core.databinding.property.ISetPropertyChangeListener;
26
import org.eclipse.core.databinding.property.SetPropertyChangeEvent;
27
28
/**
29
 * @since 3.3
30
 * 
31
 */
32
public class PropertyObservableSet extends AbstractObservableSet implements
33
		IPropertyObservable {
34
	private Object source;
35
	private ISetProperty property;
36
37
	private boolean updating = false;
38
39
	private boolean disposed = false;
40
41
	private transient volatile int modCount = 0;
42
43
	private ISetPropertyChangeListener listener = new ISetPropertyChangeListener() {
44
		public void handleSetPropertyChange(final SetPropertyChangeEvent event) {
45
			if (!disposed && !updating) {
46
				getRealm().exec(new Runnable() {
47
					public void run() {
48
						getRealm().exec(new Runnable() {
49
							public void run() {
50
								modCount++;
51
								fireSetChange(event.diff);
52
							}
53
						});
54
					}
55
				});
56
			}
57
		}
58
	};
59
60
	/**
61
	 * @param realm
62
	 * @param source
63
	 * @param property
64
	 */
65
	public PropertyObservableSet(Realm realm, Object source,
66
			ISetProperty property) {
67
		super(realm);
68
		this.source = source;
69
		this.property = property;
70
	}
71
72
	protected void firstListenerAdded() {
73
		if (!disposed) {
74
			property.addSetChangeListener(source, listener);
75
		}
76
	}
77
78
	protected void lastListenerRemoved() {
79
		if (!disposed) {
80
			property.removeSetChangeListener(source, listener);
81
		}
82
	}
83
84
	protected Set getWrappedSet() {
85
		return property.getSet(source);
86
	}
87
88
	public Object getElementType() {
89
		return property.getElementType();
90
	}
91
92
	// Queries
93
94
	protected int doGetSize() {
95
		return property.size(source);
96
	}
97
98
	// Single change operations
99
100
	public boolean add(Object o) {
101
		checkRealm();
102
		return property.add(source, o);
103
	}
104
105
	public Iterator iterator() {
106
		getterCalled();
107
		return new Iterator() {
108
			int expectedModCount = modCount;
109
			Iterator delegate = new HashSet(property.getSet(source)).iterator();
110
			Object last = null;
111
112
			public boolean hasNext() {
113
				getterCalled();
114
				checkForComodification();
115
				return delegate.hasNext();
116
			}
117
118
			public Object next() {
119
				getterCalled();
120
				checkForComodification();
121
				Object next = delegate.next();
122
				last = next;
123
				return next;
124
			}
125
126
			public void remove() {
127
				checkRealm();
128
				checkForComodification();
129
130
				delegate.remove(); // stay in sync
131
132
				property.remove(source, last);
133
134
				last = null;
135
				expectedModCount = modCount;
136
			}
137
138
			private void checkForComodification() {
139
				if (expectedModCount != modCount)
140
					throw new ConcurrentModificationException();
141
			}
142
		};
143
	}
144
145
	public boolean remove(Object o) {
146
		getterCalled();
147
		return property.remove(source, o);
148
	}
149
150
	// Bulk change operations
151
152
	public boolean addAll(Collection c) {
153
		getterCalled();
154
		return property.addAll(source, c);
155
	}
156
157
	public boolean removeAll(Collection c) {
158
		getterCalled();
159
		return property.removeAll(source, c);
160
	}
161
162
	public boolean retainAll(Collection c) {
163
		getterCalled();
164
		return property.retainAll(source, c);
165
	}
166
167
	public void clear() {
168
		getterCalled();
169
		property.clear(source);
170
	}
171
172
	public boolean equals(Object o) {
173
		return property.equals(source, o);
174
	}
175
176
	public int hashCode() {
177
		return property.hashCode(source);
178
	}
179
180
	public Object getObserved() {
181
		return source;
182
	}
183
184
	public IProperty getProperty() {
185
		return property;
186
	}
187
188
	public synchronized void dispose() {
189
		if (!disposed) {
190
			disposed = true;
191
			property.removeSetChangeListener(source, listener);
192
			property = null;
193
			source = null;
194
		}
195
		super.dispose();
196
	}
197
}
(-)src/org/eclipse/core/databinding/property/IPropertyChangeListener.java (+23 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * Marker interface for all listener types in the properties framework.
16
 * 
17
 * @noimplement This interface is not intended to be implemented by clients.
18
 * 
19
 * @since 1.2
20
 */
21
public interface IPropertyChangeListener {
22
23
}
(-)src/org/eclipse/core/databinding/property/CollectionProperty.java (+55 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import java.util.Collection;
15
16
/**
17
 * @since 1.2
18
 * 
19
 */
20
public abstract class CollectionProperty extends Property implements
21
		ICollectionProperty {
22
	abstract Collection getCollection(Object source);
23
24
	public boolean contains(Object source, Object o) {
25
		return getCollection(source).contains(o);
26
	}
27
28
	public boolean containsAll(Object source, Collection c) {
29
		return getCollection(source).containsAll(c);
30
	}
31
32
	public boolean equals(Object source, Object o) {
33
		return getCollection(source).equals(o);
34
	}
35
36
	public int hashCode(Object source) {
37
		return getCollection(source).hashCode();
38
	}
39
40
	public boolean isEmpty(Object source) {
41
		return getCollection(source).isEmpty();
42
	}
43
44
	public int size(Object source) {
45
		return getCollection(source).size();
46
	}
47
48
	public Object[] toArray(Object source, Object[] array) {
49
		return getCollection(source).toArray(array);
50
	}
51
52
	public Object[] toArray(Object source) {
53
		return getCollection(source).toArray();
54
	}
55
}
(-)src/org/eclipse/core/internal/databinding/property/SetValuePropertyObservableMap.java (+92 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import org.eclipse.core.databinding.observable.Diffs;
15
import org.eclipse.core.databinding.observable.IObserving;
16
import org.eclipse.core.databinding.observable.map.ComputedObservableMap;
17
import org.eclipse.core.databinding.observable.set.IObservableSet;
18
import org.eclipse.core.databinding.property.IValueProperty;
19
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
20
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
21
22
/**
23
 * @since 3.3
24
 * 
25
 */
26
public class SetValuePropertyObservableMap extends ComputedObservableMap
27
		implements IObserving {
28
	private IValueProperty property;
29
30
	private boolean disposed = false;
31
32
	private IValuePropertyChangeListener listener = new IValuePropertyChangeListener() {
33
		public void handleValuePropertyChange(
34
				final ValuePropertyChangeEvent event) {
35
			if (!disposed) {
36
				getRealm().exec(new Runnable() {
37
					public void run() {
38
						Object key = event.getSource();
39
						Object oldValue = event.diff.getOldValue();
40
						Object newValue = event.diff.getNewValue();
41
						fireMapChange(Diffs.createMapDiffSingleChange(key,
42
								oldValue, newValue));
43
					}
44
				});
45
			}
46
		}
47
	};
48
49
	/**
50
	 * @param keySet
51
	 * @param valueProperty
52
	 */
53
	public SetValuePropertyObservableMap(IObservableSet keySet,
54
			IValueProperty valueProperty) {
55
		super(keySet);
56
		this.property = valueProperty;
57
	}
58
59
	protected Object doGet(Object key) {
60
		return property.getValue(key);
61
	}
62
63
	protected Object doPut(Object key, Object value) {
64
		Object result = property.getValue(key);
65
		property.setValue(key, value);
66
		return result;
67
	}
68
69
	protected void hookListener(Object addedKey) {
70
		if (!disposed)
71
			property.addValueChangeListener(addedKey, listener);
72
	}
73
74
	protected void unhookListener(Object removedKey) {
75
		if (!disposed)
76
			property.removeValueChangeListener(removedKey, listener);
77
	}
78
79
	public Object getObserved() {
80
		return keySet();
81
	}
82
83
	public synchronized void dispose() {
84
		super.dispose();
85
86
		if (!disposed) {
87
			disposed = true;
88
			property = null;
89
			listener = null;
90
		}
91
	}
92
}
(-)src/org/eclipse/core/databinding/property/BasicValueProperty.java (+57 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 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
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
import org.eclipse.core.databinding.observable.Diffs;
15
import org.eclipse.core.internal.databinding.Util;
16
import org.eclipse.core.internal.databinding.property.PropertyUpdateHelper;
17
18
/**
19
 * @since 1.2
20
 * 
21
 */
22
public abstract class BasicValueProperty extends ValueProperty {
23
	private PropertyUpdateHelper updateHelper = new PropertyUpdateHelper();
24
25
	protected boolean isUpdating(Object source) {
26
		return updateHelper.isUpdating(source);
27
	}
28
29
	public void setValue(Object source, Object value) {
30
		Object oldValue = getValue(source);
31
32
		updateHelper.setUpdating(source, true);
33
		try {
34
			doSetValue(source, value);
35
		} finally {
36
			updateHelper.setUpdating(source, false);
37
		}
38
39
		if (hasListeners(source)) {
40
			Object newValue = getValue(source);
41
			if (!Util.equals(oldValue, newValue)) {
42
				fireValueChange(source, Diffs.createValueDiff(oldValue,
43
						newValue));
44
			}
45
		}
46
	}
47
48
	protected abstract void doSetValue(Object source, Object value);
49
50
	public synchronized void dispose() {
51
		if (updateHelper != null) {
52
			updateHelper.dispose();
53
			updateHelper = null;
54
		}
55
		super.dispose();
56
	}
57
}
(-)src/org/eclipse/core/internal/databinding/property/PropertyObservableValue.java (+115 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.internal.databinding.property;
13
14
import org.eclipse.core.databinding.observable.Diffs;
15
import org.eclipse.core.databinding.observable.Realm;
16
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
17
import org.eclipse.core.databinding.property.IProperty;
18
import org.eclipse.core.databinding.property.IPropertyObservable;
19
import org.eclipse.core.databinding.property.IValueProperty;
20
import org.eclipse.core.databinding.property.IValuePropertyChangeListener;
21
import org.eclipse.core.databinding.property.ValuePropertyChangeEvent;
22
import org.eclipse.core.internal.databinding.Util;
23
24
/**
25
 * @since 1.2
26
 * 
27
 */
28
public class PropertyObservableValue extends AbstractObservableValue implements
29
		IPropertyObservable {
30
	private Object source;
31
	private IValueProperty property;
32
33
	private boolean updating = false;
34
35
	private boolean disposed = false;
36
37
	private IValuePropertyChangeListener listener = new IValuePropertyChangeListener() {
38
		public void handleValuePropertyChange(
39
				final ValuePropertyChangeEvent event) {
40
			if (!disposed && !updating) {
41
				getRealm().exec(new Runnable() {
42
					public void run() {
43
						fireValueChange(event.diff);
44
					}
45
				});
46
			}
47
		}
48
	};
49
50
	/**
51
	 * @param realm
52
	 * @param source
53
	 * @param property
54
	 */
55
	public PropertyObservableValue(Realm realm, Object source,
56
			IValueProperty property) {
57
		super(realm);
58
		this.source = source;
59
		this.property = property;
60
	}
61
62
	protected void firstListenerAdded() {
63
		if (!disposed) {
64
			property.addValueChangeListener(source, listener);
65
		}
66
	}
67
68
	protected void lastListenerRemoved() {
69
		if (!disposed) {
70
			property.removeValueChangeListener(source, listener);
71
		}
72
	}
73
74
	protected Object doGetValue() {
75
		return property.getValue(source);
76
	}
77
78
	protected void doSetValue(Object value) {
79
		Object oldValue = doGetValue();
80
81
		updating = true;
82
		try {
83
			property.setValue(source, value);
84
		} finally {
85
			updating = false;
86
		}
87
88
		Object newValue = doGetValue();
89
		if (!Util.equals(oldValue, newValue)) {
90
			fireValueChange(Diffs.createValueDiff(oldValue, newValue));
91
		}
92
	}
93
94
	public Object getValueType() {
95
		return property.getValueType();
96
	}
97
98
	public Object getObserved() {
99
		return source;
100
	}
101
102
	public IProperty getProperty() {
103
		return property;
104
	}
105
106
	public synchronized void dispose() {
107
		if (!disposed) {
108
			disposed = true;
109
			property.removeValueChangeListener(source, listener);
110
			property = null;
111
			source = null;
112
		}
113
		super.dispose();
114
	}
115
}
(-)src/org/eclipse/core/databinding/property/IListPropertyChangeListener.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 */
17
public interface IListPropertyChangeListener extends IPropertyChangeListener {
18
	/**
19
	 * @param event
20
	 */
21
	public void handleListPropertyChange(ListPropertyChangeEvent event);
22
}
(-)src/org/eclipse/core/databinding/property/Property.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Matthew Hall 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
 *     Matthew Hall - initial API and implementation (bug 194734)
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding.property;
13
14
/**
15
 * @since 1.2
16
 * 
17
 */
18
public abstract class Property implements IProperty {
19
	private PropertyChangeSupport changeSupport;
20
21
	synchronized PropertyChangeSupport getChangeSupport() {
22
		if (changeSupport == null)
23
			changeSupport = new PropertyChangeSupport(this);
24
		return changeSupport;
25
	}
26
27
	/**
28
	 * Notifies the property that the first listener has been added for the
29
	 * given source object. Implementers should register a listener on the
30
	 * source object which fires an appropriate change event when a property
31
	 * change is observed on the source.
32
	 * 
33
	 * @param source
34
	 *            the source object to observe for property changes.
35
	 * @see #removeListenerFrom(Object)
36
	 */
37
	protected abstract void addListenerTo(Object source);
38
39
	/**
40
	 * Notifies the property that the last listener has been removed for the
41
	 * given source object. Implementers should unregister any previously
42
	 * registered listeners from the source.
43
	 * 
44
	 * @param source
45
	 *            the source object to stop observing for property changes.
46
	 * @see #addListenerTo(Object)
47
	 */
48
	protected abstract void removeListenerFrom(Object source);
49
50
	/**
51
	 * Returns whether this property has listeners registered for the given
52
	 * property source
53
	 * 
54
	 * @param source
55
	 *            the property source
56
	 * @return whether this property has listeners registered for the given
57
	 *         property source
58
	 */
59
	protected boolean hasListeners(Object source) {
60
		return changeSupport != null && changeSupport.hasListeners(source);
61
	}
62
63
	public synchronized void dispose() {
64
		if (changeSupport != null) {
65
			changeSupport.dispose();
66
			changeSupport = null;
67
		}
68
	}
69
}

Return to bug 194734