78
|
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.internal.databinding.ValidationStatusMap;
|
|
13
|
|
14 import java.lang.all;
|
|
15
|
|
16 import java.util.ArrayList;
|
|
17 import java.util.HashMap;
|
|
18 import java.util.Iterator;
|
|
19 import java.util.List;
|
|
20 import java.util.Map;
|
|
21 import java.util.Set;
|
|
22
|
|
23 import org.eclipse.core.databinding.Binding;
|
|
24 import org.eclipse.core.databinding.observable.ChangeEvent;
|
|
25 import org.eclipse.core.databinding.observable.Diffs;
|
|
26 import org.eclipse.core.databinding.observable.IChangeListener;
|
|
27 import org.eclipse.core.databinding.observable.Realm;
|
|
28 import org.eclipse.core.databinding.observable.list.WritableList;
|
|
29 import org.eclipse.core.databinding.observable.map.IMapChangeListener;
|
|
30 import org.eclipse.core.databinding.observable.map.MapDiff;
|
|
31 import org.eclipse.core.databinding.observable.map.ObservableMap;
|
|
32 import org.eclipse.core.databinding.observable.value.IObservableValue;
|
|
33 import org.eclipse.core.runtime.IStatus;
|
|
34
|
|
35 /**
|
|
36 * @since 1.0
|
|
37 *
|
|
38 */
|
|
39 public class ValidationStatusMap : ObservableMap {
|
|
40
|
|
41 private bool isDirty = true;
|
|
42
|
|
43 private final WritableList bindings;
|
|
44
|
|
45 private List dependencies = new ArrayList();
|
|
46
|
|
47 private IChangeListener markDirtyChangeListener = new class() IChangeListener {
|
|
48 public void handleChange(ChangeEvent event) {
|
|
49 markDirty();
|
|
50 }
|
|
51 };
|
|
52
|
|
53 /**
|
|
54 * @param realm
|
|
55 * @param bindings
|
|
56 */
|
|
57 public this(Realm realm, WritableList bindings) {
|
|
58 super(realm, new HashMap());
|
|
59 this.bindings = bindings;
|
|
60 bindings.addChangeListener(markDirtyChangeListener);
|
|
61 }
|
|
62
|
|
63 protected void getterCalled() {
|
|
64 recompute();
|
|
65 super.getterCalled();
|
|
66 }
|
|
67
|
|
68 private void markDirty() {
|
|
69 // since we are dirty, we don't need to listen anymore
|
|
70 removeElementChangeListener();
|
|
71 final Map oldMap = wrappedMap;
|
|
72 // lazy computation of diff
|
|
73 MapDiff mapDiff = new class() MapDiff {
|
|
74 private MapDiff cachedDiff = null;
|
|
75
|
|
76 private void ensureCached() {
|
|
77 if (cachedDiff is null) {
|
|
78 recompute();
|
|
79 cachedDiff = Diffs.computeMapDiff(oldMap, wrappedMap);
|
|
80 }
|
|
81 }
|
|
82
|
|
83 public Set getAddedKeys() {
|
|
84 ensureCached();
|
|
85 return cachedDiff.getAddedKeys();
|
|
86 }
|
|
87
|
|
88 public Set getChangedKeys() {
|
|
89 ensureCached();
|
|
90 return cachedDiff.getChangedKeys();
|
|
91 }
|
|
92
|
|
93 public Object getNewValue(Object key) {
|
|
94 ensureCached();
|
|
95 return cachedDiff.getNewValue(key);
|
|
96 }
|
|
97
|
|
98 public Object getOldValue(Object key) {
|
|
99 ensureCached();
|
|
100 return cachedDiff.getOldValue(key);
|
|
101 }
|
|
102
|
|
103 public Set getRemovedKeys() {
|
|
104 ensureCached();
|
|
105 return cachedDiff.getRemovedKeys();
|
|
106 }
|
|
107 };
|
|
108 wrappedMap = new HashMap();
|
|
109 isDirty = true;
|
|
110 fireMapChange(mapDiff);
|
|
111 }
|
|
112
|
|
113 private void recompute() {
|
|
114 if (isDirty) {
|
|
115 Map newContents = new HashMap();
|
|
116 for (Iterator it = bindings.iterator(); it.hasNext();) {
|
|
117 Binding binding = cast(Binding) it.next();
|
|
118 IObservableValue validationError = binding
|
|
119 .getValidationStatus();
|
|
120 dependencies.add(validationError);
|
|
121 validationError.addChangeListener(markDirtyChangeListener);
|
|
122 IStatus validationStatusValue = cast(IStatus) validationError
|
|
123 .getValue();
|
|
124 newContents.put(binding, validationStatusValue);
|
|
125 }
|
|
126 wrappedMap.putAll(newContents);
|
|
127 isDirty = false;
|
|
128 }
|
|
129 }
|
|
130
|
|
131 /*
|
|
132 * (non-Javadoc)
|
|
133 *
|
|
134 * @see org.eclipse.core.databinding.observable.list.ObservableList#dispose()
|
|
135 */
|
|
136 public void dispose() {
|
|
137 bindings.removeChangeListener(markDirtyChangeListener);
|
|
138 removeElementChangeListener();
|
|
139 super.dispose();
|
|
140 }
|
|
141
|
|
142 private void removeElementChangeListener() {
|
|
143 for (Iterator it = dependencies.iterator(); it.hasNext();) {
|
|
144 IObservableValue observableValue = cast(IObservableValue) it.next();
|
|
145 observableValue.removeChangeListener(markDirtyChangeListener);
|
|
146 }
|
|
147 }
|
|
148
|
|
149 public synchronized void addChangeListener(IChangeListener listener) {
|
|
150 // this ensures that the next change will be seen by the new listener.
|
|
151 recompute();
|
|
152 super.addChangeListener(listener);
|
|
153 }
|
|
154
|
|
155 public synchronized void addMapChangeListener(IMapChangeListener listener) {
|
|
156 // this ensures that the next change will be seen by the new listener.
|
|
157 recompute();
|
|
158 super.addMapChangeListener(listener);
|
|
159 }
|
|
160
|
|
161 }
|