KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > databinding > observable > set > MappedSet


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 package org.eclipse.core.databinding.observable.set;
13
14 import java.util.Collections JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
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 /**
29  *
30  * <p>
31  * This class is thread safe. All state accessing methods must be invoked from
32  * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
33  * listeners may be invoked from any thread.
34  * </p>
35  *
36  * @since 1.0
37  *
38  */

39 public class MappedSet extends ObservableSet {
40
41     private final IObservableMap wrappedMap;
42
43     /*
44      * Map from values (range elements) to Integer ref counts
45      */

46     private Map JavaDoc valueCounts = new HashMap JavaDoc();
47
48     private ISetChangeListener domainListener = new ISetChangeListener() {
49         public void handleSetChange(SetChangeEvent event) {
50             Set JavaDoc additions = new HashSet JavaDoc();
51             for (Iterator JavaDoc it = event.diff.getAdditions().iterator(); it.hasNext();) {
52                 Object JavaDoc added = it.next();
53                 Object JavaDoc mapValue = wrappedMap.get(added);
54                 if (handleAddition(mapValue)) {
55                     additions.add(mapValue);
56                 }
57             }
58             Set JavaDoc removals = new HashSet JavaDoc();
59             for (Iterator JavaDoc it = event.diff.getRemovals().iterator(); it.hasNext();) {
60                 Object JavaDoc removed = it.next();
61                 Object JavaDoc 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 JavaDoc additions = new HashSet JavaDoc();
74             Set JavaDoc removals = new HashSet JavaDoc();
75             for (Iterator JavaDoc it = diff.getRemovedKeys().iterator(); it.hasNext();) {
76                 Object JavaDoc key = it.next();
77                 Object JavaDoc oldValue = diff.getOldValue(key);
78                 if (handleRemoval(oldValue)) {
79                     removals.add(oldValue);
80                 }
81             }
82             for (Iterator JavaDoc it = diff.getChangedKeys().iterator(); it.hasNext();) {
83                 Object JavaDoc key = it.next();
84                 Object JavaDoc oldValue = diff.getOldValue(key);
85                 Object JavaDoc 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 JavaDoc it = diff.getAddedKeys().iterator(); it.hasNext();) {
94                 Object JavaDoc key = it.next();
95                 Object JavaDoc 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     /**
107      * @param input
108      * @param map
109      */

110     public MappedSet(IObservableSet input, IObservableMap map) {
111         super(input.getRealm(), Collections.EMPTY_SET, Object JavaDoc.class);
112         setWrappedSet(valueCounts.keySet());
113         this.wrappedMap = map;
114         this.input = input;
115         for (Iterator JavaDoc it = input.iterator(); it.hasNext();) {
116             Object JavaDoc element = it.next();
117             Object JavaDoc functionValue = wrappedMap.get(element);
118             handleAddition(functionValue);
119         }
120         input.addSetChangeListener(domainListener);
121         map.addMapChangeListener(mapChangeListener);
122     }
123
124     /**
125      * @param mapValue
126      * @return true if the given mapValue was an addition
127      */

128     protected boolean handleAddition(Object JavaDoc mapValue) {
129         Integer JavaDoc count = (Integer JavaDoc) valueCounts.get(mapValue);
130         if (count == null) {
131             valueCounts.put(mapValue, new Integer JavaDoc(1));
132             return true;
133         }
134         valueCounts.put(mapValue, new Integer JavaDoc(count.intValue() + 1));
135         return false;
136     }
137
138     /**
139      * @param mapValue
140      * @return true if the given mapValue has been removed
141      */

142     protected boolean handleRemoval(Object JavaDoc mapValue) {
143         Integer JavaDoc count = (Integer JavaDoc) valueCounts.get(mapValue);
144         if (count.intValue() <= 1) {
145             valueCounts.remove(mapValue);
146             return true;
147         }
148         valueCounts.put(mapValue, new Integer JavaDoc(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