source: main/trunk/gli/src/org/greenstone/gatherer/download/DownloadScrollPane.java@ 31878

Last change on this file since 31878 was 31822, checked in by ak19, 7 years ago

Bugfix to GLI's download pane: when having multiple download jobs queued, if you closed/stopped anything but the running job, the deleted job's would not react: the display would remain and it would still be queued. The problem was because queued jobs' states are always set to Running by DownloadScrollPane, and so the hasSignalledStop() returned false when testing if it could be deleted since nothing set it to the STOPPED state. Have now fixed this behaviour.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.download;
38
39import java.awt.*;
40import java.io.*;
41import java.net.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.tree.*;
45import org.greenstone.gatherer.*;
46import org.greenstone.gatherer.util.SafeProcess;
47
48/** This class provides access to the functionality of the WGet program, either by calling it via a shell script or by the JNI. It maintains a queue of pending jobs, and the component for showing these tasks to the user.
49 * @author John Thompson, Greenstone Digital Library, University of Waikato
50 * @version 2.3
51 */
52public class DownloadScrollPane
53 extends Thread {
54
55 /** <i>true</i> if verbose debug messages should be displayed, <i>false</i> otherwise. */
56 private boolean debug = false;
57 /** <i>true</i> if successfully completed tasks should be automatically removed from the job queue. */
58 private boolean remove_complete_jobs = true;
59
60 private JPanel filler_pane = null;
61 /** The panel that the task list will be shown in. */
62 private JPanel list_pane;
63 /** The job currently underway. */
64 private DownloadJob job;
65 /** A scroll pane which will be used to display the list of pending tasks. */
66 private JScrollPane list_scroll;
67 /** A queue of download tasks. */
68 private Vector job_queue;
69 static final private boolean simple = true;
70
71
72 public DownloadScrollPane() {
73 job = null;
74 job_queue = new Vector();
75 filler_pane = new JPanel();
76 list_pane = new JPanel();
77 list_pane.setLayout(new BoxLayout(list_pane, BoxLayout.Y_AXIS));
78 list_scroll = new JScrollPane(list_pane);
79 }
80
81 /**
82 * To be used with DownloadJob.java's old_callDownload() and old_actionPerformed()
83 * OR by uncommenting the "synchronized(this)" section in Download.java at the end of
84 * its new callDownload() along with commenting out "mummy.deleteCurrentDownloadJob(this);"
85 * in Download.java's doneCleanup().
86 */
87 public void old_deleteDownloadJob(DownloadJob delete_me) {
88 if (delete_me == job) {
89 try {
90 // Wait for the job to finish cleaning up, before we can continue cleaning up here.
91 // But sometimes the job has completed (terminated naturally) and in that case there's
92 // nothing to wait for.
93 synchronized(delete_me) {
94 if (!delete_me.hasSignalledStop()) { // don't wait if DownloadJob.COMPLETED
95 ///SafeProcess.log("**************** download scrollpane waiting for downloadjob to stop");
96 delete_me.wait();
97 }
98 }
99 } catch (Exception e) {
100 e.printStackTrace();
101 }
102 }
103
104 ///System.err.println("**************** Deleting job from download scroll pane");
105 // Close button pressed, get rid of this download's dedicated pane
106 finishedDownloadJob(delete_me, true);
107 }
108
109 /**
110 * If called to delete the current download job, this method won't do anything.
111 * But if called on any inactive download job, its display is removed.
112 */
113 public void deleteDownloadJob(DownloadJob delete_me) {
114 if (delete_me != job) {
115
116 delete_me.setState(DownloadJob.STOPPED); // it's not the current job, so not running any SafeProcess, so don't need to send interrupt, just set state to stopped
117 SafeProcess.log("**************** Deleting job from download scroll pane");
118 // Close button pressed, get rid of this download's dedicated pane
119 finishedDownloadJob(delete_me, true);
120 } // else don't do anything, we'll be contacted again when the current job can be deleted
121
122 }
123
124 /**
125 * To be called when we're ready to delete the current download job,
126 * else this method won't do anything
127 */
128 public void deleteCurrentDownloadJob(DownloadJob delete_me) {
129 if (delete_me == job) {
130 SafeProcess.log("**************** Deleting current job from download scroll pane");
131 // Close button pressed, get rid of this download's dedicated pane
132 finishedDownloadJob(delete_me, true);
133 }
134 }
135
136
137 /** To be called when a download job has terminated naturally or was prematurely stopped
138 * via the close button.
139 * Gets rid of this download's pane with buttons and progress bar if prematurely stopped. */
140 protected void finishedDownloadJob(DownloadJob delete_me, boolean removeDisplay) {
141 if (delete_me.hasSignalledStop()) {
142 if(removeDisplay) {
143 list_pane.remove(delete_me.getProgressBar());
144 list_pane.remove(filler_pane);
145 }
146 job_queue.remove(delete_me);
147 if(job_queue.size() > 0) {
148 Dimension progress_bar_size = delete_me.getProgressBar().getPreferredSize();
149 Dimension list_pane_size = list_pane.getSize();
150 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
151 progress_bar_size = null;
152 if(height > 0) {
153 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
154 list_pane.add(filler_pane);
155 }
156 list_pane_size = null;
157 }
158 list_pane.updateUI();
159 }
160 else {
161 DebugStream.println("Somehow we're trying to delete a job that is still running.");
162 }
163 }
164
165 public synchronized void downloadComplete() {
166 job.downloadComplete();
167 }
168
169 public synchronized void downloadFailed() {
170 job.downloadFailed();
171 }
172
173 public synchronized void downloadWarning() {
174 job.downloadWarning();
175 }
176
177 public JScrollPane getDownloadJobList() {
178 return list_scroll;
179 }
180
181 public synchronized boolean hasSignalledStop() {
182 return job.hasSignalledStop();
183 }
184
185 public void newDownloadJob(Download download, String mode, String proxy_url) {
186 // Create the job and fill in the details from gatherer.config.
187
188 DebugStream.println("About to create a new job");
189
190 DownloadJob new_job = new DownloadJob(download, Configuration.proxy_pass, Configuration.proxy_user, this, mode, proxy_url);
191 // Tell it to run as soon as possible
192
193 new_job.setState(DownloadJob.RUNNING);
194
195 // Add to job_queue job list.
196 job_queue.add(new_job);
197
198 // Now add it to the visual component, job list.
199
200 list_pane.remove(filler_pane);
201
202 Dimension progress_bar_size = new_job.getProgressBar().getPreferredSize();
203
204 Dimension list_pane_size = list_pane.getSize();
205
206 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
207
208 progress_bar_size = null;
209
210 list_pane.add(new_job.getProgressBar());
211
212 if(height > 0) {
213 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
214 list_pane.add(filler_pane);
215 }
216
217 list_pane_size = null;
218 //list_pane.setAlignmentX(Component.LEFT_ALIGNMENT);
219 list_pane.updateUI();
220 new_job = null; //job = (DownloadJob) job_queue.get(index);
221
222 synchronized(this) {
223 notify(); // Just incase its sleeping.
224 }
225 }
226
227 public synchronized void updateProgress(long current, long expected) {
228 job.updateProgress(current, expected);
229 }
230
231 /* There may be times when the download thread is sleeping, but the
232 * user has indicated that a previously paused job should now begin
233 * again. The flag within the job will change, so we tell the thread
234 * to start again.
235 */
236 public void resumeThread() {
237 synchronized(this) {
238 notify(); // Just incase its sleeping.
239 }
240 }
241
242 public void run() {
243 while(true) {
244 if(job_queue.size() > 0) {
245 while(!job_queue.isEmpty()) {
246 job = (DownloadJob) job_queue.firstElement();
247
248 if(job.getState() == DownloadJob.RUNNING) {
249 DownloadJob delete_me = job;
250 String jobDisplayString = job.toString();
251 DebugStream.println("DownloadJob " + jobDisplayString + " Begun.");
252 System.err.println("DownloadJob " + job.port + " " + job.toString() + " Begun.");
253 job.callDownload();
254 // Job is done. Ended naturally, don't get rid of this download's separate display panel
255 finishedDownloadJob(delete_me, false);
256 System.err.println("DownloadJob " + jobDisplayString + " complete.");
257 DebugStream.println("DownloadJob " + jobDisplayString + " complete."); // by this point job is null!
258 job = null;
259 delete_me = null;
260 }
261 }
262 try {
263 synchronized(this) {
264 DebugStream.println("WGet thread is waiting for DownloadJobs.");
265 wait();
266 }
267 } catch (InterruptedException e) {
268 // Time to get going again.
269 }
270 }
271 else {
272 try {
273 synchronized(this) {
274 DebugStream.println("WGet thread is waiting for DownloadJobs.");
275 wait();
276 }
277 } catch (InterruptedException e) {
278 // Time to get going again.
279 }
280 }
281 }
282 }
283}
Note: See TracBrowser for help on using the repository browser.