View Javadoc

1   /*
2    * This file is part of Domingo
3    * an Open Source Java-API to Lotus Notes/Domino
4    * hosted at http://domingo.sourceforge.net
5    *
6    * Copyright (c) 2003-2007 Beck et al. projects GmbH Munich, Germany (http://www.bea.de)
7    *
8    * This library is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU Lesser General Public
10   * License as published by the Free Software Foundation; either
11   * version 2.1 of the License, or (at your option) any later version.
12   *
13   * This library is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   * Lesser General Public License for more details.
17   *
18   * You should have received a copy of the GNU Lesser General Public
19   * License along with this library; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 }