/******************************************************************************* * Copyright (c) 2007, 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 *******************************************************************************/ /* * * @author Toni Kalajainen */ package org.simantics.utils.datastructures; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.Map.Entry; /** * Context dependent Key to Key Bijection Mapping. * * @param * @param */ public class MappingWithContext { public static class IntersectingContextsException extends Exception { private static final long serialVersionUID = 3411795376917295313L; public IntersectingContextsException(Object c, Object key1, Object key2) { super("The two keys "+key1+" and "+key2+" are intersecting in context "+c); } }; Map> maps = new HashMap>(); /** * Add mapping. null context applies always. * * @param context * @param leftKey * @param rightKey */ public synchronized void addMapping(Context context, Key leftKey, Key rightKey) { BijectionMap map = getOrCreateMap(context); map.map(leftKey, rightKey); } /** * Get right value with left key * @param contexts effective contexts * @param leftKey * @return a single right value or null * @throws IntersectingContextsException */ public synchronized Key getAtMostOneMappingWithLeftKey(Context[] contexts, Key leftKey) throws IntersectingContextsException { Key result = null; Context resultContext = null; for (Context c : contexts) { BijectionMap map = maps.get(c); if (map==null) continue; Key value = map.getRight(leftKey); if (value==null) continue; if (result!=null) throw new IntersectingContextsException(resultContext, value, result); result = value; resultContext = c; } return result; } /** * Get left value with right key * @param contexts effective contexts * @param rightKey * @return a single left value or null * @throws IntersectingContextsException */ public synchronized Key getAtMostOneMappingWithRightKey(Context[] contexts, Key rightKey) throws IntersectingContextsException { Key result = null; Context resultContext = null; for (Context c : contexts) { BijectionMap map = maps.get(c); if (map==null) continue; Key value = map.getLeft(rightKey); if (value==null) continue; if (result!=null) throw new IntersectingContextsException(resultContext, value, result); result = value; resultContext = c; } return result; } /** * Get all right values with left key * @param contexts effective contexts * @param leftKey * @return a single right value or null * @throws IntersectingContextsException */ public synchronized Set getMappingWithLeftKey(Context[] contexts, Key leftKey) throws IntersectingContextsException { Set result = new HashSet(); for (Context c : contexts) { BijectionMap map = maps.get(c); if (map==null) continue; Key value = map.getRight(leftKey); if (value==null) continue; result.add(value); } return result; } /** * Get all left values with right key * @param contexts effective contexts * @param rightKey * @return a single left value or null * @throws IntersectingContextsException */ public synchronized Set getMappingWithRightKey(Context[] contexts, Key rightKey) throws IntersectingContextsException { Set result = new HashSet(); for (Context c : contexts) { BijectionMap map = maps.get(c); if (map==null) continue; Key value = map.getLeft(rightKey); if (value==null) continue; result.add(value); } return result; } private synchronized BijectionMap getOrCreateMap(Context context) { BijectionMap result = maps.get(context); if (result!=null) return result; result = new BijectionMap(); maps.put(context, result); return result; } public synchronized void addMapToContext(Context context, BijectionMap map) { BijectionMap m = getOrCreateMap(context); m.addAll(map); } public synchronized Set getContexts() { return Collections.unmodifiableSet(maps.keySet()); } public synchronized Set getLeftKeys(Context context) { BijectionMap map = maps.get(context); if (map==null) return null; return Collections.unmodifiableSet(map.getLeftSet()); } public synchronized Set getRightKeys(Context context) { BijectionMap map = maps.get(context); if (map==null) return null; return Collections.unmodifiableSet(map.getRightSet()); } public synchronized Set getAllLeftKeys() { Set result = new HashSet(); for (Context context : getContexts()) result.addAll(getLeftKeys(context)); return result; } public synchronized Set getAllRightKeys() { Set result = new HashSet(); for (Context context : getContexts()) result.addAll(getRightKeys(context)); return result; } @Override public String toString() { int count = 0; StringBuilder sb = new StringBuilder(); sb.append("["); for (Entry> e : maps.entrySet()) { if (count++>0) sb.append(", "); sb.append((e.getKey()==null?"null":e.getKey().toString())); sb.append("="); sb.append(e.getValue().toString()); } sb.append("]"); return sb.toString(); } }