]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/AcornSessionManagerImpl.java
Merge commit '2ef2a5e5a52f8bfdbb5f2f47be2d3fbdcd2a8834'
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / AcornSessionManagerImpl.java
1 package org.simantics.acorn;
2
3 import java.nio.file.Path;
4 import java.util.concurrent.ConcurrentHashMap;
5
6 import org.simantics.db.Database;
7 import org.simantics.db.Session;
8 import org.simantics.db.SessionErrorHandler;
9 import org.simantics.db.SessionManager;
10 import org.simantics.db.SessionReference;
11 import org.simantics.db.authentication.UserAuthenticationAgent;
12 import org.simantics.db.common.utils.Logger;
13 import org.simantics.db.event.SessionEvent;
14 import org.simantics.db.event.SessionListener;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.service.LifecycleSupport;
17 import org.simantics.utils.datastructures.ListenerList;
18
19 import fi.vtt.simantics.procore.internal.SessionImplDb;
20 import fi.vtt.simantics.procore.internal.SessionImplSocket;
21
22 public class AcornSessionManagerImpl implements SessionManager {
23
24     private static AcornSessionManagerImpl INSTANCE;
25     
26     private ConcurrentHashMap<SessionImplSocket, SessionImplSocket> sessionMap = new ConcurrentHashMap<SessionImplSocket, SessionImplSocket>();
27     private ListenerList<SessionListener> sessionListeners = new ListenerList<SessionListener>(SessionListener.class);
28     private SessionErrorHandler errorHandler;
29
30         private Database database;
31
32     private AcornSessionManagerImpl() {}
33     
34     void finish() {
35         sessionMap = null;
36         sessionListeners = null;
37     }
38
39     @Override
40     public void addSessionListener(SessionListener listener) {
41         sessionListeners.add(listener);
42     }
43
44     @Override
45     public Session createSession(SessionReference sessionReference, UserAuthenticationAgent authAgent)
46     throws DatabaseException {
47         SessionImplDb sessionImpl = new SessionImplDb(this, authAgent);
48         boolean ok = false;
49         try {
50             Path dbFolder = sessionReference.getServerReference().getDBFolder();
51             database = AcornDatabaseManager.getDatabase(dbFolder);
52             Database.Session dbSession = database.newSession(sessionImpl);
53             sessionImpl.connect(sessionReference, dbSession);
54             sessionMap.put(sessionImpl, sessionImpl);
55             fireSessionOpened(sessionImpl);
56             ok = true;
57         } catch (Throwable e) {
58             Logger.defaultLogError("Connection failed. See exception for details.", e);
59             try {
60                 fireSessionClosed(sessionImpl, e);
61                 sessionMap.remove(sessionImpl);
62                 sessionImpl = null;
63             } catch (Throwable t) {
64             }
65             throw new DatabaseException(e);
66         } finally {
67             if (!ok && null != sessionImpl)
68                 sessionImpl.getService(LifecycleSupport.class).close();
69         }
70         return sessionImpl;
71     }
72
73     @Override
74     public void removeSessionListener(SessionListener listener) {
75         sessionListeners.remove(listener);
76     }
77
78     private void fireSessionOpened(SessionImplSocket session) {
79         SessionEvent se = new SessionEvent(session, null);
80         for (SessionListener listener : sessionListeners.getListeners()) {
81                listener.sessionOpened(se);
82         }
83     }
84
85     private void fireSessionClosed(SessionImplSocket session, Throwable cause) {
86         SessionEvent se = new SessionEvent(session, cause);
87         for (SessionListener listener : sessionListeners.getListeners()) {
88                listener.sessionClosed(se);
89         }
90     }
91
92     @Override
93     public void shutdown(Session s, Throwable cause) {
94         SessionImplSocket sis = sessionMap.get(s);
95         if (null == sis)
96             return;
97         try {
98             fireSessionClosed(sis, cause);
99         } finally {
100             sessionMap.remove(s);
101         }
102     }
103
104     @Override
105     public SessionErrorHandler getErrorHandler() {
106         return errorHandler;
107     }
108
109     @Override
110     public void setErrorHandler(SessionErrorHandler errorHandler) {
111         this.errorHandler = errorHandler;
112     }
113
114     public synchronized static AcornSessionManagerImpl getInstance() {
115         if (INSTANCE == null)
116             INSTANCE = new AcornSessionManagerImpl();
117         return INSTANCE;
118     }
119
120     @Override
121     public Database getDatabase() {
122         return database;
123     }
124
125 }