]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 package org.simantics.db.layer0;\r
2 \r
3 import java.util.Collection;\r
4 import java.util.concurrent.ConcurrentHashMap;\r
5 \r
6 import org.simantics.db.ReadGraph;\r
7 import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
8 import org.simantics.db.exception.DatabaseException;\r
9 import org.simantics.db.layer0.variable.NodeSupport;\r
10 import org.simantics.db.procedure.Listener;\r
11 \r
12 abstract public class StandardSessionManager<Node, Engine extends StandardEngine<Node>> {\r
13 \r
14     private ConcurrentHashMap<String, Listener<StandardRealm<Node,Engine>>> realmListeners = new ConcurrentHashMap<>();\r
15     private ConcurrentHashMap<String, StandardRealm<Node,Engine>> REALMS = new ConcurrentHashMap<String, StandardRealm<Node,Engine>>(); \r
16     private ConcurrentHashMap<String, NodeSupport<Node>> SUPPORTS = new ConcurrentHashMap<String, NodeSupport<Node>>(); \r
17 \r
18     // Accessing Realms should be done over ParametrizedPrimitveRead for the\r
19     // case if a realm is destroyed and new one is created with the same id than\r
20     // the previously deleted one for the listeners to get discarded and new\r
21     // registered\r
22     private class RealmRequest extends ParametrizedPrimitiveRead<String, StandardRealm<Node, Engine>> {\r
23 \r
24         public RealmRequest(String parameter) {\r
25             super(parameter);\r
26         }\r
27 \r
28         @Override\r
29         public void register(ReadGraph graph, Listener<StandardRealm<Node, Engine>> procedure) {\r
30 \r
31             StandardRealm<Node, Engine> realm = REALMS.get(parameter);\r
32             if (realm == null) {\r
33                 try {\r
34                     realm = createRealmInner(graph, parameter);\r
35                 } catch (DatabaseException e) {\r
36                     e.printStackTrace();\r
37                 }\r
38             }\r
39             \r
40             if(procedure.isDisposed()) {\r
41                 procedure.execute(realm);\r
42                 return;\r
43             }\r
44             \r
45             Listener<StandardRealm<Node,Engine>> existing = getOrDisposeListener(parameter);\r
46             assert(existing == null);\r
47             realmListeners.put(parameter, procedure);\r
48             procedure.execute(realm);\r
49         }\r
50 \r
51         private StandardRealm<Node,Engine> createRealmInner(ReadGraph graph, String id) throws DatabaseException {\r
52             Engine engine = createEngine(graph, id);\r
53             StandardRealm<Node,Engine> realm = createRealm(engine, id);\r
54             modifyRealms(id, realm);\r
55             return realm;\r
56         }\r
57     }\r
58     \r
59     protected StandardSessionManager() {\r
60     }\r
61     \r
62     private Listener<StandardRealm<Node,Engine>> getOrDisposeListener(String key) {\r
63         Listener<StandardRealm<Node,Engine>> listener = realmListeners.get(key);\r
64         if(listener != null) {\r
65             if(listener.isDisposed()) {\r
66                 realmListeners.remove(key);\r
67             } else {\r
68                 return listener;\r
69             }\r
70         }\r
71         return null;\r
72     }\r
73     \r
74     private void modifyRealms(String key, StandardRealm<Node,Engine> realm) {\r
75         if(realm != null) {\r
76             REALMS.put(key, realm);\r
77         } else {\r
78             REALMS.remove(key);\r
79         }\r
80         Listener<StandardRealm<Node,Engine>> listener = getOrDisposeListener(key);\r
81         if(listener != null) {\r
82             listener.execute(realm);\r
83         }\r
84     }\r
85 \r
86     public NodeSupport<Node> getOrCreateNodeSupport(ReadGraph graph, String id) throws DatabaseException {\r
87         synchronized(SUPPORTS) {\r
88                 NodeSupport<Node> result = SUPPORTS.get(id);\r
89                 if(result == null) {\r
90                         StandardRealm<Node,Engine> realm = getOrCreateRealm(graph, id);\r
91                         result = new NodeSupport<Node>(realm.getNodeManager());\r
92                         SUPPORTS.put(id, result);\r
93                 }\r
94                 return result;\r
95         }\r
96     }\r
97     \r
98     public StandardRealm<Node,Engine> getOrCreateRealm(ReadGraph graph, String id) throws DatabaseException {\r
99         synchronized(REALMS) {\r
100             return graph.syncRequest(new RealmRequest(id));\r
101         }\r
102     }\r
103     \r
104     protected abstract Engine createEngine(ReadGraph graph, String id) throws DatabaseException;\r
105     protected abstract StandardRealm<Node,Engine> createRealm(Engine engine, String id);\r
106     \r
107     public void removeRealm(String id) {\r
108         modifyRealms(id, null);\r
109         // if node support has been created remove it as well\r
110         SUPPORTS.remove(id);\r
111     }\r
112     \r
113     public Collection<String> getRealms() {\r
114         return REALMS.keySet();\r
115     }\r
116 }\r