KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > foxtrot > Task


1 /**
2  * Copyright (c) 2002-2005, Simone Bordet
3  * All rights reserved.
4  *
5  * This software is distributable under the BSD license.
6  * See the terms of the BSD license in the documentation provided with this software.
7  */

8
9 package foxtrot;
10
11 import java.security.AccessControlContext JavaDoc;
12 import java.security.AccessController JavaDoc;
13
14 import javax.swing.SwingUtilities JavaDoc;
15
16 /**
17  * A time-consuming task to be executed in the Worker Thread that may throw checked exceptions. <br />
18  * Users must implement the {@link #run} method with the time-consuming code, and not worry about
19  * exceptions, for example:
20  * <pre>
21  * Task task = new Task()
22  * {
23  * public Object run() throws InterruptedException
24  * {
25  * Thread.sleep(10000);
26  * return null;
27  * }
28  * };
29  * </pre>
30  * Exceptions and Errors thrown by the <code>run()</code> method will be rethrown automatically by
31  * {@link Worker#post(Task)} or by {@link ConcurrentWorker#post(Task)}
32  * @see Worker
33  * @see ConcurrentWorker
34  * @version $Revision: 1.13 $
35  */

36 public abstract class Task
37 {
38    private Object JavaDoc result;
39    private Throwable JavaDoc throwable;
40    private boolean completed;
41    private AccessControlContext JavaDoc securityContext;
42
43    /**
44     * Creates a new Task.
45     */

46    protected Task()
47    {
48       securityContext = AccessController.getContext();
49    }
50
51    /**
52     * The method to implement with time-consuming code.
53     * It should NOT be synchronized or synchronize on this Task instance, otherwise the AWT Event Dispatch Thread
54     * cannot efficiently test when this Task is completed.
55     */

56    public abstract Object JavaDoc run() throws Exception JavaDoc;
57
58    /**
59     * Returns the result of this Task operation, as set by {@link #setResult}.
60     * If an exception or an error is thrown by {@link #run}, it is rethrown here.
61     * Synchronized since the variables are accessed from 2 threads
62     * Accessed from the AWT Event Dispatch Thread.
63     * @see #setResult
64     * @see #setThrowable
65     */

66    protected final synchronized Object JavaDoc getResultOrThrow() throws Exception JavaDoc
67    {
68       Throwable JavaDoc t = getThrowable();
69       if (t != null)
70       {
71          if (t instanceof Exception JavaDoc)
72             throw (Exception JavaDoc)t;
73          else
74             throw (Error JavaDoc)t;
75       }
76       return getResult();
77    }
78
79    /**
80     * Returns the result of this Task operation, as set by {@link #setResult}.
81     * Synchronized since the variable is accessed from 2 threads
82     * Accessed from the AWT Event Dispatch Thread.
83     * @see #getResultOrThrow
84     */

85    private final synchronized Object JavaDoc getResult()
86    {
87       return result;
88    }
89
90    /**
91     * Sets the result of this Task operation, as returned by the {@link #run} method.
92     * Synchronized since the variable is accessed from 2 threads
93     * Accessed from the worker thread.
94     * Package protected, used by {@link AbstractWorkerThread}
95     * @see #getResultOrThrow
96     * @see #getResult
97     */

98    final synchronized void setResult(Object JavaDoc result)
99    {
100       this.result = result;
101    }
102
103    /**
104     * Returns the throwable as set by {@link #setThrowable}.
105     * Synchronized since the variable is accessed from 2 threads
106     * Accessed from the AWT Event Dispatch Thread.
107     */

108    final synchronized Throwable JavaDoc getThrowable()
109    {
110       return throwable;
111    }
112
113    /**
114     * Sets the throwable eventually thrown by the {@link #run} method.
115     * Synchronized since the variable is accessed from 2 threads
116     * Accessed from the worker thread.
117     * Package protected, used by {@link AbstractWorkerThread}
118     * @see #getThrowable
119     */

120    final synchronized void setThrowable(Throwable JavaDoc x)
121    {
122       throwable = x;
123    }
124
125    /**
126     * Returns whether the execution of this Task has been completed or not.
127     */

128    public final synchronized boolean isCompleted()
129    {
130       // Synchronized since the variable is accessed from 2 threads
131
// Accessed from the AWT Event Dispatch Thread.
132
return completed;
133    }
134
135    /**
136     * Sets the completion status of this Task.
137     * Synchronized since the variable is accessed from 2 threads.
138     * Accessed from the worker thread and from the AWT Event Dispatch Thread.
139     * Package protected, used by {@link AbstractWorkerThread}
140     * @see #isCompleted
141     */

142    final synchronized void setCompleted(boolean value)
143    {
144       completed = value;
145       if (value) notifyAll();
146    }
147
148    /**
149     * Returns the protection domain stack at the moment of instantiation of this Task.
150     * Synchronized since the variable is accessed from 2 threads
151     * Accessed from the worker thread.
152     * Package protected, used by {@link AbstractWorkerThread}
153     * @see #Task
154     */

155    final synchronized AccessControlContext JavaDoc getSecurityContext()
156    {
157       return securityContext;
158    }
159
160    /**
161     * Resets the internal status of this Task, that can be therefore be reused.
162     * Synchronized since the variables are accessed from 2 threads
163     * Accessed from the AWT Event Dispatch Thread.
164     * Package protected, used by Worker
165     * @see #isCompleted
166     */

167    final synchronized void reset()
168    {
169       setResult(null);
170       setThrowable(null);
171       setCompleted(false);
172    }
173
174    /**
175     * Callback invoked from the worker thread to perform some operation just after the Task
176     * has been {@link #isCompleted completed}.
177     */

178    void postRun()
179    {
180       // Needed in case that no events are posted on the AWT Event Queue
181
// via the normal mechanisms (mouse movements, key typing, etc):
182
// the AWT Event Queue is waiting in EventQueue.getNextEvent(),
183
// posting this one will wake it up and allow the event pump to
184
// finish its job and release control to the original pump
185
SwingUtilities.invokeLater(new Runnable JavaDoc()
186       {
187          public final void run()
188          {
189             if (AbstractWorker.debug) System.out.println("[Task] Run completed for task " + Task.this);
190          }
191       });
192    }
193 }
194
Popular Tags