1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.orchestra.conversation;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
25 import org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterProviderManager;
26
27 import java.io.IOException;
28 import java.io.ObjectStreamException;
29 import java.io.Serializable;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Map;
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class ConversationManager implements Serializable
48 {
49 private static final long serialVersionUID = 1L;
50
51 final static String CONVERSATION_CONTEXT_PARAM = "conversationContext";
52
53 private final static String CONVERSATION_MANAGER_KEY = "org.apache.myfaces.ConversationManager";
54 private final static String CONVERSATION_CONTEXT_REQ = "org.apache.myfaces.ConversationManager.conversationContext";
55
56 private static final Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
57
58 private final Log log = LogFactory.getLog(ConversationManager.class);
59
60
61
62
63
64
65
66
67 private long nextConversationContextId = 1;
68
69
70
71 private final Map conversationContexts = new HashMap();
72
73 protected ConversationManager()
74 {
75 }
76
77
78
79
80 public static ConversationManager getInstance()
81 {
82 return getInstance(true);
83 }
84
85
86
87
88
89
90
91
92
93
94 public static ConversationManager getInstance(boolean create)
95 {
96 FrameworkAdapter frameworkAdapter = FrameworkAdapter.getCurrentInstance();
97 if (frameworkAdapter == null)
98 {
99 if (!create)
100 {
101
102
103 return null;
104 }
105 else
106 {
107 throw new IllegalStateException("FrameworkAdapter not found");
108 }
109 }
110
111 ConversationManager conversationManager = (ConversationManager) frameworkAdapter.getSessionAttribute(
112 CONVERSATION_MANAGER_KEY);
113 if (conversationManager == null && create)
114 {
115
116
117 conversationManager = new ConversationManager();
118
119
120 RequestParameterProviderManager.getInstance().register(new ConversationRequestParameterProvider());
121
122
123 FrameworkAdapter.getCurrentInstance().setSessionAttribute(CONVERSATION_MANAGER_KEY, conversationManager);
124 }
125
126 return conversationManager;
127 }
128
129
130
131
132
133
134 private Long findConversationContextId()
135 {
136 FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
137
138
139 Long conversationContextId = (Long)fa.getRequestAttribute(CONVERSATION_CONTEXT_REQ);
140 if (conversationContextId == null)
141 {
142 if (fa.containsRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM))
143 {
144 String urlConversationContextId = fa.getRequestParameterAttribute(
145 CONVERSATION_CONTEXT_PARAM).toString();
146 conversationContextId = new Long(
147 Long.parseLong(urlConversationContextId, Character.MAX_RADIX));
148 }
149 }
150 return conversationContextId;
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 private Long getOrCreateConversationContextId()
171 {
172 Long conversationContextId = findConversationContextId();
173 if (conversationContextId == null)
174 {
175 conversationContextId = createNextConversationContextId();
176 FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
177 fa.setRequestAttribute(CONVERSATION_CONTEXT_REQ, conversationContextId);
178 }
179
180 return conversationContextId;
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 public Long getConversationContextId()
203 {
204 return getOrCreateConversationContextId();
205 }
206
207
208
209
210
211
212
213
214 private Long createNextConversationContextId()
215 {
216 Long conversationContextId;
217 synchronized(this)
218 {
219 conversationContextId = new Long(nextConversationContextId);
220 nextConversationContextId++;
221 }
222 return conversationContextId;
223 }
224
225
226
227
228
229
230
231
232 protected ConversationContext getConversationContext(Long conversationContextId)
233 {
234 synchronized (this)
235 {
236 return (ConversationContext) conversationContexts.get(conversationContextId);
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249 protected ConversationContext getOrCreateConversationContext(Long conversationContextId)
250 {
251 synchronized (this)
252 {
253 ConversationContext conversationContext = (ConversationContext) conversationContexts.get(
254 conversationContextId);
255 if (conversationContext == null)
256 {
257 conversationContext = new ConversationContext(null, conversationContextId.longValue());
258 conversationContexts.put(conversationContextId, conversationContext);
259
260
261
262 log.debug("Created context " + conversationContextId);
263 }
264 return conversationContext;
265 }
266 }
267
268
269
270
271
272
273
274
275
276 public void activateConversationContext(ConversationContext ctx)
277 {
278 FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
279 fa.setRequestAttribute(CONVERSATION_CONTEXT_REQ, ctx.getIdAsLong());
280 }
281
282
283
284
285 public void clearCurrentConversationContext()
286 {
287 Long conversationContextId = findConversationContextId();
288 if (conversationContextId != null)
289 {
290 ConversationContext conversationContext = getConversationContext(conversationContextId);
291 if (conversationContext != null)
292 {
293 conversationContext.clear();
294 }
295 }
296 }
297
298
299
300
301
302
303 protected void removeConversationContext(Long conversationContextId)
304 {
305 synchronized (this)
306 {
307 conversationContexts.remove(conversationContextId);
308 }
309 }
310
311
312
313
314
315
316 public Conversation startConversation(String name, ConversationFactory factory)
317 {
318 ConversationContext conversationContext = getOrCreateCurrentConversationContext();
319 return conversationContext.startConversation(name, factory);
320 }
321
322
323
324
325
326
327
328
329 protected void removeConversation(String name)
330 {
331 Long conversationContextId = findConversationContextId();
332 if (conversationContextId != null)
333 {
334 ConversationContext conversationContext = getConversationContext(conversationContextId);
335 if (conversationContext != null)
336 {
337 conversationContext.removeConversation(name);
338 }
339 }
340 }
341
342
343
344
345
346
347 public Conversation getConversation(String name)
348 {
349 ConversationContext conversationContext = getCurrentConversationContext();
350 if (conversationContext == null)
351 {
352 return null;
353 }
354 return conversationContext.getConversation(name);
355 }
356
357
358
359
360 public boolean hasConversation(String name)
361 {
362 ConversationContext conversationContext = getCurrentConversationContext();
363 if (conversationContext == null)
364 {
365 return false;
366 }
367 return conversationContext.hasConversation(name);
368 }
369
370
371
372
373
374 public Iterator iterateConversations()
375 {
376 ConversationContext conversationContext = getCurrentConversationContext();
377 if (conversationContext == null)
378 {
379 return EMPTY_ITERATOR;
380 }
381
382 return conversationContext.iterateConversations();
383 }
384
385
386
387
388
389
390
391
392
393
394 public ConversationContext getCurrentConversationContext()
395 {
396 Long ccid = findConversationContextId();
397 if (ccid == null)
398 {
399 return null;
400 }
401 else
402 {
403 return getConversationContext(ccid);
404 }
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418 ConversationContext getOrCreateCurrentConversationContext()
419 {
420 Long ccid = getOrCreateConversationContextId();
421 return getOrCreateConversationContext(ccid);
422 }
423
424
425
426
427
428 public boolean hasConversationContext()
429 {
430 return getCurrentConversationContext() == null;
431 }
432
433
434
435
436
437
438
439
440 public ConversationContext getCurrentRootConversationContext()
441 {
442 Long ccid = findConversationContextId();
443 if (ccid == null)
444 {
445 return null;
446 }
447
448 synchronized (this)
449 {
450 ConversationContext conversationContext = getConversationContext(ccid);
451 if (conversationContext == null)
452 {
453 return null;
454 }
455 else
456 {
457 return conversationContext.getRoot();
458 }
459 }
460 }
461
462
463
464
465
466
467
468 public ConversationMessager getMessager()
469 {
470 return FrameworkAdapter.getCurrentInstance().getConversationMessager();
471 }
472
473
474
475
476
477
478
479
480
481
482
483 protected void checkTimeouts()
484 {
485 Map.Entry[] contexts;
486 synchronized (this)
487 {
488 contexts = new Map.Entry[conversationContexts.size()];
489 conversationContexts.entrySet().toArray(contexts);
490 }
491
492 long checkTime = System.currentTimeMillis();
493
494 for (int i = 0; i<contexts.length; i++)
495 {
496 Map.Entry context = contexts[i];
497
498 Long conversationContextId = (Long) context.getKey();
499 ConversationContext conversationContext = (ConversationContext) context.getValue();
500 conversationContext.checkConversationTimeout();
501
502 if (conversationContext.getTimeout() > -1 &&
503 (conversationContext.getLastAccess() +
504 conversationContext.getTimeout()) < checkTime)
505 {
506 if (log.isDebugEnabled())
507 {
508 log.debug("end conversation context due to timeout: " + conversationContext.getId());
509 }
510
511 conversationContext.clear();
512 synchronized (this)
513 {
514 conversationContexts.remove(conversationContextId);
515 }
516 }
517 }
518 }
519
520 private void writeObject(java.io.ObjectOutputStream out) throws IOException
521 {
522
523
524 }
525
526 private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
527 {
528
529 }
530
531 private Object readResolve() throws ObjectStreamException
532 {
533
534 return null;
535 }
536 }