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 java.io.IOException;
23 import java.io.ObjectStreamException;
24 import java.io.Serializable;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Map;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
33 import org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterProviderManager;
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(CONVERSATION_MANAGER_KEY);
112 if (conversationManager == null && create)
113 {
114
115
116 conversationManager = new ConversationManager();
117
118
119 RequestParameterProviderManager.getInstance().register(new ConversationRequestParameterProvider());
120
121
122 FrameworkAdapter.getCurrentInstance().setSessionAttribute(CONVERSATION_MANAGER_KEY, conversationManager);
123 }
124
125 return conversationManager;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public Long getConversationContextId()
146 {
147 FrameworkAdapter fa = FrameworkAdapter.getCurrentInstance();
148
149
150
151 Long conversationContextId = (Long)fa.getRequestAttribute(CONVERSATION_CONTEXT_REQ);
152
153 if (conversationContextId == null)
154 {
155 if (fa.containsRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM))
156 {
157 String urlConversationContextId = fa.getRequestParameterAttribute(CONVERSATION_CONTEXT_PARAM).toString();
158 conversationContextId = new Long(Long.parseLong(urlConversationContextId, Character.MAX_RADIX));
159 }
160 else
161 {
162 synchronized(this)
163 {
164 conversationContextId = new Long(nextConversationContextId);
165 nextConversationContextId++;
166 }
167 }
168
169 fa.setRequestAttribute(CONVERSATION_CONTEXT_REQ, conversationContextId);
170 }
171
172 return conversationContextId;
173 }
174
175
176
177
178 protected ConversationContext getConversationContext(Long conversationContextId)
179 {
180 synchronized (this)
181 {
182 return (ConversationContext) conversationContexts.get(conversationContextId);
183 }
184 }
185
186
187
188
189
190 protected ConversationContext getOrCreateConversationContext(Long conversationContextId)
191 {
192 synchronized (this)
193 {
194 ConversationContext conversationContext = (ConversationContext) conversationContexts.get(conversationContextId);
195 if (conversationContext == null)
196 {
197 conversationContext = new ConversationContext(conversationContextId.longValue());
198 conversationContexts.put(conversationContextId, conversationContext);
199 }
200
201 return conversationContext;
202 }
203 }
204
205
206
207
208 public void clearCurrentConversationContext()
209 {
210 Long conversationContextId = getConversationContextId();
211 ConversationContext conversationContext = getConversationContext(conversationContextId);
212 if (conversationContext != null)
213 {
214 conversationContext.clear();
215 }
216 }
217
218
219
220
221
222
223 protected void removeConversationContext(Long conversationContextId)
224 {
225 synchronized (this)
226 {
227 conversationContexts.remove(conversationContextId);
228 }
229 }
230
231
232
233
234
235
236 public Conversation startConversation(String name, ConversationFactory factory)
237 {
238 Long conversationContextId = getConversationContextId();
239 ConversationContext conversationContext = getOrCreateConversationContext(conversationContextId);
240 return conversationContext.startConversation(name, factory);
241 }
242
243
244
245
246
247
248
249
250 protected void removeConversation(String name)
251 {
252 Long conversationContextId = getConversationContextId();
253 ConversationContext conversationContext = getConversationContext(conversationContextId);
254 if (conversationContext != null)
255 {
256 conversationContext.removeConversation(name);
257 }
258 }
259
260
261
262
263
264
265 public Conversation getConversation(String name)
266 {
267 ConversationContext conversationContext = getCurrentConversationContext();
268 if (conversationContext == null)
269 {
270 return null;
271 }
272 return conversationContext.getConversation(name);
273 }
274
275
276
277
278 public boolean hasConversation(String name)
279 {
280 ConversationContext conversationContext = getCurrentConversationContext();
281 if (conversationContext == null)
282 {
283 return false;
284 }
285 return conversationContext.hasConversation(name);
286 }
287
288
289
290
291
292 public Iterator iterateConversations()
293 {
294 ConversationContext conversationContext = getCurrentConversationContext();
295 if (conversationContext == null)
296 {
297 return EMPTY_ITERATOR;
298 }
299
300 return conversationContext.iterateConversations();
301 }
302
303
304
305
306
307
308 public ConversationContext getCurrentConversationContext()
309 {
310 Long conversationContextId = getConversationContextId();
311 ConversationContext conversationContext = getConversationContext(conversationContextId);
312 return conversationContext;
313 }
314
315
316
317
318 public boolean hasConversationContext()
319 {
320 return
321 (
322 FrameworkAdapter.getCurrentInstance().containsRequestAttribute(CONVERSATION_CONTEXT_REQ) ||
323 FrameworkAdapter.getCurrentInstance().containsRequestParameterAttribute(CONVERSATION_CONTEXT_REQ)) &&
324 getCurrentConversationContext() != null;
325 }
326
327
328
329
330
331
332
333 public ConversationMessager getMessager()
334 {
335 return FrameworkAdapter.getCurrentInstance().getConversationMessager();
336 }
337
338
339
340
341
342
343
344
345
346
347
348 protected void checkTimeouts()
349 {
350 Map.Entry[] contexts;
351 synchronized (this)
352 {
353 contexts = new Map.Entry[conversationContexts.size()];
354 conversationContexts.entrySet().toArray(contexts);
355 }
356
357 long checkTime = System.currentTimeMillis();
358
359 for (int i = 0; i<contexts.length; i++)
360 {
361 Map.Entry context = contexts[i];
362
363 Long conversationContextId = (Long) context.getKey();
364 ConversationContext conversationContext = (ConversationContext) context.getValue();
365 conversationContext.checkConversationTimeout();
366
367 if (conversationContext.getTimeout() > -1 &&
368 (conversationContext.getLastAccess() +
369 conversationContext.getTimeout()) < checkTime)
370 {
371 if (log.isDebugEnabled())
372 {
373 log.debug("end conversation context due to timeout: " + conversationContext.getId());
374 }
375
376 conversationContext.clear();
377 synchronized (this)
378 {
379 conversationContexts.remove(conversationContextId);
380 }
381 }
382 }
383 }
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403 private void writeObject(java.io.ObjectOutputStream out) throws IOException
404 {
405
406
407 }
408
409 private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
410 {
411
412 }
413
414 private Object readResolve() throws ObjectStreamException
415 {
416
417 return null;
418 }
419 }