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

Last change on this file since 17526 was 17526, checked in by ak19, 16 years ago

Dr Bainbridge adjusted code to replace the variable called busy which was used in a processor-intensive loop and causing problems when terminating wget from the Download panel when more than once download instance was running. The solution was to use Thread's wait and notify (see also DownloadJob.java).

  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 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.*;
46
47/** 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.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.3
50 */
51public class DownloadScrollPane
52 extends Thread {
53
54 /** <i>true</i> if verbose debug messages should be displayed, <i>false</i> otherwise. */
55 private boolean debug = false;
56 /** <i>true</i> if successfully completed tasks should be automatically removed from the job queue. */
57 private boolean remove_complete_jobs = true;
58
59 private JPanel filler_pane = null;
60 /** The panel that the task list will be shown in. */
61 private JPanel list_pane;
62 /** The job currently underway. */
63 private DownloadJob job;
64 /** A scroll pane which will be used to display the list of pending tasks. */
65 private JScrollPane list_scroll;
66 /** A queue of download tasks. */
67 private Vector job_queue;
68 static final private boolean simple = true;
69
70
71 public DownloadScrollPane() {
72 job = null;
73 job_queue = new Vector();
74 filler_pane = new JPanel();
75 list_pane = new JPanel();
76 list_pane.setLayout(new BoxLayout(list_pane, BoxLayout.Y_AXIS));
77 list_scroll = new JScrollPane(list_pane);
78 }
79
80 public void deleteDownloadJob(DownloadJob delete_me) {
81 if (delete_me == job) {
82 try {
83 // Wait for the job to finish cleaning up, before we can continue cleaning up here.
84 // But sometimes the job has completed (terminated naturally) and in that case there's
85 // nothing to wait for.
86 synchronized(delete_me) {
87 if (!delete_me.hasSignalledStop()) { // don't wait if DownloadJob.COMPLETED
88 delete_me.wait();
89 }
90 }
91 } catch (Exception e) {
92 e.printStackTrace();
93 }
94
95 job = null;
96
97 }
98 // Get rid of this download's dedicated pane
99 finishedDownloadJob(delete_me);
100 }
101
102 /** To be called when a download job has terminated naturally or was prematurely stopped
103 * via the close button. Gets rid of this download's pane with buttons and progress bar. */
104 protected void finishedDownloadJob(DownloadJob delete_me) {
105 if (delete_me.hasSignalledStop()) {
106 list_pane.remove(delete_me.getProgressBar());
107 job_queue.remove(delete_me);
108 list_pane.remove(filler_pane);
109 if(job_queue.size() > 0) {
110 Dimension progress_bar_size = delete_me.getProgressBar().getPreferredSize();
111 Dimension list_pane_size = list_pane.getSize();
112 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
113 progress_bar_size = null;
114 if(height > 0) {
115 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
116 list_pane.add(filler_pane);
117 }
118 list_pane_size = null;
119 }
120 list_pane.updateUI();
121 }
122 else {
123 DebugStream.println("Somehow we're trying to delete a job that is still running.");
124 }
125 }
126
127 public synchronized void downloadComplete() {
128 job.downloadComplete();
129 }
130
131 public synchronized void downloadFailed() {
132 job.downloadFailed();
133 }
134
135 public synchronized void downloadWarning() {
136 job.downloadWarning();
137 }
138
139 public JScrollPane getDownloadJobList() {
140 return list_scroll;
141 }
142
143 public synchronized boolean hasSignalledStop() {
144 return job.hasSignalledStop();
145 }
146
147 public void newDownloadJob(Download download, String mode, String proxy_url) {
148 // Create the job and fill in the details from gatherer.config.
149
150 DebugStream.println("About to create a new job");
151
152 DownloadJob new_job = new DownloadJob(download, Configuration.proxy_pass, Configuration.proxy_user, this, mode, proxy_url);
153 // Tell it to run as soon as possible
154
155 new_job.setState(DownloadJob.RUNNING);
156
157 // Add to job_queue job list.
158 job_queue.add(new_job);
159
160 // Now add it to the visual component, job list.
161
162 list_pane.remove(filler_pane);
163
164 Dimension progress_bar_size = new_job.getProgressBar().getPreferredSize();
165
166 Dimension list_pane_size = list_pane.getSize();
167
168 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
169
170 progress_bar_size = null;
171
172 list_pane.add(new_job.getProgressBar());
173
174 if(height > 0) {
175 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
176 list_pane.add(filler_pane);
177 }
178
179 list_pane_size = null;
180 //list_pane.setAlignmentX(Component.LEFT_ALIGNMENT);
181 list_pane.updateUI();
182 new_job = null; //job = (DownloadJob) job_queue.get(index);
183
184 synchronized(this) {
185 notify(); // Just incase its sleeping.
186 }
187 }
188
189 public synchronized void updateProgress(long current, long expected) {
190 job.updateProgress(current, expected);
191 }
192
193 /* There may be times when the download thread is sleeping, but the
194 * user has indicated that a previously paused job should now begin
195 * again. The flag within the job will change, so we tell the thread
196 * to start again.
197 */
198 public void resumeThread() {
199 synchronized(this) {
200 notify(); // Just incase its sleeping.
201 }
202 }
203
204 public void run() {
205 while(true) {
206 if(job_queue.size() > 0) {
207 while(!job_queue.isEmpty()) {
208 job = (DownloadJob) job_queue.firstElement();
209
210 if(job.getState() == DownloadJob.RUNNING) {
211 DownloadJob delete_me = job;
212 String jobDisplayString = job.toString();
213 DebugStream.println("DownloadJob " + jobDisplayString + " Begun.");
214 System.err.println("DownloadJob " + job.port + " " + job.toString() + " Begun.");
215 job.callDownload();
216 finishedDownloadJob(delete_me); // Job is done, get rid of the separate display panel for this download
217 System.err.println("DownloadJob " + jobDisplayString + " complete.");
218 DebugStream.println("DownloadJob " + jobDisplayString + " complete."); // by this point job is null!
219 job = null;
220 delete_me = null;
221 }
222 }
223 try {
224 synchronized(this) {
225 DebugStream.println("WGet thread is waiting for DownloadJobs.");
226 wait();
227 }
228 } catch (InterruptedException e) {
229 // Time to get going again.
230 }
231 }
232 else {
233 try {
234 synchronized(this) {
235 DebugStream.println("WGet thread is waiting for DownloadJobs.");
236 wait();
237 }
238 } catch (InterruptedException e) {
239 // Time to get going again.
240 }
241 }
242 }
243 }
244}
Note: See TracBrowser for help on using the repository browser.