1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.jhylafax;
21
22 import static net.sf.jhylafax.JHylaFAX.i18n;
23 import java.lang.reflect.InvocationTargetException;
24 import java.util.LinkedList;
25 import javax.swing.JDialog;
26 import javax.swing.SwingUtilities;
27 import org.xnap.commons.gui.ProgressDialog;
28 import org.xnap.commons.io.Job;
29 import org.xnap.commons.io.UserAbortProgressMonitor;
30
31 public class JobQueue {
32
33 private boolean jobRunning = false;
34 private long lastUpdate;
35 private LinkedList<Notification> notificationQueue = new LinkedList<Notification>();
36
37 @SuppressWarnings("unchecked")
38 public <T> T runJob(JDialog owner, final Job<T> job) throws Exception {
39 if (jobRunning) {
40 throw new RuntimeException("Concurrent job invocation");
41 }
42
43 final Object[] retSuccess = new Object[1];
44 final Throwable[] ret = new Exception[1];
45 final ProgressDialog dialog;
46
47 if (owner != null) { dialog = new ProgressDialog(owner); }
48 else { dialog = new ProgressDialog(JHylaFAX.getInstance()); }
49
50 Runnable runner = new Runnable() {
51 public void run()
52 {
53 try {
54 retSuccess[0] = job.run(new UserAbortProgressMonitor(dialog));
55 }
56 catch (Throwable e) {
57 ret[0] = e;
58 }
59 SwingUtilities.invokeLater(new Runnable() {
60 public void run() {
61 dialog.done();
62 }
63 });
64 }
65 };
66
67
68 jobRunning = true;
69
70 Thread t = new Thread(runner, "Job");
71 t.start();
72
73
74 if (owner != null) { dialog.setLocationRelativeTo(owner); }
75 else { dialog.setLocationRelativeTo(JHylaFAX.getInstance()); }
76 dialog.setTitle(i18n.tr("HylaFAX Server"));
77 dialog.setModal(true);
78 dialog.showDialog();
79
80
81 jobRunning = false;
82
83
84 processNotifications();
85
86 if (ret[0] != null) {
87 if (ret[0] instanceof Exception) {
88 throw (Exception)ret[0];
89 }
90 else {
91 throw new InvocationTargetException(ret[0]);
92 }
93 }
94 return (T)retSuccess[0];
95 }
96
97 public void setLastUpdate(long lastUpdate)
98 {
99 this.lastUpdate = lastUpdate;
100 }
101
102 public boolean isJobRunning()
103 {
104 return jobRunning;
105 }
106
107 public void addNotification(final Notification notification)
108 {
109 SwingUtilities.invokeLater(new Runnable() {
110 public void run()
111 {
112 if (isJobRunning()) {
113 addNotificationInternal(notification);
114 }
115 else {
116 runNotification(notification);
117 }
118 }
119 });
120 }
121
122 protected void runNotification(Notification notification)
123 {
124 notification.run();
125 }
126
127 private void addNotificationInternal(Notification notification)
128 {
129 notificationQueue.add(notification);
130 }
131
132 private void processNotifications()
133 {
134 if (isJobRunning()) {
135 throw new IllegalStateException();
136 }
137
138 while (!notificationQueue.isEmpty()) {
139 Notification notification = notificationQueue.removeFirst();
140 runNotification(notification);
141 }
142 }
143
144 }