View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.conversation;
20  
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.TreeMap;
24  
25  /**
26   * The ConversationContext handles all conversations within the current context
27   *
28   * @author imario@apache.org
29   */
30  public class ConversationContext
31  {
32      private final long id;
33  
34      private final Object mutex = new Object();
35      private final Map conversations = new TreeMap();
36      // private final List conversationStack = new ArrayList(10);
37      private Conversation currentConversation;
38  
39      private long lastAccess;
40  
41      protected ConversationContext(long id)
42      {
43          this.id = id;
44          touch();
45      }
46  
47      protected void touch()
48      {
49          lastAccess = System.currentTimeMillis();
50      }
51  
52      public long getLastAccess()
53      {
54          return lastAccess;
55      }
56  
57      public void shutdownContext()
58      {
59          synchronized (mutex)
60          {
61              Iterator iterConversation = conversations.values().iterator();
62              while (iterConversation.hasNext())
63              {
64                  Conversation conversation = (Conversation) iterConversation.next();
65                  conversation.endConversation(false);
66              }
67  
68              conversations.clear();
69              // conversationStack.clear();
70          }
71      }
72  
73      /**
74       * Start a conversation if not already started.<br />
75       * All nested conversations (if any) are closed if the conversation already existed.
76       * @param name
77       */
78      public void startConversation(String name, boolean persistence)
79      {
80          synchronized (mutex)
81          {
82              touch();
83              Conversation conversation = (Conversation) conversations.get(name);
84              if (conversation == null)
85              {
86                  conversation = new Conversation(name, persistence);
87                  conversations.put(name, conversation);
88                  // conversationStack.add(conversation);
89              }
90              /*
91              else
92              {
93                  endNestedConversations(conversation, false);
94              }
95              */
96              currentConversation = conversation;
97          }
98      }
99  
100     /*
101      * Ends all conversations nested under conversation
102      *
103     protected void endNestedConversations(Conversation conversation, boolean regularEnd)
104     {
105         synchronized (mutex)
106         {
107             touch();
108             while (conversationStack.size()>0)
109             {
110                 int index = conversationStack.size()-1;
111                 Conversation dependingConversation = (Conversation) conversationStack.get(index);
112                 if (conversation == dependingConversation)
113                 {
114                     return;
115                 }
116 
117                 endConversation((Conversation) conversationStack.remove(index), regularEnd);
118             }
119         }
120     }
121     */
122 
123     /**
124      * End the given conversation
125      */
126     protected void endConversation(Conversation conversation, boolean regularEnd)
127     {
128         synchronized (mutex)
129         {
130             touch();
131             conversation.endConversation(regularEnd);
132             conversations.remove(conversation.getName());
133         }
134     }
135 
136     /**
137      * End the conversation with given name.<br />
138      * This also automatically closes all nested conversations.
139      */
140     public void endConversation(String name, boolean regularEnd)
141     {
142         synchronized (mutex)
143         {
144             touch();
145             Conversation conversation = (Conversation) conversations.get(name);
146             if (conversation != null)
147             {
148                 /*
149                 while (conversationStack.size()>1)
150                 {
151                     Conversation dependingConversation = (Conversation) conversationStack.get(conversationStack.size()-1);
152                     endConversation(dependingConversation, false);
153                     if (dependingConversation == conversation)
154                     {
155                         if (conversationStack.size() > 0)
156                         {
157                             currentConversation = (Conversation) conversationStack.get(conversationStack.size()-1);
158                         }
159                         return;
160                     }
161                 }
162                 */
163                 endConversation(conversation, regularEnd);
164             }
165         }
166     }
167 
168     /**
169      * Get the current conversation. The current conversation is the one last seen by the startConversation tag.
170      */
171     public Conversation getCurrentConversation()
172     {
173         touch();
174         return currentConversation;
175     }
176 
177     /**
178      * see if there is a conversation
179      */
180     public boolean hasConversations()
181     {
182         synchronized (mutex)
183         {
184             touch();
185             return conversations.size() > 0;
186         }
187     }
188 
189     /**
190      * check if the given conversation exists
191      */
192     public boolean hasConversation(String name)
193     {
194         synchronized (mutex)
195         {
196             touch();
197             return conversations.get(name) != null;
198         }
199     }
200 
201     /**
202      * get a conversation by name
203      */
204     public Conversation getConversation(String name)
205     {
206         synchronized (mutex)
207         {
208             touch();
209             return (Conversation) conversations.get(name);
210         }
211     }
212 
213     /**
214      * find the conversation which holds the given instance
215      */
216     public Conversation findConversation(Object instance)
217     {
218         synchronized (mutex)
219         {
220             touch();
221             Iterator iterConversations = conversations.values().iterator();
222             while (iterConversations.hasNext())
223             {
224                 Conversation conversation = (Conversation) iterConversations.next();
225                 if (conversation.hasBean(instance))
226                 {
227                     return conversation;
228                 }
229             }
230         }
231         return null;
232     }
233 
234     /**
235      * inject all beans from the conversation context to their configured scope
236     protected void injectConversationBeans(FacesContext context)
237     {
238         Set alreadyAdded = new TreeSet(new ValueBindingKey());
239 
240         for (int i = conversationStack.size(); i>0; i--)
241         {
242             Conversation conversation = (Conversation) conversationStack.get(i-1);
243             Iterator iterBeans = conversation.iterateBeanEntries();
244             while (iterBeans.hasNext())
245             {
246                 Map.Entry bean = (Map.Entry) iterBeans.next();
247                 if (!alreadyAdded.contains(bean.getKey()))
248                 {
249                     ((ValueBinding) bean.getKey()).setValue(context, bean.getValue());
250                 }
251             }
252         }
253     }
254      */
255 
256     /**
257      * find the bean named <code>name</code> in the conversation stack
258      */
259     public Object findBean(String name)
260     {
261         synchronized (mutex)
262         {
263             touch();
264             /*
265             for (int i = conversationStack.size(); i>0; i--)
266             {
267                 Conversation conversation = (Conversation) conversationStack.get(i-1);
268                 if (conversation.hasBean(name))
269                 {
270                     return conversation.getBean(name);
271                 }
272             }
273             */
274             Iterator iterConversations = conversations.values().iterator();
275             while (iterConversations.hasNext())
276             {
277                 Conversation conversation = (Conversation) iterConversations.next();
278                 if (conversation.hasBean(name))
279                 {
280                     return conversation.getBean(name);
281                 }
282             }
283 
284             return null;
285         }
286     }
287 
288     /**
289      * find the persistence manager in the conversation stack
290      */
291     public PersistenceManager getPersistenceManager()
292     {
293         synchronized (mutex)
294         {
295             touch();
296             /*
297             for (int i = conversationStack.size(); i>0; i--)
298             {
299                 Conversation conversation = (Conversation) conversationStack.get(i-1);
300                 if (conversation.isPersistence())
301                 {
302                     return conversation.getPersistenceManager();
303                 }
304             }
305             */
306             Iterator iterConversations = conversations.values().iterator();
307             while (iterConversations.hasNext())
308             {
309                 Conversation conversation = (Conversation) iterConversations.next();
310                 if (conversation.isPersistence())
311                 {
312                     return conversation.getPersistenceManager();
313                 }
314             }
315 
316             return null;
317         }
318     }
319 
320     /**
321      * detach all conversations from their underlaying persistence
322      */
323     public void detachPersistence()
324     {
325         synchronized (mutex)
326         {
327             touch();
328             /*
329             for (int i = conversationStack.size(); i>0; i--)
330             {
331                 Conversation conversation = (Conversation) conversationStack.get(i-1);
332                 if (conversation.isPersistence())
333                 {
334                     conversation.getPersistenceManager().detach();
335                 }
336             }
337             */
338             Iterator iterConversations = conversations.values().iterator();
339             while (iterConversations.hasNext())
340             {
341                 Conversation conversation = (Conversation) iterConversations.next();
342                 if (conversation.isPersistence())
343                 {
344                     conversation.getPersistenceManager().detach();
345                 }
346             }
347         }
348     }
349 
350     /**
351      * detach all conversations from their underlaying persistence
352      */
353     public void purgePersistence()
354     {
355         synchronized (mutex)
356         {
357             touch();
358             /*
359             for (int i = conversationStack.size(); i>0; i--)
360             {
361                 Conversation conversation = (Conversation) conversationStack.get(i-1);
362                 if (conversation.isPersistence())
363                 {
364                     conversation.getPersistenceManager().purge();
365                 }
366             }
367             */
368             Iterator iterConversations = conversations.values().iterator();
369             while (iterConversations.hasNext())
370             {
371                 Conversation conversation = (Conversation) iterConversations.next();
372                 if (conversation.isPersistence())
373                 {
374                     conversation.getPersistenceManager().purge();
375                 }
376             }
377         }
378     }
379 
380     /**
381      * attach all conversations to their underlaying persistence
382      */
383     public void attachPersistence()
384     {
385         synchronized (mutex)
386         {
387             touch();
388             /*
389             for (int i = conversationStack.size(); i>0; i--)
390             {
391                 Conversation conversation = (Conversation) conversationStack.get(i-1);
392                 if (conversation.isPersistence())
393                 {
394                     conversation.getPersistenceManager().attach();
395                 }
396             }
397             */
398             Iterator iterConversations = conversations.values().iterator();
399             while (iterConversations.hasNext())
400             {
401                 Conversation conversation = (Conversation) iterConversations.next();
402                 if (conversation.isPersistence())
403                 {
404                     conversation.getPersistenceManager().attach();
405                 }
406             }
407         }
408     }
409 
410     public long getId()
411     {
412         return id;
413     }
414 }