| /******************************************************************************* |
| * Copyright (c) 2005, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Brad Reynolds - bug 159539 |
| * Brad Reynolds - bug 140644 |
| * Brad Reynolds - bug 159940 |
| * Brad Reynolds - bug 116920, 159768 |
| *******************************************************************************/ |
| package org.eclipse.core.databinding; |
| |
| import java.util.Iterator; |
| |
| import org.eclipse.core.databinding.observable.Observables; |
| import org.eclipse.core.databinding.observable.Realm; |
| import org.eclipse.core.databinding.observable.list.IObservableList; |
| import org.eclipse.core.databinding.observable.list.WritableList; |
| import org.eclipse.core.databinding.observable.map.IObservableMap; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.internal.databinding.ValidationStatusMap; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IStatus; |
| |
| /** |
| * A DataBindingContext is the point of contact for the creation and management of |
| * {@link Binding bindings}. |
| * <p> |
| * A DataBindingContext provides the following abilities: |
| * <ul> |
| * <li>Ability to create bindings between |
| * {@link IObservableValue observable values}.</li> |
| * <li>Ability to create bindings between |
| * {@link IObservableList observable lists}.</li> |
| * <li>Access to the bindings created by the instance.</li> |
| * <li>Access to the validation status of its bindings.</li> |
| * </ul> |
| * </p> |
| * <p> |
| * Multiple contexts can be used at any point in time. One strategy for the |
| * management of contexts is the aggregation of validation statuses. For example |
| * an <code>IWizardPage</code> could use a single context and the statuses |
| * could be aggregated to set the page status and fulfillment. Each page in the |
| * <code>IWizard</code> would have its own context instance. |
| * </p> |
| * |
| * @since 1.0 |
| */ |
| public class DataBindingContext { |
| private WritableList bindings; |
| |
| /** |
| * Unmodifiable version of {@link #bindings} for public exposure. |
| */ |
| private IObservableList unmodifiableBindings; |
| |
| private IObservableMap validationStatusMap; |
| |
| private Realm validationRealm; |
| |
| /** |
| * Creates a data binding context, using the current default realm for the |
| * validation observables. |
| * |
| * @see Realm |
| */ |
| public DataBindingContext() { |
| this(Realm.getDefault()); |
| } |
| |
| /** |
| * Creates a data binding context using the given realm for the validation |
| * observables. |
| * |
| * @param validationRealm |
| * the realm to be used for the validation observables |
| * |
| * @see Realm |
| */ |
| public DataBindingContext(Realm validationRealm) { |
| Assert.isNotNull(validationRealm); |
| this.validationRealm = validationRealm; |
| bindings = new WritableList(validationRealm); |
| |
| unmodifiableBindings = Observables.unmodifiableObservableList(bindings); |
| validationStatusMap = new ValidationStatusMap(validationRealm, |
| bindings); |
| } |
| |
| /** |
| * Creates a {@link Binding} to synchronize the values of two |
| * {@link IObservableValue observable values}. During synchronization |
| * validation and conversion can be employed to customize the process. For |
| * specifics on the customization of the process see |
| * {@link UpdateValueStrategy}. |
| * |
| * @param targetObservableValue |
| * target value, commonly a UI widget |
| * @param modelObservableValue |
| * model value |
| * @param targetToModel |
| * strategy to employ when the target is the source of the change |
| * and the model is the destination |
| * @param modelToTarget |
| * strategy to employ when the model is the source of the change |
| * and the target is the destination |
| * @return created binding |
| * |
| * @see UpdateValueStrategy |
| */ |
| public final Binding bindValue(IObservableValue targetObservableValue, |
| IObservableValue modelObservableValue, |
| UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) { |
| UpdateValueStrategy targetToModelStrategy = targetToModel != null ? targetToModel |
| : createTargetToModelUpdateValueStrategy(targetObservableValue, modelObservableValue); |
| UpdateValueStrategy modelToTargetStrategy = modelToTarget != null ? modelToTarget |
| : createModelToTargetUpdateValueStrategy(modelObservableValue, targetObservableValue); |
| targetToModelStrategy.fillDefaults(targetObservableValue, modelObservableValue); |
| modelToTargetStrategy.fillDefaults(modelObservableValue, targetObservableValue); |
| ValueBinding result = new ValueBinding(targetObservableValue, |
| modelObservableValue, targetToModelStrategy, |
| modelToTargetStrategy); |
| result.init(this); |
| return result; |
| } |
| |
| /** |
| * Returns an update value strategy to be used for copying values from the |
| * from value to the to value. Clients may override. |
| * |
| * @param fromValue |
| * @param toValue |
| * @return a update value strategy |
| */ |
| protected UpdateValueStrategy createModelToTargetUpdateValueStrategy( |
| IObservableValue fromValue, IObservableValue toValue) { |
| return new UpdateValueStrategy(); |
| } |
| |
| /** |
| * Returns an update value strategy to be used for copying values from the |
| * from value to the to value. Clients may override. |
| * |
| * @param fromValue |
| * @param toValue |
| * @return a update value strategy |
| */ |
| protected UpdateValueStrategy createTargetToModelUpdateValueStrategy( |
| IObservableValue fromValue, IObservableValue toValue) { |
| return new UpdateValueStrategy(); |
| } |
| |
| /** |
| * Creates a {@link Binding} to synchronize the values of two |
| * {@link IObservableList observable lists}. During synchronization |
| * validation and conversion can be employed to customize the process. For |
| * specifics on the customization of the process see |
| * {@link UpdateListStrategy}. |
| * |
| * @param targetObservableList |
| * target list, commonly a list representing a list in the UI |
| * @param modelObservableList |
| * model list |
| * @param targetToModel |
| * strategy to employ when the target is the source of the change |
| * and the model is the destination |
| * @param modelToTarget |
| * strategy to employ when the model is the source of the change |
| * and the target is the destination |
| * @return created binding |
| * |
| * @see UpdateListStrategy |
| */ |
| public final Binding bindList(IObservableList targetObservableList, |
| IObservableList modelObservableList, |
| UpdateListStrategy targetToModel, UpdateListStrategy modelToTarget) { |
| UpdateListStrategy targetToModelStrategy = targetToModel != null ? targetToModel |
| : createTargetToModelUpdateListStrategy(targetObservableList, |
| modelObservableList); |
| UpdateListStrategy modelToTargetStrategy = modelToTarget != null ? modelToTarget |
| : createModelToTargetUpdateListStrategy(modelObservableList, |
| targetObservableList); |
| targetToModelStrategy.fillDefaults(targetObservableList, |
| modelObservableList); |
| modelToTargetStrategy.fillDefaults(modelObservableList, |
| targetObservableList); |
| ListBinding result = new ListBinding(targetObservableList, |
| modelObservableList, targetToModelStrategy, |
| modelToTargetStrategy); |
| result.init(this); |
| return result; |
| } |
| |
| /** |
| * @param modelObservableList |
| * @param targetObservableList |
| * @return an update list strategy |
| */ |
| protected UpdateListStrategy createModelToTargetUpdateListStrategy( |
| IObservableList modelObservableList, |
| IObservableList targetObservableList) { |
| return new UpdateListStrategy(); |
| } |
| |
| /** |
| * @param targetObservableList |
| * @param modelObservableList |
| * @return an update list strategy |
| */ |
| protected UpdateListStrategy createTargetToModelUpdateListStrategy( |
| IObservableList targetObservableList, |
| IObservableList modelObservableList) { |
| return new UpdateListStrategy(); |
| } |
| |
| /** |
| * Disposes of this data binding context and all bindings that were added to |
| * this context. |
| */ |
| public final void dispose() { |
| Binding[] bindingArray = (Binding[]) bindings.toArray(new Binding[bindings.size()]); |
| for (int i = 0; i < bindingArray.length; i++) { |
| bindingArray[i].dispose(); |
| } |
| } |
| |
| /** |
| * Returns an unmodifiable observable list with elements of type |
| * {@link Binding}, ordered by time of addition. |
| * |
| * @return the observable list containing all bindings |
| */ |
| public final IObservableList getBindings() { |
| return unmodifiableBindings; |
| } |
| |
| /** |
| * Returns an observable map from bindings (type: {@link Binding}) to |
| * statuses (type: {@link IStatus}). The keys of the map are the bindings |
| * returned by {@link #getBindings()}, and the values are the current |
| * validaion status objects for each binding. |
| * |
| * @return the observable map from bindings to status objects. |
| */ |
| public final IObservableMap getValidationStatusMap() { |
| return validationStatusMap; |
| } |
| |
| /** |
| * Adds the given binding to this data binding context. |
| * |
| * @param binding |
| * The binding to add. |
| */ |
| public void addBinding(Binding binding) { |
| bindings.add(binding); |
| } |
| |
| /** |
| * Updates all model observable objects to reflect the current state of the |
| * target observable objects. |
| * |
| */ |
| public final void updateModels() { |
| for (Iterator it = bindings.iterator(); it.hasNext();) { |
| Binding binding = (Binding) it.next(); |
| binding.updateTargetToModel(); |
| } |
| } |
| |
| /** |
| * Updates all target observable objects to reflect the current state of the |
| * model observable objects. |
| * |
| */ |
| public final void updateTargets() { |
| for (Iterator it = bindings.iterator(); it.hasNext();) { |
| Binding binding = (Binding) it.next(); |
| binding.updateModelToTarget(); |
| } |
| } |
| |
| /** |
| * Removes the given binding. |
| * |
| * @param binding |
| * @return <code>true</code> if was associated with the context, |
| * <code>false</code> if not |
| */ |
| public boolean removeBinding(Binding binding) { |
| return bindings.remove(binding); |
| } |
| |
| /** |
| * Returns the validation realm. |
| * |
| * @return the realm for the validation observables |
| * @see Realm |
| */ |
| public final Realm getValidationRealm() { |
| return validationRealm; |
| } |
| } |