001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)WorkThread.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.engine.xslt.framework;
030:
031: import java.util.logging.Logger;
032: import com.sun.jbi.engine.xslt.TransformationEngineContext;
033:
034: /**
035: * This class executes the command in its thread. The class is always a part of
036: * a threadpool and cannot exist on its own.
037: *
038: * @author Sun Microsystems, Inc.
039: */
040: class WorkThread implements Runnable {
041: /**
042: * Default Thread sleep time in milliseconds.
043: */
044: private static final int DEFAULT_THREAD_SLEEP_TIME = 100;
045:
046: /**
047: * Thread sleep time in milliseconds.
048: */
049: private static int sThreadSleeptime = DEFAULT_THREAD_SLEEP_TIME;
050:
051: /**
052: * Container for holding the command to be executed in this thread.
053: */
054: private Command mCurrentCommand;
055:
056: /**
057: * Internal handle to the logger instance.
058: */
059: private Logger mLog;
060:
061: /**
062: * Flag to hold the state of the Thread. Valid states are "INIT", "READY",
063: * "PROCESS" and "STOP"
064: */
065: private String mState;
066:
067: /**
068: * Internal handle to the thread in which this runnable object is running.
069: */
070: private Thread mThread;
071:
072: /**
073: * Internal handle to WorkThreadPool.
074: */
075: private WorkThreadPool mThreadPool;
076:
077: /**
078: * A flag which indicates whether the thread should continue processing or
079: * not.
080: */
081: private boolean mContinue;
082:
083: /**
084: * Creates a new instance of WorkThread.
085: *
086: * @param workThreadPool - worker thread pool parent
087: */
088: WorkThread(WorkThreadPool workThreadPool) {
089: mThreadPool = workThreadPool;
090: mLog = TransformationEngineContext.getInstance().getLogger("");
091: setState("INIT");
092: }
093:
094: /**
095: * Sets the log file.
096: *
097: * @param logFile log file.
098: */
099: public void setLogger(String logFile) {
100: mLog = mLog.getLogger(logFile);
101: }
102:
103: /**
104: * Gets the thread name
105: *
106: * @return thread name.
107: */
108: public String getName() {
109: return mThread.getName();
110: }
111:
112: /**
113: * Sets the sleep time for the thread.
114: *
115: * @param time in millieseconds
116: */
117: public void setSleepTime(int time) {
118: sThreadSleeptime = time;
119: }
120:
121: /**
122: * The method polls the container for a new work when the thread is ready
123: * to do work. This is indicated by the method doWork(). If there is new
124: * work, it processes the command in its thread. Once the command has been
125: * processed, it clears its work container and notifies the thread pool
126: * that it is now free. The method will clean up the thread and shut
127: * itself down when its state is set to "STOP".
128: */
129: public void run() {
130: mThread = Thread.currentThread();
131: mLog.info("Running thread " + mThread.getName());
132: mContinue = true;
133:
134: while (mContinue) {
135: if (isWorkAssigned()) {
136: try {
137: processCommand();
138: } catch (Throwable th) {
139: mLog.info("The command failed to execute");
140: th.printStackTrace();
141: }
142:
143: clearCommand();
144: mThreadPool.releaseThread(this );
145: }
146:
147: try {
148: Thread.sleep(sThreadSleeptime);
149: } catch (InterruptedException interruptException) {
150: // someone must have interrupted this thread
151: // do nothing
152: mLog.info("Received an interrupt signal in "
153: + mThread.getName());
154: }
155: }
156:
157: mLog.info("Thread " + mThread.getName() + " has been stopped");
158:
159: }
160:
161: /**
162: * Assigns the command to this thread.
163: *
164: * @param command - command instance.
165: */
166: synchronized void setCommand(Command command) {
167: if (mCurrentCommand == null) {
168: mCurrentCommand = command;
169: }
170: }
171:
172: /**
173: * Gets the command associated with this thread.
174: *
175: * @return the command associated with the thread
176: */
177: synchronized Command getCommand() {
178: return mCurrentCommand;
179: }
180:
181: /**
182: * Sets the State of the Worker Thread.
183: *
184: * @param state - worker thread state.
185: */
186: void setState(String state) {
187: mState = state;
188: }
189:
190: /**
191: * Returns the State of the Worker Thread.
192: *
193: * @return mState - worker thread state.
194: */
195: public String getState() {
196: return mState;
197: }
198:
199: /**
200: * Returns a boolean indicating if work has been assigned to this thread.
201: *
202: * @return true if work has been allocated to this thread; otherwise false.
203: */
204: synchronized boolean isWorkAssigned() {
205: return (mCurrentCommand != null);
206: }
207:
208: /**
209: * Clears the command associated with the thread.
210: */
211: void clearCommand() {
212: mCurrentCommand = null;
213: }
214:
215: /**
216: * Processes the command in this thread.
217: */
218: void processCommand() {
219: mCurrentCommand.execute();
220: }
221:
222: /**
223: * Stops the worker thread.
224: *
225: * @throws IllegalStateException DOCUMENT ME!
226: */
227: void stop() {
228: if (mContinue) {
229: mLog.fine("Shutting down thread " + getName());
230: mContinue = false;
231:
232: try {
233: // Interrupt the thread so that it can shutdown quickly
234: // This will also enable the command implementation to cleanup quickly.
235: mThread.interrupt();
236: } catch (SecurityException securityException) {
237: mLog.warning("Could not interrupt thread");
238: mLog.warning("Details : "
239: + securityException.toString());
240: }
241:
242: try {
243: //Wait for the thread to stop
244: mThread.join();
245: } catch (InterruptedException exp) {
246: // do nothing
247: }
248: mThread = null;
249: } else {
250: throw new IllegalStateException("Thread is not running");
251: }
252: }
253: }
|