1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.sf.sail.core.beans;
24
25 import java.beans.beancontext.BeanContextServiceProvider;
26 import java.beans.beancontext.BeanContextServices;
27 import java.beans.beancontext.BeanContextServicesSupport;
28 import java.io.File;
29 import java.io.FileOutputStream;
30 import java.io.PrintStream;
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37
38 import net.sf.sail.core.beans.event.SessionEvent;
39 import net.sf.sail.core.beans.event.SessionEventListener;
40 import net.sf.sail.core.beans.service.AgentService;
41 import net.sf.sail.core.beans.service.AnnotationService;
42 import net.sf.sail.core.beans.service.SessionService;
43 import net.sf.sail.core.entity.Offering;
44 import net.sf.sail.core.entity.User;
45 import net.sf.sail.core.session.DefaultSessionService;
46 import net.sf.sail.core.session.SessionDataService;
47 import net.sf.sail.core.uuid.SessionUuid;
48
49 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
50
51
52
53
54
55
56
57
58 public class SessionContext extends BeanContextServicesSupport {
59
60
61
62 private static final Logger logger = Logger.getLogger(SessionContext.class
63 .getName());
64
65 private static final long serialVersionUID = 1L;
66
67
68
69
70 class ServiceProvider implements BeanContextServiceProvider {
71
72 SessionService sessionService = new DefaultSessionService(
73 SessionContext.this);
74
75 AgentService agentService = null;
76 AnnotationService annotationService = null;
77
78 void register(BeanContextServices bcs) {
79 bcs.addService(SessionService.class, serviceProvider);
80 bcs.addService(AgentService.class, serviceProvider);
81 bcs.addService(AnnotationService.class, serviceProvider);
82 }
83
84
85
86
87
88 public void releaseService(BeanContextServices bcs, Object requestor,
89 Object service) {
90
91
92
93 return;
94 }
95
96 @SuppressWarnings("unchecked")
97 public Iterator getCurrentServiceSelectors(BeanContextServices bcs,
98 Class serviceClass) {
99 throw new UnsupportedOperationException();
100 }
101
102 @SuppressWarnings("unchecked")
103 public Object getService(BeanContextServices bcs, Object requestor,
104 Class serviceClass, Object serviceSelector) {
105 if (serviceClass == SessionService.class) {
106 return sessionService;
107 } else if (serviceClass == AgentService.class) {
108 return agentService;
109 } else if (serviceClass == AnnotationService.class) {
110 return annotationService;
111 } else {
112 return null;
113 }
114 }
115 }
116
117 private final ServiceProvider serviceProvider = new ServiceProvider();
118
119 SessionUuid sessionId;
120
121 SessionDataService sessionDataService;
122
123 Offering offering;
124
125 protected Date startTime;
126
127 protected Date stopTime;
128
129
130 public static boolean exitOnClose = true;
131
132 public Offering getOffering() {
133 return offering;
134 }
135
136 public void setOffering(Offering offering) {
137 this.offering = offering;
138 }
139
140 List<SessionEventListener> sessionEventListeners = new ArrayList<SessionEventListener>();
141
142 private boolean initiated;
143
144 private boolean terminationInProgress = false;
145
146
147 private long timeDrift;
148
149 public void addSessionEventListener(SessionEventListener sel) {
150 sessionEventListeners.add(sel);
151 }
152
153 protected void fireSessionEvent(SessionEvent se) {
154 for (Object element : sessionEventListeners) {
155 SessionEventListener listener = (SessionEventListener) element;
156 switch (se.getID()) {
157 case SessionEvent.INITIATE:
158 listener.sessionInitiated(se);
159 break;
160 case SessionEvent.START:
161 listener.sessionStarted(se);
162 break;
163 case SessionEvent.END:
164 listener.sessionStopped(se);
165 break;
166 }
167 }
168 }
169
170 public void addUser(User user) {
171 serviceProvider.sessionService.addUser(user);
172 }
173
174 public void initiate() {
175 if (sessionDataService == null)
176 throw new IllegalStateException(
177 "initiate() called before sessionDataService property set");
178 BeanContextServices bcs = getBeanContextServicesPeer();
179 serviceProvider.register(bcs);
180 fireSessionEvent(new SessionEvent(this, SessionEvent.INITIATE));
181 initiated = true;
182 }
183
184 public void start() {
185 if (!initiated)
186 throw new IllegalStateException("start() called before initiate()");
187 if (startTime == null) {
188 initStartTime();
189 }
190 fireSessionEvent(new SessionEvent(this, SessionEvent.START));
191 logger.info("Session started at " + startTime);
192 }
193
194 public void tryToTerminate() {
195 logger.info("trying to terminate");
196 if (terminationInProgress) {
197 logger.severe("already trying to terminate. ignoring.");
198 return;
199 }
200 terminationInProgress = true;
201 stopTime = new Date();
202 fireSessionEvent(new SessionEvent(this, SessionEvent.END));
203 logger.info("Session ended at " + stopTime);
204
205 Thread t = new Thread() {
206 public void run() {
207 dumpPersistance();
208 if (exitOnClose) System.exit(0);
209 terminationInProgress = false;
210 }
211 };
212 t.start();
213 }
214
215 public Date getStartTime() {
216 return startTime;
217 }
218
219 public void initStartTime() {
220 if (startTime == null) {
221 String strTime = ((DefaultSessionService)(serviceProvider.sessionService)).getProperty("sds_time", "0");
222 long sdsTime = Long.parseLong(strTime);
223 if (sdsTime == 0) {
224 startTime = new Date();
225 timeDrift = 0;
226 } else {
227 startTime = new Date(sdsTime);
228 timeDrift = java.lang.System.currentTimeMillis() - startTime.getTime();
229 }
230 }
231 }
232
233 public long getTimeDifference() {
234 return timeDrift;
235 }
236
237 public Date getStopTime() {
238 return stopTime;
239 }
240
241 public SessionUuid getSessionId() {
242 return sessionId;
243 }
244
245 public void setSessionId(SessionUuid sessionId) {
246 this.sessionId = sessionId;
247 }
248
249 public SessionDataService getSessionDataService() {
250 return sessionDataService;
251 }
252
253 public void setSessionDataService(SessionDataService sessionDataService) {
254 this.sessionDataService = sessionDataService;
255 serviceProvider.agentService =
256 sessionDataService.getPersistenceService(this);
257 serviceProvider.annotationService =
258 sessionDataService.getAnnotationService();
259 }
260
261
262
263
264
265
266 public void setProperty(String key, String value)
267 {
268 ((DefaultSessionService)(serviceProvider.sessionService)).setProperty(key, value);
269 }
270
271
272
273
274
275
276 public SessionService getSessionService()
277 {
278 return serviceProvider.sessionService;
279 }
280
281
282
283
284 public long getOffsetMilliseconds() {
285 return java.lang.System.currentTimeMillis() - startTime.getTime() - timeDrift;
286 }
287
288
289
290
291 protected void dumpPersistance() {
292 try {
293 File file = File.createTempFile("saildump", ".xml");
294 logger.info("dumping persistance data to " + file);
295 PrintStream ps = new PrintStream(new FileOutputStream(file));
296 serviceProvider.agentService.dump(this, ps);
297 if (logger.isLoggable(Level.CONFIG)) {
298 logger.info("done.");
299 }
300 } catch (Exception e) {
301 logger.log(Level.SEVERE, "FAILED to dump persistance data", e);
302 }
303 }
304
305 @Override
306 public String toString() {
307 return ReflectionToStringBuilder.toString(this);
308 }
309 }
310