78
|
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 159539
|
|
11 * Brad Reynolds - bug 140644
|
|
12 * Brad Reynolds - bug 159940
|
|
13 * Brad Reynolds - bug 116920, 159768
|
|
14 * Matthew Hall - bugs 118516, 124684, 218269
|
|
15 * Boris Bokowski - bug 218269
|
|
16 *******************************************************************************/
|
|
17 module org.eclipse.core.databinding.DataBindingContext;
|
81
|
18 import org.eclipse.core.databinding.ListBinding;
|
|
19 import org.eclipse.core.databinding.ValueBinding;
|
|
20 import org.eclipse.core.databinding.UpdateListStrategy;
|
|
21 import org.eclipse.core.databinding.UpdateValueStrategy;
|
|
22 import org.eclipse.core.databinding.UpdateSetStrategy;
|
|
23 import org.eclipse.core.databinding.SetBinding;
|
|
24 import org.eclipse.core.databinding.Binding;
|
|
25 import org.eclipse.core.databinding.ValidationStatusProvider;
|
78
|
26
|
|
27 import java.lang.all;
|
|
28
|
|
29 import java.util.Iterator;
|
|
30
|
|
31 import org.eclipse.core.databinding.observable.Observables;
|
|
32 import org.eclipse.core.databinding.observable.Realm;
|
|
33 import org.eclipse.core.databinding.observable.list.IObservableList;
|
|
34 import org.eclipse.core.databinding.observable.list.WritableList;
|
|
35 import org.eclipse.core.databinding.observable.map.IObservableMap;
|
|
36 import org.eclipse.core.databinding.observable.set.IObservableSet;
|
|
37 import org.eclipse.core.databinding.observable.value.IObservableValue;
|
|
38 import org.eclipse.core.internal.databinding.ValidationStatusMap;
|
|
39 import org.eclipse.core.runtime.Assert;
|
|
40 import org.eclipse.core.runtime.IStatus;
|
|
41
|
|
42 /**
|
|
43 * A DataBindingContext is the point of contact for the creation and management
|
|
44 * of {@link Binding bindings}, and aggregates validation statuses of its
|
|
45 * bindings, or more generally, its validation status providers.
|
|
46 * <p>
|
|
47 * A DataBindingContext provides the following abilities:
|
|
48 * <ul>
|
|
49 * <li>Ability to create bindings between
|
|
50 * {@link IObservableValue observable values}.</li>
|
|
51 * <li>Ability to create bindings between
|
|
52 * {@link IObservableList observable lists}.</li>
|
|
53 * <li>Access to the bindings created by the instance.</li>
|
|
54 * <li>Access to the list of validation status providers (this includes all
|
|
55 * bindings).</li>
|
|
56 * </ul>
|
|
57 * </p>
|
|
58 * <p>
|
|
59 * Multiple contexts can be used at any point in time. One strategy for the
|
|
60 * management of contexts is the aggregation of validation statuses. For example
|
|
61 * an <code>IWizardPage</code> could use a single context and the statuses
|
|
62 * could be aggregated to set the page status and fulfillment. Each page in the
|
|
63 * <code>IWizard</code> would have its own context instance.
|
|
64 * </p>
|
|
65 *
|
|
66 * @since 1.0
|
|
67 */
|
|
68 public class DataBindingContext {
|
|
69 private WritableList bindings;
|
|
70 private WritableList validationStatusProviders;
|
|
71
|
|
72 /**
|
|
73 * Unmodifiable version of {@link #bindings} for public exposure.
|
|
74 */
|
|
75 private IObservableList unmodifiableBindings;
|
|
76 /**
|
|
77 * Unmodifiable version of {@link #validationStatusProviders} for public
|
|
78 * exposure.
|
|
79 */
|
|
80 private IObservableList unmodifiableStatusProviders;
|
|
81
|
|
82 private IObservableMap validationStatusMap;
|
|
83
|
|
84 private Realm validationRealm;
|
|
85
|
|
86 /**
|
|
87 * Creates a data binding context, using the current default realm for the
|
|
88 * validation observables.
|
|
89 *
|
|
90 * @see Realm
|
|
91 */
|
|
92 public this() {
|
|
93 this(Realm.getDefault());
|
|
94 }
|
|
95
|
|
96 /**
|
|
97 * Creates a data binding context using the given realm for the validation
|
|
98 * observables.
|
|
99 *
|
|
100 * @param validationRealm
|
|
101 * the realm to be used for the validation observables
|
|
102 *
|
|
103 * @see Realm
|
|
104 */
|
|
105 public this(Realm validationRealm) {
|
|
106 Assert.isNotNull(validationRealm, "Validation realm cannot be null"); //$NON-NLS-1$
|
|
107 this.validationRealm = validationRealm;
|
|
108
|
|
109 bindings = new WritableList(validationRealm);
|
|
110 unmodifiableBindings = Observables.unmodifiableObservableList(bindings);
|
|
111
|
|
112 validationStatusProviders = new WritableList(validationRealm);
|
|
113 unmodifiableStatusProviders = Observables
|
|
114 .unmodifiableObservableList(validationStatusProviders);
|
|
115
|
|
116 validationStatusMap = new ValidationStatusMap(validationRealm, bindings);
|
|
117 }
|
|
118
|
|
119 /**
|
|
120 * Creates a {@link Binding} to synchronize the values of two
|
|
121 * {@link IObservableValue observable values}. During synchronization
|
|
122 * validation and conversion can be employed to customize the process. For
|
|
123 * specifics on the customization of the process see
|
|
124 * {@link UpdateValueStrategy}.
|
|
125 *
|
|
126 * @param targetObservableValue
|
|
127 * target value, commonly a UI widget
|
|
128 * @param modelObservableValue
|
|
129 * model value
|
|
130 * @param targetToModel
|
|
131 * strategy to employ when the target is the source of the change
|
|
132 * and the model is the destination
|
|
133 * @param modelToTarget
|
|
134 * strategy to employ when the model is the source of the change
|
|
135 * and the target is the destination
|
|
136 * @return created binding
|
|
137 *
|
|
138 * @see UpdateValueStrategy
|
|
139 */
|
|
140 public final Binding bindValue(IObservableValue targetObservableValue,
|
|
141 IObservableValue modelObservableValue,
|
|
142 UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
|
|
143 UpdateValueStrategy targetToModelStrategy = targetToModel !is null ? targetToModel
|
|
144 : createTargetToModelUpdateValueStrategy(targetObservableValue, modelObservableValue);
|
|
145 UpdateValueStrategy modelToTargetStrategy = modelToTarget !is null ? modelToTarget
|
|
146 : createModelToTargetUpdateValueStrategy(modelObservableValue, targetObservableValue);
|
|
147 targetToModelStrategy.fillDefaults(targetObservableValue, modelObservableValue);
|
|
148 modelToTargetStrategy.fillDefaults(modelObservableValue, targetObservableValue);
|
|
149 ValueBinding result = new ValueBinding(targetObservableValue,
|
|
150 modelObservableValue, targetToModelStrategy,
|
|
151 modelToTargetStrategy);
|
|
152 result.init(this);
|
|
153 return result;
|
|
154 }
|
|
155
|
|
156 /**
|
|
157 * Returns an update value strategy to be used for copying values from the
|
|
158 * from value to the to value. Clients may override.
|
|
159 *
|
|
160 * @param fromValue
|
|
161 * @param toValue
|
|
162 * @return a update value strategy
|
|
163 */
|
|
164 protected UpdateValueStrategy createModelToTargetUpdateValueStrategy(
|
|
165 IObservableValue fromValue, IObservableValue toValue) {
|
|
166 return new UpdateValueStrategy();
|
|
167 }
|
|
168
|
|
169 /**
|
|
170 * Returns an update value strategy to be used for copying values from the
|
|
171 * from value to the to value. Clients may override.
|
|
172 *
|
|
173 * @param fromValue
|
|
174 * @param toValue
|
|
175 * @return a update value strategy
|
|
176 */
|
|
177 protected UpdateValueStrategy createTargetToModelUpdateValueStrategy(
|
|
178 IObservableValue fromValue, IObservableValue toValue) {
|
|
179 return new UpdateValueStrategy();
|
|
180 }
|
|
181
|
|
182 /**
|
|
183 * Creates a {@link Binding} to synchronize the values of two
|
|
184 * {@link IObservableList observable lists}. During synchronization
|
|
185 * validation and conversion can be employed to customize the process. For
|
|
186 * specifics on the customization of the process see
|
|
187 * {@link UpdateListStrategy}.
|
|
188 *
|
|
189 * @param targetObservableList
|
|
190 * target list, commonly a list representing a list in the UI
|
|
191 * @param modelObservableList
|
|
192 * model list
|
|
193 * @param targetToModel
|
|
194 * strategy to employ when the target is the source of the change
|
|
195 * and the model is the destination
|
|
196 * @param modelToTarget
|
|
197 * strategy to employ when the model is the source of the change
|
|
198 * and the target is the destination
|
|
199 * @return created binding
|
|
200 *
|
|
201 * @see UpdateListStrategy
|
|
202 */
|
|
203 public final Binding bindList(IObservableList targetObservableList,
|
|
204 IObservableList modelObservableList,
|
|
205 UpdateListStrategy targetToModel, UpdateListStrategy modelToTarget) {
|
|
206 UpdateListStrategy targetToModelStrategy = targetToModel !is null ? targetToModel
|
|
207 : createTargetToModelUpdateListStrategy(targetObservableList,
|
|
208 modelObservableList);
|
|
209 UpdateListStrategy modelToTargetStrategy = modelToTarget !is null ? modelToTarget
|
|
210 : createModelToTargetUpdateListStrategy(modelObservableList,
|
|
211 targetObservableList);
|
|
212 targetToModelStrategy.fillDefaults(targetObservableList,
|
|
213 modelObservableList);
|
|
214 modelToTargetStrategy.fillDefaults(modelObservableList,
|
|
215 targetObservableList);
|
|
216 ListBinding result = new ListBinding(targetObservableList,
|
|
217 modelObservableList, targetToModelStrategy,
|
|
218 modelToTargetStrategy);
|
|
219 result.init(this);
|
|
220 return result;
|
|
221 }
|
|
222
|
|
223 /**
|
|
224 * @param modelObservableList
|
|
225 * @param targetObservableList
|
|
226 * @return an update list strategy
|
|
227 */
|
|
228 protected UpdateListStrategy createModelToTargetUpdateListStrategy(
|
|
229 IObservableList modelObservableList,
|
|
230 IObservableList targetObservableList) {
|
|
231 return new UpdateListStrategy();
|
|
232 }
|
|
233
|
|
234 /**
|
|
235 * @param targetObservableList
|
|
236 * @param modelObservableList
|
|
237 * @return an update list strategy
|
|
238 */
|
|
239 protected UpdateListStrategy createTargetToModelUpdateListStrategy(
|
|
240 IObservableList targetObservableList,
|
|
241 IObservableList modelObservableList) {
|
|
242 return new UpdateListStrategy();
|
|
243 }
|
|
244
|
|
245 /**
|
|
246 * Creates a {@link Binding} to synchronize the values of two
|
|
247 * {@link IObservableSet observable sets}. During synchronization
|
|
248 * validation and conversion can be employed to customize the process. For
|
|
249 * specifics on the customization of the process see
|
|
250 * {@link UpdateSetStrategy}.
|
|
251 *
|
|
252 * @param targetObservableSet
|
|
253 * target set, commonly a set representing a set in the UI
|
|
254 * @param modelObservableSet
|
|
255 * model set
|
|
256 * @param targetToModel
|
|
257 * strategy to employ when the target is the source of the change
|
|
258 * and the model is the destination
|
|
259 * @param modelToTarget
|
|
260 * strategy to employ when the model is the source of the change
|
|
261 * and the target is the destination
|
|
262 * @return created binding
|
|
263 * @since 1.1
|
|
264 */
|
|
265 public final Binding bindSet(IObservableSet targetObservableSet,
|
|
266 IObservableSet modelObservableSet, UpdateSetStrategy targetToModel,
|
|
267 UpdateSetStrategy modelToTarget) {
|
|
268 if (targetToModel is null)
|
|
269 targetToModel = createTargetToModelUpdateSetStrategy(
|
|
270 targetObservableSet, modelObservableSet);
|
|
271 if (modelToTarget is null)
|
|
272 modelToTarget = createModelToTargetUpdateSetStrategy(
|
|
273 modelObservableSet, targetObservableSet);
|
|
274 targetToModel.fillDefaults(targetObservableSet, modelObservableSet);
|
|
275 modelToTarget.fillDefaults(modelObservableSet, targetObservableSet);
|
|
276 SetBinding result = new SetBinding(targetObservableSet,
|
|
277 modelObservableSet, targetToModel, modelToTarget);
|
|
278 result.init(this);
|
|
279 return result;
|
|
280 }
|
|
281
|
|
282 /**
|
|
283 * @param targetObservableSet
|
|
284 * @param modelObservableSet
|
|
285 * @return a default set update strategy
|
|
286 * @since 1.1
|
|
287 */
|
|
288 protected UpdateSetStrategy createTargetToModelUpdateSetStrategy(
|
|
289 IObservableSet targetObservableSet,
|
|
290 IObservableSet modelObservableSet) {
|
|
291 return new UpdateSetStrategy();
|
|
292 }
|
|
293
|
|
294 /**
|
|
295 * @param modelObservableSet
|
|
296 * @param targetObservableSet
|
|
297 * @return a default set update strategy
|
|
298 * @since 1.1
|
|
299 */
|
|
300 protected UpdateSetStrategy createModelToTargetUpdateSetStrategy(
|
|
301 IObservableSet modelObservableSet,
|
|
302 IObservableSet targetObservableSet) {
|
|
303 return new UpdateSetStrategy();
|
|
304 }
|
|
305
|
|
306 /**
|
|
307 * Disposes of this data binding context and all bindings and validation
|
|
308 * status providers that were added to this context.
|
|
309 */
|
|
310 public final void dispose() {
|
|
311 Binding[] bindingArray = cast(Binding[]) bindings.toArray(new Binding[bindings.size()]);
|
|
312 for (int i = 0; i < bindingArray.length; i++) {
|
|
313 bindingArray[i].dispose();
|
|
314 }
|
|
315 ValidationStatusProvider[] statusProviderArray = cast(ValidationStatusProvider[]) validationStatusProviders
|
|
316 .toArray(new ValidationStatusProvider[validationStatusProviders
|
|
317 .size()]);
|
|
318 for (int i = 0; i < statusProviderArray.length; i++) {
|
|
319 if (!statusProviderArray[i].isDisposed())
|
|
320 statusProviderArray[i].dispose();
|
|
321 }
|
|
322 }
|
|
323
|
|
324 /**
|
|
325 * Returns an unmodifiable observable list with elements of type
|
|
326 * {@link Binding}, ordered by time of addition.
|
|
327 *
|
|
328 * @return the observable list containing all bindings
|
|
329 */
|
|
330 public final IObservableList getBindings() {
|
|
331 return unmodifiableBindings;
|
|
332 }
|
|
333
|
|
334 /**
|
|
335 * Returns an unmodifiable observable list with elements of type
|
|
336 * {@link ValidationStatusProvider}, ordered by time of addition.
|
|
337 *
|
|
338 * @return the observable list containing all bindings
|
|
339 * @since 1.1
|
|
340 */
|
|
341 public final IObservableList getValidationStatusProviders() {
|
|
342 return unmodifiableStatusProviders;
|
|
343 }
|
|
344
|
|
345 /**
|
|
346 * Returns an observable map from bindings (type: {@link Binding}) to
|
|
347 * statuses (type: {@link IStatus}). The keys of the map are the bindings
|
|
348 * returned by {@link #getBindings()}, and the values are the current
|
|
349 * validaion status objects for each binding.
|
|
350 *
|
|
351 * @return the observable map from bindings to status objects.
|
|
352 *
|
|
353 * @deprecated as of 1.1, please use {@link #getValidationStatusProviders()}
|
|
354 */
|
|
355 public final IObservableMap getValidationStatusMap() {
|
|
356 return validationStatusMap;
|
|
357 }
|
|
358
|
|
359 /**
|
|
360 * Adds the given binding to this data binding context. This will also add
|
|
361 * the given binding to the list of validation status providers.
|
|
362 *
|
|
363 * @param binding
|
|
364 * The binding to add.
|
|
365 * @see #addValidationStatusProvidercast(ValidationStatusProvider)
|
|
366 * @see #getValidationStatusProviders()
|
|
367 */
|
|
368 public void addBinding(Binding binding) {
|
|
369 addValidationStatusProvider(binding);
|
|
370 bindings.add(binding);
|
|
371 }
|
|
372
|
|
373 /**
|
|
374 * Adds the given validation status provider to this data binding context.
|
|
375 *
|
|
376 * @param validationStatusProvider
|
|
377 * The validation status provider to add.
|
|
378 * @since 1.1
|
|
379 */
|
|
380 public void addValidationStatusProvider(
|
|
381 ValidationStatusProvider validationStatusProvider) {
|
|
382 validationStatusProviders.add(validationStatusProvider);
|
|
383 }
|
|
384
|
|
385 /**
|
|
386 * Updates all model observable objects to reflect the current state of the
|
|
387 * target observable objects.
|
|
388 *
|
|
389 */
|
|
390 public final void updateModels() {
|
|
391 for (Iterator it = bindings.iterator(); it.hasNext();) {
|
|
392 Binding binding = cast(Binding) it.next();
|
|
393 binding.updateTargetToModel();
|
|
394 }
|
|
395 }
|
|
396
|
|
397 /**
|
|
398 * Updates all target observable objects to reflect the current state of the
|
|
399 * model observable objects.
|
|
400 *
|
|
401 */
|
|
402 public final void updateTargets() {
|
|
403 for (Iterator it = bindings.iterator(); it.hasNext();) {
|
|
404 Binding binding = cast(Binding) it.next();
|
|
405 binding.updateModelToTarget();
|
|
406 }
|
|
407 }
|
|
408
|
|
409 /**
|
|
410 * Removes the given binding.
|
|
411 *
|
|
412 * @param binding
|
|
413 * @return <code>true</code> if was associated with the context,
|
|
414 * <code>false</code> if not
|
|
415 */
|
|
416 public bool removeBinding(Binding binding) {
|
|
417 return bindings.remove(binding) && removeValidationStatusProvider(binding);
|
|
418 }
|
|
419
|
|
420 /**
|
|
421 * Removes the validation status provider.
|
|
422 *
|
|
423 * @param validationStatusProvider
|
|
424 * @return <code>true</code> if was associated with the context,
|
|
425 * <code>false</code> if not
|
|
426 * @since 1.1
|
|
427 */
|
|
428 public bool removeValidationStatusProvider(
|
|
429 ValidationStatusProvider validationStatusProvider) {
|
|
430 return validationStatusProviders.remove(validationStatusProvider);
|
|
431 }
|
|
432
|
|
433 /**
|
|
434 * Returns the validation realm.
|
|
435 *
|
|
436 * @return the realm for the validation observables
|
|
437 * @see Realm
|
|
438 */
|
|
439 public final Realm getValidationRealm() {
|
|
440 return validationRealm;
|
|
441 }
|
|
442 }
|