Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/virtuosotechnologies/lib/asyncjob/AbstractAsyncJobRunner.java


1   /*
2   ================================================================================
3   
4     FILE:  AbstractAsyncJobRunner.java
5     
6     PROJECT:
7     
8       Virtuoso Utilities
9     
10    CONTENTS:
11    
12      Abstract base class for AsyncJobRunner
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.lib.asyncjob;
43  
44  
45  import com.virtuosotechnologies.lib.util.EventBroadcastHelper;
46  
47  
48  /**
49   * Abstract base class for AsyncJobRunner
50   */
51  public abstract class AbstractAsyncJobRunner 
52  implements AsyncJobRunner
53  {
54    private EventBroadcastHelper broadcaster_;
55    
56    
57    /**
58     * Constructor
59     */
60    protected AbstractAsyncJobRunner()
61    {
62      broadcaster_ = new EventBroadcastHelper(AsyncJobListener.class);
63    }
64    
65    
66    /**
67     * Add a job listener.
68     *
69     * @param listener listener to add
70     */
71    public void addAsyncJobListener(
72      AsyncJobListener listener)
73    {
74      broadcaster_.addListenerWeak(listener);
75    }
76    
77    
78    /**
79     * Remove a job listener.
80     *
81     * @param listener listener to remove
82     */
83    public void removeAsyncJobListener(
84      AsyncJobListener listener)
85    {
86      broadcaster_.removeListener(listener);
87    }
88    
89    
90    /**
91     * Run a job synchronously
92     *
93     * @param execution job to run
94     */
95    protected void runJobSynchronously(
96      final ExecutionImpl execution)
97    {
98      if (execution.isStarted())
99      {
100       throw new IllegalStateException("Can't reuse an ExecutionImpl.");
101     }
102     final AsyncJob job = execution.getAsyncJob();
103     AsyncJobStartedEvent sev = new AsyncJobStartedEvent(this, job, execution);
104     broadcaster_.fireEvent(AsyncJobListener.JOB_STARTED_METHOD, sev);
105     execution.start(sev);
106     try
107     {
108       Object result = job.run(
109         new AsyncJobProgressReporter()
110         {
111           public void updateProgress(
112             float fractionDone,
113             String progressString)
114           {
115             AsyncJobProgressEvent ev = new AsyncJobProgressEvent(
116               AbstractAsyncJobRunner.this, job,
117               fractionDone, progressString);
118             broadcaster_.fireEvent(
119               AsyncJobListener.JOB_PROGRESSED_METHOD, ev);
120             execution.update(ev);
121           }
122         });
123       AsyncJobCompletedEvent ev = new AsyncJobCompletedEvent(this, job, result);
124       broadcaster_.fireEvent(AsyncJobListener.JOB_COMPLETED_METHOD, ev);
125       execution.succeed(ev);
126     }
127     catch (AsyncJobException ex)
128     {
129       AsyncJobFailedEvent ev = new AsyncJobFailedEvent(this, job, ex);
130       broadcaster_.fireEvent(AsyncJobListener.JOB_FAILED_METHOD, ev);
131       execution.fail(ev);
132     }
133     catch (Throwable th)
134     {
135       AsyncJobException ex = new AsyncJobException(th);
136       AsyncJobFailedEvent ev = new AsyncJobFailedEvent(this, job, ex);
137       broadcaster_.fireEvent(AsyncJobListener.JOB_FAILED_METHOD, ev);
138       execution.fail(ev);
139       if (th instanceof Error || th instanceof RuntimeException)
140       {
141         th.printStackTrace();
142       }
143     }
144   }
145   
146   
147   /**
148    * Execution tracker implementation
149    */
150   protected class ExecutionImpl
151   implements AsyncJobExecution
152   {
153     private AsyncJob job_;
154     private EventBroadcastHelper broadcaster_;
155     private boolean started_;
156     private boolean finished_;
157     private Object result_;
158     private AsyncJobException exception_;
159     
160     
161     /**
162      * Subclass-visible constructor
163      */
164     protected ExecutionImpl(
165       AsyncJob job)
166     {
167       job_ = job;
168       broadcaster_ = new EventBroadcastHelper(AsyncJobListener.class);
169       finished_ = false;
170       result_ = null;
171       exception_ = null;
172     }
173     
174     
175     /**
176      * Get the runner running this job
177      *
178      * @return the AsyncJobRunner
179      */
180     public AsyncJobRunner getAsyncJobRunner()
181     {
182       return AbstractAsyncJobRunner.this;
183     }
184     
185     
186     /**
187      * Get the job being run
188      *
189      * @return the AsyncJob
190      */
191     public AsyncJob getAsyncJob()
192     {
193       return job_;
194     }
195     
196     
197     /**
198      * Wait until the job is finished.
199      *
200      * @return true if the job succeeded, false if it failed
201      */
202     public synchronized boolean waitForCompletion()
203     throws
204       InterruptedException
205     {
206       if (!finished_)
207       {
208         wait();
209       }
210       return exception_ == null;
211     }
212     
213     
214     /**
215      * Has the job started yet?
216      *
217      * @return true if the job has started
218      */
219     public boolean isStarted()
220     {
221       return started_;
222     }
223     
224     
225     /**
226      * Has the job finished yet?
227      *
228      * @return true if the job has finished
229      */
230     public synchronized boolean isFinished()
231     {
232       return finished_;
233     }
234     
235     
236     /**
237      * Get the job result value.
238      *
239      * @return the result value (which may be null) or null if the job is
240      *    not finished or failed.
241      */
242     public synchronized Object getResult()
243     {
244       return result_;
245     }
246     
247     
248     /**
249      * Get the job failure exception.
250      *
251      * @return the exception with which the job failed, or null if the job is
252      *    not finished or did not fail.
253      */
254     public synchronized AsyncJobException getException()
255     {
256       return exception_;
257     }
258     
259     
260     /**
261      * Add an execution listener.
262      *
263      * @param listener listener to add
264      */
265     public void addAsyncJobListener(
266       AsyncJobListener listener)
267     {
268       broadcaster_.addListenerWeak(listener);
269     }
270     
271     
272     /**
273      * Remove an execution listener.
274      *
275      * @param listener listener to remove
276      */
277     public void removeAsyncJobListener(
278       AsyncJobListener listener)
279     {
280       broadcaster_.removeListener(listener);
281     }
282     
283     
284     private void start(
285       AsyncJobStartedEvent ev)
286     {
287       synchronized(this)
288       {
289         started_ = true;
290       }
291       broadcaster_.fireEvent(AsyncJobListener.JOB_STARTED_METHOD, ev);
292     }
293     
294     
295     private void update(
296       AsyncJobProgressEvent ev)
297     {
298       broadcaster_.fireEvent(AsyncJobListener.JOB_PROGRESSED_METHOD, ev);
299     }
300     
301     
302     private void succeed(
303       AsyncJobCompletedEvent ev)
304     {
305       synchronized(this)
306       {
307         result_ = ev.getResult();
308         finished_ = true;
309         notifyAll();
310       }
311       broadcaster_.fireEvent(AsyncJobListener.JOB_COMPLETED_METHOD, ev);
312     }
313     
314     
315     private void fail(
316       AsyncJobFailedEvent ev)
317     {
318       synchronized(this)
319       {
320         result_ = ev.getException();
321         finished_ = true;
322         notifyAll();
323       }
324       broadcaster_.fireEvent(AsyncJobListener.JOB_FAILED_METHOD, ev);
325     }
326   }
327 }