--- /dev/null
+package fi.vtt.simantics.procore.internal;\r
+\r
+import java.util.concurrent.CopyOnWriteArrayList;\r
+\r
+import org.simantics.db.SessionManager;\r
+import org.simantics.db.SessionReference;\r
+import org.simantics.db.common.TransactionPolicyRelease;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.InternalException;\r
+import org.simantics.db.exception.TimeoutException;\r
+import org.simantics.db.impl.query.QueryProcessor;\r
+import org.simantics.db.service.LifecycleSupport;\r
+import org.simantics.db.service.TransactionPolicySupport;\r
+\r
+public class LifecycleSupportImpl implements LifecycleSupport {\r
+\r
+ final private SessionImplSocket session;\r
+ final private CopyOnWriteArrayList<LifecycleListener> listeners = new CopyOnWriteArrayList<LifecycleListener>();\r
+\r
+ LifecycleSupportImpl(SessionImplSocket session) {\r
+ this.session = session;\r
+ }\r
+\r
+ @Override\r
+ public long getId() {\r
+ return session.graphSession.getSessionId();\r
+ }\r
+\r
+ @Override\r
+ public boolean isClosing() {\r
+ return session.state.isClosing();\r
+ }\r
+\r
+ @Override\r
+ public boolean isClosed() {\r
+ return session.state.isClosed();\r
+ }\r
+\r
+ @Override\r
+ final public SessionReference getSessionReference() {\r
+ if (session.graphSession == null)\r
+ return null;\r
+ return session.graphSession.getSessionReference();\r
+ }\r
+\r
+ @Override\r
+ final public SessionManager getSessionManager() {\r
+ return session.sessionManagerImpl;\r
+ }\r
+\r
+ @Override\r
+ public void ping() throws DatabaseException {\r
+ session.graphSession.execute("");\r
+ }\r
+\r
+ @Override\r
+ public void close()\r
+ throws DatabaseException {\r
+ GraphSession graphSession = session.graphSession;\r
+ try {\r
+ this.close(0, false);\r
+ } catch (TimeoutException e) {\r
+ this.close(-1, true);\r
+ } finally {\r
+ if (null != graphSession)\r
+ try {\r
+ // Graph session expects start and stop.\r
+ // If we miss stop then server will not know that we disconnected deliberately.\r
+ graphSession.stop();\r
+ } catch (InternalException e) {\r
+ Logger.defaultLogError("GraphSession.stop failed.", e);\r
+ }\r
+ }\r
+ }\r
+ @Override\r
+ final public void close(long timeout, boolean force)\r
+ throws DatabaseException {\r
+ session.registerService(TransactionPolicySupport.class, new TransactionPolicyRelease());\r
+ State.WaitStatus status = session.state.waitClosing(timeout);\r
+ switch (status) {\r
+ case IsClosed:\r
+ case IsClosing:\r
+ return;\r
+ case Timeout:\r
+ if (!force)\r
+ throw new TimeoutException("Close timeout, use force!");\r
+ // Intentionally dropping to next case.\r
+ case CanBeClosed:\r
+ try {\r
+ QueryProcessor prosessor = session.getQueryProvider2();\r
+ if (prosessor!=null) prosessor.dispose();\r
+ session.virtualGraphServerSupport.disposeVirtualGraphs();\r
+ session.removeTemporaryData();\r
+ // Release the session from the manager.\r
+ session.graphSession.close();\r
+ session.serviceLocator.dispose(); // This will close local sessions created when registering services.\r
+ } finally {\r
+ session.state.close();\r
+ session.clusterTable.dispose(); session.clusterTable = null;\r
+ session.sessionManagerImpl.shutdown(session, null);\r
+ session.sessionManagerImpl = null;\r
+ session.user = null;\r
+ session.graphSession = null;\r
+ }\r
+ break;\r
+ default:\r
+ throw new DatabaseException();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void addListener(LifecycleListener listener) {\r
+ listeners.add(listener);\r
+ }\r
+\r
+ @Override\r
+ public void removeListener(LifecycleListener listener) {\r
+ listeners.remove(listener);\r
+ }\r
+\r
+ void fireListeners(LifecycleState newState) {\r
+ for(LifecycleListener listener : listeners) listener.stateChanged(newState);\r
+ }\r
+\r
+}\r