001: /*
002: * CoadunationLib: The coaduntion implementation library.
003: * Copyright (C) 2006 Rift IT Contracting
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
018: *
019: * ThreadGroupManager.java
020: *
021: * This object is responsible for managing the thread groups within Coadunation.
022: */
023:
024: // package path
025: package com.rift.coad.lib.thread;
026:
027: // java imports
028: import java.util.Map;
029: import java.util.HashMap;
030:
031: // logging import
032: import org.apache.log4j.Logger;
033:
034: // coadunation imports
035: import com.rift.coad.lib.common.RandomGuid;
036: import com.rift.coad.lib.configuration.Configuration;
037: import com.rift.coad.lib.configuration.ConfigurationFactory;
038: import com.rift.coad.lib.security.Validator;
039:
040: /**
041: * This object is responsible for managing the thread groups within Coadunation.
042: *
043: * @author Brett Chaldecott
044: */
045: public class ThreadGroupManager {
046:
047: /**
048: * The class loader thread group.
049: */
050: public class LoaderThreadGroupManager {
051: // private member variables
052: private ThreadGroup threadGroup = null;
053: private CoadunationThreadGroup coadThreadGroup = null;
054:
055: /**
056: * The class loader thread group manager
057: */
058: public LoaderThreadGroupManager(
059: CoadunationThreadGroup coadThreadGroup)
060: throws ThreadException {
061: try {
062: threadGroup = new ThreadGroup(RandomGuid.getInstance()
063: .getGuid());
064: this .coadThreadGroup = coadThreadGroup
065: .createThreadGroup();
066: } catch (Exception ex) {
067: throw new ThreadException("Failed to create the "
068: + "LoaderThreadGroupManager : "
069: + ex.getMessage(), ex);
070: }
071: }
072:
073: /**
074: * This method returns the JAVA thread group.
075: */
076: public ThreadGroup getThreadGroup() {
077: return threadGroup;
078: }
079:
080: /**
081: * This method returns the reference to the coad thread group.
082: */
083: public CoadunationThreadGroup getCoadThreadGroup() {
084: return coadThreadGroup;
085: }
086:
087: /**
088: * This method terminates the thread groups
089: */
090: public void terminate() {
091: try {
092: coadThreadGroup.terminate();
093: if (threadGroup.activeCount() > 0) {
094: log
095: .warn("There may still be threads in daemon that has "
096: + "undeployed.");
097: }
098: try {
099: threadGroup.destroy();
100: } catch (Exception ex) {
101: log.debug("Failed to destroy the thread group "
102: + ex.getMessage(), ex);
103: }
104: } catch (Exception ex) {
105: log.error(
106: "Failed to terminate the thread group cleanly "
107: + ex.getMessage(), ex);
108: }
109: }
110: }
111:
112: // class constants
113: private final static String ROLE = "role";
114:
115: // the classes singletons
116: private static ThreadGroupManager threadGroupManager = null;
117: protected static Logger log = Logger
118: .getLogger(ThreadGroupManager.class.getName());
119:
120: // classes private member variables
121: private Map managedGroups = new HashMap();
122:
123: // static member variables
124: private static String role = null;
125:
126: // setup the role
127: static {
128: try {
129: Configuration configuration = ConfigurationFactory
130: .getInstance().getConfig(ThreadGroupManager.class);
131: role = configuration.getString(ROLE);
132: } catch (Exception ex) {
133: log.error(
134: "Failed to retrieve the thread group manager role : "
135: + ex.getMessage(), ex);
136: throw new RuntimeException(
137: "Failed to retrieve the thread group manager role : "
138: + ex.getMessage(), ex);
139: }
140: }
141:
142: /** Creates a new instance of ThreadGroupManager */
143: private ThreadGroupManager() {
144: }
145:
146: /**
147: * This method is responsible for getting and instance of the thread group
148: * manager.
149: *
150: * @return The reference to the in memory thread group.
151: */
152: public static synchronized ThreadGroupManager getInstance() {
153: if (threadGroupManager == null) {
154: threadGroupManager = new ThreadGroupManager();
155: }
156: return threadGroupManager;
157: }
158:
159: /**
160: * This method inits the thread group for the given class loader.
161: *
162: * @param coadThreadGroup The thread group to start.
163: */
164: public void initThreadGroup(CoadunationThreadGroup coadThreadGroup)
165: throws ThreadException {
166: LoaderThreadGroupManager loaderThreadGroupManager = new LoaderThreadGroupManager(
167: coadThreadGroup);
168: ClassLoader classLoader = Thread.currentThread()
169: .getContextClassLoader();
170: synchronized (managedGroups) {
171: managedGroups.put(classLoader, loaderThreadGroupManager);
172: }
173: }
174:
175: /**
176: * This method returns the reference to the thread group
177: */
178: public ThreadGroup getThreadGroup() {
179: ClassLoader classLoader = Thread.currentThread()
180: .getContextClassLoader();
181: LoaderThreadGroupManager loaderThreadGroupManager = null;
182: synchronized (managedGroups) {
183: if (!managedGroups.containsKey(classLoader)) {
184: return null;
185: }
186: loaderThreadGroupManager = (LoaderThreadGroupManager) managedGroups
187: .get(classLoader);
188: }
189: return loaderThreadGroupManager.getThreadGroup();
190: }
191:
192: /**
193: * This method returns the reference to the thread group
194: */
195: public void terminateThreadGroup() {
196: ClassLoader classLoader = Thread.currentThread()
197: .getContextClassLoader();
198: LoaderThreadGroupManager loaderThreadGroupManager = null;
199: synchronized (managedGroups) {
200: if (!managedGroups.containsKey(classLoader)) {
201: return;
202: }
203: loaderThreadGroupManager = (LoaderThreadGroupManager) managedGroups
204: .get(classLoader);
205: managedGroups.remove(classLoader);
206: }
207: loaderThreadGroupManager.terminate();
208: }
209:
210: /**
211: * This method returns the reference to the thread group
212: */
213: public void addThreadToGroup(BasicThread thread, String username)
214: throws ThreadException, Exception {
215: Validator.validate(ThreadGroupManager.class, role);
216: ClassLoader classLoader = Thread.currentThread()
217: .getContextClassLoader();
218: LoaderThreadGroupManager loaderThreadGroupManager = null;
219: synchronized (managedGroups) {
220: if (!managedGroups.containsKey(classLoader)) {
221: return;
222: }
223: loaderThreadGroupManager = (LoaderThreadGroupManager) managedGroups
224: .get(classLoader);
225: }
226: loaderThreadGroupManager.getCoadThreadGroup().addThread(thread,
227: username);
228: }
229: }
|