/******************************************************************************* * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: * Soyatec - initial API and implementation *******************************************************************************/ package org.eclipse.papyrus.xwt.internal.core; import org.eclipse.core.databinding.Binding; import org.eclipse.core.databinding.UpdateListStrategy; import org.eclipse.core.databinding.UpdateSetStrategy; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.IObservable; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.set.IObservableSet; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.papyrus.xwt.IDataBindingInfo; import org.eclipse.papyrus.xwt.IDataProvider; import org.eclipse.papyrus.xwt.IValidationRule; import org.eclipse.papyrus.xwt.IValueConverter; import org.eclipse.papyrus.xwt.InverseValueConverter; import org.eclipse.papyrus.xwt.XWT; import org.eclipse.papyrus.xwt.databinding.IBindingContext; import org.eclipse.papyrus.xwt.internal.utils.ObjectUtil; import org.eclipse.papyrus.xwt.validation.InverseValidationRule; /** * @author jliu <jin.liu@soyatec.com> */ public class BindingGate { public static final UpdateSetStrategy POLICY_UPDATE = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE); private final IBindingContext dataBindingContext; public BindingGate(IBindingContext dataBindingContext) { super(); this.dataBindingContext = dataBindingContext; } public Binding bind(IObservableValue source, IObservableValue target) { return bind(source, target, null); } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core. * databinding.observable.value.IObservableValue, * org.eclipse.core.databinding.observable.value.IObservableValue) */ public Binding bind(IObservable source, IObservable target, IDataBindingInfo dataBinding) { if(source instanceof IObservableValue && target instanceof IObservableValue) { return bindValue((IObservableValue)source, (IObservableValue)target, dataBinding); } else if(source instanceof IObservableSet && target instanceof IObservableSet) { IValueConverter converter = null; int sourceToTargetPolicy = UpdateSetStrategy.POLICY_UPDATE; int targetToSourcePolicy = UpdateSetStrategy.POLICY_UPDATE; // Set policy to UpdateValueStrategy. if(dataBinding != null) { switch(dataBinding.getMode()) { case OneWay: targetToSourcePolicy = UpdateSetStrategy.POLICY_NEVER; break; case OneTime: sourceToTargetPolicy = UpdateSetStrategy.POLICY_NEVER; targetToSourcePolicy = UpdateSetStrategy.POLICY_NEVER; break; default: break; } converter = dataBinding.getConverter(); } UpdateSetStrategy sourceToTarget = new UpdateSetStrategy(sourceToTargetPolicy); UpdateSetStrategy targetToSource = new UpdateSetStrategy(targetToSourcePolicy); return bindSet((IObservableSet)target, (IObservableSet)source, targetToSource, sourceToTarget, converter); } else if(source instanceof IObservableList && target instanceof IObservableList) { IValueConverter converter = null; int sourceToTargetPolicy = UpdateListStrategy.POLICY_UPDATE; int targetToSourcePolicy = UpdateListStrategy.POLICY_UPDATE; // Set policy to UpdateValueStrategy. if(dataBinding != null) { switch(dataBinding.getMode()) { case OneWay: targetToSourcePolicy = UpdateListStrategy.POLICY_NEVER; break; case OneTime: sourceToTargetPolicy = UpdateListStrategy.POLICY_NEVER; targetToSourcePolicy = UpdateListStrategy.POLICY_NEVER; break; default: break; } converter = dataBinding.getConverter(); } UpdateListStrategy sourceToTarget = new UpdateListStrategy(sourceToTargetPolicy); UpdateListStrategy targetToSource = new UpdateListStrategy(targetToSourcePolicy); return bindList((IObservableList)target, (IObservableList)source, targetToSource, sourceToTarget, converter); } throw new IllegalStateException(); } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core. * databinding.observable.value.IObservableValue, * org.eclipse.core.databinding.observable.value.IObservableValue) */ public Binding bindList(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IValueConverter converter) { if(converter != null) { return bindList(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter)); } else { return bindList(source, target, sourceToTarget, targetToSource, null, null); } } /** * * @param source * @param target * @param sourceToTarget * if it is null, the default converter will be update policy * @param targetToSource * if it is null, the default converter will be update policy * @param sourceToTargetConvertor * if it is null, the default converter will be used * @param targetToSourceConvertor * if it is null, the default converter will be used */ public Binding bindList(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) { if(source != null && target != null) { if(sourceToTarget == null) { sourceToTarget = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE); } if(targetToSource == null) { targetToSource = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE); } if(sourceToTargetConvertor != null) { sourceToTarget.setConverter(sourceToTargetConvertor); } if(targetToSourceConvertor != null) { targetToSource.setConverter(targetToSourceConvertor); } this.dataBindingContext.bindList(target, source, targetToSource, sourceToTarget); } return null; } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core. * databinding.observable.value.IObservableValue, * org.eclipse.core.databinding.observable.value.IObservableValue) */ public Binding bindSet(IObservableSet source, IObservableSet target, UpdateSetStrategy sourceToTarget, UpdateSetStrategy targetToSource, IValueConverter converter) { if(converter != null) { return bindSet(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter)); } else { return bindSet(source, target, sourceToTarget, targetToSource, null, null); } } /** * * @param source * @param target * @param sourceToTarget * if it is null, the default converter will be update policy * @param targetToSource * if it is null, the default converter will be update policy * @param sourceToTargetConvertor * if it is null, the default converter will be used * @param targetToSourceConvertor * if it is null, the default converter will be used */ public Binding bindSet(IObservableSet source, IObservableSet target, UpdateSetStrategy sourceToTarget, UpdateSetStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) { if(source != null && target != null) { if(sourceToTarget == null) { sourceToTarget = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE); } if(targetToSource == null) { targetToSource = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE); } if(sourceToTargetConvertor != null) { sourceToTarget.setConverter(sourceToTargetConvertor); } if(targetToSourceConvertor != null) { targetToSource.setConverter(targetToSourceConvertor); } this.dataBindingContext.bindSet(target, source, targetToSource, sourceToTarget); } return null; } /** * * @param source * @param target * @param sourceToTarget * if it is null, the default converter will be update policy * @param targetToSource * if it is null, the default converter will be update policy * @param sourceToTargetConvertor * if it is null, the default converter will be used * @param targetToSourceConvertor * if it is null, the default converter will be used */ public Binding bind(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) { if(source != null && target != null) { if(sourceToTarget == null) { sourceToTarget = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE); } if(targetToSource == null) { targetToSource = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE); } if(sourceToTargetConvertor != null) { sourceToTarget.setConverter(sourceToTargetConvertor); } if(targetToSourceConvertor != null) { targetToSource.setConverter(targetToSourceConvertor); } this.dataBindingContext.bindList(target, source, targetToSource, sourceToTarget); } return null; } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core. * databinding.observable.value.IObservableValue, * org.eclipse.core.databinding.observable.value.IObservableValue) */ private Binding bindValue(IObservableValue source, IObservableValue target, IDataBindingInfo dataBinding) { IValueConverter converter = null; IValidationRule[] validators = null; int sourceToTargetPolicy = UpdateValueStrategy.POLICY_UPDATE; int targetToSourcePolicy = UpdateValueStrategy.POLICY_UPDATE; // Set policy to UpdateValueStrategy. if(dataBinding != null) { switch(dataBinding.getMode()) { case OneWay: targetToSourcePolicy = UpdateValueStrategy.POLICY_NEVER; break; case OneTime: sourceToTargetPolicy = UpdateValueStrategy.POLICY_NEVER; targetToSourcePolicy = UpdateValueStrategy.POLICY_NEVER; break; default: break; } converter = dataBinding.getConverter(); validators = dataBinding.getValidators(); } UpdateValueStrategy sourceToTarget = new UpdateValueStrategy(sourceToTargetPolicy); UpdateValueStrategy targetToSource = new UpdateValueStrategy(targetToSourcePolicy); bindValidators(validators, sourceToTarget, targetToSource); return bind(source, target, sourceToTarget, targetToSource, converter); } private void bindValidators(IValidationRule[] validators, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource) { if(validators != null) { for(IValidationRule validator : validators) { switch(validator.getBindingMode()) { case SourceToTarget: addValidatorToStrategy(sourceToTarget, validator); break; case TargetToSource: addValidatorToStrategy(targetToSource, new InverseValidationRule(validator)); break; case Both: default: addValidatorToStrategy(sourceToTarget, validator); addValidatorToStrategy(targetToSource, new InverseValidationRule(validator)); } } } } private void addValidatorToStrategy(UpdateValueStrategy strategy, IValidationRule validator) { switch(validator.getPhase()) { case AfterGet: strategy.setAfterGetValidator(validator); break; case AfterConvert: strategy.setAfterConvertValidator(validator); break; case BeforeSet: default: strategy.setBeforeSetValidator(validator); } } /* * (non-Javadoc) * * @see * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core. * databinding.observable.value.IObservableValue, * org.eclipse.core.databinding.observable.value.IObservableValue) */ public Binding bind(IObservableValue source, IObservableValue target, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource, IValueConverter converter) { if(converter != null) { return bind(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter)); } else { return bind(source, target, sourceToTarget, targetToSource, null, null); } } /** * * @param source * @param target * @param sourceToTarget * if it is null, the default converter will be update policy * @param targetToSource * if it is null, the default converter will be update policy * @param sourceToTargetConvertor * if it is null, the default converter will be used * @param targetToSourceConvertor * if it is null, the default converter will be used */ public Binding bind(IObservableValue source, IObservableValue target, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) { if(source != null && target != null) { if(sourceToTarget == null) { sourceToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); } if(targetToSource == null) { targetToSource = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); } // Add converter to UpdateValueStrategy. IDataProvider sourceDataProvider = XWT.findDataProvider(source); Object sourceValueType = sourceDataProvider.getDataType(null); if(sourceValueType == null) { sourceValueType = Object.class; } IDataProvider targetDataProvider = XWT.findDataProvider(target); Object targetValueType = targetDataProvider.getDataType(null); if(targetValueType == null) { targetValueType = Object.class; } Class<?> sourceType = (sourceValueType instanceof Class<?>) ? (Class<?>)sourceValueType : sourceValueType.getClass(); Class<?> targetType = (targetValueType instanceof Class<?>) ? (Class<?>)targetValueType : targetValueType.getClass(); if(sourceType == null) { sourceType = Object.class; } else { sourceType = ObjectUtil.normalizedType(sourceType); } if(targetType == null) { targetType = Object.class; } else { targetType = ObjectUtil.normalizedType(targetType); } if(sourceToTarget.getUpdatePolicy() != UpdateValueStrategy.POLICY_NEVER) { if(sourceToTargetConvertor != null) { sourceToTarget.setConverter(sourceToTargetConvertor); } else if(!targetType.isAssignableFrom(sourceType)) { IConverter m2t = XWT.findConvertor(sourceType, targetType); if(m2t != null) { sourceToTarget.setConverter(m2t); } } } if(targetToSource.getUpdatePolicy() != UpdateValueStrategy.POLICY_NEVER) { if(targetToSourceConvertor != null) { targetToSource.setConverter(targetToSourceConvertor); } else if(!sourceType.isAssignableFrom(targetType)) { IConverter t2m = XWT.findConvertor(targetType, sourceType); if(t2m != null) { targetToSource.setConverter(t2m); } } } this.dataBindingContext.bindValue(target, source, targetToSource, sourceToTarget); } return null; } }