--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.vtt.simantics.procore.internal;\r
+\r
+import java.io.IOException;\r
+import java.nio.file.Path;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+import org.simantics.db.Database;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.SessionErrorHandler;\r
+import org.simantics.db.SessionManager;\r
+import org.simantics.db.SessionReference;\r
+import org.simantics.db.authentication.UserAuthenticationAgent;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.event.SessionEvent;\r
+import org.simantics.db.event.SessionListener;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.server.DatabaseManager;\r
+import org.simantics.db.service.LifecycleSupport;\r
+\r
+import fi.vtt.simantics.procore.ProCoreSessionReference;\r
+\r
+class SessionManagerImpl implements SessionManager {\r
+ private ConcurrentHashMap<SessionImplSocket, SessionImplSocket> sessionMap = new ConcurrentHashMap<SessionImplSocket, SessionImplSocket>();\r
+ private ListenerList<SessionListener> sessionListeners = new ListenerList<SessionListener>(SessionListener.class);\r
+ private SessionErrorHandler errorHandler;\r
+ private Database database;\r
+\r
+ SessionManagerImpl() throws IOException {\r
+ }\r
+\r
+ void finish() {\r
+ sessionMap = null;\r
+ sessionListeners = null;\r
+ }\r
+\r
+ @Override\r
+ public void addSessionListener(SessionListener listener) {\r
+ sessionListeners.add(listener);\r
+ }\r
+\r
+ @Override\r
+ public Session createSession(SessionReference sessionReference, UserAuthenticationAgent authAgent)\r
+ throws DatabaseException, IOException {\r
+ if (!(sessionReference instanceof ProCoreSessionReference))\r
+ throw new DatabaseException("Illegal argument. ProCoreSessionReference needed for creation of corresponding session. ref=" + sessionReference);\r
+ SessionImplDb sessionImpl = new SessionImplDb(this, authAgent);\r
+ boolean ok = false;\r
+ try {\r
+ ProCoreSessionReference pcsr = (ProCoreSessionReference)sessionReference;\r
+ Path dbFolder = pcsr.serverReference.dbFolder;\r
+ database = DatabaseManager.getDatabase(dbFolder);\r
+ Database.Session dbSession = database.newSession(sessionImpl);\r
+ sessionImpl.connect(sessionReference, dbSession);\r
+ sessionMap.put(sessionImpl, sessionImpl);\r
+ fireSessionOpened(sessionImpl);\r
+ ok = true;\r
+ } catch (IOException e) {\r
+ sessionImpl = null;\r
+ throw e;\r
+ } catch (Throwable e) {\r
+ Logger.defaultLogError("Connection failed. See exception for details.", e);\r
+ try {\r
+ fireSessionClosed(sessionImpl, e);\r
+ sessionMap.remove(sessionImpl);\r
+ sessionImpl = null;\r
+ } catch (Throwable t) {\r
+ }\r
+ throw new DatabaseException(e);\r
+ } finally {\r
+ if (!ok && null != sessionImpl)\r
+ sessionImpl.getService(LifecycleSupport.class).close();\r
+ }\r
+ return sessionImpl;\r
+ }\r
+\r
+ @Override\r
+ public void removeSessionListener(SessionListener listener) {\r
+ sessionListeners.remove(listener);\r
+ }\r
+\r
+ private void fireSessionOpened(SessionImplSocket session) {\r
+ SessionEvent se = new SessionEvent(session, null);\r
+ for (SessionListener listener : sessionListeners.getListeners()) {\r
+ listener.sessionOpened(se);\r
+ }\r
+ }\r
+\r
+ private void fireSessionClosed(SessionImplSocket session, Throwable cause) {\r
+ SessionEvent se = new SessionEvent(session, cause);\r
+ for (SessionListener listener : sessionListeners.getListeners()) {\r
+ listener.sessionClosed(se);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void shutdown(Session s, Throwable cause) {\r
+ SessionImplSocket sis = sessionMap.get(s);\r
+ if (null == sis)\r
+ return;\r
+ try {\r
+ fireSessionClosed(sis, cause);\r
+ } finally {\r
+ sessionMap.remove(s);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public SessionErrorHandler getErrorHandler() {\r
+ return errorHandler;\r
+ }\r
+\r
+ @Override\r
+ public void setErrorHandler(SessionErrorHandler errorHandler) {\r
+ this.errorHandler = errorHandler;\r
+ }\r
+\r
+ @Override\r
+ public Database getDatabase() {\r
+ return database;\r
+ }\r
+\r
+}\r