--- /dev/null
+package fi.vtt.simantics.procore.internal;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.db.Disposable;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.impl.internal.RandomAccessValueSupport;\r
+import org.simantics.db.impl.internal.ResourceData;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * A simple implementation of {@link RandomAccessValueSupport}.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class RandomAccessValueSupportImpl implements RandomAccessValueSupport {\r
+\r
+ private final static boolean DEBUG = false;\r
+\r
+ /**\r
+ * The map of services maintained by the workbench window. These services\r
+ * are initialized during workbench window during the\r
+ * {@link #configureShell(Shell)}. This value is <code>null</code> until\r
+ * a service is registered.\r
+ */\r
+ private Map<Resource, ResourceData> values = new HashMap<Resource, ResourceData>();\r
+\r
+ /**\r
+ * Constructs a new random access value registry.\r
+ */\r
+ public RandomAccessValueSupportImpl() {\r
+ }\r
+\r
+ @Override\r
+ public ResourceData get(Resource resource) {\r
+ synchronized (this) {\r
+ return values.get(resource);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Registers a service with this locator. If there is an existing service\r
+ * matching the same <code>api</code> and it implements\r
+ * {@link Disposable}, it will be disposed.\r
+ * \r
+ * @param api\r
+ * This is the interface that the service implements. Must not be\r
+ * <code>null</code>.\r
+ * @param service\r
+ * The service to register. This must be some implementation of\r
+ * <code>api</code>. This value must not be <code>null</code>.\r
+ */\r
+ public void put(final Resource resource, final ResourceData data) {\r
+ synchronized (this) {\r
+ final ResourceData current = values.get(resource);\r
+ if (current != null)\r
+ throw new IllegalStateException(\r
+ "Value already registered for resource " + resource\r
+ + ": " + current + ". Tried to register "\r
+ + data);\r
+\r
+ if (DEBUG)\r
+ System.out.println(this + ": register " + resource + " -> " + data);\r
+\r
+ values.put(resource, data);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Collection<Pair<Resource, ResourceData>> entries() {\r
+ synchronized (this) {\r
+ if (values.isEmpty())\r
+ return Collections.emptyList();\r
+ Collection<Pair<Resource, ResourceData>> result = new ArrayList<Pair<Resource, ResourceData>>( values.size() );\r
+ for (Map.Entry<Resource, ResourceData> entry : values.entrySet()) {\r
+ result.add( Pair.make( entry.getKey(), entry.getValue() ) );\r
+ }\r
+ return result;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Collection<Pair<Resource, ResourceData>> removeAll() {\r
+ synchronized (this) {\r
+ if (values.isEmpty())\r
+ return Collections.emptyList();\r
+ if (DEBUG)\r
+ System.out.println(this + ": remove " + values.size() + " registrations");\r
+ Collection<Pair<Resource, ResourceData>> result = new ArrayList<Pair<Resource, ResourceData>>( values.size() );\r
+ for (Map.Entry<Resource, ResourceData> entry : values.entrySet()) {\r
+ result.add( Pair.make( entry.getKey(), entry.getValue() ) );\r
+ }\r
+ values.clear();\r
+ return result;\r
+ }\r
+ }\r
+\r
+}\r