1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.plugin.gift.net;
21
22 import java.awt.event.ActionEvent;
23 import java.io.File;
24 import java.util.Enumeration;
25 import java.util.Hashtable;
26 import java.util.LinkedList;
27
28 import javax.swing.Action;
29 import javax.swing.Icon;
30
31 import org.xnap.XNap;
32 import org.xnap.gui.util.IconHelper;
33 import org.xnap.peer.Peer;
34 import org.xnap.plugin.Plugin;
35 import org.xnap.plugin.gift.GiFTPlugin;
36 import org.xnap.plugin.gift.action.AbstractClearSourcesAction;
37 import org.xnap.transfer.AbstractDownload;
38 import org.xnap.transfer.Segment;
39 import org.xnap.transfer.action.AbstractDeleteAction;
40 import org.xnap.transfer.action.AbstractFindMoreSourcesAction;
41 import org.xnap.transfer.action.AbstractTransferAction;
42
43
44
45 /***
46 * GiFTDownloadContainer
47 *
48 * @author <a href="mailto:taval@users.sf.net">Tammo van Lessen</a>
49 * @version CVS $Id: GiFTDownloadContainer.java,v 1.6 2004/03/23 19:36:21 vanto Exp $
50 */
51 public class GiFTDownloadContainer extends AbstractDownload {
52
53
54 private String gid = "";
55 private boolean done = false;
56 private boolean paused = true;
57
58 /***
59 * The number of bytes that were already transfered when the
60 * container was constructed.
61 */
62 private GiFTDaemon daemon;
63 private long offset;
64 private long totalBytesTransferred;
65 private String filename;
66 private String hash;
67 private long currentRate;
68 private long filesize;
69 private String status;
70 private Hashtable sources;
71 private LinkedList segments = new LinkedList();
72
73 private AbstractTransferAction cancelAction = new CancelAction();
74
75
76
77 /***
78 * Constructor for GiFTDownloadContainer.
79 *
80 * @param filename DOCUMENT ME!
81 * @param hash DOCUMENT ME!
82 * @param filesize DOCUMENT ME!
83 * @param transmit DOCUMENT ME!
84 * @param state DOCUMENT ME!
85 */
86 public GiFTDownloadContainer(GiFTDaemon daemon, String filename,
87 String hash, long filesize)
88 {
89 this.daemon = daemon;
90
91 this.filename = filename;
92 this.filesize = filesize;
93 this.hash = hash;
94
95 this.sources = new Hashtable();
96 this.status = XNap.tr("Waiting for daemon");
97 }
98
99 /***
100 *
101 */
102 public void cancel()
103 {
104 daemon.changeDownload(this, "cancel");
105 setStatus(XNap.tr("Cancelling"));
106 }
107
108 /***
109 * @see xnap.net.ITransferContainer#getFilename()
110 */
111 public String getFilename() {
112 return filename.substring(filename.lastIndexOf("/") + 1);
113 }
114
115 /***
116 * @see xnap.net.ITransferContainer#getFilesize()
117 */
118 public long getFilesize() {
119 return filesize;
120 }
121
122 public Plugin getPlugin()
123 {
124 return GiFTPlugin.getInstance();
125 }
126
127 /***
128 * Invoked by {@link GiFTDaemon} when the download has been deleted.
129 */
130 void deleted()
131 {
132
133
134 if (!done) {
135 done();
136 setStatus("Deleted");
137 }
138 }
139
140 private void done()
141 {
142 done = true;
143 transferStopped();
144 }
145
146 /***
147 * @see xnap.transfer.Transfer#getActions()
148 */
149 public Action[] getActions(String url)
150 {
151 return new Action[] {
152 new PauseAction(),
153 cancelAction,
154 new CancelSourceAction(url),
155 new FindMoreSourcesAction(),
156 new ClearSourcesAction(),
157 };
158 }
159
160 public Action[] getActions()
161 {
162 return getActions(null);
163 }
164
165 /***
166 * @see xnap.transfer.Transfer#getFile()
167 */
168 public File getFile()
169 {
170 return null;
171 }
172
173 /***
174 * @see xnap.transfer.Transfer#getPeer()
175 */
176 public Peer getPeer()
177 {
178 return null;
179 }
180
181 public Segment[] getSegments()
182 {
183 return (Segment[])segments.toArray(new Segment[0]);
184 }
185
186 /***
187 * @see xnap.transfer.Transfer#getStatus()
188 */
189 public String getStatus()
190 {
191 return status;
192 }
193
194 /***
195 * @see xnap.transfer.Transfer#getTotalBytesTransferred()
196 */
197 public long getTotalBytesTransferred()
198 {
199 return totalBytesTransferred;
200 }
201
202 /***
203 * @see xnap.transfer.Transfer#isDone()
204 */
205 public boolean isDone()
206 {
207 return done;
208 }
209
210 /***
211 * @see xnap.transfer.Transfer#isRunning()
212 */
213 public boolean isRunning()
214 {
215 return !done && !paused;
216 }
217
218 /***
219 * @see xnap.transfer.AbstractTransfer#getBytesTransferred()
220 */
221 public long getBytesTransferred()
222 {
223 return totalBytesTransferred - offset;
224 }
225
226 /***
227 * @see xnap.transfer.Transfer#getCurrentRate()
228 */
229 public long getCurrentRate()
230 {
231 return currentRate;
232 }
233
234
235 public void markChildren()
236 {
237 Enumeration enumeration = sources.elements();
238 while (enumeration.hasMoreElements()) {
239 GiFTDownload element = (GiFTDownload) enumeration.nextElement();
240 element.setMarked(true);
241 }
242 }
243
244 public void orphanMarkedChildren()
245 {
246 Enumeration enumeration = sources.elements();
247 while (enumeration.hasMoreElements()) {
248 GiFTDownload element
249 = (GiFTDownload) enumeration.nextElement();
250 if (element.isMarked()) {
251 element.setState("Inactive", null);
252 }
253 }
254 }
255
256 /***
257 *
258 */
259 public void clearOrphaned()
260 {
261 Enumeration enumeration = sources.elements();
262 while (enumeration.hasMoreElements()) {
263 GiFTDownload element = (GiFTDownload) enumeration.nextElement();
264 if (element.getStatus().equals("Inactive")) {
265 sources.remove(element);
266 remove(element);
267 }
268 }
269 }
270
271 public GiFTDownload getSourceByURL(String url)
272 {
273 return (GiFTDownload)sources.get(url);
274 }
275
276 public GiFTDownload addSource(GiFTUser user, String url)
277 {
278 GiFTDownload d = new GiFTDownload(this, user, url);
279
280
281 Segment[] s = d.getSegments();
282 segments.add(s[0]);
283
284 sources.put(url, d);
285 add(d);
286
287 return d;
288 }
289
290 /***
291 * @return unique id
292 */
293 public String getGID()
294 {
295 return gid;
296 }
297
298 /***
299 * @return unique hash
300 */
301 public String getHash()
302 {
303 return hash;
304 }
305
306 public Icon getIcon()
307 {
308 return GiFTPlugin.ICON_16;
309 }
310
311 /***
312 *
313 */
314 public void pause()
315 {
316 daemon.changeDownload(this, (paused) ? "unpause" : "pause");
317 }
318
319 public void setGID(String gid)
320 {
321 this.gid = gid;
322 }
323
324 public void setCurrentRate(long currentRate)
325 {
326 this.currentRate = currentRate;
327 }
328
329 public void setOffset(long offset)
330 {
331 this.offset = offset;
332 }
333
334 /***
335 * Invoked by {@link Enginge} when the download state changed.
336 */
337 public void setState(String state)
338 {
339 if (state.equals("Active")) {
340 if (paused) {
341 paused = false;
342 transferStarted();
343 }
344 }
345 else if (state.equals("Paused")) {
346 if (!paused) {
347 paused = true;
348 transferStopped();
349 }
350 }
351 else if (state.equals("Completed")) {
352 if (!done) {
353 done();
354
355 Enumeration enumeration = sources.elements();
356 while (enumeration.hasMoreElements()) {
357 GiFTDownload download
358 = (GiFTDownload)enumeration.nextElement();
359 download.setState("Complete", null);
360 }
361 }
362 }
363
364 setStatus(state);
365 }
366
367 private void setStatus(String status)
368 {
369 this.status = status;
370 stateChanged();
371 }
372
373 public void setTotalBytesTransferred(long totalBytesTransferred)
374 {
375 this.totalBytesTransferred = totalBytesTransferred;
376 }
377
378 private class CancelAction extends AbstractDeleteAction {
379
380 public void actionPerformed(ActionEvent e)
381 {
382 GiFTDownloadContainer.this.cancel();
383 }
384
385 }
386
387 private class CancelSourceAction extends AbstractDeleteAction {
388
389 private String url;
390
391 public CancelSourceAction(String url)
392 {
393 this.url = url;
394
395 putValue(Action.NAME, XNap.tr("Delete Source"));
396 setEnabled(url != null);
397 }
398
399 public void actionPerformed(ActionEvent e)
400 {
401 daemon.deleteSource(GiFTDownloadContainer.this, url);
402 }
403
404 }
405
406
407 private class ClearSourcesAction extends AbstractClearSourcesAction {
408
409 public void actionPerformed(ActionEvent e)
410 {
411 GiFTDownloadContainer.this.clearOrphaned();
412 }
413
414 }
415
416 private class FindMoreSourcesAction extends AbstractFindMoreSourcesAction {
417
418 public void actionPerformed(ActionEvent e)
419 {
420 setStatus(XNap.tr("Retrieving more sources"));
421 daemon.locate(GiFTDownloadContainer.this);
422 }
423
424 }
425
426 private class PauseAction extends AbstractTransferAction {
427
428 public PauseAction()
429 {
430 putValue(Action.NAME, XNap.tr("(Un)Pause Download"));
431 putValue(Action.SHORT_DESCRIPTION,
432 XNap.tr("Pauses or unpauses the download."));
433 putValue(IconHelper.XNAP_ICON, "player_pause.png");
434 }
435
436 public void actionPerformed(ActionEvent e)
437 {
438 GiFTDownloadContainer.this.pause();
439 }
440
441 }
442
443 }