Mercurial > projects > dwt2
annotate org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/set/MappedSet.d @ 88:9e0ab372d5d8
Revert from TypeInfo/ClassInfo to java.lang.Class
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 19 Apr 2009 11:10:09 +0200 |
parents | 6be48cf9f95c |
children |
rev | line source |
---|---|
78 | 1 /******************************************************************************* |
2 * Copyright (c) 2006, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 *******************************************************************************/ | |
11 | |
12 module org.eclipse.core.databinding.observable.set.MappedSet; | |
81 | 13 import org.eclipse.core.databinding.observable.set.ISetChangeListener; |
14 import org.eclipse.core.databinding.observable.set.SetChangeEvent; | |
15 import org.eclipse.core.databinding.observable.set.IObservableSet; | |
16 import org.eclipse.core.databinding.observable.set.ObservableSet; | |
78 | 17 |
18 import java.lang.all; | |
19 | |
20 import java.util.Collections; | |
21 import java.util.HashMap; | |
22 import java.util.HashSet; | |
23 import java.util.Iterator; | |
24 import java.util.Map; | |
25 import java.util.Set; | |
26 | |
27 import org.eclipse.core.databinding.observable.Diffs; | |
28 import org.eclipse.core.databinding.observable.Realm; | |
29 import org.eclipse.core.databinding.observable.map.IMapChangeListener; | |
30 import org.eclipse.core.databinding.observable.map.IObservableMap; | |
31 import org.eclipse.core.databinding.observable.map.MapChangeEvent; | |
32 import org.eclipse.core.databinding.observable.map.MapDiff; | |
33 | |
34 /** | |
35 * | |
36 * <p> | |
37 * This class is thread safe. All state accessing methods must be invoked from | |
38 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing | |
39 * listeners may be invoked from any thread. | |
40 * </p> | |
41 * | |
42 * @since 1.0 | |
43 * | |
44 */ | |
45 public class MappedSet : ObservableSet { | |
46 | |
47 private final IObservableMap wrappedMap; | |
48 | |
49 /* | |
50 * Map from values (range elements) to Integer ref counts | |
51 */ | |
85 | 52 private Map valueCounts; |
78 | 53 |
85 | 54 private ISetChangeListener domainListener; |
55 class DomainListener : ISetChangeListener { | |
78 | 56 public void handleSetChange(SetChangeEvent event) { |
57 Set additions = new HashSet(); | |
58 for (Iterator it = event.diff.getAdditions().iterator(); it.hasNext();) { | |
59 Object added = it.next(); | |
60 Object mapValue = wrappedMap.get(added); | |
61 if (handleAddition(mapValue)) { | |
62 additions.add(mapValue); | |
63 } | |
64 } | |
65 Set removals = new HashSet(); | |
66 for (Iterator it = event.diff.getRemovals().iterator(); it.hasNext();) { | |
67 Object removed = it.next(); | |
68 Object mapValue = wrappedMap.get(removed); | |
69 if (handleRemoval(mapValue)) { | |
70 removals.add(mapValue); | |
71 } | |
72 } | |
73 fireSetChange(Diffs.createSetDiff(additions, removals)); | |
74 } | |
75 }; | |
76 | |
85 | 77 private IMapChangeListener mapChangeListener; |
78 class MapChangeListener : IMapChangeListener { | |
78 | 79 public void handleMapChange(MapChangeEvent event) { |
80 MapDiff diff = event.diff; | |
81 Set additions = new HashSet(); | |
82 Set removals = new HashSet(); | |
83 for (Iterator it = diff.getRemovedKeys().iterator(); it.hasNext();) { | |
84 Object key = it.next(); | |
85 Object oldValue = diff.getOldValue(key); | |
86 if (handleRemoval(oldValue)) { | |
87 removals.add(oldValue); | |
88 } | |
89 } | |
90 for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) { | |
91 Object key = it.next(); | |
92 Object oldValue = diff.getOldValue(key); | |
93 Object newValue = diff.getNewValue(key); | |
94 if (handleRemoval(oldValue)) { | |
95 removals.add(oldValue); | |
96 } | |
97 if (handleAddition(newValue)) { | |
98 additions.add(newValue); | |
99 } | |
100 } | |
101 for (Iterator it = diff.getAddedKeys().iterator(); it.hasNext();) { | |
102 Object key = it.next(); | |
103 Object newValue = diff.getNewValue(key); | |
104 if (handleAddition(newValue)) { | |
105 additions.add(newValue); | |
106 } | |
107 } | |
108 fireSetChange(Diffs.createSetDiff(additions, removals)); | |
109 } | |
110 }; | |
111 | |
112 private IObservableSet input; | |
113 | |
114 /** | |
115 * @param input | |
116 * @param map | |
117 */ | |
118 public this(IObservableSet input, IObservableMap map) { | |
85 | 119 valueCounts = new HashMap(); |
120 domainListener = new DomainListener(); | |
121 mapChangeListener = new MapChangeListener(); | |
88
9e0ab372d5d8
Revert from TypeInfo/ClassInfo to java.lang.Class
Frank Benoit <benoit@tionex.de>
parents:
85
diff
changeset
|
122 super(input.getRealm(), Collections.EMPTY_SET, Class.fromType!(Object)); |
78 | 123 setWrappedSet(valueCounts.keySet()); |
124 this.wrappedMap = map; | |
125 this.input = input; | |
126 for (Iterator it = input.iterator(); it.hasNext();) { | |
127 Object element = it.next(); | |
128 Object functionValue = wrappedMap.get(element); | |
129 handleAddition(functionValue); | |
130 } | |
131 input.addSetChangeListener(domainListener); | |
132 map.addMapChangeListener(mapChangeListener); | |
133 } | |
134 | |
135 /** | |
136 * @param mapValue | |
137 * @return true if the given mapValue was an addition | |
138 */ | |
139 protected bool handleAddition(Object mapValue) { | |
140 Integer count = cast(Integer) valueCounts.get(mapValue); | |
141 if (count is null) { | |
142 valueCounts.put(mapValue, new Integer(1)); | |
143 return true; | |
144 } | |
145 valueCounts.put(mapValue, new Integer(count.intValue() + 1)); | |
146 return false; | |
147 } | |
148 | |
149 /** | |
150 * @param mapValue | |
151 * @return true if the given mapValue has been removed | |
152 */ | |
153 protected bool handleRemoval(Object mapValue) { | |
154 Integer count = cast(Integer) valueCounts.get(mapValue); | |
155 if (count.intValue() <= 1) { | |
156 valueCounts.remove(mapValue); | |
157 return true; | |
158 } | |
159 valueCounts.put(mapValue, new Integer(count.intValue() - 1)); | |
160 return false; | |
161 } | |
162 | |
163 public synchronized void dispose() { | |
164 wrappedMap.removeMapChangeListener(mapChangeListener); | |
165 input.removeSetChangeListener(domainListener); | |
166 } | |
167 | |
168 } |