]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MappingWithContext.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / MappingWithContext.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 /*
13  *
14  * @author Toni Kalajainen
15  */
16 package org.simantics.utils.datastructures;
17
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.Map.Entry;
24
25
26 /**
27  * Context dependent Key to Key Bijection Mapping.  
28  *
29  * @param <Context>
30  * @param <Key>
31  */
32 public class MappingWithContext<Context, Key> {
33
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);
38                 }
39         };
40         
41         Map<Context, BijectionMap<Key, Key>> maps = 
42                 new HashMap<Context, BijectionMap<Key, Key>>();
43         
44         /**
45          * Add mapping. null context applies always.
46          * 
47          * @param context
48          * @param leftKey
49          * @param rightKey
50          */
51         public synchronized void addMapping(Context context, Key leftKey, Key rightKey)
52         {
53                 BijectionMap<Key, Key> map = getOrCreateMap(context);
54                 map.map(leftKey, rightKey);             
55         }
56
57         /**
58          * Get right value with left key
59          * @param contexts effective contexts
60          * @param leftKey
61          * @return a single right value or null
62          * @throws IntersectingContextsException
63          */
64         public synchronized Key getAtMostOneMappingWithLeftKey(Context[] contexts, Key leftKey)
65         throws IntersectingContextsException
66         {
67                 Key result = null;
68                 Context resultContext = null;
69                 for (Context c : contexts)
70                 {
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);
76                         result = value;
77                         resultContext = c;
78                 }
79
80                 return result;
81         }
82
83         /**
84          * Get left value with right key
85          * @param contexts effective contexts
86          * @param rightKey
87          * @return a single left value or null
88          * @throws IntersectingContextsException
89          */
90         public synchronized Key getAtMostOneMappingWithRightKey(Context[] contexts, Key rightKey)
91         throws IntersectingContextsException
92         {
93                 Key result = null;
94                 Context resultContext = null;
95                 for (Context c : contexts)
96                 {
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);
102                         result = value;
103                         resultContext = c;
104                 }
105
106                 return result;
107         }
108         
109         /**
110          * Get all right values with left key
111          * @param contexts effective contexts
112          * @param leftKey
113          * @return a single right value or null
114          * @throws IntersectingContextsException
115          */
116         public synchronized Set<Key> getMappingWithLeftKey(Context[] contexts, Key leftKey)
117         throws IntersectingContextsException
118         {
119                 Set<Key> result = new HashSet<Key>();
120                 for (Context c : contexts)
121                 {
122                         BijectionMap<Key, Key> map = maps.get(c);
123                         if (map==null) continue;
124                         Key value = map.getRight(leftKey);
125                         if (value==null) continue;
126                         result.add(value);
127                 }
128                 return result;
129         }
130
131         /**
132          * Get all left values with right key
133          * @param contexts effective contexts
134          * @param rightKey
135          * @return a single left value or null
136          * @throws IntersectingContextsException
137          */
138         public synchronized Set<Key> getMappingWithRightKey(Context[] contexts, Key rightKey)
139         throws IntersectingContextsException
140         {
141                 Set<Key> result = new HashSet<Key>();
142                 for (Context c : contexts)
143                 {
144                         BijectionMap<Key, Key> map = maps.get(c);
145                         if (map==null) continue;
146                         Key value = map.getLeft(rightKey);
147                         if (value==null) continue;
148                         result.add(value);
149                 }
150                 return result;
151         }       
152         
153         private synchronized BijectionMap<Key, Key> getOrCreateMap(Context context)
154         {
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);              
159                 return result; 
160         }
161         
162         public synchronized void addMapToContext(Context context, BijectionMap<Key, Key> map)
163         {
164                 BijectionMap<Key, Key> m = getOrCreateMap(context);
165                 m.addAll(map);
166         }
167         
168         public synchronized Set<Context> getContexts()
169         {
170                 return Collections.unmodifiableSet(maps.keySet());
171         }
172         
173         public synchronized Set<Key> getLeftKeys(Context context)
174         {
175                 BijectionMap<Key, Key> map = maps.get(context);
176                 if (map==null) return null;
177                 return Collections.unmodifiableSet(map.getLeftSet());           
178         }
179         
180         public synchronized Set<Key> getRightKeys(Context context)
181         {
182                 BijectionMap<Key, Key> map = maps.get(context);
183                 if (map==null) return null;
184                 return Collections.unmodifiableSet(map.getRightSet());          
185         }
186
187         public synchronized Set<Key> getAllLeftKeys()
188         {
189                 Set<Key> result = new HashSet<Key>();
190                 for (Context context : getContexts())
191                         result.addAll(getLeftKeys(context));
192                 return result;
193         }
194         
195         public synchronized Set<Key> getAllRightKeys()
196         {
197                 Set<Key> result = new HashSet<Key>();
198                 for (Context context : getContexts())
199                         result.addAll(getRightKeys(context));
200                 return result;
201         }
202         
203     @Override
204     public String toString() {
205         int count = 0;
206         StringBuilder sb = new StringBuilder();
207         sb.append("[");
208         for (Entry<Context, BijectionMap<Key, Key>> e : maps.entrySet())
209         {
210                 if (count++>0) sb.append(", ");
211                 sb.append((e.getKey()==null?"null":e.getKey().toString()));
212                 sb.append("=");
213                 sb.append(e.getValue().toString());             
214         }
215         sb.append("]");
216         return sb.toString();
217     }   
218         
219 }