From a06f745f245fe0f80b0ea1dd07a3b9806d1acb57 Mon Sep 17 00:00:00 2001 From: David McKnight Date: Thu, 17 Feb 2011 21:26:32 +0000 Subject: [PATCH] [334839] File Content Conflict is not handled properly --- .../resources/SystemEditableRemoteFile.java | 38 ++++- .../SystemUniversalTempFileListener.java | 24 ++- .../actions/SystemUploadConflictAction.java | 145 +++++++++++++----- .../StandardCredentialsProvider.java | 6 +- 4 files changed, 170 insertions(+), 43 deletions(-) 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 5c8ffe2c0d5..5f4e09dad90 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2010 IBM Corporation and others. + * Copyright (c) 2002, 2011 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 @@ -41,6 +41,7 @@ * David McKnight (IBM) - [310215] SystemEditableRemoteFile.open does not behave as expected * David McKnight (IBM) - [324519] SystemEditableRemoteFile throws NPE when used in headless mode * David McKnight (IBM) - [325502] The default editor for a file is not updated when opened in RSE explorer + * David McKnight (IBM) - [334839] File Content Conflict is not handled properly *******************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -67,6 +68,8 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; import org.eclipse.osgi.util.NLS; import org.eclipse.rse.core.IRSESystemType; import org.eclipse.rse.core.RSECorePlugin; @@ -114,6 +117,7 @@ import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.internal.WorkbenchPage; import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; @@ -1663,6 +1667,9 @@ public class SystemEditableRemoteFile implements ISystemEditableRemoteObject, IP SystemIFileProperties properties = new SystemIFileProperties(file); properties.setRemoteFileObject(this); + if (properties.getDirty()){ + updateDirtyIndicator(); + } } /** @@ -1976,6 +1983,19 @@ public class SystemEditableRemoteFile implements ISystemEditableRemoteObject, IP return true; } + private void markEditorDirty(){ + ITextEditor textEditor = (ITextEditor)editor; + IDocumentProvider provider = textEditor.getDocumentProvider(); + if (provider != null){ + IDocument doc = provider.getDocument(textEditor.getEditorInput()); + String content = doc.get(); + try { + doc.replace(0, content.length(), content); + } catch (BadLocationException e) { + } + } + } + public void updateDirtyIndicator() { // for lpex dirty indicator @@ -1985,6 +2005,22 @@ public class SystemEditableRemoteFile implements ISystemEditableRemoteObject, IP { ((ISystemTextEditor) editor).updateDirtyIndicator(); } + else if (editor instanceof ITextEditor){ // mark dirty by updating editor contents + // only do this if we need to mark it as dirty + SystemIFileProperties properties = new SystemIFileProperties(localFile); + if (properties.getDirty()){ + if (Display.getCurrent() == null){ // if we're not on a UI thread + Display.getDefault().asyncExec(new Runnable() { + public void run() { + markEditorDirty(); + } + }); + } + else { + markEditorDirty(); + } + } + } } } 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 0fe26c59a47..5e04182bcba 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, 2010 IBM Corporation and others. All rights reserved. + * Copyright (c) 2002, 2011 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 @@ -26,6 +26,7 @@ * David McKnight (IBM) - [249544] Save conflict dialog appears when saving files in the editor * David McKnight (IBM) - [256048] Saving a member open in Remote LPEX editor while Working Offline doesn't set the dirty property * David McKnight (IBM) - [191284] Confusing behaviour when editing a Readonly file. + * David McKnight (IBM) - [334839] File Content Conflict is not handled properly ********************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -54,6 +55,8 @@ import org.eclipse.rse.ui.view.ISystemEditableRemoteObject; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PartInitException; +import org.eclipse.ui.activities.WorkbenchActivityHelper; +import org.eclipse.ui.internal.Workbench; /** * This class manages listening for resource changes within our temp file project @@ -397,8 +400,8 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener // indicate that the temp file is no longer dirty properties.setDirty(false); - editable.updateDirtyIndicator(); - + if (editable.isDirty()) + editable.updateDirtyIndicator(); } else if (storedModifiedStamp == -1) { @@ -430,17 +433,26 @@ public class SystemUniversalTempFileListener extends SystemTempFileListener final SystemEditableRemoteFile remoteEdit = editable; final IFile tFile = tempFile; final IRemoteFile rFile = remoteFile; + final SystemIFileProperties fProperties = properties; // upload is run in a job, so the conflict action/dialog needs to run in UI thread Display.getDefault().asyncExec(new Runnable() { public void run() { - Shell shell = RSEUIPlugin.getTheSystemRegistryUI().getShell(); - + boolean closing = Workbench.getInstance().isClosing(); + Shell shell = null; + if (closing){ + shell = Display.getDefault().getActiveShell(); + } + else { + shell = RSEUIPlugin.getTheSystemRegistryUI().getShell(); + } SystemUploadConflictAction conflictAction = new SystemUploadConflictAction(shell, tFile, rFile, remoteNewer); conflictAction.run(); - remoteEdit.updateDirtyIndicator(); + if (fProperties.getDirty()){ + remoteEdit.updateDirtyIndicator(); + } } }); 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 8bc114f7632..4edd97fdbf6 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2010 IBM Corporation and others. + * Copyright (c) 2002, 2011 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 @@ -25,12 +25,14 @@ * Kevin Doyle (IBM) - [242389] [usability] RSE Save Conflict dialog should indicate which file is in conflict * David McKnight (IBM) - [267247] Wrong encoding * David McKnight (IBM) - [330804] Change the default selection of Save Conflict dialog + * David McKnight (IBM) - [334839] File Content Conflict is not handled properly *******************************************************************************/ package org.eclipse.rse.internal.files.ui.actions; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; @@ -67,6 +69,8 @@ import org.eclipse.rse.ui.actions.SystemBaseAction; import org.eclipse.rse.ui.dialogs.SystemPromptDialog; import org.eclipse.rse.ui.messages.SystemMessageDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; @@ -83,6 +87,7 @@ import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.internal.Workbench; import org.eclipse.ui.part.FileEditorInput; @@ -141,8 +146,12 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn } ReopenAction reopen = new ReopenAction(_tempFile, _saveasFile); - - Display.getDefault().asyncExec(reopen); + if (Display.getCurrent() != null){ + reopen.run(); + } + else { + Display.getDefault().asyncExec(reopen); + } } return Status.OK_STATUS; } @@ -166,13 +175,20 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn String srcEncoding = RemoteFileUtility.getSourceEncoding(_tempFile); fs.download(_remoteFile, _tempFile.getLocation().makeAbsolute().toOSString(), srcEncoding, monitor); - + + // need to refresh this otherwise the local resource will be out of sync + _tempFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor()); properties.setRemoteFileTimeStamp(_remoteFile.getLastModified()); - //properties.setRemoteFileTimeStamp(-1); - - properties.setDirty(false); - properties.setUsedBinaryTransfer(_remoteFile.isBinary()); - } + properties.setDirty(false); + properties.setUsedBinaryTransfer(_remoteFile.isBinary()); + + Display.getDefault().asyncExec(new Runnable(){ + public void run(){ + IEditorPart part = getEditorFor(_tempFile); + part.setFocus(); + } + }); + } catch (final SystemMessageException e) { Display.getDefault().asyncExec(new Runnable() { @@ -275,6 +291,25 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn _overwriteLocal = _overwriteLocalButton.getSelection(); _overwriteRemote = _overwriteRemoteButton.getSelection(); _saveas = _saveasButton.getSelection(); + if (_saveas){ + if (_saveasLocation == null){ + try { + _saveasLocation = _remoteFile.getParentRemoteFileSubSystem().getRemoteFileObject(_saveasFileEntry.getText(), new NullProgressMonitor()); + } catch (SystemMessageException e) { + } + if (_saveasLocation == null){ + enableOkButton(false); + _errorMessage = new SimpleSystemMessage(Activator.PLUGIN_ID, + ISystemFileConstants.MSG_VALIDATE_PATH_EMPTY, + IStatus.ERROR, + FileResources.MSG_VALIDATE_PATH_EMPTY, + FileResources.MSG_VALIDATE_PATH_EMPTY_DETAILS); + + setErrorMessage(_errorMessage); + return; + } + } + } close(); } @@ -374,6 +409,23 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn _saveasFileEntry = new Text(s, SWT.BORDER); _saveasFileEntry.setEnabled(true); + _saveasFileEntry.addKeyListener(new KeyListener() { + + public void keyReleased(KeyEvent e) { + String loc = _saveasFileEntry.getText(); + if (loc != null && loc.length() > 0){ + _errorMessage = null; + setErrorMessage(_errorMessage); + enableOkButton(true); + } + else { + enableOkButton(false); + } + } + + public void keyPressed(KeyEvent e) { + } + }); GridData fileEntryData = new GridData(GridData.FILL_BOTH); fileEntryData.widthHint = 100; @@ -525,31 +577,7 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn _saveasFile = saveasFile; } - private IEditorPart getEditorFor(IFile tempFile) - { - - IWorkbenchWindow window = SystemBasePlugin.getActiveWorkbenchWindow(); - if (window != null) - { - IWorkbenchPage page = window.getActivePage(); - if (page != null) - { - IEditorPart editor = page.getActiveEditor(); - IEditorInput input = editor.getEditorInput(); - if (input instanceof FileEditorInput) - { - FileEditorInput finput = (FileEditorInput) input; - if (finput.getFile().getFullPath().equals(tempFile.getFullPath())) - { - return editor; - } - } - } - } - - return null; - } - + public void run() { try @@ -589,6 +617,21 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn e.printStackTrace(); } } + else { + // editor closed, possibly due to shutdown + // can't manipulate editors, but we can at least make the original temp file uptodate + SystemIFileProperties properties = new SystemIFileProperties(_tempFile); + SystemEditableRemoteFile edit = (SystemEditableRemoteFile)properties.getRemoteFileObject(); + if (edit != null){ + try { + edit.download(getShell()); + edit.addAsListener(); + edit.setLocalResourceProperties(); + } + catch (Exception e){ + } + } + } } } @@ -637,7 +680,13 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn { IRemoteFile remoteFile = cnfDialog.getSaveasLocation(); BackgroundSaveasJob sjob = new BackgroundSaveasJob(remoteFile); - sjob.schedule(); + + if (Workbench.getInstance().isClosing()){ + sjob.run(new NullProgressMonitor()); + } + else { + sjob.schedule(); + } } } else @@ -647,4 +696,30 @@ public class SystemUploadConflictAction extends SystemBaseAction implements Runn properties.setDirty(true); } } + + private IEditorPart getEditorFor(IFile tempFile) + { + + IWorkbenchWindow window = SystemBasePlugin.getActiveWorkbenchWindow(); + if (window != null) + { + IWorkbenchPage page = window.getActivePage(); + if (page != null) + { + IEditorPart editor = page.getActiveEditor(); + IEditorInput input = editor.getEditorInput(); + if (input instanceof FileEditorInput) + { + FileEditorInput finput = (FileEditorInput) input; + if (finput.getFile().getFullPath().equals(tempFile.getFullPath())) + { + return editor; + } + } + } + } + + return null; + } + } diff --git a/rse/plugins/org.eclipse.rse.ui/subsystems/org/eclipse/rse/ui/subsystems/StandardCredentialsProvider.java b/rse/plugins/org.eclipse.rse.ui/subsystems/org/eclipse/rse/ui/subsystems/StandardCredentialsProvider.java index b896655ad50..7b308b5f5b0 100644 --- a/rse/plugins/org.eclipse.rse.ui/subsystems/org/eclipse/rse/ui/subsystems/StandardCredentialsProvider.java +++ b/rse/plugins/org.eclipse.rse.ui/subsystems/org/eclipse/rse/ui/subsystems/StandardCredentialsProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2007, 2009 IBM Corporation and others. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -15,6 +15,7 @@ * Richie Yu (IBM) - [241716] Handle change expired password * Don Yantzi (IBM) - [233970] Handle messages provided by ICredentialsValidator * David Dykstal (IBM) - [261047] StandardCredentialsProvider does not cause a reacquire of a password when validation fails in a background thread + * David McKnight (IBM) - [334839] File Content Conflict is not handled properly ********************************************************************************/ package org.eclipse.rse.ui.subsystems; @@ -79,6 +80,9 @@ public class StandardCredentialsProvider extends AbstractCredentialsProvider { */ public void run() { Shell shell = getShell(); + if (shell == null){ + shell = new Shell(); // need this for the case of being prompted during workbench shutdown + } if (shell != null) { ISystemPasswordPromptDialog dialog = getPasswordPromptDialog(shell); dialog.setSystemInput(getConnectorService());