1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.common;
20
21 import static org.mycore.common.events.MCRSessionEvent.Type.created;
22 import static org.mycore.common.events.MCRSessionEvent.Type.destroyed;
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.stream.Collectors;
31
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
34 import org.mycore.common.events.MCRSessionListener;
35 import org.mycore.util.concurrent.MCRReadWriteGuard;
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class MCRSessionMgr {
50
51 private static Map<String, MCRSession> sessions = Collections.synchronizedMap(new HashMap<String, MCRSession>());
52
53 private static List<MCRSessionListener> listeners = new ArrayList<>();
54
55 private static MCRReadWriteGuard listenersGuard = new MCRReadWriteGuard();
56
57 private static final Logger LOGGER = LogManager.getLogger();
58
59
60
61
62
63
64
65 private static ThreadLocal<MCRSession> theThreadLocalSession = ThreadLocal.withInitial(MCRSession::new);
66
67 private static ThreadLocal<Boolean> isSessionAttached = ThreadLocal.withInitial(() -> Boolean.FALSE);
68
69 private static ThreadLocal<Boolean> isSessionCreationLocked = new ThreadLocal<>() {
70 @Override
71 protected Boolean initialValue() {
72 return Boolean.TRUE;
73 }
74 };
75
76
77
78
79
80
81
82
83 public static MCRSession getCurrentSession() {
84 if (isSessionCreationLocked.get()) {
85 throw new MCRException("Session creation is locked!");
86 }
87 isSessionAttached.set(Boolean.TRUE);
88 return theThreadLocalSession.get();
89 }
90
91 private static void checkSessionLock() {
92 if (isSessionCreationLocked.get()) {
93 throw new MCRException("Session creation is locked!");
94 }
95 }
96
97
98
99
100
101
102
103
104 public static void setCurrentSession(MCRSession theSession) {
105 if (hasCurrentSession()) {
106 MCRSession currentSession = getCurrentSession();
107 if (currentSession != theSession && currentSession.getID() != null) {
108 LOGGER.error("Current session will be released: " + currentSession,
109 new MCRException("Current thread already has a session attached!"));
110 releaseCurrentSession();
111 }
112
113 }
114 unlock();
115 theSession.activate();
116 theThreadLocalSession.set(theSession);
117 isSessionAttached.set(Boolean.TRUE);
118 }
119
120
121
122
123
124
125
126
127
128 public static void releaseCurrentSession() {
129
130 if (theThreadLocalSession != null && hasCurrentSession()) {
131 MCRSession session = theThreadLocalSession.get();
132 session.passivate();
133 MCRSession.LOGGER.debug("MCRSession released {}", session.getID());
134 theThreadLocalSession.remove();
135 isSessionAttached.remove();
136 lock();
137 }
138 }
139
140
141
142
143
144
145 public static boolean hasCurrentSession() {
146 return isSessionAttached.get();
147 }
148
149
150
151
152
153
154
155 public static String getCurrentSessionID() {
156 if (hasCurrentSession()) {
157 return getCurrentSession().getID();
158 }
159 return null;
160 }
161
162
163
164
165 public static void lock() {
166 isSessionCreationLocked.set(true);
167 }
168
169
170
171
172 public static void unlock() {
173 isSessionCreationLocked.set(false);
174 }
175
176
177
178
179 public static boolean isLocked() {
180 return isSessionCreationLocked.get();
181 }
182
183
184
185
186 public static MCRSession getSession(String sessionID) {
187 MCRSession s = sessions.get(sessionID);
188 if (s == null) {
189 MCRSession.LOGGER.warn("MCRSession with ID {} not cached any more", sessionID);
190 }
191 return s;
192 }
193
194
195
196
197
198
199
200
201 static void addSession(MCRSession session) {
202 sessions.put(session.getID(), session);
203 session.fireSessionEvent(created, session.concurrentAccess.get());
204 }
205
206
207
208
209
210
211
212
213 static void removeSession(MCRSession session) {
214 sessions.remove(session.getID());
215 session.fireSessionEvent(destroyed, session.concurrentAccess.get());
216 }
217
218
219
220
221
222
223 public static void addSessionListener(MCRSessionListener listener) {
224 listenersGuard.write(() -> listeners.add(listener));
225 }
226
227
228
229
230
231
232 public static void removeSessionListener(MCRSessionListener listener) {
233 listenersGuard.write(() -> listeners.remove(listener));
234 }
235
236
237
238
239 static List<MCRSessionListener> getListeners() {
240 return listenersGuard.read(() -> listeners.stream().collect(Collectors.toList()));
241 }
242
243 public static void close() {
244 listenersGuard.write(() -> {
245 Collection<MCRSession> var = sessions.values();
246 for (MCRSession session : var.toArray(new MCRSession[var.size()])) {
247 session.close();
248 }
249 LogManager.getLogger(MCRSessionMgr.class).info("Removing thread locals...");
250 isSessionAttached = null;
251 theThreadLocalSession = null;
252 listeners.clear();
253 LogManager.getLogger(MCRSessionMgr.class).info("...done.");
254 });
255 listenersGuard = null;
256 }
257
258 public static Map<String, MCRSession> getAllSessions() {
259 return sessions;
260 }
261
262 }