1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package de.bea.domingo.proxy;
24
25 import de.bea.domingo.DNotesException;
26 import de.bea.domingo.DNotesFactory;
27 import de.bea.domingo.DNotesMonitor;
28 import de.bea.domingo.monitor.NullMonitor;
29
30 /***
31 * The NotesThread class extends java.lang.Thread to include special
32 * initialization and termination code for Domino.
33 *
34 * <p>This extension to Thread is required to run Java programs that make local
35 * calls to the Domino classes, but is not allowed for applications that make
36 * remote calls. An application that makes both local and remote calls must
37 * determine dynamically when to use the static methods sinitThread and
38 * stermThread. This includes threads invoked by AWT that access Domino objects.</p>
39 *
40 * <p>To execute threads through the Runnable interface, implement Runnable and
41 * include a run method as you would for any class using threads.</p>
42 *
43 * <p>To execute threads through inheritance, extend NotesThread instead of
44 * Thread and include a runNotes method instead of run.</p>
45 *
46 * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
47 */
48 public class DNotesThread extends Thread {
49
50 /*** Indicates whether an instance is initialized. */
51 private boolean initialized = false;
52
53 /*** Reference to optional associated Runnable. */
54 private Runnable target = null;
55
56 /*** Base Monitor instance. */
57 private DNotesMonitor monitor = NullMonitor.getInstance();
58
59 /***
60 * Allocates a new <code>DNotesThread</code> object. This constructor has
61 * the same effect as <code>DNotesThread(null, null,</code>
62 * <i>name</i><code>)</code>, where <b><i>name</i></b> is
63 * a newly generated name. Automatically generated names are of the
64 * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
65 *
66 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
67 */
68 public DNotesThread() {
69 super();
70 setDaemon(true);
71 }
72
73 /***
74 * Allocates a new <code>Thread</code> object. This constructor has the
75 * same effect as <code>Thread(null, null, name)</code>.
76 *
77 * @param name the name of the new thread.
78 *
79 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
80 */
81 public DNotesThread(final String name) {
82 super(name);
83 setDaemon(true);
84 }
85
86 /***
87 * Allocates a new <code>DNotesThread</code> object. This constructor has
88 * the same effect as <code>DNotesThread(null, target,</code> <i>name</i><code>)</code>,
89 * where <i>name</i> is a newly generated name. Automatically generated
90 * names are of the form <code>"Thread-"+</code><i>n</i>, where <i>n</i>
91 * is an integer.
92 *
93 * @param theTarget the object whose <code>run</code> method is called.
94 *
95 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
96 */
97 public DNotesThread(final Runnable theTarget) {
98 super();
99 this.target = theTarget;
100 setDaemon(true);
101 }
102
103 /***
104 * Allocates a new <code>DNotesThread</code> object. This constructor has
105 * the same effect as <code>DNotesThread(group, target,</code> <i>name</i><code>)</code>,
106 * where <i>name</i> is a newly generated name. Automatically generated
107 * names are of the form <code>"Thread-"+</code><i>n</i>, where <i>n</i>
108 * is an integer.
109 *
110 * @param group the thread group.
111 * @param theTarget the object whose <code>run</code> method is called.
112 *
113 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
114 */
115 public DNotesThread(final ThreadGroup group, final Runnable theTarget) {
116 super(group, "domingo thread group");
117 this.target = theTarget;
118 setDaemon(true);
119 }
120
121 /***
122 * Allocates a new <code>DNotesThread</code> object. This constructor has
123 * the same effect as <code>DNotesThread(null, target, name)</code>.
124 *
125 * @param theTarget the object whose <code>run</code> method is called.
126 * @param name the name of the new thread.
127 *
128 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
129 */
130 public DNotesThread(final Runnable theTarget, final String name) {
131 super(name);
132 this.target = theTarget;
133 setDaemon(true);
134 }
135
136 /***
137 * Allocates a new <code>Thread</code> object. This constructor has the
138 * same effect as <code>Thread(null, target, name)</code>.
139 *
140 * @param group the thread group.
141 * @param name the name of the new thread.
142 *
143 * @see DNotesThread#DNotesThread(ThreadGroup, Runnable, String)
144 */
145 public DNotesThread(final ThreadGroup group, final String name) { super(group, name);
146 setDaemon(true);
147 }
148
149 /***
150 * Allocates a new <code>DNotesThread</code> object so that it has
151 * <code>target</code> as its run object, has the specified
152 * <code>name</code> as its name, and belongs to the thread group referred
153 * to by <code>group</code>. <p> If <code>group</code> is
154 * <code>null</code> and there is a security manager, the group is
155 * determined by the security manager's <code>getThreadGroup</code>
156 * method. If <code>group</code> is <code>null</code> and there is not a
157 * security manager, or the security manager's <code>getThreadGroup</code>
158 * method returns <code>null</code>, the group is set to be the same
159 * ThreadGroup as the thread that is creating the new thread.
160 *
161 * <p>If there is a security manager, its <code>checkAccess</code> method
162 * is called with the ThreadGroup as its argument. <p>In addition, its
163 * <code>checkPermission</code> method is called with the
164 * <code>RuntimePermission("enableContextClassLoaderOverride")</code>
165 * permission when invoked directly or indirectly by the constructor of a
166 * subclass which overrides the <code>getContextClassLoader</code> or
167 * <code>setContextClassLoader</code> methods. This may result in a
168 * SecurityException.</p>
169 *
170 * <p>If the <code>target</code> argument is not <code>null</code>,
171 * the <code>run</code> method of the <code>target</code> is called when
172 * this thread is started. If the target argument is <code>null</code>,
173 * this thread's <code>run</code> method is called when this thread is
174 * started. <p> The priority of the newly created thread is set equal to the
175 * priority of the thread creating it, that is, the currently running
176 * thread. The method <code>setPriority</code> may be used to change the
177 * priority to a new value.</p>
178 *
179 * <p>The newly created thread is initially marked as being a daemon
180 * thread.</p>
181 *
182 * @param group the thread group.
183 * @param theTarget the object whose <code>run</code> method is called.
184 * @param name the name of the new thread.
185 *
186 * @see java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
187 * java.lang.String)
188 */
189 public DNotesThread(final ThreadGroup group, final Runnable theTarget, final String name) {
190 super(group, name);
191 target = theTarget;
192 setDaemon(true);
193 }
194
195 /***
196 * Set the monitor.
197 *
198 * @param theMonitor the monitor
199 * @see de.bea.domingo.DNotesFactory#setMonitor(de.bea.domingo.DNotesMonitor)
200 */
201 public final void setMonitor(final DNotesMonitor theMonitor) {
202 this.monitor = theMonitor;
203 }
204
205 /***
206 * @see de.bea.domingo.proxy.DNotesThread#initThread()
207 */
208 protected final void initThread() {
209 if (!initialized) {
210 DNotesFactory.getInstance().sinitThread();
211 initialized = true;
212 }
213 try {
214 notifyAll();
215 } catch (RuntimeException e) {
216 monitor.error("Cannot initialize domingo thread", e);
217 }
218 }
219
220 /***
221 * @see de.bea.domingo.proxy.DNotesThread#termThread()
222 */
223 protected final void termThread() {
224 if (initialized) {
225 DNotesFactory.getInstance().stermThread();
226 initialized = false;
227 }
228 }
229
230 /***
231 * Runs a Notes process.
232 *
233 * @throws DNotesException if any error occurred in running the thread
234 */
235 public void runNotes() throws DNotesException {
236 }
237
238 /***
239 * @see java.lang.Runnable#run()
240 */
241 public final void run() {
242 try {
243 if (target != null) {
244 target.run();
245 } else {
246 runNotes();
247 }
248 } catch (Throwable e) {
249 monitor.error("Cannot run domingo thread", e);
250 }
251 }
252
253 /***
254 * @see java.lang.Object#finalize()
255 *
256 * @throws Throwable the <code>Exception</code> raised by this method
257 */
258 protected final void finalize() throws Throwable {
259 if (initialized) {
260 System.err.println("Thread not properly terminated.");
261 }
262 super.finalize();
263 }
264 }