1 package org.simantics.db.layer0;
\r
3 import java.util.Collection;
\r
4 import java.util.concurrent.ConcurrentHashMap;
\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
12 abstract public class StandardSessionManager<Node, Engine extends StandardEngine<Node>> {
\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
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
22 private class RealmRequest extends ParametrizedPrimitiveRead<String, StandardRealm<Node, Engine>> {
\r
24 public RealmRequest(String parameter) {
\r
29 public void register(ReadGraph graph, Listener<StandardRealm<Node, Engine>> procedure) {
\r
31 StandardRealm<Node, Engine> realm = REALMS.get(parameter);
\r
32 if (realm == null) {
\r
34 realm = createRealmInner(graph, parameter);
\r
35 } catch (DatabaseException e) {
\r
36 e.printStackTrace();
\r
40 if(procedure.isDisposed()) {
\r
41 procedure.execute(realm);
\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
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
59 protected StandardSessionManager() {
\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
74 private void modifyRealms(String key, StandardRealm<Node,Engine> realm) {
\r
76 REALMS.put(key, realm);
\r
80 Listener<StandardRealm<Node,Engine>> listener = getOrDisposeListener(key);
\r
81 if(listener != null) {
\r
82 listener.execute(realm);
\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
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
104 protected abstract Engine createEngine(ReadGraph graph, String id) throws DatabaseException;
\r
105 protected abstract StandardRealm<Node,Engine> createRealm(Engine engine, String id);
\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
113 public Collection<String> getRealms() {
\r
114 return REALMS.keySet();
\r