comparison org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/map/ComputedObservableMap.d @ 78:0a55d2d5a946

Added file for databinding
author Frank Benoit <benoit@tionex.de>
date Tue, 14 Apr 2009 11:35:29 +0200
parents
children 383ce7bd736b
comparison
equal deleted inserted replaced
76:f05e6e8b2f2d 78:0a55d2d5a946
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.map.ComputedObservableMap;
13
14 import java.lang.all;
15
16 import java.util.AbstractSet;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.eclipse.core.databinding.observable.Diffs;
25 import org.eclipse.core.databinding.observable.set.IObservableSet;
26 import org.eclipse.core.databinding.observable.set.ISetChangeListener;
27 import org.eclipse.core.databinding.observable.set.SetChangeEvent;
28
29 /**
30 * Maps objects to one of their attributes. Tracks changes to the underlying
31 * observable set of objects (keys), as well as changes to attribute values.
32 */
33 public abstract class ComputedObservableMap : AbstractObservableMap {
34
35 private final IObservableSet keySet;
36
37 private ISetChangeListener setChangeListener = new class() ISetChangeListener {
38 public void handleSetChange(SetChangeEvent event) {
39 Set addedKeys = new HashSet(event.diff.getAdditions());
40 Set removedKeys = new HashSet(event.diff.getRemovals());
41 Map oldValues = new HashMap();
42 Map newValues = new HashMap();
43 for (Iterator it = removedKeys.iterator(); it.hasNext();) {
44 Object removedKey = it.next();
45 Object oldValue = doGet(removedKey);
46 unhookListener(removedKey);
47 if (oldValue !is null) {
48 oldValues.put(removedKey, oldValue);
49 }
50 }
51 for (Iterator it = addedKeys.iterator(); it.hasNext();) {
52 Object addedKey = it.next();
53 hookListener(addedKey);
54 Object newValue = doGet(addedKey);
55 newValues.put(addedKey, newValue);
56 }
57 fireMapChange(Diffs.createMapDiff(addedKeys, removedKeys,
58 Collections.EMPTY_SET, oldValues, newValues));
59 }
60 };
61
62 private Set entrySet = new EntrySet();
63
64 private class EntrySet : AbstractSet {
65
66 public Iterator iterator() {
67 return new class() Iterator {
68
69 final Iterator keyIterator;
70 this(){
71 keyIterator = keySet.iterator();
72 }
73
74 public bool hasNext() {
75 return keyIterator.hasNext();
76 }
77
78 public Object next() {
79 return new class() Map.Entry {
80 Object key;
81 this(){
82 key = keyIterator.next();
83 }
84
85 public Object getKey() {
86 return key;
87 }
88
89 public Object getValue() {
90 return get(getKey());
91 }
92
93 public Object setValue(Object value) {
94 return put(getKey(), value);
95 }
96 };
97 }
98
99 public void remove() {
100 keyIterator.remove();
101 }
102 };
103 }
104
105 public int size() {
106 return keySet.size();
107 }
108
109 }
110
111 /**
112 * @param keySet
113 */
114 public this(IObservableSet keySet) {
115 super(keySet.getRealm());
116 this.keySet = keySet;
117 this.keySet.addSetChangeListener(setChangeListener);
118 }
119
120 protected void init() {
121 for (Iterator it = this.keySet.iterator(); it.hasNext();) {
122 Object key = it.next();
123 hookListener(key);
124 }
125 }
126
127 protected final void fireSingleChange(Object key, Object oldValue,
128 Object newValue) {
129 fireMapChange(Diffs.createMapDiffSingleChange(key, oldValue, newValue));
130 }
131
132 public Set entrySet() {
133 return entrySet;
134 }
135
136 public Set keySet() {
137 return keySet;
138 }
139
140 final public Object get(Object key) {
141 return doGet(key);
142 }
143
144 final public Object put(Object key, Object value) {
145 return doPut(key, value);
146 }
147
148 /**
149 * @param removedKey
150 */
151 protected abstract void unhookListener(Object removedKey);
152
153 /**
154 * @param addedKey
155 */
156 protected abstract void hookListener(Object addedKey);
157
158 /**
159 * @param key
160 * @return the value for the given key
161 */
162 protected abstract Object doGet(Object key);
163
164 /**
165 * @param key
166 * @param value
167 * @return the old value for the given key
168 */
169 protected abstract Object doPut(Object key, Object value);
170 }