001: /*
002: * FtpSaveProcess.java
003: *
004: * Copyright (C) 1998-2003 Peter Graves
005: * $Id: FtpSaveProcess.java,v 1.2 2003/07/05 17:42:59 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import javax.swing.SwingUtilities;
025:
026: public class FtpSaveProcess implements BackgroundProcess, Constants {
027: private final Buffer buffer;
028: private final File source;
029: private FtpFile destination;
030: private final FtpSession session;
031:
032: // Option for saveAs(), saveCopy().
033: private boolean confirmOverwrite;
034:
035: // Option for save().
036: private boolean confirmIfDestinationChanged;
037:
038: // Title for message dialogs.
039: private String title;
040:
041: private Runnable successRunnable;
042: private ProgressNotifier progressNotifier;
043: private String listing;
044: private boolean force;
045:
046: public FtpSaveProcess(Buffer buffer, File source,
047: FtpFile destination, FtpSession session) {
048: this .buffer = buffer;
049: Debug.assertTrue(buffer != null);
050: this .source = source;
051: Debug.assertTrue(source != null);
052: this .destination = destination;
053: Debug.assertTrue(destination != null);
054: this .session = session;
055: Debug.assertTrue(session != null);
056: Debug.assertTrue(session.isLocked());
057: }
058:
059: public final void setConfirmOverwrite(boolean b) {
060: confirmOverwrite = b;
061: }
062:
063: public final void setConfirmIfDestinationChanged(boolean b) {
064: confirmIfDestinationChanged = b;
065: }
066:
067: public final void setTitle(String s) {
068: title = s;
069: }
070:
071: public final void setSuccessRunnable(Runnable r) {
072: successRunnable = r;
073: }
074:
075: public final String getListing() {
076: return listing;
077: }
078:
079: public void start() {
080: Debug.assertTrue(SwingUtilities.isEventDispatchThread());
081: if (!buffer.isLocked()) {
082: Log.debug("start() buffer is not locked");
083: if (!buffer.lock()) {
084: MessageDialog.showMessageDialog("Buffer is busy",
085: buffer.getFile().netPath());
086: session.unlock();
087: return;
088: }
089: Log.debug("start() buffer locked OK");
090: }
091: Debug.assertTrue(buffer.isLocked());
092: buffer.setBusy(true);
093: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
094: Editor ed = it.nextEditor();
095: if (ed.getBuffer() == buffer)
096: ed.setWaitCursor();
097: }
098: new Thread(this ).start();
099: }
100:
101: public void run() {
102: Debug.assertTrue(buffer.isLocked());
103: try {
104: buffer.setBackgroundProcess(this );
105: if (source.isFile())
106: doSave();
107: buffer.setBackgroundProcess(null);
108: } finally {
109: buffer.unlock();
110: }
111: }
112:
113: public void doSave() {
114: Log.debug("doSave force = " + force);
115: Debug.assertTrue(buffer != null);
116: Debug.assertTrue(source != null);
117: Debug.assertTrue(!SwingUtilities.isEventDispatchThread());
118:
119: final String hostName = destination.getHostName();
120: progressNotifier = new StatusBarProgressNotifier(buffer);
121: session.setProgressNotifier(progressNotifier);
122: if (!session.verifyConnected()) {
123: String message = session.getErrorText();
124: if (message == null)
125: message = "Unable to connect to " + hostName
126: + " on port " + destination.getPort();
127: errorRunnable.setMessage(message);
128: buffer.setBusy(false);
129: SwingUtilities.invokeLater(errorRunnable);
130: session.unlock();
131: return;
132: }
133: final boolean destinationExists = session.exists(destination
134: .canonicalPath());
135: int permissions = destinationExists ? session
136: .getPermissions(destination) : 0;
137: if (!force) {
138: if (confirmOverwrite) {
139: // Check to see if destination file exists on remote host.
140: if (session.exists(destination.canonicalPath())) {
141: // Confirm before overwriting. Leave the session
142: // locked for now.
143: SwingUtilities
144: .invokeLater(confirmOverwriteRunnable);
145: return;
146: }
147: }
148: if (confirmIfDestinationChanged && destinationExists) {
149: // Check to see if destination file has changed on remote host.
150: String s = session
151: .getDirectoryListingForFile(destination
152: .canonicalPath());
153: if (!s.equals(buffer.getListing())) {
154: // Destination file has changed since it was loaded. Leave
155: // the session locked for now.
156: SwingUtilities
157: .invokeLater(confirmDestinationChangedRunnable);
158: return;
159: }
160: }
161: }
162: final boolean saveInPlace = buffer
163: .getBooleanProperty(Property.SAVE_IN_PLACE);
164: int result = session.put(source, destination, source.length(),
165: saveInPlace);
166: if (result == SUCCESS) {
167: if (permissions != 0 && !saveInPlace)
168: session.chmod(destination, permissions);
169: listing = session.getDirectoryListingForFile(destination
170: .canonicalPath());
171: buffer.setBusy(false);
172: if (successRunnable != null)
173: SwingUtilities.invokeLater(successRunnable);
174: } else if (result == CANCELLED) {
175: SwingUtilities.invokeLater(cancelRunnable);
176: } else {
177: // Error.
178: buffer.setBusy(false);
179: if (errorRunnable != null) {
180: errorRunnable.setMessage(session.getErrorText());
181: SwingUtilities.invokeLater(errorRunnable);
182: }
183: }
184: // And in any case...
185: session.unlock();
186: }
187:
188: public synchronized void cancel() {
189: if (progressNotifier != null) {
190: progressNotifier.cancel();
191: progressNotifier.progressStop();
192: progressNotifier
193: .setText("Transfer cancelled, cleaning up...");
194: }
195: }
196:
197: // Confirm overwrite of existing destination file for saveAs() and
198: // saveCopy().
199: private final Runnable confirmOverwriteRunnable = new Runnable() {
200: public void run() {
201: Debug.assertTrue(SwingUtilities.isEventDispatchThread());
202: Debug.assertTrue(session.isLocked());
203: final Editor editor = Editor.currentEditor();
204: editor.setDefaultCursor();
205: String text = "Overwrite existing file "
206: + destination.getName() + " on "
207: + destination.getHostName() + "?";
208: final boolean confirmed = editor.confirm(title, text);
209: if (confirmed) {
210: force = true;
211: start();
212: } else {
213: buffer.setBusy(false);
214: session.unlock();
215: }
216: }
217: };
218:
219: // Confirm save if destination file has changed on the remote host since
220: // it was loaded.
221: private final Runnable confirmDestinationChangedRunnable = new Runnable() {
222: public void run() {
223: Debug.assertTrue(SwingUtilities.isEventDispatchThread());
224: final Editor editor = Editor.currentEditor();
225: editor.setDefaultCursor();
226: String text = destination.getName() + " has changed on "
227: + destination.getHostName() + ". Save anyway?";
228: final boolean confirmed = editor.confirm(title, text);
229: if (confirmed) {
230: force = true;
231: start();
232: } else {
233: buffer.setBusy(false);
234: session.unlock();
235: }
236: }
237: };
238:
239: private final Runnable cancelRunnable = new Runnable() {
240: public void run() {
241: buffer.setBusy(false);
242: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
243: Editor ed = it.nextEditor();
244: if (ed.getBuffer() == buffer) {
245: ed.status("Transfer cancelled");
246: ed.setDefaultCursor();
247: }
248: }
249: MessageDialog
250: .showMessageDialog("Transfer cancelled", title);
251: }
252: };
253:
254: private final ErrorRunnable errorRunnable = new ErrorRunnable(
255: "Save failed");
256: }
|