1 11 12 package org.eclipse.core.internal.databinding; 13 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import org.eclipse.core.databinding.Binding; 22 import org.eclipse.core.databinding.observable.ChangeEvent; 23 import org.eclipse.core.databinding.observable.Diffs; 24 import org.eclipse.core.databinding.observable.IChangeListener; 25 import org.eclipse.core.databinding.observable.Realm; 26 import org.eclipse.core.databinding.observable.list.WritableList; 27 import org.eclipse.core.databinding.observable.map.IMapChangeListener; 28 import org.eclipse.core.databinding.observable.map.MapDiff; 29 import org.eclipse.core.databinding.observable.map.ObservableMap; 30 import org.eclipse.core.databinding.observable.value.IObservableValue; 31 import org.eclipse.core.runtime.IStatus; 32 33 37 public class ValidationStatusMap extends ObservableMap { 38 39 private boolean isDirty = true; 40 41 private final WritableList bindings; 42 43 private List dependencies = new ArrayList (); 44 45 private IChangeListener markDirtyChangeListener = new IChangeListener() { 46 public void handleChange(ChangeEvent event) { 47 markDirty(); 48 } 49 }; 50 51 55 public ValidationStatusMap(Realm realm, WritableList bindings) { 56 super(realm, new HashMap ()); 57 this.bindings = bindings; 58 bindings.addChangeListener(markDirtyChangeListener); 59 } 60 61 protected void getterCalled() { 62 recompute(); 63 super.getterCalled(); 64 } 65 66 private void markDirty() { 67 removeElementChangeListener(); 69 final Map oldMap = wrappedMap; 70 MapDiff mapDiff = new MapDiff() { 72 private MapDiff cachedDiff = null; 73 74 private void ensureCached() { 75 if (cachedDiff == null) { 76 recompute(); 77 cachedDiff = Diffs.computeMapDiff(oldMap, wrappedMap); 78 } 79 } 80 81 public Set getAddedKeys() { 82 ensureCached(); 83 return cachedDiff.getAddedKeys(); 84 } 85 86 public Set getChangedKeys() { 87 ensureCached(); 88 return cachedDiff.getChangedKeys(); 89 } 90 91 public Object getNewValue(Object key) { 92 ensureCached(); 93 return cachedDiff.getNewValue(key); 94 } 95 96 public Object getOldValue(Object key) { 97 ensureCached(); 98 return cachedDiff.getOldValue(key); 99 } 100 101 public Set getRemovedKeys() { 102 ensureCached(); 103 return cachedDiff.getRemovedKeys(); 104 } 105 }; 106 wrappedMap = new HashMap (); 107 isDirty = true; 108 fireMapChange(mapDiff); 109 } 110 111 private void recompute() { 112 if (isDirty) { 113 Map newContents = new HashMap (); 114 for (Iterator it = bindings.iterator(); it.hasNext();) { 115 Binding binding = (Binding) it.next(); 116 IObservableValue validationError = binding 117 .getValidationStatus(); 118 dependencies.add(validationError); 119 validationError.addChangeListener(markDirtyChangeListener); 120 IStatus validationStatusValue = (IStatus) validationError 121 .getValue(); 122 newContents.put(binding, validationStatusValue); 123 } 124 wrappedMap.putAll(newContents); 125 isDirty = false; 126 } 127 } 128 129 134 public void dispose() { 135 bindings.removeChangeListener(markDirtyChangeListener); 136 removeElementChangeListener(); 137 super.dispose(); 138 } 139 140 private void removeElementChangeListener() { 141 for (Iterator it = dependencies.iterator(); it.hasNext();) { 142 IObservableValue observableValue = (IObservableValue) it.next(); 143 observableValue.removeChangeListener(markDirtyChangeListener); 144 } 145 } 146 147 public synchronized void addChangeListener(IChangeListener listener) { 148 recompute(); 150 super.addChangeListener(listener); 151 } 152 153 public synchronized void addMapChangeListener(IMapChangeListener listener) { 154 recompute(); 156 super.addMapChangeListener(listener); 157 } 158 159 } 160 | Popular Tags |