KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > databinding > observable > map > BidirectionalMap


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 package org.eclipse.core.databinding.observable.map;
12
13 import java.util.Collections JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.databinding.observable.Realm;
21
22 /**
23  *
24  * <p>
25  * This class is thread safe. All state accessing methods must be invoked from
26  * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
27  * listeners may be invoked from any thread.
28  * </p>
29  * @since 1.0
30  *
31  */

32 public class BidirectionalMap extends ObservableMap {
33
34     private Map JavaDoc valueToElements = new HashMap JavaDoc();
35
36     private IMapChangeListener mapListener = new IMapChangeListener() {
37
38         public void handleMapChange(MapChangeEvent event) {
39             MapDiff diff = event.diff;
40             for (Iterator JavaDoc it = diff.getAddedKeys().iterator(); it.hasNext();) {
41                 Object JavaDoc addedKey = it.next();
42                 addMapping(addedKey, diff.getNewValue(addedKey));
43             }
44             for (Iterator JavaDoc it = diff.getChangedKeys().iterator(); it.hasNext();) {
45                 Object JavaDoc changedKey = it.next();
46                 removeMapping(changedKey, diff.getOldValue(changedKey));
47                 addMapping(changedKey, diff.getNewValue(changedKey));
48             }
49             for (Iterator JavaDoc it = diff.getRemovedKeys().iterator(); it.hasNext();) {
50                 Object JavaDoc removedKey = it.next();
51                 removeMapping(removedKey, diff.getOldValue(removedKey));
52             }
53             fireMapChange(diff);
54         }
55     };
56
57     /**
58      * @param wrappedMap
59      */

60     public BidirectionalMap(IObservableMap wrappedMap) {
61         super(wrappedMap.getRealm(), wrappedMap);
62         wrappedMap.addMapChangeListener(mapListener);
63         for (Iterator JavaDoc it = wrappedMap.entrySet().iterator(); it.hasNext();) {
64             Map.Entry JavaDoc entry = (Entry) it.next();
65             addMapping(entry.getKey(), entry.getValue());
66         }
67     }
68
69     /**
70      * @param key
71      * @param value
72      */

73     private void addMapping(Object JavaDoc key, Object JavaDoc value) {
74         Object JavaDoc elementOrSet = valueToElements.get(value);
75         if (elementOrSet == null) {
76             valueToElements.put(value, key);
77             return;
78         }
79         if (!(elementOrSet instanceof Set JavaDoc)) {
80             elementOrSet = new HashSet JavaDoc(Collections.singleton(elementOrSet));
81             valueToElements.put(value, elementOrSet);
82         }
83         Set JavaDoc set = (Set JavaDoc) elementOrSet;
84         set.add(key);
85     }
86
87     /**
88      * @param functionValue
89      * @param element
90      */

91     private void removeMapping(Object JavaDoc functionValue, Object JavaDoc element) {
92         Object JavaDoc elementOrSet = valueToElements.get(functionValue);
93         if (elementOrSet instanceof Set JavaDoc) {
94             Set JavaDoc set = (Set JavaDoc) elementOrSet;
95             set.remove(element);
96             if (set.size() == 0) {
97                 valueToElements.remove(functionValue);
98             }
99         } else {
100             valueToElements.remove(functionValue);
101         }
102     }
103
104 }
105
Popular Tags