package jadex.rules.rulesystem.rete.nodes; import jadex.rules.rulesystem.rete.Tuple; import jadex.rules.state.IOAVState; import jadex.rules.state.OAVJavaType; import jadex.rules.state.OAVObjectType; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * A mixed identity hash map allows to store java objects * using identity and java values (numbers, strings, etc.) * using equality. Rete tuples are always stored by equality. */ public class MixedIdentityHashMap implements Map { //-------- attributes -------- /** The state. */ protected IOAVState state; /** The equality map. */ protected Map equality; /** The identity map. */ protected Map identity; //-------- constructors -------- /** * Create a new mixed identity map. */ public MixedIdentityHashMap(IOAVState state) { this.state = state; this.equality = new LinkedHashMap(); this.identity = new IdentityHashMap(); } //-------- Map interface -------- public void clear() { equality.clear(); identity.clear(); } public boolean containsKey(Object key) { return equality.containsKey(key) || identity.containsKey(key); } public boolean containsValue(Object value) { return equality.containsValue(value) || identity.containsValue(value); } public Object get(Object key) { return equality.containsKey(key) ? equality.get(key) : identity.get(key); } public boolean isEmpty() { return equality.isEmpty() && identity.isEmpty(); } public Object put(Object key, Object value) { OAVObjectType type = key!=null && !(key instanceof Tuple) ? state.getType(key) : null; return type instanceof OAVJavaType && !OAVJavaType.KIND_VALUE.equals(((OAVJavaType)type).getKind()) ? identity.put(key, value) : equality.put(key, value); } public void putAll(Map map) { for(Iterator it=map.keySet().iterator(); it.hasNext();) { Object key = it.next(); put(key, map.get(key)); } } public Object remove(Object key) { return equality.containsKey(key) ? equality.remove(key) : identity.remove(key); } public int size() { return equality.size() + identity.size(); } public Collection values() { List vals = new ArrayList(); vals.addAll(equality.values()); vals.addAll(identity.values()); return vals; } public Set entrySet() { throw new UnsupportedOperationException("Not yet implemented"); } public Set keySet() { Set keys = new HashSet(); keys.addAll(equality.keySet()); keys.addAll(identity.keySet()); return keys; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((equality == null) ? 0 : equality.hashCode()); result = prime * result + ((identity == null) ? 0 : identity.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); return result; } public boolean equals(Object obj) { boolean ret = false; if(obj instanceof MixedIdentityHashMap) { MixedIdentityHashMap other = (MixedIdentityHashMap)obj; ret = equality.equals(other.equality) && identity.equals(other.identity) && state.equals(other.state); } return ret; } }