comparison org.eclipse.core.databinding/src/org/eclipse/core/databinding/observable/map/BidirectionalMap.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 module org.eclipse.core.databinding.observable.map.BidirectionalMap;
12
13 import java.lang.all;
14
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Iterator;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.core.databinding.observable.Realm;
23
24 /**
25 *
26 * <p>
27 * This class is thread safe. All state accessing methods must be invoked from
28 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
29 * listeners may be invoked from any thread.
30 * </p>
31 * @since 1.0
32 *
33 */
34 public class BidirectionalMap : ObservableMap {
35
36 private Map valueToElements = new HashMap();
37
38 private IMapChangeListener mapListener = new class() IMapChangeListener {
39
40 public void handleMapChange(MapChangeEvent event) {
41 MapDiff diff = event.diff;
42 for (Iterator it = diff.getAddedKeys().iterator(); it.hasNext();) {
43 Object addedKey = it.next();
44 addMapping(addedKey, diff.getNewValue(addedKey));
45 }
46 for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) {
47 Object changedKey = it.next();
48 removeMapping(changedKey, diff.getOldValue(changedKey));
49 addMapping(changedKey, diff.getNewValue(changedKey));
50 }
51 for (Iterator it = diff.getRemovedKeys().iterator(); it.hasNext();) {
52 Object removedKey = it.next();
53 removeMapping(removedKey, diff.getOldValue(removedKey));
54 }
55 fireMapChange(diff);
56 }
57 };
58
59 /**
60 * @param wrappedMap
61 */
62 public this(IObservableMap wrappedMap) {
63 super(wrappedMap.getRealm(), wrappedMap);
64 wrappedMap.addMapChangeListener(mapListener);
65 for (Iterator it = wrappedMap.entrySet().iterator(); it.hasNext();) {
66 Map.Entry entry = cast(Entry) it.next();
67 addMapping(entry.getKey(), entry.getValue());
68 }
69 }
70
71 /**
72 * @param key
73 * @param value
74 */
75 private void addMapping(Object key, Object value) {
76 Object elementOrSet = valueToElements.get(value);
77 if (elementOrSet is null) {
78 valueToElements.put(value, key);
79 return;
80 }
81 if (!( null !is cast(Set)elementOrSet )) {
82 elementOrSet = new HashSet(Collections.singleton(elementOrSet));
83 valueToElements.put(value, elementOrSet);
84 }
85 Set set = cast(Set) elementOrSet;
86 set.add(key);
87 }
88
89 /**
90 * @param functionValue
91 * @param element
92 */
93 private void removeMapping(Object functionValue, Object element) {
94 Object elementOrSet = valueToElements.get(functionValue);
95 if ( null !is cast(Set)elementOrSet ) {
96 Set set = cast(Set) elementOrSet;
97 set.remove(element);
98 if (set.size() is 0) {
99 valueToElements.remove(functionValue);
100 }
101 } else {
102 valueToElements.remove(functionValue);
103 }
104 }
105
106 }