diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemEditableRemoteFile.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemEditableRemoteFile.java index db0f47da040..1fb58bb7f5a 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemEditableRemoteFile.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemEditableRemoteFile.java @@ -32,6 +32,7 @@ * Kevin Doyle (IBM) - [224162] SystemEditableRemoteFile.saveAs does not work because FileServiceSubSytem.upload does invalid check * David McKnight (IBM) - [225747] [dstore] Trying to connect to an "Offline" system throws an NPE * David McKnight (IBM) - [229610] [api] File transfers should use workspace text file encoding + * David McKnight (IBM) - [235221] Files truncated on exit of Eclipse *******************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -1017,6 +1018,10 @@ public class SystemEditableRemoteFile implements ISystemEditableRemoteObject, IP } } } + + if (activePage == null){ + return NOT_OPEN; + } IEditorReference[] activeReferences = activePage.getEditorReferences(); diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemTempFileListener.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemTempFileListener.java index 4d7a08570ca..96b7e26f238 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemTempFileListener.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemTempFileListener.java @@ -22,6 +22,7 @@ * David McKnight (IBM) - [205297] Editor upload should not be on main thread * David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible * David McKnight (IBM) - [225747] [dstore] Trying to connect to an "Offline" system throws an NPE + * David McKnight (IBM) - [235221] Files truncated on exit of Eclipse *******************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -34,6 +35,10 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -49,6 +54,7 @@ import org.eclipse.rse.core.filters.ISystemFilterReference; import org.eclipse.rse.core.model.IHost; import org.eclipse.rse.core.model.ISystemRegistry; import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.internal.files.ui.Activator; import org.eclipse.rse.internal.files.ui.FileResources; import org.eclipse.rse.internal.files.ui.resources.SystemRemoteEditManager; import org.eclipse.rse.subsystems.files.core.SystemIFileProperties; @@ -61,7 +67,6 @@ import org.eclipse.rse.ui.SystemBasePlugin; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.progress.UIJob; -import org.eclipse.ui.progress.WorkbenchJob; /** * This class manages listening for resource changes within our temp file project @@ -69,6 +74,43 @@ import org.eclipse.ui.progress.WorkbenchJob; * changes to the remote files. */ public abstract class SystemTempFileListener implements IResourceChangeListener { + private class TempFileSaveParticipant implements ISaveParticipant + { + private SystemTempFileListener _listener; + + public TempFileSaveParticipant(SystemTempFileListener listener){ + _listener = listener; + } + + public void doneSaving(ISaveContext context) { + } + + public void prepareToSave(ISaveContext context) throws CoreException { + } + + public void rollback(ISaveContext context) { + } + + public void saving(ISaveContext context) throws CoreException { + + // wait for completion of synch + while (isSynching()){ + try { + Thread.sleep(1000); + } + catch (Exception e){ + + } + } + } + + private boolean isSynching() + { + return _isSynching || _changedResources.size() > 0; + } + + } + private ArrayList _changedResources; private ArrayList _ignoredFiles = new ArrayList(); private volatile boolean _isSynching; @@ -78,7 +120,15 @@ public abstract class SystemTempFileListener implements IResourceChangeListener { _changedResources = new ArrayList(); _isSynching = false; - _isEnabled = true; + _isEnabled = true; + + ISaveParticipant saveParticipant = new TempFileSaveParticipant(this); + try { + ResourcesPlugin.getWorkspace().addSaveParticipant(Activator.getDefault(), saveParticipant); + } + catch (CoreException e){ + SystemBasePlugin.logError("Exception adding save participant", e); //$NON-NLS-1$ + } } public void setEnabled(boolean flag) @@ -126,7 +176,6 @@ public abstract class SystemTempFileListener implements IResourceChangeListener { if (_isEnabled) { - IResourceDelta delta = event.getDelta(); if (delta != null) { @@ -138,6 +187,9 @@ public abstract class SystemTempFileListener implements IResourceChangeListener if (_changedResources.size() > 0 && !_isSynching) { + // indicating synching here instead of in SynchResourcesJob because + // otherwise two calls can get into here creating two jobs + _isSynching = true; synchRemoteResourcesOnThread(); } } @@ -176,41 +228,7 @@ public abstract class SystemTempFileListener implements IResourceChangeListener return Status.OK_STATUS; } } - - /*** - * @deprecated don't use this class, it's only here because to remove it would be - * an API change, and we can't do that until 3.0. Instead of using this, - * SynchResourcesJob should be used. - */ - public class RefreshResourcesUIJob extends WorkbenchJob - { - public RefreshResourcesUIJob() - { - super(FileResources.RSEOperation_message); - } - - public IStatus runInUIThread(IProgressMonitor monitor) - { - _isSynching = true; - try { - IFile[] filesToSync; - synchronized(_changedResources) { - filesToSync = (IFile[])_changedResources.toArray(new IFile[_changedResources.size()]); - _changedResources.clear(); - } - monitor.beginTask(FileResources.MSG_SYNCHRONIZE_PROGRESS, IProgressMonitor.UNKNOWN); - setName(FileResources.MSG_SYNCHRONIZE_PROGRESS); - for (int i = 0; i < filesToSync.length; i++) - { - synchronizeTempWithRemote(filesToSync[i], monitor); - } - } finally { - _isSynching = false; - monitor.done(); - } - return Status.OK_STATUS; - } - } + /** * Used for doing the upload from a job @@ -226,21 +244,27 @@ public abstract class SystemTempFileListener implements IResourceChangeListener public IStatus run(IProgressMonitor monitor) { - _isSynching = true; try { - IFile[] filesToSync; - synchronized(_changedResources) { - filesToSync = (IFile[])_changedResources.toArray(new IFile[_changedResources.size()]); - _changedResources.clear(); + // using while loop because changed resources could get added after the original batch + while (!_changedResources.isEmpty()){ + IFile[] filesToSync; + synchronized(_changedResources) { + filesToSync = (IFile[])_changedResources.toArray(new IFile[_changedResources.size()]); + _changedResources.clear(); + } + + monitor.beginTask(FileResources.MSG_SYNCHRONIZE_PROGRESS, IProgressMonitor.UNKNOWN); + setName(FileResources.MSG_SYNCHRONIZE_PROGRESS); + for (int i = 0; i < filesToSync.length; i++) + { + synchronizeTempWithRemote(filesToSync[i], monitor); + } } - - monitor.beginTask(FileResources.MSG_SYNCHRONIZE_PROGRESS, IProgressMonitor.UNKNOWN); - setName(FileResources.MSG_SYNCHRONIZE_PROGRESS); - for (int i = 0; i < filesToSync.length; i++) - { - synchronizeTempWithRemote(filesToSync[i], monitor); - } - } finally { + } + catch (Exception e){ + e.printStackTrace(); + } + finally { _isSynching = false; monitor.done(); } @@ -716,5 +740,7 @@ public abstract class SystemTempFileListener implements IResourceChangeListener } return false; } + + } diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemUniversalTempFileListener.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemUniversalTempFileListener.java index 760eddd6912..f2424648527 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemUniversalTempFileListener.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/SystemUniversalTempFileListener.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2002, 2007 IBM Corporation and others. All rights reserved. + * Copyright (c) 2002, 2008 IBM Corporation and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html @@ -22,6 +22,7 @@ * Kevin Doyle (IBM) - [197976] Synch up Read-Only attribute when performing save based on local copy * Kevin Doyle (IBM) - [204810] Saving file in Eclipse does not update remote file * Kevin Doyle (IBM) - [210389] Display error dialog when setting file not read-only fails when saving + * David McKnight (IBM) - [235221] Files truncated on exit of Eclipse ********************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -211,7 +212,7 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener final SystemEditableRemoteFile fEditable = editable; Display.getDefault().asyncExec(new Runnable() { public void run() { - try { + // defect - we get a save event when saving during a close // in that case, we shouldn't reopen the editor // I think this was originally here so that, if a save is done on @@ -220,12 +221,15 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener // now call check method before if (fEditable.checkOpenInEditor() != ISystemEditableRemoteObject.NOT_OPEN) { - fEditable.openEditor(); - } + try { + fEditable.openEditor(); + } + catch (PartInitException e) { + } + } + fEditable.addAsListener(); - } catch (PartInitException e) { - } - } + } }); editable.setLocalResourceProperties(); } @@ -287,9 +291,6 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener Display.getDefault().syncExec(msgAction); } - // get the remote file object again so that we have a fresh remote timestamp - remoteFile.markStale(true); - IRemoteFile parent = remoteFile.getParentRemoteFile(); @@ -300,19 +301,25 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener registry.fireEvent(new SystemResourceChangeEvent(parent, ISystemResourceChangeEvents.EVENT_REFRESH, null)); } + // waiting to make sure the file's timestamp is uptodate + Thread.sleep(1000); + + // get the remote file object again so that we have a fresh remote timestamp + remoteFile.markStale(true); remoteFile = fs.getRemoteFileObject(remoteFile.getAbsolutePath(), monitor); registry.fireEvent(new SystemResourceChangeEvent(remoteFile, ISystemResourceChangeEvents.EVENT_PROPERTY_CHANGE, remoteFile)); + long ts = remoteFile.getLastModified(); // set the stored timestamp to be the same as the remote timestamp - properties.setRemoteFileTimeStamp(remoteFile.getLastModified()); + properties.setRemoteFileTimeStamp(ts); // indicate that the temp file is no longer dirty properties.setDirty(false); editable.updateDirtyIndicator(); - - } + + } else if (storedModifiedStamp == -1) { // hack because Eclipse send out event after replacing local file with remote diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemUploadConflictAction.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemUploadConflictAction.java index c8ab3b86e6a..bef3d31fdab 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemUploadConflictAction.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemUploadConflictAction.java @@ -20,10 +20,12 @@ * David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared * David McKnight (IBM) - [224377] "open with" menu does not have "other" option * Xuan Chen (IBM) - [225506] [api][breaking] RSE UI leaks non-API types + * David McKnight (IBM) - [235221] Files truncated on exit of Eclipse *******************************************************************************/ package org.eclipse.rse.internal.files.ui.actions; + import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -36,8 +38,8 @@ import org.eclipse.rse.core.events.ISystemResourceChangeEvents; import org.eclipse.rse.core.events.SystemResourceChangeEvent; import org.eclipse.rse.core.subsystems.SubSystem; import org.eclipse.rse.core.subsystems.SubSystem.SystemMessageDialogRunnable; -import org.eclipse.rse.files.ui.dialogs.ISaveAsDialog; import org.eclipse.rse.files.ui.dialogs.FileDialogFactory; +import org.eclipse.rse.files.ui.dialogs.ISaveAsDialog; import org.eclipse.rse.files.ui.resources.SystemEditableRemoteFile; import org.eclipse.rse.internal.files.ui.Activator; import org.eclipse.rse.internal.files.ui.FileResources; @@ -196,9 +198,17 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn IRemoteFileSubSystem fs = _remoteFile.getParentRemoteFileSubSystem(); SystemIFileProperties properties = new SystemIFileProperties(_tempFile); fs.upload(_tempFile.getLocation().makeAbsolute().toOSString(), _remoteFile, SystemEncodingUtil.ENCODING_UTF_8, monitor); + // wait for timestamp to update before re-fetching remote file + try { + Thread.sleep(1000); + } + catch (Exception e){ + + } _remoteFile.markStale(true); _remoteFile = fs.getRemoteFileObject(_remoteFile.getAbsolutePath(), new NullProgressMonitor()); - properties.setRemoteFileTimeStamp(_remoteFile.getLastModified()); + long ts = _remoteFile.getLastModified(); + properties.setRemoteFileTimeStamp(ts); properties.setDirty(false); } catch (RemoteFileSecurityException e)