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