1 11 package org.eclipse.jface.internal.databinding.internal.viewers; 12 13 import java.util.Collections ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.Set ; 18 19 import org.eclipse.core.databinding.observable.Diffs; 20 import org.eclipse.core.databinding.observable.IStaleListener; 21 import org.eclipse.core.databinding.observable.StaleEvent; 22 import org.eclipse.core.databinding.observable.set.AbstractObservableSet; 23 import org.eclipse.core.databinding.observable.set.IObservableSet; 24 import org.eclipse.core.databinding.observable.set.ISetChangeListener; 25 import org.eclipse.core.databinding.observable.set.SetChangeEvent; 26 import org.eclipse.core.databinding.observable.set.SetDiff; 27 import org.eclipse.core.internal.databinding.observable.tree.IUnorderedTreeProvider; 28 import org.eclipse.core.internal.databinding.observable.tree.TreePath; 29 30 34 public class LeafNodesSet extends AbstractObservableSet { 35 36 private HashSet leafNodes = new HashSet (); 37 38 private HashMap mapElementsOntoNodeInfo = new HashMap (); 39 40 private IUnorderedTreeProvider tree; 41 42 private Object input; 43 44 private int staleCount = 0; 45 46 private class NodeInfo implements IStaleListener, ISetChangeListener { 47 private int count; 49 50 private TreePath treePath; 52 53 IObservableSet children; 55 56 private boolean wasStale = false; 57 58 61 public NodeInfo(TreePath treePath) { 62 this.treePath = treePath; 63 children = tree.createChildSet(this.treePath); 64 if (children != null) { 65 children.addStaleListener(this); 66 children.addSetChangeListener(this); 67 } 68 count = 1; 69 } 70 71 public void handleSetChange(SetChangeEvent event) { 72 processDiff(treePath, event.diff); 73 } 74 75 public void handleStale(StaleEvent event) { 76 if (wasStale != children.isStale()) { 77 if (wasStale) { 78 staleCount--; 79 } else { 80 staleCount++; 81 } 82 wasStale = !wasStale; 83 } 84 setStale(staleCount > 0); 85 } 86 87 90 public void dispose() { 91 if (children != null) { 92 children.dispose(); 93 children = null; 94 if (wasStale) { 95 staleCount--; 96 } 97 } 98 } 99 } 100 101 107 public LeafNodesSet(IUnorderedTreeProvider tree) { 108 this(null, tree); 109 } 110 111 120 public LeafNodesSet(Object initialInput, IUnorderedTreeProvider tree) { 121 super(tree.getRealm()); 122 this.tree = tree; 123 if (initialInput != null) { 124 setInput(initialInput); 125 } 126 } 127 128 private void processDiff(TreePath treePath, SetDiff diff) { 129 Set removals = new HashSet (); 130 HashSet additions = new HashSet (); 131 132 for (Iterator iter = diff.getRemovals().iterator(); iter.hasNext();) { 133 Object next = iter.next(); 134 135 elementRemoved(treePath.createChildPath(next), removals); 136 } 137 138 for (Iterator iter = diff.getAdditions().iterator(); iter.hasNext();) { 139 Object next = iter.next(); 140 141 elementDiscovered(treePath.createChildPath(next), additions); 142 } 143 144 HashSet newRemovals = new HashSet (); 145 newRemovals.addAll(removals); 146 newRemovals.removeAll(additions); 147 148 HashSet newAdditions = new HashSet (); 149 newAdditions.addAll(additions); 150 newAdditions.removeAll(removals); 151 152 leafNodes.addAll(newAdditions); 153 leafNodes.removeAll(newRemovals); 154 155 if (!newAdditions.isEmpty() || !newRemovals.isEmpty()) { 156 setStale(staleCount > 0); 157 fireSetChange(Diffs.createSetDiff(newAdditions, newRemovals)); 158 } 159 } 160 161 167 public void setInput(Object input) { 168 Set removals = Collections.EMPTY_SET; 169 Set additions = Collections.EMPTY_SET; 170 if (this.input != null) { 171 removals = Collections.singleton(this.input); 172 } else if (input != null) { 173 additions = Collections.singleton(input); 174 } 175 this.input = input; 176 processDiff(TreePath.EMPTY, Diffs.createSetDiff(additions, removals)); 177 } 178 179 186 private void elementRemoved(TreePath treePath, Set removals) { 187 NodeInfo newNode = (NodeInfo) mapElementsOntoNodeInfo.get(treePath); 188 189 if (newNode != null) { 190 newNode = new NodeInfo(treePath); 191 newNode.count--; 192 if (newNode.count == 0) { 193 mapElementsOntoNodeInfo.remove(treePath); 194 if (newNode.children != null) { 195 for (Iterator iter = newNode.children.iterator(); iter 196 .hasNext();) { 197 Object next = iter.next(); 198 199 elementRemoved(treePath.createChildPath(next), removals); 200 } 201 newNode.children.dispose(); 202 } else { 203 removals.add(treePath); 204 } 205 } 206 } 207 } 208 209 216 private void elementDiscovered(TreePath treePath, HashSet additions) { 217 NodeInfo newNode = (NodeInfo) mapElementsOntoNodeInfo.get(treePath); 218 219 if (newNode == null) { 220 newNode = new NodeInfo(treePath); 221 mapElementsOntoNodeInfo.put(treePath, newNode); 222 if (newNode.children != null) { 223 for (Iterator iter = newNode.children.iterator(); iter 224 .hasNext();) { 225 Object next = iter.next(); 226 227 elementDiscovered(treePath.createChildPath(next), additions); 228 } 229 } else { 230 additions.add(treePath); 231 } 232 } else { 233 newNode.count++; 235 } 236 } 237 238 protected Set getWrappedSet() { 239 return leafNodes; 240 } 241 242 public Object getElementType() { 243 return Object .class; 244 } 245 246 public void dispose() { 247 for (Iterator iter = mapElementsOntoNodeInfo.values().iterator(); iter 248 .hasNext();) { 249 NodeInfo next = (NodeInfo) iter.next(); 250 251 if (next.children != null) { 252 next.dispose(); 253 } 254 } 255 256 mapElementsOntoNodeInfo.clear(); 257 leafNodes.clear(); 258 super.dispose(); 259 } 260 } 261 | Popular Tags |