/******************************************************************************* * Copyright (c) 2010 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard.binding.impl; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import org.simantics.databoard.binding.ArrayBinding; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.MapBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.MapType; /** * Binds java.util.Map to MapType * * This Binding type accepts all java.util.Map instances, but creates * java.util.TreeMap instances by default. * * @author Reino Ruusu */ @SuppressWarnings("rawtypes") public class DefaultMapBinding extends MapBinding { public DefaultMapBinding(Binding keyBinding, Binding valueBinding) { super(keyBinding, valueBinding); } public DefaultMapBinding(MapType mapType, Binding keyBinding, Binding valueBinding) { super(mapType, keyBinding, valueBinding); } public void postConstruction() { } @Override public Object create() { return new TreeMap( keyBinding ); } @SuppressWarnings("unchecked") @Override public Object create(Object[] keys, Object[] values) { if (keys.length != values.length) throw new IllegalArgumentException("Equal length arrays expected"); int len = keys.length; Map result = new TreeMap( keyBinding ); for (int i = 0; i < len; i++) { Object key = keys[i]; Object value = values[i]; result.put(key, value); } return result; } @SuppressWarnings("unchecked") @Override public Object create(List keys, List values) { if (keys.size()!=values.size()) throw new IllegalArgumentException("Equal length arrays expected"); int len = keys.size(); Map result = new TreeMap( keyBinding ); for (int i=0; i map) { return map; } @Override public void clear(Object map) { ((Map) map).clear(); } @Override public boolean containsKey(Object map, Object key) { Map m = ((Map) map); return m.containsKey(key); } @Override public boolean containsValue(Object map, Object value) { Map m = ((Map) map); Binding vb = getValueBinding(); for (Object v : m.values()) { if (vb.equals(v, value)) return true; } return false; } @Override public Object get(Object map, Object key) { Map m = ((Map) map); return m.get(key); } @SuppressWarnings("unchecked") @Override public Object[] getKeys(Object map) { Map m = ((Map) map); return m.keySet().toArray(new Object[m.size()]); } @SuppressWarnings("unchecked") @Override public void getKeys(Object map, Set keys) throws BindingException { Map m = ((Map)map); keys.addAll(m.keySet()); } /** * Count the number of entries between two keyes * @param from * @param fromInclusive * @param end * @param endInclusive * @throws BindingException */ @SuppressWarnings("unchecked") @Override public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException { // Assert end > from if (keyBinding.compare(from, end)>0) return 0; if (src instanceof TreeMap) { TreeMap m = (TreeMap) src; Map sm = m.subMap(from, fromInclusive, end, endInclusive); return sm.size(); } else { int result = 0; Map m = ((Map)src); for (Object k : m.keySet()) { int fk = keyBinding.compare(from, k); int ek = keyBinding.compare(k, end); boolean fromMatches = fromInclusive ? fk<=0 : fk<0; boolean endMatches = endInclusive ? ek<=0 : ek <0; if ( fromMatches && endMatches ) result++; } return result; } } /** * Read a range of entries * * @param src * @param from * @param fromInclusive * @param end * @param endInclusive * @param dstKeyArrayBinding * @param dstKeyArray * @param dstValueArrayBinding * @param dstValueArray * @throws BindingException */ 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 { if (src instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit); } else { return new HashMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit); } } @SuppressWarnings("unchecked") @Override public Object[] getValues(Object map) { Map m = ((Map) map); return m.values().toArray(new Object[m.size()]); } @Override public void put(Object map, K key, V value) { @SuppressWarnings("unchecked") Map m = ((Map) map); m.put(key, value); } @Override public void putAll(Object dstMap, Map srcMap) { @SuppressWarnings("unchecked") Map dst = ((Map) dstMap); dst.putAll(srcMap); } @SuppressWarnings("unchecked") @Override public void getAll(Object mapFrom, Map to) { Map m = ((Map) mapFrom); to.putAll(m); } @SuppressWarnings("unchecked") @Override public void getAll(Object mapFrom, Object[] keys, Object[] values) { Map m = (Map) mapFrom; int i = 0; for (Entry e : (Set>) m.entrySet()) { keys[i] = e.getKey(); values[i] = e.getValue(); i++; } } @Override public Object remove(Object map, Object key) { Map m = ((Map) map); return m.remove(key); } @Override public int size(Object map) { Map m = ((Map) map); return m.size(); } @Override public boolean isInstance(Object obj) { return obj instanceof Map; } @Override public int deepHashValue(Object map, IdentityHashMap hashedObjects) throws BindingException { int result = 0; Map m = ((Map) map); @SuppressWarnings("unchecked") Set s = m.entrySet(); for (Entry e : s) { int keyTree = getKeyBinding().deepHashValue(e.getKey(), hashedObjects); int valueTree = getValueBinding().deepHashValue(e.getValue(), hashedObjects); result += (keyTree ^ valueTree); } return result; } @Override public Object getCeilingKey(Object map, Object key) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getCeilingKey(map, key); } else { return new HashMapBinding(keyBinding, valueBinding).getCeilingKey(map, key); } } @Override public Object getFirstKey(Object map) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getFirstKey(map); } else { return new HashMapBinding(keyBinding, valueBinding).getFirstKey(map); } } @Override public Object getFloorKey(Object map, Object key) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getFloorKey(map, key); } else { return new HashMapBinding(keyBinding, valueBinding).getFloorKey(map, key); } } @Override public Object getHigherKey(Object map, Object key) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getHigherKey(map, key); } else { return new HashMapBinding(keyBinding, valueBinding).getHigherKey(map, key); } } @Override public Object getLastKey(Object map) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getLastKey(map); } else { return new HashMapBinding(keyBinding, valueBinding).getLastKey(map); } } @Override public Object getLowerKey(Object map, Object key) { if (map instanceof TreeMap) { return new TreeMapBinding(keyBinding, valueBinding).getLowerKey(map, key); } else { return new HashMapBinding(keyBinding, valueBinding).getLowerKey(map, key); } } }