KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > internal > databinding > provisional > observable > mapping > BidirectionalMapping


1 /*******************************************************************************
2  * Copyright (c) 2006 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.jface.internal.databinding.provisional.observable.mapping;
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.jface.internal.databinding.provisional.observable.IObservable;
22 import org.eclipse.jface.internal.databinding.provisional.observable.set.IObservableSet;
23 import org.eclipse.jface.internal.databinding.provisional.observable.set.ISetChangeListener;
24 import org.eclipse.jface.internal.databinding.provisional.observable.set.SetDiff;
25 import org.eclipse.jface.internal.databinding.provisional.observable.set.WritableSet;
26
27 /**
28  * @since 1.0
29  *
30  */

31 public class BidirectionalMapping extends AbstractObservableMapping implements
32         IBidirectionalMapping, IObservableMappingWithDomain {
33
34     private final IObservableMapping wrappedMapping;
35
36     private IObservableSet range;
37
38     private Map JavaDoc valueToElements = new HashMap JavaDoc();
39
40     private ISetChangeListener domainListener = new ISetChangeListener() {
41         public void handleSetChange(IObservableSet source, SetDiff diff) {
42             Set JavaDoc rangeAdditions = new HashSet JavaDoc();
43             for (Iterator JavaDoc it = diff.getAdditions().iterator(); it.hasNext();) {
44                 Object JavaDoc added = it.next();
45                 Object JavaDoc mappingValue = wrappedMapping.getMappingValue(added);
46                 rangeAdditions.add(mappingValue);
47                 addMapping(mappingValue, added);
48             }
49             range.addAll(rangeAdditions);
50             for (Iterator JavaDoc it = diff.getRemovals().iterator(); it.hasNext();) {
51                 Object JavaDoc removed = it.next();
52                 removeMapping(wrappedMapping.getMappingValue(removed), removed);
53             }
54             range.retainAll(valueToElements.keySet());
55         }
56     };
57
58     private IMappingChangeListener mappingChangeListener = new IMappingChangeListener() {
59         public void handleMappingValueChange(IObservable source,
60                 MappingDiff diff) {
61             Set JavaDoc affectedElements = diff.getElements();
62             for (Iterator JavaDoc it = affectedElements.iterator(); it.hasNext();) {
63                 Object JavaDoc element = it.next();
64                 Object JavaDoc oldFunctionValue = diff.getOldMappingValues(element,
65                         new int[0])[0];
66                 Object JavaDoc newFunctionValue = diff.getNewMappingValues(element,
67                         new int[0])[0];
68                 removeMapping(oldFunctionValue, element);
69                 addMapping(newFunctionValue, element);
70             }
71             Set JavaDoc tempRange = valueToElements.keySet();
72             range.addAll(tempRange);
73             range.retainAll(tempRange);
74             fireMappingValueChange(diff);
75         }
76     };
77
78     private IObservableSet domain;
79
80     /**
81      * @param functionWithDomain
82      */

83     public BidirectionalMapping(IObservableMappingWithDomain functionWithDomain) {
84         this(functionWithDomain, functionWithDomain.getDomain());
85     }
86
87     /**
88      * @param wrappedMapping
89      * @param domain
90      */

91     public BidirectionalMapping(IObservableMapping wrappedMapping,
92             IObservableSet domain) {
93         this.wrappedMapping = wrappedMapping;
94         this.domain = domain;
95         Set JavaDoc tempRange = new HashSet JavaDoc();
96         for (Iterator JavaDoc it = domain.iterator(); it.hasNext();) {
97             Object JavaDoc element = it.next();
98             Object JavaDoc functionValue = wrappedMapping.getMappingValue(element);
99             addMapping(functionValue, element);
100             tempRange.add(functionValue);
101         }
102         this.range = new WritableSet(tempRange);
103         domain.addSetChangeListener(domainListener);
104     }
105
106     /**
107      * @param functionValue
108      * @param element
109      * @param b
110      */

111     private void addMapping(Object JavaDoc functionValue, Object JavaDoc element) {
112         Object JavaDoc elementOrSet = valueToElements.get(functionValue);
113         if (elementOrSet == null) {
114             valueToElements.put(functionValue, element);
115             return;
116         }
117         if (!(elementOrSet instanceof Set JavaDoc)) {
118             elementOrSet = new HashSet JavaDoc(Collections.singleton(elementOrSet));
119             valueToElements.put(functionValue, elementOrSet);
120         }
121         Set JavaDoc set = (Set JavaDoc) elementOrSet;
122         set.add(element);
123     }
124
125     /**
126      * @param functionValue
127      * @param element
128      * @param b
129      */

130     private void removeMapping(Object JavaDoc functionValue, Object JavaDoc element) {
131         Object JavaDoc elementOrSet = valueToElements.get(functionValue);
132         if (elementOrSet instanceof Set JavaDoc) {
133             Set JavaDoc set = (Set JavaDoc) elementOrSet;
134             set.remove(element);
135             if (set.size() == 0) {
136                 valueToElements.remove(functionValue);
137             }
138         } else {
139             valueToElements.remove(functionValue);
140         }
141     }
142
143     protected Object JavaDoc doGetMappingValue(Object JavaDoc element) {
144         return wrappedMapping.getMappingValue(element);
145     }
146
147     public void setMappingValue(Object JavaDoc element, Object JavaDoc value) {
148         wrappedMapping.setMappingValue(element, value);
149     }
150
151     public IObservableSet getRange() {
152         return range;
153     }
154
155     public Set JavaDoc getDomainElementsForValue(Object JavaDoc value) {
156         return null;
157     }
158
159     public void dispose() {
160         wrappedMapping.removeMappingChangeListener(mappingChangeListener);
161         domain.removeSetChangeListener(domainListener);
162     }
163
164     public IObservableSet getDomain() {
165         return domain;
166     }
167
168     public Object JavaDoc getValueType() {
169         return wrappedMapping.getValueType();
170     }
171
172 }
173
Popular Tags