1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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 *******************************************************************************/
14 * @author Toni Kalajainen
16 package org.simantics.utils.datastructures;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
23 import java.util.Map.Entry;
27 * Context dependent Key to Key Bijection Mapping.
32 public class MappingWithContext<Context, Key> {
34 public static class IntersectingContextsException extends Exception {
35 private static final long serialVersionUID = 3411795376917295313L;
36 public IntersectingContextsException(Object c, Object key1, Object key2) {
37 super("The two keys "+key1+" and "+key2+" are intersecting in context "+c);
41 Map<Context, BijectionMap<Key, Key>> maps =
42 new HashMap<Context, BijectionMap<Key, Key>>();
45 * Add mapping. null context applies always.
51 public synchronized void addMapping(Context context, Key leftKey, Key rightKey)
53 BijectionMap<Key, Key> map = getOrCreateMap(context);
54 map.map(leftKey, rightKey);
58 * Get right value with left key
59 * @param contexts effective contexts
61 * @return a single right value or null
62 * @throws IntersectingContextsException
64 public synchronized Key getAtMostOneMappingWithLeftKey(Context[] contexts, Key leftKey)
65 throws IntersectingContextsException
68 Context resultContext = null;
69 for (Context c : contexts)
71 BijectionMap<Key, Key> map = maps.get(c);
72 if (map==null) continue;
73 Key value = map.getRight(leftKey);
74 if (value==null) continue;
75 if (result!=null) throw new IntersectingContextsException(resultContext, value, result);
84 * Get left value with right key
85 * @param contexts effective contexts
87 * @return a single left value or null
88 * @throws IntersectingContextsException
90 public synchronized Key getAtMostOneMappingWithRightKey(Context[] contexts, Key rightKey)
91 throws IntersectingContextsException
94 Context resultContext = null;
95 for (Context c : contexts)
97 BijectionMap<Key, Key> map = maps.get(c);
98 if (map==null) continue;
99 Key value = map.getLeft(rightKey);
100 if (value==null) continue;
101 if (result!=null) throw new IntersectingContextsException(resultContext, value, result);
110 * Get all right values with left key
111 * @param contexts effective contexts
113 * @return a single right value or null
114 * @throws IntersectingContextsException
116 public synchronized Set<Key> getMappingWithLeftKey(Context[] contexts, Key leftKey)
117 throws IntersectingContextsException
119 Set<Key> result = new HashSet<Key>();
120 for (Context c : contexts)
122 BijectionMap<Key, Key> map = maps.get(c);
123 if (map==null) continue;
124 Key value = map.getRight(leftKey);
125 if (value==null) continue;
132 * Get all left values with right key
133 * @param contexts effective contexts
135 * @return a single left value or null
136 * @throws IntersectingContextsException
138 public synchronized Set<Key> getMappingWithRightKey(Context[] contexts, Key rightKey)
139 throws IntersectingContextsException
141 Set<Key> result = new HashSet<Key>();
142 for (Context c : contexts)
144 BijectionMap<Key, Key> map = maps.get(c);
145 if (map==null) continue;
146 Key value = map.getLeft(rightKey);
147 if (value==null) continue;
153 private synchronized BijectionMap<Key, Key> getOrCreateMap(Context context)
155 BijectionMap<Key, Key> result = maps.get(context);
156 if (result!=null) return result;
157 result = new BijectionMap<Key, Key>();
158 maps.put(context, result);
162 public synchronized void addMapToContext(Context context, BijectionMap<Key, Key> map)
164 BijectionMap<Key, Key> m = getOrCreateMap(context);
168 public synchronized Set<Context> getContexts()
170 return Collections.unmodifiableSet(maps.keySet());
173 public synchronized Set<Key> getLeftKeys(Context context)
175 BijectionMap<Key, Key> map = maps.get(context);
176 if (map==null) return null;
177 return Collections.unmodifiableSet(map.getLeftSet());
180 public synchronized Set<Key> getRightKeys(Context context)
182 BijectionMap<Key, Key> map = maps.get(context);
183 if (map==null) return null;
184 return Collections.unmodifiableSet(map.getRightSet());
187 public synchronized Set<Key> getAllLeftKeys()
189 Set<Key> result = new HashSet<Key>();
190 for (Context context : getContexts())
191 result.addAll(getLeftKeys(context));
195 public synchronized Set<Key> getAllRightKeys()
197 Set<Key> result = new HashSet<Key>();
198 for (Context context : getContexts())
199 result.addAll(getRightKeys(context));
204 public String toString() {
206 StringBuilder sb = new StringBuilder();
208 for (Entry<Context, BijectionMap<Key, Key>> e : maps.entrySet())
210 if (count++>0) sb.append(", ");
211 sb.append((e.getKey()==null?"null":e.getKey().toString()));
213 sb.append(e.getValue().toString());
216 return sb.toString();