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