KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > internal > Worker


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.compare.internal;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.jface.operation.IRunnableWithProgress;
19
20 /**
21  * A worker performs a set of tasks in order and accumulates any errors
22  * that may have occurred. If the same task is queued multiple times,
23  * the last occurrence will be run. If a task is queued while it is
24  * running, the running task will be canceled and the task added
25  * to the end of the work queue.
26  */

27 public class Worker implements IRunnableWithProgress {
28
29     private final WorkQueue work = new WorkQueue();
30     private boolean isWorking;
31     private final List JavaDoc errors = new ArrayList JavaDoc();
32     private WorkProgressMonitor currentMonitor;
33     private IRunnableWithProgress currentTask;
34     private final String JavaDoc taskName;
35     
36     /**
37      * Progress monitor that supports local cancelation of a task.
38      */

39     private static class WorkProgressMonitor extends ProgressMonitorWrapper {
40         private boolean localCancel;
41         protected WorkProgressMonitor(IProgressMonitor monitor) {
42             super(monitor);
43         }
44         public void cancelTask() {
45             localCancel = true;
46         }
47         public boolean isCanceled() {
48             return localCancel || super.isCanceled();
49         }
50     }
51     
52     public Worker(String JavaDoc taskName) {
53         this.taskName = taskName;
54     }
55     
56     public void run(IProgressMonitor monitor) {
57         errors.clear();
58         SubMonitor pm = SubMonitor.convert(monitor, getTaskName(), 100);
59         try {
60             isWorking = true;
61             while (!work.isEmpty()) {
62                 try {
63                     performNextTask(pm);
64                     checkCancelled(pm);
65                 } catch (OperationCanceledException e) {
66                     // Only cancel all the work if the outer monitor is canceled
67
checkCancelled(pm);
68                 } catch (InterruptedException JavaDoc e) {
69                     // Only cancel all the work if the outer monitor is canceled
70
checkCancelled(pm);
71                 } catch (InvocationTargetException JavaDoc e) {
72                     handleError(e.getTargetException());
73                 }
74                 pm.setWorkRemaining(100);
75             }
76         } catch (OperationCanceledException e) {
77             // The user chose to cancel
78
work.clear();
79         } finally {
80             isWorking = false;
81             if (monitor!= null)
82                 monitor.done();
83             currentMonitor = null;
84             currentTask = null;
85         }
86     }
87
88     private WorkProgressMonitor subMonitorFor(SubMonitor pm, int ticks) {
89         return new WorkProgressMonitor(pm.newChild(ticks));
90     }
91
92     private void handleError(Throwable JavaDoc targetException) {
93         errors.add(targetException);
94     }
95     
96     public Throwable JavaDoc[] getErrors() {
97         return (Throwable JavaDoc[]) errors.toArray(new Throwable JavaDoc[errors.size()]);
98     }
99
100     private void checkCancelled(SubMonitor pm) {
101         if (pm.isCanceled())
102             throw new OperationCanceledException();
103     }
104
105     protected String JavaDoc getTaskName() {
106         return taskName;
107     }
108
109     private void performNextTask(SubMonitor pm) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
110         synchronized (this) {
111             if (work.isEmpty())
112                 return;
113             currentTask = work.remove();
114         }
115         currentMonitor = subMonitorFor(pm, 10);
116         currentTask.run(currentMonitor);
117     }
118
119     public synchronized void add(IRunnableWithProgress r) {
120         if (currentTask != null && currentTask.equals(r)) {
121             currentMonitor.cancelTask();
122         }
123         work.add(r);
124     }
125
126     public boolean isWorking() {
127         return isWorking;
128     }
129
130     public boolean hasWork() {
131         return isWorking() || !work.isEmpty();
132     }
133
134 }
135
Popular Tags