]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/TreeMapBinding.java
Fixing several binding-related bugs
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / impl / TreeMapBinding.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.binding.impl;
13
14 import java.util.IdentityHashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 import java.util.TreeMap;
20
21 import org.simantics.databoard.Bindings;
22 import org.simantics.databoard.adapter.AdaptException;
23 import org.simantics.databoard.adapter.Adapter;
24 import org.simantics.databoard.adapter.AdapterConstructionException;
25 import org.simantics.databoard.binding.ArrayBinding;
26 import org.simantics.databoard.binding.Binding;
27 import org.simantics.databoard.binding.MapBinding;
28 import org.simantics.databoard.binding.error.BindingException;
29 import org.simantics.databoard.type.MapType;
30
31 /**
32  * Binds java.util.TreeMap to MapType
33  * 
34  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
35  */
36 @SuppressWarnings("all")
37 public class TreeMapBinding extends MapBinding {
38
39         public TreeMapBinding(Binding keyBinding, Binding valueBinding) {
40                 super(keyBinding, valueBinding);
41         }
42
43         public TreeMapBinding(MapType mapType, Binding keyBinding,
44                         Binding valueBinding) {
45                 super(mapType, keyBinding, valueBinding);
46         }
47
48         public void postConstruction() {
49         }
50
51         @Override
52         public Object create() {
53                 return new TreeMap( getKeyBinding() );
54         }
55
56         @Override
57         public Object create(Object[] keys, Object[] values) {
58                 if (keys.length != values.length)
59                         throw new IllegalArgumentException("Equal length arrays expected");
60
61                 int len = keys.length;
62                 TreeMap result = new TreeMap( getKeyBinding() );
63
64                 for (int i = 0; i < len; i++) {
65                         Object key = keys[i];
66                         Object value = values[i];
67                         result.put(key, value);
68                 }
69
70                 return result;
71         }
72         
73         
74         @Override
75         public Object create(List<Object> keys, List<Object> values) {
76                 if (keys.size()!=values.size())
77                         throw new IllegalArgumentException("Equal length arrays expected");
78                 
79                 int len = keys.size();
80                 TreeMap result = new TreeMap( getKeyBinding() );
81                 
82                 for (int i=0; i<len; i++) {
83                         Object key = keys.get(i);
84                         Object value = values.get(i);
85                         result.put(key, value);
86                 }
87                 
88                 return result;
89         }       
90
91         @Override
92         public Object create(Map initialMap) {
93                 // Replace with TreeMap. Create comparator from binding.
94                 TreeMap result = new TreeMap( getKeyBinding() );
95                 result.putAll(initialMap);
96                 return result;
97         }
98         
99         @SuppressWarnings("unchecked")
100         @Override
101         public void clear(Object map) {
102                 ((Map) map).clear();
103         }
104
105         @SuppressWarnings("unchecked")
106         @Override
107         public boolean containsKey(Object map, Object key) {
108                 Map m = ((Map) map);
109                 return m.containsKey(key);
110         }
111
112         @SuppressWarnings("unchecked")
113         @Override
114         public boolean containsValue(Object map, Object value) {
115                 Map m = ((Map) map);
116                 Binding vb = getValueBinding();
117                 for (Object v : m.values())
118                 {
119                         if (vb.equals(v, value)) return true;
120                 }
121                 return false;
122         }
123
124         @SuppressWarnings("unchecked")
125         @Override
126         public Object get(Object map, Object key) {
127                 Map m = ((Map) map);
128                 return m.get(key);
129         }
130
131         @SuppressWarnings("unchecked")
132         @Override
133         public Object[] getKeys(Object map) {
134                 Map m = ((Map) map);
135                 return m.keySet().toArray(new Object[m.size()]);
136         }
137         
138         @Override
139         public void getKeys(Object map, Set<Object> keys) throws BindingException {
140                 Map m = ((Map)map);
141                 keys.addAll(m.keySet());
142         }       
143         
144         /**
145          * Count the number of entries between two keyes
146          * @param from
147      * @param fromInclusive
148          * @param end 
149      * @param endInclusive
150          * @throws BindingException
151          */
152         @SuppressWarnings("unchecked")
153         @Override
154         public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException {
155                 // Assert end > from
156                 if (keyBinding.compare(from, end)>0) return 0;
157                 
158                 TreeMap m = (TreeMap) src;
159                 Map sm = m.subMap(from, fromInclusive, end, endInclusive);
160                 return sm.size();
161         }
162         
163         /**
164          * Read a range of entries
165          * 
166          * @param src
167          * @param from
168      * @param fromInclusive
169          * @param end 
170      * @param endInclusive
171          * @param dstKeyArrayBinding
172          * @param dstKeyArray
173      * @param dstValueArrayBinding
174          * @param dstValueArray
175          * @throws BindingException
176          */
177         public int getEntries(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive, ArrayBinding dstKeyArrayBinding, Object dstKeyArray, ArrayBinding dstValueArrayBinding, Object dstValueArray, int limit) throws BindingException {
178                 try {
179                         // Assert end > from
180                         if (keyBinding.compare(from, end)>0) return 0;
181
182                         TreeMap m = (TreeMap) src;
183                         Map sm = m.subMap(from, fromInclusive, end, endInclusive);
184                         int dkc = dstKeyArrayBinding.size( dstKeyArray );
185                         int dvc = dstValueArrayBinding.size( dstValueArray );
186                         Adapter ka = Bindings.getTypeAdapter(keyBinding, dstKeyArrayBinding.getComponentBinding());
187                         Adapter va = Bindings.getTypeAdapter(valueBinding, dstValueArrayBinding.getComponentBinding());
188                         int i = 0;
189                         Set<Map.Entry<Object, Object>> es = sm.entrySet();
190                         for (Entry<Object, Object> e : es) {
191                                 if (limit>=0 && i>=limit) break;
192                                 Object dk = ka.adapt( e.getKey() );
193                                 Object dv = va.adapt( e.getValue() );
194                                 if (i<dkc) dstKeyArrayBinding.set(dstKeyArray, i, dk); else dstKeyArrayBinding.add(dstKeyArray, dk);
195                                 if (i<dvc) dstValueArrayBinding.set(dstValueArray, i, dv); else dstValueArrayBinding.add(dstValueArray, dv);
196                                 i++;
197                         }
198                         return i;
199                 } catch (AdapterConstructionException e) {
200                         throw new BindingException(e);
201                 } catch (AdaptException e) {
202                         throw new BindingException(e);
203                 }
204         }
205         
206
207         @SuppressWarnings("unchecked")
208         @Override
209         public Object[] getValues(Object map) {
210                 Map m = ((Map) map);
211                 return m.values().toArray(new Object[m.size()]);
212         }
213
214         @Override
215         public <K, V> void put(Object map, K key, V value) {
216                 Map<K, V> m = ((Map<K, V>) map);
217                 m.put(key, value);
218         }
219
220         @Override
221         public <K, V> void putAll(Object dstMap, Map<K, V> srcMap) {
222                 Map<K, V> dst = ((Map<K, V>) dstMap);
223                 dst.putAll(srcMap);
224         }
225
226         @Override
227         public void getAll(Object mapFrom, Map to) {
228                 Map<?, ?> m = ((Map<?, ?>) mapFrom);
229                 to.putAll(m);
230         }
231
232         @SuppressWarnings("unchecked")
233         @Override
234         public void getAll(Object mapFrom, Object[] keys, Object[] values) {
235                 TreeMap m = (TreeMap) mapFrom;
236                 int i = 0;
237                 for (Entry<Object, Object> e : (Set<Entry<Object, Object>>) m.entrySet()) {
238                         keys[i] = e.getKey();
239                         values[i] = e.getValue();
240                         i++;
241                 }
242         }
243         
244         @SuppressWarnings("unchecked")
245         @Override
246         public Object remove(Object map, Object key) {
247                 Map m = ((Map) map);
248                 return m.remove(key);
249         }
250
251         @SuppressWarnings("unchecked")
252         @Override
253         public int size(Object map) {
254                 Map m = ((Map) map);
255                 return m.size();
256         }
257
258         @SuppressWarnings("unchecked")
259         @Override
260         public boolean isInstance(Object obj) {
261                 return obj instanceof Map;
262         }
263
264         @Override
265     public int deepHashValue(Object map, IdentityHashMap<Object, Object> hashedObjects) throws BindingException {
266                 int result = 0;
267                 Map m = ((Map) map);
268                 Set<Entry> s = m.entrySet();
269                 for (Entry e : s) {
270                         int keyTree = getKeyBinding().deepHashValue(e.getKey(), hashedObjects);
271                         int valueTree = getValueBinding().deepHashValue(e.getValue(), hashedObjects);
272                         result += (keyTree ^ valueTree);
273                 }
274                 return result;
275         }
276
277         @Override
278         public Object getCeilingKey(Object map, Object key) {
279                 TreeMap m = ((TreeMap) map);
280                 return m.ceilingKey(key);
281         }
282
283         @Override
284         public Object getFirstKey(Object map) {
285                 TreeMap m = ((TreeMap) map);
286                 return m.firstKey();
287         }
288
289         @Override
290         public Object getFloorKey(Object map, Object key) {
291                 TreeMap m = ((TreeMap) map);
292                 return m.floorKey(key);
293         }
294
295         @Override
296         public Object getHigherKey(Object map, Object key) {
297                 TreeMap m = ((TreeMap) map);
298                 return m.higherKey(key);
299         }
300
301         @Override
302         public Object getLastKey(Object map) {
303                 TreeMap m = ((TreeMap) map);
304                 return m.lastKey();
305         }
306
307         @Override
308         public Object getLowerKey(Object map, Object key) {
309                 TreeMap m = ((TreeMap) map);
310                 return m.lowerKey(key);
311         }
312
313 }