1 11 package org.eclipse.jface.internal.databinding.internal.observable; 12 13 import org.eclipse.jface.internal.databinding.provisional.DataBindingContext; 14 import org.eclipse.jface.internal.databinding.provisional.description.Property; 15 import org.eclipse.jface.internal.databinding.provisional.observable.Diffs; 16 import org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractObservableValue; 17 import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue; 18 import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangeListener; 19 import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff; 20 import org.eclipse.jface.util.Assert; 21 22 26 public class NestedObservableValue extends AbstractObservableValue { 27 28 private boolean updating = false; 29 30 private IValueChangeListener innerChangeListener = new IValueChangeListener() { 31 public void handleValueChange(IObservableValue source, ValueDiff diff) { 32 if (!updating) { 33 fireValueChange(diff); 34 } 35 } 36 }; 37 38 private Object currentOuterValue; 39 40 private Object feature; 41 42 private IObservableValue innerObservableValue; 43 44 private DataBindingContext databindingContext; 45 46 private Object featureType; 47 48 private IObservableValue outerObservableValue; 49 50 56 public NestedObservableValue(DataBindingContext databindingContext, 57 IObservableValue outerObservableValue, Object feature, 58 Class featureType) { 59 this.databindingContext = databindingContext; 60 this.feature = feature; 61 this.featureType = featureType; 62 this.outerObservableValue = outerObservableValue; 63 updateInnerObservableValue(outerObservableValue); 64 65 outerObservableValue.addValueChangeListener(outerChangeListener); 66 } 67 68 IValueChangeListener outerChangeListener = new IValueChangeListener() { 69 public void handleValueChange(IObservableValue source, ValueDiff diff) { 70 Object oldValue = doGetValue(); 71 updateInnerObservableValue(outerObservableValue); 72 fireValueChange(Diffs.createValueDiff(oldValue, doGetValue())); 73 } 74 }; 75 76 private void updateInnerObservableValue( 77 IObservableValue outerObservableValue) { 78 currentOuterValue = outerObservableValue.getValue(); 79 if (innerObservableValue != null) { 80 innerObservableValue.removeValueChangeListener(innerChangeListener); 81 innerObservableValue.dispose(); 82 } 83 if (currentOuterValue == null) { 84 innerObservableValue = null; 85 } else { 86 this.innerObservableValue = (IObservableValue) databindingContext 87 .createObservable(new Property(currentOuterValue, feature)); 88 Object innerValueType = innerObservableValue.getValueType(); 89 if (featureType == null) { 90 featureType = innerValueType; 91 } else { 92 Assert 93 .isTrue(featureType.equals(innerValueType), 94 "Cannot change value type in a nested observable value"); } 96 innerObservableValue.addValueChangeListener(innerChangeListener); 97 } 98 } 99 100 public void setValue(Object value) { 101 if (innerObservableValue != null) 102 innerObservableValue.setValue(value); 103 } 104 105 public Object doGetValue() { 106 return innerObservableValue == null ? null : innerObservableValue 107 .getValue(); 108 } 109 110 public Object getValueType() { 111 return featureType; 112 } 113 114 public void dispose() { 115 super.dispose(); 116 117 if (outerObservableValue != null) { 118 outerObservableValue.removeValueChangeListener(outerChangeListener); 119 outerObservableValue.dispose(); 120 } 121 if (innerObservableValue != null) { 122 innerObservableValue.removeValueChangeListener(innerChangeListener); 123 innerObservableValue.dispose(); 124 } 125 currentOuterValue = null; 126 databindingContext = null; 127 feature = null; 128 innerObservableValue = null; 129 innerChangeListener = null; 130 } 131 132 } 133 | Popular Tags |