1 /*******************************************************************************
2 * Copyright (c) 2010 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.databoard.binding.impl;
14 import java.util.IdentityHashMap;
15 import java.util.List;
17 import java.util.Map.Entry;
19 import java.util.TreeMap;
21 import org.simantics.databoard.binding.ArrayBinding;
22 import org.simantics.databoard.binding.Binding;
23 import org.simantics.databoard.binding.MapBinding;
24 import org.simantics.databoard.binding.error.BindingException;
25 import org.simantics.databoard.type.MapType;
28 * Binds java.util.Map to MapType
30 * This Binding type accepts all java.util.Map instances, but creates
31 * java.util.TreeMap instances by default.
33 * @author Reino Ruusu <reino.ruusu@vtt.fi>
35 @SuppressWarnings("rawtypes")
36 public class DefaultMapBinding extends MapBinding {
38 public DefaultMapBinding(Binding keyBinding, Binding valueBinding) {
39 super(keyBinding, valueBinding);
42 public DefaultMapBinding(MapType mapType, Binding keyBinding,
43 Binding valueBinding) {
44 super(mapType, keyBinding, valueBinding);
47 public void postConstruction() {
51 public Object create() {
52 return new TreeMap<Object,Object>( keyBinding );
55 @SuppressWarnings("unchecked")
57 public Object create(Object[] keys, Object[] values) {
58 if (keys.length != values.length)
59 throw new IllegalArgumentException("Equal length arrays expected");
61 int len = keys.length;
62 Map result = new TreeMap<Object,Object>( keyBinding );
64 for (int i = 0; i < len; i++) {
66 Object value = values[i];
67 result.put(key, value);
74 @SuppressWarnings("unchecked")
76 public Object create(List<Object> keys, List<Object> values) {
77 if (keys.size()!=values.size())
78 throw new IllegalArgumentException("Equal length arrays expected");
80 int len = keys.size();
81 Map result = new TreeMap<Object,Object>( keyBinding );
83 for (int i=0; i<len; i++) {
84 Object key = keys.get(i);
85 Object value = values.get(i);
86 result.put(key, value);
93 public Object create(Map<?,?> map) {
98 public void clear(Object map) {
103 public boolean containsKey(Object map, Object key) {
105 return m.containsKey(key);
109 public boolean containsValue(Object map, Object value) {
111 Binding vb = getValueBinding();
112 for (Object v : m.values())
114 if (vb.equals(v, value)) return true;
120 public Object get(Object map, Object key) {
125 @SuppressWarnings("unchecked")
127 public Object[] getKeys(Object map) {
129 return m.keySet().toArray(new Object[m.size()]);
132 @SuppressWarnings("unchecked")
134 public void getKeys(Object map, Set<Object> keys) throws BindingException {
136 keys.addAll(m.keySet());
140 * Count the number of entries between two keyes
142 * @param fromInclusive
144 * @param endInclusive
145 * @throws BindingException
147 @SuppressWarnings("unchecked")
149 public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException {
151 if (keyBinding.compare(from, end)>0) return 0;
153 if (src instanceof TreeMap) {
154 TreeMap m = (TreeMap) src;
155 Map sm = m.subMap(from, fromInclusive, end, endInclusive);
160 Map<Object, Object> m = ((Map<Object, Object>)src);
161 for (Object k : m.keySet()) {
162 int fk = keyBinding.compare(from, k);
163 int ek = keyBinding.compare(k, end);
164 boolean fromMatches = fromInclusive ? fk<=0 : fk<0;
165 boolean endMatches = endInclusive ? ek<=0 : ek <0;
166 if ( fromMatches && endMatches ) result++;
173 * Read a range of entries
177 * @param fromInclusive
179 * @param endInclusive
180 * @param dstKeyArrayBinding
182 * @param dstValueArrayBinding
183 * @param dstValueArray
184 * @throws BindingException
186 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 {
187 if (src instanceof TreeMap) {
188 return new TreeMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit);
191 return new HashMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit);
196 @SuppressWarnings("unchecked")
198 public Object[] getValues(Object map) {
200 return m.values().toArray(new Object[m.size()]);
204 public <K, V> void put(Object map, K key, V value) {
205 @SuppressWarnings("unchecked")
206 Map<K, V> m = ((Map<K, V>) map);
211 public <K, V> void putAll(Object dstMap, Map<K, V> srcMap) {
212 @SuppressWarnings("unchecked")
213 Map<K, V> dst = ((Map<K, V>) dstMap);
217 @SuppressWarnings("unchecked")
219 public void getAll(Object mapFrom, Map to) {
220 Map<?, ?> m = ((Map<?, ?>) mapFrom);
224 @SuppressWarnings("unchecked")
226 public void getAll(Object mapFrom, Object[] keys, Object[] values) {
227 Map m = (Map) mapFrom;
229 for (Entry<Object, Object> e : (Set<Entry<Object, Object>>) m.entrySet()) {
230 keys[i] = e.getKey();
231 values[i] = e.getValue();
237 public Object remove(Object map, Object key) {
239 return m.remove(key);
243 public int size(Object map) {
249 public boolean isInstance(Object obj) {
250 return obj instanceof Map;
254 public int deepHashValue(Object map, IdentityHashMap<Object, Object> hashedObjects) throws BindingException {
257 @SuppressWarnings("unchecked")
258 Set<Entry> s = m.entrySet();
260 int keyTree = getKeyBinding().deepHashValue(e.getKey(), hashedObjects);
261 int valueTree = getValueBinding().deepHashValue(e.getValue(), hashedObjects);
262 result += (keyTree ^ valueTree);
268 public Object getCeilingKey(Object map, Object key) {
269 if (map instanceof TreeMap) {
270 return new TreeMapBinding(keyBinding, valueBinding).getCeilingKey(map, key);
273 return new HashMapBinding(keyBinding, valueBinding).getCeilingKey(map, key);
278 public Object getFirstKey(Object map) {
279 if (map instanceof TreeMap) {
280 return new TreeMapBinding(keyBinding, valueBinding).getFirstKey(map);
283 return new HashMapBinding(keyBinding, valueBinding).getFirstKey(map);
288 public Object getFloorKey(Object map, Object key) {
289 if (map instanceof TreeMap) {
290 return new TreeMapBinding(keyBinding, valueBinding).getFloorKey(map, key);
293 return new HashMapBinding(keyBinding, valueBinding).getFloorKey(map, key);
298 public Object getHigherKey(Object map, Object key) {
299 if (map instanceof TreeMap) {
300 return new TreeMapBinding(keyBinding, valueBinding).getHigherKey(map, key);
303 return new HashMapBinding(keyBinding, valueBinding).getHigherKey(map, key);
308 public Object getLastKey(Object map) {
309 if (map instanceof TreeMap) {
310 return new TreeMapBinding(keyBinding, valueBinding).getLastKey(map);
313 return new HashMapBinding(keyBinding, valueBinding).getLastKey(map);
318 public Object getLowerKey(Object map, Object key) {
319 if (map instanceof TreeMap) {
320 return new TreeMapBinding(keyBinding, valueBinding).getLowerKey(map, key);
323 return new HashMapBinding(keyBinding, valueBinding).getLowerKey(map, key);