X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2FMappingWithContext.java;fp=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2FMappingWithContext.java;h=eed25a632ca84224336111a4f5083ea8c0592985;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MappingWithContext.java b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MappingWithContext.java new file mode 100644 index 000000000..eed25a632 --- /dev/null +++ b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MappingWithContext.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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(); + } + +}