]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/StandardSessionManager.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / StandardSessionManager.java
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/StandardSessionManager.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/StandardSessionManager.java
new file mode 100644 (file)
index 0000000..0f9a919
--- /dev/null
@@ -0,0 +1,116 @@
+package org.simantics.db.layer0;\r
+\r
+import java.util.Collection;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.NodeSupport;\r
+import org.simantics.db.procedure.Listener;\r
+\r
+abstract public class StandardSessionManager<Node, Engine extends StandardEngine<Node>> {\r
+\r
+    private ConcurrentHashMap<String, Listener<StandardRealm<Node,Engine>>> realmListeners = new ConcurrentHashMap<>();\r
+    private ConcurrentHashMap<String, StandardRealm<Node,Engine>> REALMS = new ConcurrentHashMap<String, StandardRealm<Node,Engine>>(); \r
+    private ConcurrentHashMap<String, NodeSupport<Node>> SUPPORTS = new ConcurrentHashMap<String, NodeSupport<Node>>(); \r
+\r
+    // Accessing Realms should be done over ParametrizedPrimitveRead for the\r
+    // case if a realm is destroyed and new one is created with the same id than\r
+    // the previously deleted one for the listeners to get discarded and new\r
+    // registered\r
+    private class RealmRequest extends ParametrizedPrimitiveRead<String, StandardRealm<Node, Engine>> {\r
+\r
+        public RealmRequest(String parameter) {\r
+            super(parameter);\r
+        }\r
+\r
+        @Override\r
+        public void register(ReadGraph graph, Listener<StandardRealm<Node, Engine>> procedure) {\r
+\r
+            StandardRealm<Node, Engine> realm = REALMS.get(parameter);\r
+            if (realm == null) {\r
+                try {\r
+                    realm = createRealmInner(graph, parameter);\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\r
+            \r
+            if(procedure.isDisposed()) {\r
+                procedure.execute(realm);\r
+                return;\r
+            }\r
+            \r
+            Listener<StandardRealm<Node,Engine>> existing = getOrDisposeListener(parameter);\r
+            assert(existing == null);\r
+            realmListeners.put(parameter, procedure);\r
+            procedure.execute(realm);\r
+        }\r
+\r
+        private StandardRealm<Node,Engine> createRealmInner(ReadGraph graph, String id) throws DatabaseException {\r
+            Engine engine = createEngine(graph, id);\r
+            StandardRealm<Node,Engine> realm = createRealm(engine, id);\r
+            modifyRealms(id, realm);\r
+            return realm;\r
+        }\r
+    }\r
+    \r
+    protected StandardSessionManager() {\r
+    }\r
+    \r
+    private Listener<StandardRealm<Node,Engine>> getOrDisposeListener(String key) {\r
+        Listener<StandardRealm<Node,Engine>> listener = realmListeners.get(key);\r
+        if(listener != null) {\r
+            if(listener.isDisposed()) {\r
+                realmListeners.remove(key);\r
+            } else {\r
+                return listener;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    private void modifyRealms(String key, StandardRealm<Node,Engine> realm) {\r
+        if(realm != null) {\r
+            REALMS.put(key, realm);\r
+        } else {\r
+            REALMS.remove(key);\r
+        }\r
+        Listener<StandardRealm<Node,Engine>> listener = getOrDisposeListener(key);\r
+        if(listener != null) {\r
+            listener.execute(realm);\r
+        }\r
+    }\r
+\r
+    public NodeSupport<Node> getOrCreateNodeSupport(ReadGraph graph, String id) throws DatabaseException {\r
+        synchronized(SUPPORTS) {\r
+               NodeSupport<Node> result = SUPPORTS.get(id);\r
+               if(result == null) {\r
+                       StandardRealm<Node,Engine> realm = getOrCreateRealm(graph, id);\r
+                       result = new NodeSupport<Node>(realm.getNodeManager());\r
+                       SUPPORTS.put(id, result);\r
+               }\r
+               return result;\r
+        }\r
+    }\r
+    \r
+    public StandardRealm<Node,Engine> getOrCreateRealm(ReadGraph graph, String id) throws DatabaseException {\r
+        synchronized(REALMS) {\r
+            return graph.syncRequest(new RealmRequest(id));\r
+        }\r
+    }\r
+    \r
+    protected abstract Engine createEngine(ReadGraph graph, String id) throws DatabaseException;\r
+    protected abstract StandardRealm<Node,Engine> createRealm(Engine engine, String id);\r
+    \r
+    public void removeRealm(String id) {\r
+        modifyRealms(id, null);\r
+        // if node support has been created remove it as well\r
+        SUPPORTS.remove(id);\r
+    }\r
+    \r
+    public Collection<String> getRealms() {\r
+        return REALMS.keySet();\r
+    }\r
+}\r