comparison org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusMap.d @ 78:0a55d2d5a946

Added file for databinding
author Frank Benoit <benoit@tionex.de>
date Tue, 14 Apr 2009 11:35:29 +0200
parents
children 6be48cf9f95c
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
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 }