]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.acorn/src/org/simantics/acorn/AcornSessionManagerImpl.java
Sharing org.simantics.acorn for everyone to use
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / AcornSessionManagerImpl.java
diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornSessionManagerImpl.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornSessionManagerImpl.java
new file mode 100644 (file)
index 0000000..1a1e160
--- /dev/null
@@ -0,0 +1,125 @@
+package org.simantics.acorn;
+
+import java.nio.file.Path;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.simantics.db.Database;
+import org.simantics.db.Session;
+import org.simantics.db.SessionErrorHandler;
+import org.simantics.db.SessionManager;
+import org.simantics.db.SessionReference;
+import org.simantics.db.authentication.UserAuthenticationAgent;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.event.SessionEvent;
+import org.simantics.db.event.SessionListener;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.LifecycleSupport;
+import org.simantics.utils.datastructures.ListenerList;
+
+import fi.vtt.simantics.procore.internal.SessionImplDb;
+import fi.vtt.simantics.procore.internal.SessionImplSocket;
+
+public class AcornSessionManagerImpl implements SessionManager {
+
+    private static AcornSessionManagerImpl INSTANCE;
+    
+    private ConcurrentHashMap<SessionImplSocket, SessionImplSocket> sessionMap = new ConcurrentHashMap<SessionImplSocket, SessionImplSocket>();
+    private ListenerList<SessionListener> sessionListeners = new ListenerList<SessionListener>(SessionListener.class);
+    private SessionErrorHandler errorHandler;
+
+       private Database database;
+
+    private AcornSessionManagerImpl() {}
+    
+    void finish() {
+        sessionMap = null;
+        sessionListeners = null;
+    }
+
+    @Override
+    public void addSessionListener(SessionListener listener) {
+        sessionListeners.add(listener);
+    }
+
+    @Override
+    public Session createSession(SessionReference sessionReference, UserAuthenticationAgent authAgent)
+    throws DatabaseException {
+        SessionImplDb sessionImpl = new SessionImplDb(this, authAgent);
+        boolean ok = false;
+        try {
+            Path dbFolder = sessionReference.getServerReference().getDBFolder();
+            database = AcornDatabaseManager.getDatabase(dbFolder);
+            Database.Session dbSession = database.newSession(sessionImpl);
+            sessionImpl.connect(sessionReference, dbSession);
+            sessionMap.put(sessionImpl, sessionImpl);
+            fireSessionOpened(sessionImpl);
+            ok = true;
+        } catch (Throwable e) {
+            Logger.defaultLogError("Connection failed. See exception for details.", e);
+            try {
+                fireSessionClosed(sessionImpl, e);
+                sessionMap.remove(sessionImpl);
+                sessionImpl = null;
+            } catch (Throwable t) {
+            }
+            throw new DatabaseException(e);
+        } finally {
+            if (!ok && null != sessionImpl)
+                sessionImpl.getService(LifecycleSupport.class).close();
+        }
+        return sessionImpl;
+    }
+
+    @Override
+    public void removeSessionListener(SessionListener listener) {
+        sessionListeners.remove(listener);
+    }
+
+    private void fireSessionOpened(SessionImplSocket session) {
+        SessionEvent se = new SessionEvent(session, null);
+        for (SessionListener listener : sessionListeners.getListeners()) {
+               listener.sessionOpened(se);
+        }
+    }
+
+    private void fireSessionClosed(SessionImplSocket session, Throwable cause) {
+        SessionEvent se = new SessionEvent(session, cause);
+        for (SessionListener listener : sessionListeners.getListeners()) {
+               listener.sessionClosed(se);
+        }
+    }
+
+    @Override
+    public void shutdown(Session s, Throwable cause) {
+        SessionImplSocket sis = sessionMap.get(s);
+        if (null == sis)
+            return;
+        try {
+            fireSessionClosed(sis, cause);
+        } finally {
+            sessionMap.remove(s);
+        }
+    }
+
+    @Override
+    public SessionErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+    @Override
+    public void setErrorHandler(SessionErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    public synchronized static AcornSessionManagerImpl getInstance() {
+        if (INSTANCE == null)
+            INSTANCE = new AcornSessionManagerImpl();
+        return INSTANCE;
+    }
+
+    @Override
+    public Database getDatabase() {
+        return database;
+    }
+
+}