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.orchestra.conversation;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  /***
28   * The ConversationWiperThread will trigger the conversation timeout check.
29   * <p>
30   * This is typically started from a servlet session listener when the webapp starts.
31   * 
32   * @see org.apache.myfaces.orchestra.servlet.ConversationManagerSessionListener.
33   */
34  public class ConversationWiperThread extends Thread
35  {
36  	private final Log log = LogFactory.getLog(ConversationWiperThread.class);
37  
38  	private final long checkTime;
39  
40  	private Map conversationManagers = new HashMap();
41  
42  	/***
43  	 * Constructor.
44  	 * 
45  	 * @param checkTime is interval in milliseconds between scans of the existing
46  	 * ConversationManagers to look for timeouts.
47  	 */
48  	public ConversationWiperThread(long checkTime)
49  	{
50  		this.checkTime = checkTime;
51  
52  		setDaemon(true);
53  		setName(ConversationWiperThread.class.getName());
54  	}
55  
56  	/***
57  	 * Add a ConversationManager to check.
58  	 * <p>
59  	 * If there is already a ConversationManager associated with the given
60  	 * <code>id</code>, the old ConversationManager will be replaced.
61  	 */
62  	public void addConversationManager(String id, ConversationManager conversationManager)
63  	{
64  		synchronized (conversationManagers)
65  		{
66  			conversationManagers.put(id, conversationManager);
67  		}
68  	}
69  
70  	/***
71  	 * Remove a ConversationManager from the list to check.
72  	 */
73  	public void removeConversationManager(String id)
74  	{
75  		synchronized (conversationManagers)
76  		{
77  			conversationManagers.remove(id);
78  		}
79  	}
80  
81  	public void run()
82  	{
83  		if (log.isDebugEnabled())
84  		{
85  			log.debug("ConversationWiperThread startup"); // NON-NLS
86  		}
87  		_run();
88  		if (log.isInfoEnabled())
89  		{
90  			log.debug("ConversationWiperThread shtudown"); // NON-NLS
91  		}
92  	}
93  
94  	private void _run()
95  	{
96  		while (!isInterrupted())
97  		{
98  			ConversationManager[] managersArray;
99  			synchronized (conversationManagers)
100 			{
101 				managersArray = new ConversationManager[conversationManagers.size()];
102 				conversationManagers.values().toArray(managersArray);
103 			}
104 
105 			for (int i = 0; i<managersArray.length; i++)
106 			{
107 				ConversationManager conversationManager = managersArray[i];
108 				conversationManager.checkTimeouts();
109 			}
110 
111 			try
112 			{
113 				Thread.sleep(checkTime);
114 			}
115 			catch (InterruptedException e)
116 			{
117 				return;
118 			}
119 		}
120 	}
121 }