001: /*
002: * This program is free software; you can redistribute it and/or
003: * modify it under the terms of the GNU General Public License
004: * as published by the Free Software Foundation; either version 2
005: * of the License, or (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011:
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
015: */
016: package net.sf.jftp.gui.base;
017:
018: import java.awt.BorderLayout;
019: import java.awt.event.ActionEvent;
020: import java.awt.event.ActionListener;
021: import java.util.Enumeration;
022: import java.util.Hashtable;
023:
024: import javax.swing.ImageIcon;
025: import javax.swing.JLabel;
026: import javax.swing.JList;
027: import javax.swing.JScrollPane;
028:
029: import net.sf.jftp.JFtp;
030: import net.sf.jftp.config.Settings;
031: import net.sf.jftp.gui.base.dir.DirCellRenderer;
032: import net.sf.jftp.gui.base.dir.DirEntry;
033: import net.sf.jftp.gui.framework.HImage;
034: import net.sf.jftp.gui.framework.HImageButton;
035: import net.sf.jftp.gui.framework.HPanel;
036: import net.sf.jftp.net.ConnectionHandler;
037: import net.sf.jftp.net.DataConnection;
038: import net.sf.jftp.net.HttpTransfer;
039: import net.sf.jftp.net.Transfer;
040: import net.sf.jftp.system.LocalIO;
041: import net.sf.jftp.system.UpdateDaemon;
042: import net.sf.jftp.system.logging.Log;
043:
044: public class DownloadList extends HPanel implements ActionListener {
045: //private HImageButton rotate = new HImageButton(Settings.cmdImage,"rotate","Toggle selected transfer...",this);
046: //private int rotator = 0;
047: //private static final String SEP = "--> ";
048: public Hashtable sizeCache = new Hashtable();
049:
050: //private JTextArea text = new JTextArea();
051: private JList text = new JList();
052: private Hashtable downloads = new Hashtable();
053: //private boolean working = false;
054: private long oldtime = 0;
055: private HImageButton resume = new HImageButton(
056: Settings.resumeImage, "resume",
057: "Resume selected transfer...", this );
058: private HImageButton pause = new HImageButton(Settings.pauseImage,
059: "pause", "Pause selected transfer...", this );
060: private HImageButton cancel = new HImageButton(
061: Settings.deleteImage, "delete",
062: "Cancel selected transfer...", this );
063: private HImageButton clear = new HImageButton(Settings.clearImage,
064: "clear", "Remove old/stalled items from output...", this );
065:
066: public DownloadList() {
067: setLayout(new BorderLayout());
068:
069: resume.setRolloverIcon(new ImageIcon(HImage.getImage(this ,
070: Settings.resumeImage2)));
071: resume.setRolloverEnabled(true);
072: pause.setRolloverIcon(new ImageIcon(HImage.getImage(this ,
073: Settings.pauseImage2)));
074: pause.setRolloverEnabled(true);
075: clear.setRolloverIcon(new ImageIcon(HImage.getImage(this ,
076: Settings.clearImage2)));
077: clear.setRolloverEnabled(true);
078: cancel.setRolloverIcon(new ImageIcon(HImage.getImage(this ,
079: Settings.deleteImage2)));
080: cancel.setRolloverEnabled(true);
081:
082: text.setCellRenderer(new DirCellRenderer());
083:
084: HPanel cmdP = new HPanel();
085:
086: // cmdP.add(rotate);
087: cmdP.add(clear);
088:
089: cmdP.add(new JLabel(" "));
090:
091: cmdP.add(resume);
092: cmdP.add(pause);
093:
094: cmdP.add(new JLabel(" "));
095:
096: cmdP.add(cancel);
097:
098: clear.setSize(24, 24);
099: clear.setBorder(true);
100: cancel.setSize(24, 24);
101: cancel.setBorder(true);
102:
103: // rotate.setSize(24,24);
104: // rotate.setBorder(true);
105: resume.setSize(24, 24);
106: resume.setBorder(true);
107: pause.setSize(24, 24);
108: pause.setBorder(true);
109:
110: //*** MY ADDITIONS
111: clear.setToolTipText("Remove old/stalled items from output...");
112:
113: resume.setToolTipText("Resume selected transfer...");
114: pause.setToolTipText("Pause selected transfer...");
115: cancel.setToolTipText("Cancel selected transfer...");
116:
117: //***
118: JScrollPane dP = new JScrollPane(text);
119: add("South", cmdP);
120: add("Center", dP);
121: }
122:
123: public void fresh() {
124: downloads = new Hashtable();
125: updateArea();
126: }
127:
128: public void actionPerformed(ActionEvent e) {
129: if (e.getActionCommand().equals("delete")) {
130: deleteCon();
131: } else if (e.getActionCommand().equals("clear")
132: || (e.getSource() == AppMenuBar.clearItems)) {
133: //FtpConnection con = JFtp.getControlConnection();
134: //JFtp.getConnectionHandler().fireProgressClear(con);
135: fresh();
136: }
137:
138: // else if(e.getActionCommand().equals("rotate"))
139: // {
140: // rotator++;
141: // if(rotator >= downloads.size()) rotator = 0;
142: // }
143: else if (e.getActionCommand().equals("pause")) {
144: pauseCon();
145: } else if (e.getActionCommand().equals("resume")) {
146: resumeCon();
147: }
148: }
149:
150: private void deleteCon() {
151: try {
152: String cmd = getActiveItem();
153:
154: if (cmd == null) {
155: return;
156: }
157:
158: if ((cmd.indexOf(Transfer.QUEUED) >= 0)
159: || (cmd.indexOf(Transfer.PAUSED) >= 0)) {
160: cmd = getFile(cmd);
161:
162: try {
163: Transfer d = (Transfer) JFtp.getConnectionHandler()
164: .getConnections().get(cmd);
165:
166: if (d == null) {
167: return;
168: }
169:
170: d.work = false;
171: d.pause = false;
172: } catch (Exception ex) {
173: ex.printStackTrace();
174: }
175: } else {
176: cmd = getFile(cmd);
177:
178: ConnectionHandler h = JFtp.getConnectionHandler();
179:
180: //Enumeration e =h.getConnections().keys();
181: //while(e.hasMoreElements()) Log.out("available transfer: " + (String) e.nextElement());
182: Object o = h.getConnections().get(cmd);
183:
184: Log.out("aborting transfer: " + cmd);
185: Log.out("connection handler present: " + h
186: + ", pool size: " + h.getConnections().size());
187:
188: if (o instanceof HttpTransfer) {
189: Transfer d = (Transfer) o;
190: d.work = false;
191: updateList(cmd, DataConnection.FAILED, -1, -1);
192:
193: return;
194: } else {
195: Transfer d = (Transfer) o;
196:
197: DataConnection con = d.getDataConnection();
198: con.getCon().work = false;
199:
200: try {
201: con.sock.close();
202:
203: //con.getCon().abort();
204: //if(Settings.getEnableMultiThreading()) con.getCon().disconnect();
205: } catch (Exception ex) {
206: ex.printStackTrace();
207:
208: //System.out.println("no socket close");
209: }
210: }
211:
212: LocalIO.pause(500);
213: updateList(getRawFile(getActiveItem()),
214: DataConnection.FAILED, -1, -1);
215: }
216: } catch (Exception ex) {
217: Log.debug("Action is not supported for this connection.");
218: ex.printStackTrace();
219: }
220: }
221:
222: // fake pause, it disconnects instead
223: private void pauseCon() {
224: try {
225: String cmd = getActiveItem();
226:
227: if (cmd == null) {
228: return;
229: }
230:
231: if ((cmd.indexOf(DataConnection.GET) >= 0)
232: || (cmd.indexOf(DataConnection.PUT) >= 0)) {
233: cmd = getFile(cmd);
234:
235: Object o = JFtp.getConnectionHandler().getConnections()
236: .get(cmd);
237:
238: if (o == null) {
239: return;
240: }
241:
242: Transfer d = (Transfer) o;
243: d.pause = true;
244:
245: DataConnection con = d.getDataConnection();
246:
247: try {
248: con.sock.close();
249: } catch (Exception ex) {
250: ex.printStackTrace();
251: }
252:
253: d.prepare();
254: }
255: } catch (Exception ex) {
256: Log.debug("Action is not supported for this connection.");
257: }
258: }
259:
260: private void resumeCon() {
261: try {
262: String cmd = getActiveItem();
263:
264: if (cmd == null) {
265: return;
266: }
267:
268: if ((cmd.indexOf(Transfer.PAUSED) >= 0)
269: || (cmd.indexOf(Transfer.QUEUED) >= 0)) {
270: cmd = getFile(cmd);
271:
272: try {
273: Object o = JFtp.getConnectionHandler()
274: .getConnections().get(cmd);
275:
276: if (o == null) {
277: return;
278: }
279:
280: Transfer d = (Transfer) o;
281: d.work = true;
282: d.pause = false;
283: } catch (Exception ex) {
284: ex.printStackTrace();
285: }
286: }
287: } catch (Exception ex) {
288: Log.debug("Action is not supported for this connection.");
289: }
290: }
291:
292: private String getActiveItem() {
293: String tmp = (String) text.getSelectedValue().toString();
294:
295: if (tmp == null) {
296: return "";
297: } else {
298: return tmp;
299: }
300: }
301:
302: public synchronized void updateList(String file, String type,
303: long bytes, long size) {
304: String message = type + ": <" + file + "> ";
305:
306: if (!safeUpdate()) {
307: if (!type.startsWith(DataConnection.DFINISHED)
308: && !type.startsWith(DataConnection.FINISHED)
309: && !type.startsWith(DataConnection.FAILED)
310: && !type.startsWith(Transfer.PAUSED)
311: && !type.startsWith(Transfer.REMOVED)) {
312: return;
313: }
314: }
315:
316: // directory
317: int count = 0;
318:
319: if (type.startsWith(DataConnection.GETDIR)
320: || type.startsWith(DataConnection.PUTDIR)
321: || type.startsWith(DataConnection.PUTDIR)
322: || type.startsWith(DataConnection.DFINISHED)) {
323: //System.out.println(type);
324: String tmp = type.substring(type.indexOf(":") + 1);
325: type = type.substring(0, type.indexOf(":"));
326: count = Integer.parseInt(tmp);
327: message = type + ": <" + file + "> ";
328: }
329:
330: // ---------------
331: //System.out.print(size+":");
332: String tmp;
333: long s = (long) (size / 1024);
334:
335: if (s > 0) {
336: tmp = Long.toString(s);
337: } else {
338: tmp = "?";
339: }
340:
341: //System.out.println(message);
342: if (type.equals(DataConnection.GET)
343: || type.equals(DataConnection.PUT)) {
344: message = message + (int) (bytes / 1024) + " / " + tmp
345: + " kb";
346: } else if (type.equals(DataConnection.GETDIR)
347: || type.equals(DataConnection.PUTDIR)) {
348: message = message + (int) (bytes / 1024) + " kb of file #"
349: + count;
350: } else if (type.startsWith(DataConnection.DFINISHED)) {
351: message = message + " " + count + " files.";
352: }
353:
354: if (type.equals(DataConnection.FINISHED)
355: || type.startsWith(DataConnection.DFINISHED)) {
356: try {
357: JFtp.getConnectionHandler().removeConnection(file);
358: } catch (Exception ex) {
359: // SMB does not need this
360: }
361:
362: UpdateDaemon.updateCall();
363: } else if (type.equals(DataConnection.FAILED)) {
364: UpdateDaemon.updateCall();
365: }
366:
367: downloads.put(file, message);
368:
369: updateArea();
370: }
371:
372: private synchronized DirEntry[] toArray() {
373: DirEntry[] f = new DirEntry[downloads.size()];
374: int i = 0;
375:
376: Enumeration k = downloads.elements();
377:
378: while (k.hasMoreElements()) {
379: String tmp = (String) k.nextElement();
380: DirEntry d = new DirEntry(tmp, null);
381:
382: if (getFile(tmp).endsWith("/")) {
383: d.setDirectory();
384: }
385:
386: d.setNoRender();
387: f[i] = d;
388: i++;
389: }
390:
391: return f;
392: }
393:
394: private synchronized void updateArea() {
395: int idx = text.getSelectedIndex();
396:
397: DirEntry[] f = toArray();
398:
399: text.setListData(f);
400:
401: if ((f.length == 1) && (idx < 0)) {
402: text.setSelectedIndex(0);
403: } else {
404: text.setSelectedIndex(idx);
405: }
406: }
407:
408: private String getFile(String msg) {
409: String f = msg.substring(msg.indexOf("<") + 1);
410: f = f.substring(0, f.lastIndexOf(">"));
411:
412: //System.out.println(f);
413: return getRealName(f);
414: }
415:
416: private String getRealName(String file) {
417: //System.out.println(">>>"+file);
418: try {
419: Enumeration e = JFtp.getConnectionHandler()
420: .getConnections().keys();
421:
422: while (e.hasMoreElements()) {
423: String tmp = (String) e.nextElement();
424:
425: //System.out.println(tmp);
426: if (tmp.endsWith(file)) {
427: return tmp;
428: }
429: }
430: } catch (Exception ex) {
431: // SMB does not need this
432: }
433:
434: return file;
435: }
436:
437: private String getRawFile(String msg) {
438: String f = msg.substring(msg.indexOf("<") + 1);
439: f = f.substring(0, f.lastIndexOf(">"));
440:
441: //System.out.println(f);
442: return f;
443: }
444:
445: private boolean safeUpdate() {
446: long time = System.currentTimeMillis();
447:
448: if ((time - oldtime) < Settings.refreshDelay) {
449: return false;
450: }
451:
452: oldtime = time;
453:
454: return true;
455: }
456: }
|