X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2FStandardSessionManager.java;fp=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2FStandardSessionManager.java;h=0f9a919a3f2d881392c8b5313d7a90878dfc0555;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..0f9a919a3 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/StandardSessionManager.java @@ -0,0 +1,116 @@ +package org.simantics.db.layer0; + +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.common.request.ParametrizedPrimitiveRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.NodeSupport; +import org.simantics.db.procedure.Listener; + +abstract public class StandardSessionManager> { + + private ConcurrentHashMap>> realmListeners = new ConcurrentHashMap<>(); + private ConcurrentHashMap> REALMS = new ConcurrentHashMap>(); + private ConcurrentHashMap> SUPPORTS = new ConcurrentHashMap>(); + + // Accessing Realms should be done over ParametrizedPrimitveRead for the + // case if a realm is destroyed and new one is created with the same id than + // the previously deleted one for the listeners to get discarded and new + // registered + private class RealmRequest extends ParametrizedPrimitiveRead> { + + public RealmRequest(String parameter) { + super(parameter); + } + + @Override + public void register(ReadGraph graph, Listener> procedure) { + + StandardRealm realm = REALMS.get(parameter); + if (realm == null) { + try { + realm = createRealmInner(graph, parameter); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + if(procedure.isDisposed()) { + procedure.execute(realm); + return; + } + + Listener> existing = getOrDisposeListener(parameter); + assert(existing == null); + realmListeners.put(parameter, procedure); + procedure.execute(realm); + } + + private StandardRealm createRealmInner(ReadGraph graph, String id) throws DatabaseException { + Engine engine = createEngine(graph, id); + StandardRealm realm = createRealm(engine, id); + modifyRealms(id, realm); + return realm; + } + } + + protected StandardSessionManager() { + } + + private Listener> getOrDisposeListener(String key) { + Listener> listener = realmListeners.get(key); + if(listener != null) { + if(listener.isDisposed()) { + realmListeners.remove(key); + } else { + return listener; + } + } + return null; + } + + private void modifyRealms(String key, StandardRealm realm) { + if(realm != null) { + REALMS.put(key, realm); + } else { + REALMS.remove(key); + } + Listener> listener = getOrDisposeListener(key); + if(listener != null) { + listener.execute(realm); + } + } + + public NodeSupport getOrCreateNodeSupport(ReadGraph graph, String id) throws DatabaseException { + synchronized(SUPPORTS) { + NodeSupport result = SUPPORTS.get(id); + if(result == null) { + StandardRealm realm = getOrCreateRealm(graph, id); + result = new NodeSupport(realm.getNodeManager()); + SUPPORTS.put(id, result); + } + return result; + } + } + + public StandardRealm getOrCreateRealm(ReadGraph graph, String id) throws DatabaseException { + synchronized(REALMS) { + return graph.syncRequest(new RealmRequest(id)); + } + } + + protected abstract Engine createEngine(ReadGraph graph, String id) throws DatabaseException; + protected abstract StandardRealm createRealm(Engine engine, String id); + + public void removeRealm(String id) { + modifyRealms(id, null); + // if node support has been created remove it as well + SUPPORTS.remove(id); + } + + public Collection getRealms() { + return REALMS.keySet(); + } +}