KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > lib > thread > CoadunationThreadGroup


1 /*
2  * CoadunationLib: The coaduntion implementation library.
3  * Copyright (C) 2006 Rift IT Contracting
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * CoadunationThreadGroup.java
20  *
21  * This object is responsible for loading the JMX Bean into memory from the
22  * deployment loader passed to it.
23  */

24
25 package com.rift.coad.lib.thread;
26
27 // the import paths
28
import java.util.Vector JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.ArrayList JavaDoc;
31
32 // logging import
33
import org.apache.log4j.Logger;
34
35 // coadunation imports
36
import com.rift.coad.lib.security.UserSession;
37 import com.rift.coad.lib.security.user.UserSessionManager;
38 import com.rift.coad.lib.configuration.ConfigurationFactory;
39 import com.rift.coad.lib.configuration.Configuration;
40 import com.rift.coad.lib.security.user.UserStoreManager;
41
42
43 /**
44  * This object is responsible for controlling the creation and administration of
45  * a grouping of threads.
46  *
47  * @author Brett Chaldecott
48  */

49 public class CoadunationThreadGroup {
50     
51     /**
52      * This object contains the list of threads in memory for a grouping. It
53      */

54     public class ThreadList {
55         // the class log variable
56
protected Logger log =
57             Logger.getLogger(ThreadList.class.getName());
58         
59         // member variables
60
private boolean terminated = false;
61         private Vector JavaDoc threads = null;
62         
63         /**
64          * The default constructor of the thread list.
65          */

66         public ThreadList() {
67             threads = new Vector JavaDoc();
68         }
69         
70         
71         /**
72          * This method adds a new thread to the list of threads.
73          *
74          * @param thread The reference to the thread to add.
75          */

76         public synchronized boolean addThread(BasicThread thread) {
77             if (terminated == false) {
78                 threads.add(thread);
79                 return true;
80             }
81             return false;
82         }
83         
84         
85         /**
86          * Returns a copy of the current threads.
87          *
88          * @return The list of the current threads.
89          */

90         public synchronized Vector JavaDoc getThreads() {
91            Vector JavaDoc threads = new Vector JavaDoc() ;
92            threads.addAll(this.threads);
93            return threads;
94         }
95         
96         
97         /**
98          * This method removes an object from the list that matches.
99          *
100          * @param thread The reference to the thread to remove.
101          */

102         public synchronized void remove(BasicThread thread) {
103             for (int index = 0; index < threads.size(); index++) {
104                 if (threads.get(index) == thread) {
105                     log.info("Object equal removing ["
106                             + thread.getId() + "] id [" +
107                             ((BasicThread)threads.get(index)).getId() + "]");
108                     threads.remove(thread);
109                     break;
110                 }
111             }
112         }
113         
114         
115         /**
116          * This method sets the terminated flag for this object.
117          */

118         public synchronized void terminate() {
119             terminated = true;
120         }
121         
122         
123         /**
124          * This method will return true if this object is terminated
125          */

126         public synchronized boolean isTerminated() {
127             return terminated;
128         }
129     }
130     
131     // the classes constant static variables
132
private final static String JavaDoc THREAD_TERMINATE_TIMEOUT = "Thread_Terminate_Timeout";
133     
134     // the class log variable
135
protected Logger log =
136         Logger.getLogger(CoadunationThreadGroup.class.getName());
137     
138     // the classes private member variables
139
private UserSessionManager sessionManager = null;
140     private UserStoreManager userStoreManager = null;
141     private ThreadList threadList = null;
142     private long threadTerminateTimeout = 0;
143     private CoadunationThreadGroup parent = null;
144     
145     
146     /**
147      *
148      * Creates a new instance of CoadunationThreadGroup
149      *
150      *
151      * @param sessionManager A reference to the user session manager.
152      * @param userStoreManager The user store object.
153      */

154     public CoadunationThreadGroup(UserSessionManager sessionManager,
155             UserStoreManager userStoreManager) throws ThreadException {
156         this.sessionManager = sessionManager;
157         this.userStoreManager = userStoreManager;
158         this.threadList = new ThreadList();
159         try {
160             Configuration config = ConfigurationFactory.getInstance().getConfig(
161                     this.getClass());
162             threadTerminateTimeout = config.getLong(THREAD_TERMINATE_TIMEOUT);
163             
164         } catch (Exception JavaDoc ex) {
165             throw new ThreadException(
166                     "Failed to retrieve default thread terminate timeout.",ex);
167         }
168     }
169     
170     
171     /**
172      *
173      * Creates a new instance of CoadunationThreadGroup
174      *
175      *
176      * @param sessionManager A reference to the user session manager.
177      * @param userStoreManager The user store object.
178      */

179     private CoadunationThreadGroup(CoadunationThreadGroup parent, UserSessionManager sessionManager,
180             UserStoreManager userStoreManager) throws ThreadException {
181         if (parent == null) {
182             throw new ThreadException("The parent thread group is invalid");
183         }
184         this.parent = parent;
185         this.sessionManager = sessionManager;
186         this.userStoreManager = userStoreManager;
187         this.threadList = new ThreadList();
188         try {
189             Configuration config = ConfigurationFactory.getInstance().getConfig(
190                     this.getClass());
191             threadTerminateTimeout = config.getLong(THREAD_TERMINATE_TIMEOUT);
192             
193         } catch (Exception JavaDoc ex) {
194             throw new ThreadException(
195                     "Failed to retrieve default thread terminate timeout.",ex);
196         }
197     }
198     
199     
200     /**
201      * This method will start the required number of threads of the given class
202      * type.
203      *
204      * @param classRef The reference to the class type.
205      * @param username The name of the user.
206      * @param number The number of threads to start.
207      * @exception ThreadException
208      */

209     public void startThreads(Class JavaDoc classRef, String JavaDoc username, int number)
210     throws ThreadException {
211         try{
212             validateThreadClass(classRef);
213             for (int count = 0; count < number; count++) {
214                 BasicThread threadRef = (BasicThread)classRef.newInstance();
215                 if (threadRef instanceof CoadunationThread) {
216                     throw new ThreadException(
217                             "Must inherit from Basic Thread and not Coad Thread.");
218                 }
219                 addThread(threadRef,username);
220                 // make sure the context loader is set corretly for all
221
// newly created threads
222
threadRef.setContextClassLoader(Thread.currentThread().
223                         getContextClassLoader());
224                 
225                 // start the thread
226
threadRef.start();
227             }
228         } catch (Exception JavaDoc ex) {
229             throw new ThreadException("Failed to add threads for [" +
230                     classRef.getName() + "] because :" + ex.getMessage(),ex);
231         }
232     }
233     
234     
235     /**
236      * This method will start the required number of threads of the given class
237      * type.
238      *
239      * @param threadRef The reference to the class type.
240      * @param username The name of the user.
241      * @exception ThreadException
242      */

243     public void addThread(BasicThread threadRef, String JavaDoc username)
244     throws ThreadException {
245         try {
246             UserSession user = userStoreManager.getUserInfo(username);
247             threadRef.setSessionManager(sessionManager);
248             threadRef.setUser(user);
249             threadRef.setCoadThreadGroup(this);
250             
251             // make sure the context loader is set corretly for all
252
// newly created threads
253
threadRef.setContextClassLoader(Thread.currentThread().
254                     getContextClassLoader());
255         } catch (Exception JavaDoc ex) {
256             throw new ThreadException(
257                     "Failed to add a thread to this group : " + ex.getMessage()
258                     ,ex);
259         }
260     }
261     
262     
263     /**
264      * This method will add a thread to this thread grouping.
265      *
266      * @return TRUE if the thread has been added false if it could not be added.
267      * @param threadRef The reference to the thread object to add.
268      * @exception ThreadException
269      */

270     protected boolean addThread(BasicThread threadRef) throws ThreadException {
271         return threadList.addThread(threadRef);
272     }
273     
274     
275     /**
276      * This method will remove the thread reference from the object.
277      *
278      * @param threadRef The reference to removed.
279      * @exception ThreadException
280      */

281     protected void removeThread(BasicThread threadRef) {
282         threadList.remove(threadRef);
283     }
284     
285     
286     /**
287      * This method returns the parent object referenced by this object.
288      *
289      * @return The parent of this object.
290      */

291     public CoadunationThreadGroup getParent() {
292         return parent;
293     }
294     
295     
296     /**
297      * This method returns the thread information for all the threads controlled
298      * by this object.
299      *
300      * @return The list containing the thread information.
301      */

302     public List JavaDoc getThreadInfo() throws ThreadException {
303         List JavaDoc threadInfoList = new ArrayList JavaDoc();
304         Vector JavaDoc threads = threadList.getThreads();
305         for (int i = 0; i < threads.size(); i++) {
306             BasicThread thread = (BasicThread)threads.get(i);
307             ThreadInfo threadInfo = new ThreadInfo(thread.getId(),
308                     thread.getClass(), thread.getUser(), thread.getState(),
309                     thread.getInfo());
310             threadInfoList.add(threadInfo);
311         }
312         return threadInfoList;
313     }
314     
315     
316     /**
317      * This method will return the terminated flag value.
318      */

319     public boolean isTerminated() {
320         return threadList.isTerminated();
321     }
322     
323     /**
324      * This method terminates the threads being maintained by this thread
325      * grouping.
326      */

327     public synchronized void terminate() {
328         
329         // the object has already been terminated
330
if (threadList.isTerminated()) {
331             return;
332         }
333         
334         // call soft terminate on running threads.
335
threadList.terminate();
336         
337         Vector JavaDoc threads = threadList.getThreads();
338         for (int i = 0; i < threads.size(); i++) {
339             BasicThread thread = (BasicThread)threads.get(i);
340             try {
341                 thread.terminate();
342             } catch(Exception JavaDoc ex) {
343                 log.error("Failed to terminate thread [" + thread.getId() +
344                         "] class [" + thread.getClass().getName() +
345                         "] because : " + ex.getMessage(),ex);
346             }
347         }
348         
349         // call join on the thread
350
for (int i = 0; i < threads.size(); i++) {
351             BasicThread thread = (BasicThread)threads.get(i);
352             try {
353                 thread.join(getThreadTimeout(thread));
354             } catch(Exception JavaDoc ex) {
355                 log.error("Failed to wait for thread [" + thread.getId() +
356                         "] class [" + thread.getClass().getName() +
357                         "] because : " + ex.getMessage(),ex);
358             }
359         }
360         
361         
362         // call the depricated stop method on the threads that have not stopped
363
// within the designated time
364
for (int i = 0; i < threads.size(); i++) {
365             BasicThread thread = (BasicThread)threads.get(i);
366             try {
367                 if (thread.getState() != Thread.State.TERMINATED) {
368                     log.error("The thread [" + thread.getId() +
369                         "] class [" + thread.getClass().getName() +
370                         "] has not been terminated forcing it to stop.");
371                     thread.stop();
372                 }
373             } catch(Exception JavaDoc ex) {
374                 log.error("Failed to wait for thread [" + thread.getId() +
375                         "] class [" + thread.getClass().getName() +
376                         "] because : " + ex.getMessage(),ex);
377             }
378         }
379     }
380     
381     
382     /**
383      * This method retrieve the thread timout period for a given object.
384      *
385      * @return The long containing the thread time out.
386      * @param obj The object to retrieve the thread timeout for.
387      */

388     private long getThreadTimeout(Object JavaDoc obj) {
389         try {
390             Configuration config = ConfigurationFactory.getInstance().getConfig(
391                     obj.getClass());
392             return config.getLong(THREAD_TERMINATE_TIMEOUT);
393         } catch (Exception JavaDoc ex) {
394             return threadTerminateTimeout;
395         }
396     }
397     
398     
399     /**
400      * This method creates a new child thread group.
401      *
402      * @return The newly created thread group.
403      * @exception ThreadException
404      */

405     public CoadunationThreadGroup createThreadGroup() throws ThreadException {
406         return new CoadunationThreadGroup(this,sessionManager,userStoreManager);
407     }
408     
409     
410     /**
411      * This method validates the class references is valid.
412      *
413      * @param classRef The class reference that is passed in for validation.
414      */

415     private void validateThreadClass(Class JavaDoc classRef) throws ThreadException {
416         Class JavaDoc tempClass = classRef.getSuperclass();
417         while (tempClass != null) {
418             System.out.println("Class : " + tempClass.getName());
419             if (tempClass.getName().
420                     equals("com.rift.coad.lib.thread.BasicThread")) {
421                 return;
422             }
423             tempClass = classRef.getSuperclass();
424         }
425         throw new ThreadException(
426                 "This object does not inherit from BasicThread [" +
427                 classRef.getName() + "]");
428     }
429 }
430
Popular Tags