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

Last change on this file since 17773 was 17773, checked in by ak19, 15 years ago

Fixed bug I introduced in recent changes to Download panel which caused an infinite exception to be thrown (thread problem) if you viewed the log for a different download job's URL after having viewed the log for a previous download job's URL.

  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 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 setJobToNull();//job = null;
96
97 }
98 // Get rid of this download's dedicated pane
99 finishedDownloadJob(delete_me);
100 }
101
102 synchronized protected void setJobToNull() { job = null; }
103
104 /** To be called when a download job has terminated naturally or was prematurely stopped
105 * via the close button. Gets rid of this download's pane with buttons and progress bar. */
106 protected void finishedDownloadJob(DownloadJob delete_me) {
107 if (delete_me.hasSignalledStop()) {
108 list_pane.remove(delete_me.getProgressBar());
109 job_queue.remove(delete_me);
110 list_pane.remove(filler_pane);
111 if(job_queue.size() > 0) {
112 Dimension progress_bar_size = delete_me.getProgressBar().getPreferredSize();
113 Dimension list_pane_size = list_pane.getSize();
114 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
115 progress_bar_size = null;
116 if(height > 0) {
117 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
118 list_pane.add(filler_pane);
119 }
120 list_pane_size = null;
121 }
122 list_pane.updateUI();
123 }
124 else {
125 DebugStream.println("Somehow we're trying to delete a job that is still running.");
126 }
127 }
128
129 public synchronized void downloadComplete() {
130 job.downloadComplete();
131 }
132
133 public synchronized void downloadFailed() {
134 job.downloadFailed();
135 }
136
137 public synchronized void downloadWarning() {
138 job.downloadWarning();
139 }
140
141 public JScrollPane getDownloadJobList() {
142 return list_scroll;
143 }
144
145 public synchronized boolean hasSignalledStop() {
146 return job.hasSignalledStop();
147 }
148
149 public void newDownloadJob(Download download, String mode, String proxy_url) {
150 // Create the job and fill in the details from gatherer.config.
151
152 DebugStream.println("About to create a new job");
153
154 DownloadJob new_job = new DownloadJob(download, Configuration.proxy_pass, Configuration.proxy_user, this, mode, proxy_url);
155 // Tell it to run as soon as possible
156
157 new_job.setState(DownloadJob.RUNNING);
158
159 // Add to job_queue job list.
160 job_queue.add(new_job);
161
162 // Now add it to the visual component, job list.
163
164 list_pane.remove(filler_pane);
165
166 Dimension progress_bar_size = new_job.getProgressBar().getPreferredSize();
167
168 Dimension list_pane_size = list_pane.getSize();
169
170 int height = list_pane_size.height - (job_queue.size() * progress_bar_size.height);
171
172 progress_bar_size = null;
173
174 list_pane.add(new_job.getProgressBar());
175
176 if(height > 0) {
177 filler_pane.setPreferredSize(new Dimension(list_pane_size.width, height));
178 list_pane.add(filler_pane);
179 }
180
181 list_pane_size = null;
182 //list_pane.setAlignmentX(Component.LEFT_ALIGNMENT);
183 list_pane.updateUI();
184 new_job = null; //job = (DownloadJob) job_queue.get(index);
185
186 synchronized(this) {
187 notify(); // Just incase its sleeping.
188 }
189 }
190
191 public synchronized void updateProgress(long current, long expected) {
192 job.updateProgress(current, expected);
193 }
194
195 /* There may be times when the download thread is sleeping, but the
196 * user has indicated that a previously paused job should now begin
197 * again. The flag within the job will change, so we tell the thread
198 * to start again.
199 */
200 public void resumeThread() {
201 synchronized(this) {
202 notify(); // Just incase its sleeping.
203 }
204 }
205
206 public void run() {
207 while(true) {
208 if(job_queue.size() > 0) {
209 while(!job_queue.isEmpty()) {
210 job = (DownloadJob) job_queue.firstElement();
211
212 if(job.getState() == DownloadJob.RUNNING) {
213 DownloadJob delete_me = job;
214 String jobDisplayString = job.toString();
215 DebugStream.println("DownloadJob " + jobDisplayString + " Begun.");
216 System.err.println("DownloadJob " + job.port + " " + job.toString() + " Begun.");
217 if(job != null) {
218 job.callDownload();
219 }
220 finishedDownloadJob(delete_me); // Job is done, get rid of the separate display panel for this download
221 System.err.println("DownloadJob " + jobDisplayString + " complete.");
222 DebugStream.println("DownloadJob " + jobDisplayString + " complete."); // by this point job is null!
223 job = null;
224 delete_me = null;
225 }
226 }
227 try {
228 synchronized(this) {
229 DebugStream.println("WGet thread is waiting for DownloadJobs.");
230 wait();
231 }
232 } catch (InterruptedException e) {
233 // Time to get going again.
234 }
235 }
236 else {
237 try {
238 synchronized(this) {
239 DebugStream.println("WGet thread is waiting for DownloadJobs.");
240 wait();
241 }
242 } catch (InterruptedException e) {
243 // Time to get going again.
244 }
245 }
246 }
247 }
248}
Note: See TracBrowser for help on using the repository browser.