1 /*
2 * SSHTools - Java SSH2 API
3 *
4 * Copyright (C) 2002-2003 Lee David Painter and Contributors.
5 *
6 * Contributions made by:
7 *
8 * Brett Smith
9 * Richard Pernavas
10 * Erwin Bolwidt
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26 package com.sshtools.j2ssh;
27
28 import com.sshtools.j2ssh.configuration.ConfigurationLoader;
29
30 import java.util.HashMap;
31
32
33 /**
34 * <p>
35 * Enables the J2SSH application framework to execute threads in the context of
36 * a given session.
37 * </p>
38 *
39 * @author Lee David Painter
40 * @version $Revision: 1.25 $
41 *
42 * @since 0.2.0
43 */
44 public class SshThread extends Thread {
45 private static HashMap names = new HashMap();
46
47 /** The raw session id generating during the first key exchange. */
48 protected byte[] sessionId;
49
50 /** A string representation of the session id. */
51 protected String sessionIdString = null;
52
53 /** The thread owner */
54 protected String username;
55
56 /** The thread properties */
57 private HashMap settings = new HashMap();
58
59 /**
60 * <p>
61 * Constructs an SshThread.
62 * </p>
63 *
64 * @param target The target to execute
65 * @param name The name of the thread
66 * @param daemon run as a daemon thread?
67 *
68 * @since 0.2.0
69 */
70 public SshThread(Runnable target, String name, boolean daemon) {
71 super(target);
72 setProperties(name, daemon);
73 }
74
75 public SshThread(String name, boolean daemon) {
76 setProperties(name, daemon);
77 }
78
79 private void setProperties(String name, boolean daemon) {
80 Integer i;
81
82 if (names.containsKey(name)) {
83 i = new Integer(((Integer) names.get(name)).intValue() + 1);
84 } else {
85 i = new Integer(1);
86 }
87
88 names.put(name, i);
89 setName(name + " " + Integer.toHexString(i.intValue() & 0xFF));
90 setDaemon(daemon);
91
92 if (ConfigurationLoader.isContextClassLoader()) {
93 setContextClassLoader(ConfigurationLoader.getContextClassLoader());
94 }
95 }
96
97 /**
98 * <p>
99 * Sets the session id for this thread.
100 * </p>
101 *
102 * @param sessionId the session id created during the first key exchange.
103 *
104 * @since 0.2.0
105 */
106 public void setSessionId(byte[] sessionId) {
107 if (sessionId != null) {
108 this.sessionId = new byte[sessionId.length];
109 System.arraycopy(sessionId, 0, this.sessionId, 0, sessionId.length);
110 sessionIdString = String.valueOf(new String(sessionId).hashCode() &
111 0xFFFFFFFFL);
112 }
113 }
114
115 /**
116 * <p>
117 * Returns the session id string for this thread.
118 * </p>
119 *
120 * @return a string representation of the session id
121 *
122 * @since 0.2.0
123 */
124 public String getSessionIdString() {
125 return sessionIdString;
126 }
127
128 /**
129 * <p>
130 * Set the username for this thread.
131 * </p>
132 *
133 * @param username the thread owner
134 *
135 * @since 0.2.0
136 */
137 public void setUsername(String username) {
138 this.username = username;
139 }
140
141 /**
142 * <p>
143 * Gets the username for this thread.
144 * </p>
145 *
146 * @return the thread owner
147 *
148 * @since 0.2.0
149 */
150 public String getUsername() {
151 return username;
152 }
153
154 /**
155 * <p>
156 * Create's a cloned copy of this thread with the given target and name.
157 * </p>
158 *
159 * @param target the target to execute
160 * @param name the thread name
161 *
162 * @return the cloned thread
163 *
164 * @since 0.2.0
165 */
166 public SshThread cloneThread(Runnable target, String name) {
167 SshThread thread = new SshThread(target, name, isDaemon());
168 thread.setSessionId(sessionId);
169 thread.setUsername(username);
170 thread.settings.putAll(settings);
171
172 return thread;
173 }
174
175 /**
176 * <p>
177 * Sets a property in the thread.
178 * </p>
179 *
180 * @param name the name of the property
181 * @param value the property value
182 *
183 * @since 0.2.0
184 */
185 public void setProperty(String name, Object value) {
186 settings.put(name, value);
187 }
188
189 /**
190 * <p>
191 * Gets a property from this thread.
192 * </p>
193 *
194 * @param name the name of the property
195 *
196 * @return the property value
197 *
198 * @since 0.2.0
199 */
200 public Object getProperty(String name) {
201 return settings.get(name);
202 }
203
204 /**
205 * <p>
206 * Determine if this thread contains the given property.
207 * </p>
208 *
209 * @param name the name of the property
210 *
211 * @return true if the property exists, otherwise false
212 *
213 * @since 0.2.0
214 */
215 public boolean containsProperty(String name) {
216 return settings.containsKey(name);
217 }
218
219 /**
220 * <p>
221 * Call to determine the username of the current thread context.
222 * </p>
223 *
224 * <p>
225 * This should be called when the caller is certain that the current thread
226 * is running in an <code>SshThread</code> context. If not a runtime
227 * exception is thrown.
228 * </p>
229 *
230 * @return the owner of the current thread
231 *
232 * @throws SshRuntimeException if the current thread is not an
233 * <code>SshThread</code>
234 *
235 * @since 0.2.0
236 */
237 public static String getCurrentThreadUser() throws SshRuntimeException {
238 String username;
239
240 if (Thread.currentThread() instanceof SshThread) {
241 return ((SshThread) Thread.currentThread()).getUsername();
242 } else {
243 throw new SshRuntimeException(
244 "The current thread is not running within an SshThread context");
245 }
246 }
247
248 public static boolean hasUserContext() {
249 if (Thread.currentThread() instanceof SshThread) {
250 return ((SshThread) Thread.currentThread()).getUsername() != null;
251 } else {
252 throw new SshRuntimeException(
253 "The current thread is not running within an SshThread context");
254 }
255 }
256
257 /**
258 * <p>
259 * Returns the session id of the current thread context.
260 * </p>
261 *
262 * <p>
263 * This should be called when the caller is certain that the current thread
264 * is running in an <code>SshThread</code> context. If not a Runtime
265 * exception is thrown.
266 * </p>
267 *
268 * @return the session id of the current thread
269 *
270 * @throws SshRuntimeException if the current thread is not an
271 * <code>SshThread</code>
272 *
273 * @since 0.2.0
274 */
275 public static String getCurrentSessionId() throws SshRuntimeException {
276 String username;
277
278 if (Thread.currentThread() instanceof SshThread) {
279 return ((SshThread) Thread.currentThread()).getSessionIdString();
280 } else {
281 throw new SshRuntimeException(
282 "The current thread is not running within an SshThread context");
283 }
284 }
285
286 /**
287 * <p>
288 * Returns the current <code>SshThread</code>.
289 * </p>
290 *
291 * <p>
292 * This should be called when the caller is certain that the current thread
293 * is running in an <code>SshThread</code> context. If not a Runtime
294 * exception is thrown.
295 * </p>
296 *
297 * @return the current <code>SshThread</code>
298 *
299 * @throws SshRuntimeException if the current thread is not an
300 * <code>SshThread</code>
301 *
302 * @since 0.2.0
303 */
304 public static SshThread getCurrentThread() throws SshRuntimeException {
305 if (Thread.currentThread() instanceof SshThread) {
306 return (SshThread) Thread.currentThread();
307 } else {
308 throw new SshRuntimeException(
309 "The current thread is not an SshThread");
310 }
311 }
312 }