1 11 12 package org.eclipse.core.databinding.observable.set; 13 14 import java.util.Collections ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import org.eclipse.core.databinding.observable.Diffs; 22 import org.eclipse.core.databinding.observable.Realm; 23 import org.eclipse.core.databinding.observable.map.IMapChangeListener; 24 import org.eclipse.core.databinding.observable.map.IObservableMap; 25 import org.eclipse.core.databinding.observable.map.MapChangeEvent; 26 import org.eclipse.core.databinding.observable.map.MapDiff; 27 28 39 public class MappedSet extends ObservableSet { 40 41 private final IObservableMap wrappedMap; 42 43 46 private Map valueCounts = new HashMap (); 47 48 private ISetChangeListener domainListener = new ISetChangeListener() { 49 public void handleSetChange(SetChangeEvent event) { 50 Set additions = new HashSet (); 51 for (Iterator it = event.diff.getAdditions().iterator(); it.hasNext();) { 52 Object added = it.next(); 53 Object mapValue = wrappedMap.get(added); 54 if (handleAddition(mapValue)) { 55 additions.add(mapValue); 56 } 57 } 58 Set removals = new HashSet (); 59 for (Iterator it = event.diff.getRemovals().iterator(); it.hasNext();) { 60 Object removed = it.next(); 61 Object mapValue = wrappedMap.get(removed); 62 if (handleRemoval(mapValue)) { 63 removals.add(mapValue); 64 } 65 } 66 fireSetChange(Diffs.createSetDiff(additions, removals)); 67 } 68 }; 69 70 private IMapChangeListener mapChangeListener = new IMapChangeListener() { 71 public void handleMapChange(MapChangeEvent event) { 72 MapDiff diff = event.diff; 73 Set additions = new HashSet (); 74 Set removals = new HashSet (); 75 for (Iterator it = diff.getRemovedKeys().iterator(); it.hasNext();) { 76 Object key = it.next(); 77 Object oldValue = diff.getOldValue(key); 78 if (handleRemoval(oldValue)) { 79 removals.add(oldValue); 80 } 81 } 82 for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) { 83 Object key = it.next(); 84 Object oldValue = diff.getOldValue(key); 85 Object newValue = diff.getNewValue(key); 86 if (handleRemoval(oldValue)) { 87 removals.add(oldValue); 88 } 89 if (handleAddition(newValue)) { 90 additions.add(newValue); 91 } 92 } 93 for (Iterator it = diff.getAddedKeys().iterator(); it.hasNext();) { 94 Object key = it.next(); 95 Object newValue = diff.getNewValue(key); 96 if (handleAddition(newValue)) { 97 additions.add(newValue); 98 } 99 } 100 fireSetChange(Diffs.createSetDiff(additions, removals)); 101 } 102 }; 103 104 private IObservableSet input; 105 106 110 public MappedSet(IObservableSet input, IObservableMap map) { 111 super(input.getRealm(), Collections.EMPTY_SET, Object .class); 112 setWrappedSet(valueCounts.keySet()); 113 this.wrappedMap = map; 114 this.input = input; 115 for (Iterator it = input.iterator(); it.hasNext();) { 116 Object element = it.next(); 117 Object functionValue = wrappedMap.get(element); 118 handleAddition(functionValue); 119 } 120 input.addSetChangeListener(domainListener); 121 map.addMapChangeListener(mapChangeListener); 122 } 123 124 128 protected boolean handleAddition(Object mapValue) { 129 Integer count = (Integer ) valueCounts.get(mapValue); 130 if (count == null) { 131 valueCounts.put(mapValue, new Integer (1)); 132 return true; 133 } 134 valueCounts.put(mapValue, new Integer (count.intValue() + 1)); 135 return false; 136 } 137 138 142 protected boolean handleRemoval(Object mapValue) { 143 Integer count = (Integer ) valueCounts.get(mapValue); 144 if (count.intValue() <= 1) { 145 valueCounts.remove(mapValue); 146 return true; 147 } 148 valueCounts.put(mapValue, new Integer (count.intValue() - 1)); 149 return false; 150 } 151 152 public synchronized void dispose() { 153 wrappedMap.removeMapChangeListener(mapChangeListener); 154 input.removeSetChangeListener(domainListener); 155 } 156 157 } 158 | Popular Tags |