78
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2008 Matthew Hall 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 * Matthew Hall - initial API and implementation (bug 221704)
|
|
10 * Matthew Hall - bug 223114
|
|
11 ******************************************************************************/
|
|
12
|
|
13 module org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableMap;
|
|
14
|
|
15 import java.lang.all;
|
|
16
|
|
17 import java.util.Collections;
|
|
18 import java.util.HashMap;
|
|
19 import java.util.Map;
|
|
20
|
|
21 import org.eclipse.core.databinding.observable.Diffs;
|
|
22 import org.eclipse.core.databinding.observable.map.IMapChangeListener;
|
|
23 import org.eclipse.core.databinding.observable.map.IObservableMap;
|
|
24 import org.eclipse.core.databinding.observable.map.MapChangeEvent;
|
|
25 import org.eclipse.core.databinding.observable.map.ObservableMap;
|
|
26 import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
|
|
27 import org.eclipse.core.databinding.observable.value.IObservableValue;
|
|
28 import org.eclipse.core.databinding.observable.value.IValueChangeListener;
|
|
29 import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
|
|
30
|
|
31 /**
|
|
32 * @since 1.1
|
|
33 *
|
|
34 */
|
|
35 public class DetailObservableMap : ObservableMap {
|
|
36 private bool updating = false;
|
|
37
|
|
38 private IObservableValue master;
|
|
39 private IObservableFactory detailFactory;
|
|
40
|
|
41 private IObservableMap detailMap;
|
|
42
|
85
|
43 private IValueChangeListener masterChangeListener;
|
|
44 class MasterChangeListener : IValueChangeListener {
|
78
|
45 public void handleValueChange(ValueChangeEvent event) {
|
|
46 Map oldMap = new HashMap(wrappedMap);
|
|
47 updateDetailMap();
|
|
48 fireMapChange(Diffs.computeMapDiff(oldMap, wrappedMap));
|
|
49 }
|
|
50 };
|
|
51
|
85
|
52 private IMapChangeListener detailChangeListener;
|
|
53 class DetailChangeListener : IMapChangeListener {
|
78
|
54 public void handleMapChange(MapChangeEvent event) {
|
|
55 if (!updating) {
|
|
56 fireMapChange(event.diff);
|
|
57 }
|
|
58 }
|
|
59 };
|
|
60
|
|
61 /**
|
|
62 * Constructs a new DetailObservableMap
|
|
63 *
|
|
64 * @param detailFactory
|
|
65 * observable factory that creates IObservableMap instances given
|
|
66 * the current value of master observable value
|
|
67 * @param master
|
|
68 *
|
|
69 */
|
|
70 public this(IObservableFactory detailFactory,
|
|
71 IObservableValue master) {
|
85
|
72 masterChangeListener = new MasterChangeListener();
|
|
73 detailChangeListener = new DetailChangeListener();
|
78
|
74 super(master.getRealm(), Collections.EMPTY_MAP);
|
|
75 this.master = master;
|
|
76 this.detailFactory = detailFactory;
|
|
77
|
|
78 updateDetailMap();
|
|
79 master.addValueChangeListener(masterChangeListener);
|
|
80 }
|
|
81
|
|
82 private void updateDetailMap() {
|
|
83 Object masterValue = master.getValue();
|
|
84 if (detailMap !is null) {
|
|
85 detailMap.removeMapChangeListener(detailChangeListener);
|
|
86 detailMap.dispose();
|
|
87 }
|
|
88
|
|
89 if (masterValue is null) {
|
|
90 detailMap = null;
|
|
91 wrappedMap = Collections.EMPTY_MAP;
|
|
92 } else {
|
|
93 detailMap = cast(IObservableMap) detailFactory
|
|
94 .createObservable(masterValue);
|
|
95 wrappedMap = detailMap;
|
|
96 detailMap.addMapChangeListener(detailChangeListener);
|
|
97 }
|
|
98 }
|
|
99
|
|
100 public Object put(Object key, Object value) {
|
|
101 return detailMap.put(key, value);
|
|
102 }
|
|
103
|
|
104 public void putAll(Map map) {
|
|
105 detailMap.putAll(map);
|
|
106 }
|
|
107
|
|
108 public Object remove(Object key) {
|
|
109 return detailMap.remove(key);
|
|
110 }
|
|
111
|
|
112 public void clear() {
|
|
113 detailMap.clear();
|
|
114 }
|
|
115
|
|
116 public synchronized void dispose() {
|
|
117 if (master !is null) {
|
|
118 master.removeValueChangeListener(masterChangeListener);
|
|
119 master = null;
|
|
120 masterChangeListener = null;
|
|
121 }
|
|
122 detailFactory = null;
|
|
123 if (detailMap !is null) {
|
|
124 detailMap.removeMapChangeListener(detailChangeListener);
|
|
125 detailMap.dispose();
|
|
126 detailMap = null;
|
|
127 }
|
|
128 detailChangeListener = null;
|
|
129 super.dispose();
|
|
130 }
|
|
131
|
|
132 }
|