1 11 package org.eclipse.jface.internal.databinding.internal; 12 13 import org.eclipse.jface.internal.databinding.provisional.BindSpec; 14 import org.eclipse.jface.internal.databinding.provisional.Binding; 15 import org.eclipse.jface.internal.databinding.provisional.BindingEvent; 16 import org.eclipse.jface.internal.databinding.provisional.BindingException; 17 import org.eclipse.jface.internal.databinding.provisional.DataBindingContext; 18 import org.eclipse.jface.internal.databinding.provisional.conversion.IConverter; 19 import org.eclipse.jface.internal.databinding.provisional.observable.Diffs; 20 import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue; 21 import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangeListener; 22 import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangingListener; 23 import org.eclipse.jface.internal.databinding.provisional.observable.value.IVetoableValue; 24 import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff; 25 import org.eclipse.jface.internal.databinding.provisional.observable.value.WritableValue; 26 import org.eclipse.jface.internal.databinding.provisional.validation.IDomainValidator; 27 import org.eclipse.jface.internal.databinding.provisional.validation.IValidator; 28 import org.eclipse.jface.internal.databinding.provisional.validation.ValidationError; 29 30 34 public class ValueBinding extends Binding { 35 36 private final IObservableValue target; 37 38 private final IObservableValue model; 39 40 private IValidator targetValidator; 41 42 private IConverter targetToModelConverter; 43 44 private IConverter modelToTargetConverter; 45 46 private IDomainValidator domainValidator; 47 48 private boolean updating = false; 49 50 private WritableValue partialValidationErrorObservable = new WritableValue( 51 ValidationError.class, null); 52 53 private WritableValue validationErrorObservable = new WritableValue( 54 ValidationError.class, null); 55 56 62 public ValueBinding(DataBindingContext context, IObservableValue target, 63 IObservableValue model, BindSpec bindSpec) { 64 super(context); 65 this.target = target; 66 this.model = model; 67 if (bindSpec.updateTarget()) { 68 modelToTargetConverter = bindSpec.getModelToTargetConverter(); 69 if (modelToTargetConverter == null) { 70 throw new BindingException( 71 "Missing model to target converter from " + model.getValueType() + " to " + target.getValueType()); } 73 if (!context.isAssignableFromTo(model.getValueType(), 74 modelToTargetConverter.getFromType())) { 75 throw new BindingException( 76 "model to target converter does not convert from model type. Expected: " + model.getValueType() + ", actual: " + modelToTargetConverter.getFromType()); } 78 if (!context.isAssignableFromTo(modelToTargetConverter.getToType(), 79 target.getValueType())) { 80 throw new BindingException( 81 "model to target converter does convert to target type. Expected: " + target.getValueType() + ", actual: " + modelToTargetConverter.getToType()); } 83 model.addValueChangeListener(modelChangeListener); 84 } 85 if (bindSpec.updateModel()) { 86 targetToModelConverter = bindSpec.getTargetToModelConverter(); 87 if (targetToModelConverter == null) { 88 throw new BindingException( 89 "Missing target to model converter from " + target.getValueType() + " to " + model.getValueType()); } 91 if (!context.isAssignableFromTo(target.getValueType(), 92 targetToModelConverter.getFromType())) { 93 throw new BindingException( 94 "target to model converter does not convert from target type. Expected: " + target.getValueType() + ", actual: " + targetToModelConverter.getFromType()); } 96 if (!context.isAssignableFromTo(targetToModelConverter.getToType(), 97 model.getValueType())) { 98 throw new BindingException( 99 "target to model converter does convert to model type. Expected: " + model.getValueType() + ", actual: " + targetToModelConverter.getToType()); } 101 targetValidator = bindSpec.getTypeConversionValidator(); 102 if (targetValidator == null) { 103 throw new BindingException("Missing validator"); } 105 domainValidator = bindSpec.getDomainValidator(); 106 target.addValueChangeListener(targetChangeListener); 107 if (target instanceof IVetoableValue) { 108 ((IVetoableValue) target) 109 .addValueChangingListener(targetChangingListener); 110 } 111 } 112 updateTargetFromModel(); 113 } 114 115 private final IValueChangingListener targetChangingListener = new IValueChangingListener() { 116 public boolean handleValueChanging(IVetoableValue source, ValueDiff diff) { 117 if (updating) 118 return true; 119 Object value = diff.getNewValue(); 122 ValidationError partialValidationError = targetValidator 123 .isPartiallyValid(value); 124 partialValidationErrorObservable.setValue(partialValidationError); 125 return partialValidationError == null; 126 } 127 }; 128 129 private final IValueChangeListener targetChangeListener = new IValueChangeListener() { 130 public void handleValueChange(IObservableValue source, ValueDiff diff) { 131 if (updating) 132 return; 133 updateModelFromTarget(diff); 136 } 137 }; 138 139 private IValueChangeListener modelChangeListener = new IValueChangeListener() { 140 public void handleValueChange(IObservableValue source, ValueDiff diff) { 141 if (updating) 142 return; 143 doUpdateTargetFromModel(diff); 145 } 146 }; 147 148 156 public void updateModelFromTarget(ValueDiff diff) { 157 BindingEvent e = new BindingEvent(model, target, diff, 158 BindingEvent.EVENT_COPY_TO_MODEL, 159 BindingEvent.PIPELINE_AFTER_GET) { 160 }; 161 e.originalValue = target.getValue(); 162 if (failure(errMsg(fireBindingEvent(e)))) { 163 return; 164 } 165 166 ValidationError validationError = doValidate(e.originalValue); 167 if (validationError != null) { 168 return; 169 } 170 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_VALIDATE; 171 if (failure(errMsg(fireBindingEvent(e)))) { 172 return; 173 } 174 175 try { 176 updating = true; 177 178 e.convertedValue = targetToModelConverter.convert(e.originalValue); 179 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CONVERT; 180 if (failure(errMsg(fireBindingEvent(e)))) { 181 return; 182 } 183 184 validationError = doDomainValidation(e.convertedValue); 185 if (validationError != null) { 186 return; 187 } 188 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_BUSINESS_VALIDATE; 189 if (failure(errMsg(fireBindingEvent(e)))) { 190 return; 191 } 192 193 model.setValue(e.convertedValue); 194 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CHANGE; 195 fireBindingEvent(e); 196 } catch (Exception ex) { 197 ValidationError error = ValidationError.error(BindingMessages 198 .getString("ValueBinding_ErrorWhileSettingValue")); validationErrorObservable.setValue(error); 200 } finally { 201 updating = false; 202 } 203 } 204 205 209 private ValidationError doDomainValidation(Object convertedValue) { 210 if (domainValidator == null) { 211 return null; 212 } 213 ValidationError validationError = domainValidator 214 .isValid(convertedValue); 215 return errMsg(validationError); 216 } 217 218 private ValidationError doValidate(Object value) { 219 if (targetValidator == null) 220 return null; 221 ValidationError validationError = targetValidator.isValid(value); 222 return errMsg(validationError); 223 } 224 225 private ValidationError errMsg(ValidationError validationError) { 226 partialValidationErrorObservable.setValue(null); 227 validationErrorObservable.setValue(validationError); 228 return validationError; 229 } 230 231 private boolean failure(ValidationError errorMessage) { 232 if (errorMessage != null 234 && errorMessage.status == ValidationError.ERROR) { 235 return true; 236 } 237 return false; 238 } 239 240 public void updateTargetFromModel() { 241 doUpdateTargetFromModel(null); 242 } 243 244 247 public void doUpdateTargetFromModel(ValueDiff diff) { 248 try { 249 updating = true; 250 BindingEvent e = new BindingEvent(model, target, diff, 251 BindingEvent.EVENT_COPY_TO_TARGET, 252 BindingEvent.PIPELINE_AFTER_GET) { 253 }; 254 e.originalValue = model.getValue(); 255 if (failure(errMsg(fireBindingEvent(e)))) { 256 return; 257 } 258 259 e.convertedValue = modelToTargetConverter.convert(e.originalValue); 260 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CONVERT; 261 if (failure(errMsg(fireBindingEvent(e)))) { 262 return; 263 } 264 265 target.setValue(e.convertedValue); 266 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_CHANGE; 267 if (failure(errMsg(fireBindingEvent(e)))) { 268 return; 269 } 270 271 doValidate(target.getValue()); 272 e.pipelinePosition = BindingEvent.PIPELINE_AFTER_VALIDATE; 273 fireBindingEvent(e); 274 } finally { 275 updating = false; 276 } 277 } 278 279 public IObservableValue getValidationError() { 280 return validationErrorObservable; 281 } 282 283 public IObservableValue getPartialValidationError() { 284 return partialValidationErrorObservable; 285 } 286 287 public void updateModelFromTarget() { 288 updateModelFromTarget(Diffs.createValueDiff(target.getValue(), target 289 .getValue())); 290 } 291 } 292 | Popular Tags |