diff --git a/rse/examples/org.eclipse.rse.examples.tutorial/src/samples/model/TeamResourceAdapter.java b/rse/examples/org.eclipse.rse.examples.tutorial/src/samples/model/TeamResourceAdapter.java index d5320bb1884..e6e7391ed2c 100644 --- a/rse/examples/org.eclipse.rse.examples.tutorial/src/samples/model/TeamResourceAdapter.java +++ b/rse/examples/org.eclipse.rse.examples.tutorial/src/samples/model/TeamResourceAdapter.java @@ -12,6 +12,7 @@ * * Contributors: * Martin Oberhuber (Wind River) - Adapted original tutorial code to Open RSE. + * Xuan Chen (IBM) - [160775] [api] [breaking] [nl] rename (at least within a zip) blocks UI thread ********************************************************************************/ package samples.model; @@ -139,9 +140,9 @@ public class TeamResourceAdapter extends AbstractSystemViewAdapter implements * Intercept of parent method to actually do the rename. RSE supplies the rename GUI, but * defers the action work of renaming to this adapter method. * - * @see org.eclipse.rse.ui.view.AbstractSystemViewAdapter#doRename(Shell, Object, String) + * @see org.eclipse.rse.ui.view.AbstractSystemViewAdapter#doRename(Shell, Object, String, IProgressMonitor) */ - public boolean doRename(Shell shell, Object element, String newName) + public boolean doRename(Shell shell, Object element, String newName, IProgressMonitor monitor) { ((TeamResource)element).setName(newName); return true; diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/UniversalFileTransferUtility.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/UniversalFileTransferUtility.java index 74bf5317d53..87aaadaf241 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/UniversalFileTransferUtility.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/files/ui/resources/UniversalFileTransferUtility.java @@ -33,6 +33,7 @@ * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems * David McKnight (IBM) - [209375] new API copyRemoteResourcesToWorkspaceMultiple to optimize downloads * Rupen Mardirossian (IBM) - [208435] added constructor to nested RenameRunnable class to take in names that are previously used as a parameter for multiple renaming instances, passed through check collision as well through overloading. + * Xuan Chen (IBM) - [160775] [api] [breaking] [nl] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.files.ui.resources; @@ -1892,12 +1893,12 @@ public class UniversalFileTransferUtility ISystemArchiveHandler handler = ArchiveHandlerManager.getInstance().getRegisteredHandler(dest); - VirtualChild[] arcContents = handler.getVirtualChildrenList(); + VirtualChild[] arcContents = handler.getVirtualChildrenList(null); monitor.beginTask(FileResources.RESID_SUPERTRANSFER_PROGMON_SUBTASK_EXTRACT, arcContents.length); for (int i = 0; i < arcContents.length; i++) { - if (arcContents[i].isDirectory && handler.getVirtualChildren(arcContents[i].fullName) == null) continue; + if (arcContents[i].isDirectory && handler.getVirtualChildren(arcContents[i].fullName, null) == null) continue; String currentTargetPath = targetResource.getParent().getLocation().toOSString() + localSS.getSeparator() + useLocalSeparator(arcContents[i].fullName); IRemoteFile currentTarget = localSS.getRemoteFileObject(currentTargetPath, monitor); boolean replace = false; diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemCopyRemoteFileAction.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemCopyRemoteFileAction.java index a73590d0177..8c47063a074 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemCopyRemoteFileAction.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemCopyRemoteFileAction.java @@ -17,6 +17,7 @@ * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Kevin Doyle (IBM) - [196588] Move Dialog doesn't show Archives * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.files.ui.actions; @@ -58,6 +59,7 @@ import org.eclipse.rse.ui.dialogs.SystemRenameSingleDialog; import org.eclipse.rse.ui.dialogs.SystemSimpleContentElement; import org.eclipse.rse.ui.validators.IValidatorRemoteSelection; import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** @@ -131,7 +133,32 @@ public class SystemCopyRemoteFileAction extends SystemBaseCopyAction // -------------------------- // PARENT METHOD OVERRIDES... // -------------------------- - + public static class RenameRunnable implements Runnable + { + private IRemoteFile _targetFileOrFolder; + private String _newName; + public RenameRunnable(IRemoteFile targetFileOrFolder) + { + _targetFileOrFolder = targetFileOrFolder; + } + + public void run() { + ValidatorFileUniqueName validator = null; + SystemRenameSingleDialog dlg = new SystemRenameSingleDialog(null, true, _targetFileOrFolder, validator); // true => copy-collision-mode + + dlg.open(); + if (!dlg.wasCancelled()) + _newName = dlg.getNewName(); + else + _newName = null; + } + + public String getNewName() + { + return _newName; + } + } + /** * @see SystemBaseCopyAction#checkForCollision(Shell, IProgressMonitor, Object, Object, String) * @param shell Window to host dialog @@ -165,12 +192,9 @@ public class SystemCopyRemoteFileAction extends SystemBaseCopyAction // object's system view adaptor for its name validator. See getNameValidator in SystemViewRemoteFileAdapter. phil ValidatorFileUniqueName validator = null; // new ValidatorFileUniqueName(shell, targetFolder, srcFileOrFolder.isDirectory()); //SystemCollisionRenameDialog dlg = new SystemCollisionRenameDialog(shell, validator, oldName); - SystemRenameSingleDialog dlg = new SystemRenameSingleDialog(shell, true, targetFileOrFolder, validator); // true => copy-collision-mode - dlg.open(); - if (!dlg.wasCancelled()) - newName = dlg.getNewName(); - else - newName = null; + RenameRunnable rr = new RenameRunnable(targetFileOrFolder); + Display.getDefault().syncExec(rr); + newName = rr.getNewName(); } } catch (SystemMessageException e) { SystemBasePlugin.logError("SystemCopyRemoteFileAction.checkForCollision()", e); //$NON-NLS-1$ diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemMoveRemoteFileAction.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemMoveRemoteFileAction.java index 97074a1ddb1..2fb7e64e2eb 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemMoveRemoteFileAction.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/actions/SystemMoveRemoteFileAction.java @@ -17,12 +17,17 @@ * Kevin Doyle (IBM) - [198007] Moving multiple folders allows moving to themselves * Kevin Doyle (IBM) - [160769] Move Resource dialog allows user to continue on invalid destination * Kevin Doyle (IBM) - [199324] [nls] Move dialog SystemMessages should be added/updated + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.files.ui.actions; import java.util.Vector; +import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.viewers.Viewer; import org.eclipse.rse.core.RSECorePlugin; import org.eclipse.rse.core.events.ISystemRemoteChangeEvents; import org.eclipse.rse.core.filters.ISystemFilterReference; @@ -35,6 +40,7 @@ import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; import org.eclipse.rse.ui.ISystemMessages; import org.eclipse.rse.ui.RSEUIPlugin; import org.eclipse.rse.ui.actions.SystemBaseCopyAction; +import org.eclipse.rse.ui.messages.SystemMessageDialog; import org.eclipse.rse.ui.validators.IValidatorRemoteSelection; import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; import org.eclipse.swt.widgets.Shell; @@ -51,6 +57,86 @@ public class SystemMoveRemoteFileAction extends SystemCopyRemoteFileAction private SystemMessage invalidFilterMsg = null; protected Vector movedFiles = new Vector(); + private class MoveRemoteFileJob extends WorkspaceJob + { + + /** + * RenameJob job. + * @param message text used as the title of the job + */ + public MoveRemoteFileJob(String message) + { + super(message); + setUser(true); + } + + public IStatus runInWorkspace(IProgressMonitor monitor) + { + SystemMessage msg = getCopyingMessage(); + + IStatus status = Status.OK_STATUS; + + try + { + int steps = oldObjects.length; + monitor.beginTask(msg.getLevelOneText(), steps); + copiedOk = true; + String oldName = null; + String newName = null; + Object oldObject = null; + newNames = new String[oldNames.length]; + for (int idx=0; copiedOk && (idx 0) + { + //Get the moved file names + String movedFileName = ((IRemoteFile)movedFiles.get(0)).getName(); + for (int i=1; i<(movedFiles.size()); i++) + { + movedFileName = movedFileName + "\n" + ((IRemoteFile)movedFiles.get(i)).getName(); //$NON-NLS-1$ + } + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_MOVE_INTERRUPTED); + thisMessage.makeSubstitution(movedFileName); + SystemMessageDialog.displayErrorMessage(shell, thisMessage); + status = Status.CANCEL_STATUS; + } + else + { + SystemMessageDialog.displayErrorMessage(shell, exc.getSystemMessage()); + } + } + catch (Exception exc) + { + copiedOk = false; + exc.printStackTrace(); + } + + if (movedFiles.size() > 0) + { + copyComplete(); //Need to reflect the views. + } + + return status; + } + } + /** * Constructor */ @@ -74,6 +160,16 @@ public class SystemMoveRemoteFileAction extends SystemCopyRemoteFileAction //targetEqualsSrcMsg = null; } + + public void run(IProgressMonitor monitor) + throws java.lang.reflect.InvocationTargetException, + java.lang.InterruptedException + { + SystemMessage moveMessage = getCopyingMessage(); + moveMessage.makeSubstitution(""); //$NON-NLS-1$ + MoveRemoteFileJob moveRemoteFileJob = new MoveRemoteFileJob(moveMessage.getLevelOneText()); + moveRemoteFileJob.schedule(); + } /** * @param targetContainer will be the IRemoteFile folder selected to move into @@ -189,8 +285,9 @@ public class SystemMoveRemoteFileAction extends SystemCopyRemoteFileAction ISubSystem fileSS = targetFolder.getParentRemoteFileSubSystem(); //RSECorePlugin.getTheSystemRegistry().fireRemoteResourceChangeEvent( // ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DELETED, copiedFiles, firstSelectionParent.getAbsolutePath(), fileSS, null, null); + Viewer originatingViewer = getViewer(); RSECorePlugin.getTheSystemRegistry().fireRemoteResourceChangeEvent( - ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DELETED, movedFiles, firstSelectionParent.getAbsolutePath(), fileSS, null, null); + ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DELETED, movedFiles, firstSelectionParent.getAbsolutePath(), fileSS, null, originatingViewer); /* old release 1.0 way of doing it... diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java index 01afb2a98fd..2c5d12353a7 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteFileAdapter.java @@ -38,6 +38,7 @@ * David McKnight (IBM) - [209375] download using copyRemoteResourcesToWorkspaceMultiple * Rupen Mardirossian (IBM) - [208435] added constructor to nested RenameRunnable class to take in names that are previously used as a parameter for multiple renaming instances * David McKnight (IBM) - [209660] need to check if remote encoding has changed before using cached file + * Xuan Chen (IBM) - [160775] [api] [breaking] [nl] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.files.ui.view; @@ -153,6 +154,7 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IElementCollector; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.omg.PortableServer.AdapterActivator; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.NumberFormat; @@ -2006,7 +2008,38 @@ public class SystemViewRemoteFileAdapter } catch (SystemMessageException e) { - SystemMessageDialog.displayMessage(e); + if (monitor.isCanceled() && resultSet.size() > 0) + { + //Get the moved file names + Object thisObject = resultSet.get(0); + String copiedFileNames = null; + if (thisObject instanceof IRemoteFile) + { + copiedFileNames = ((IRemoteFile)thisObject).getName(); + for (int i=1; i<(resultSet.size()); i++) + { + if (thisObject instanceof IRemoteFile) + { + copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)thisObject).getName(); + } + } + } + //getMessage("RSEG1125").makeSubstitution(movedFileName)); + if (copiedFileNames != null) + { + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_COPY_INTERRUPTED); + thisMessage.makeSubstitution(copiedFileNames); + SystemMessageDialog.displayErrorMessage(shell, thisMessage); + } + else + { + SystemMessageDialog.displayMessage(e); + } + } + else + { + SystemMessageDialog.displayMessage(e); + } } catch (Exception e) { @@ -2035,7 +2068,47 @@ public class SystemViewRemoteFileAdapter } catch (SystemMessageException e) { - SystemMessageDialog.displayMessage(e); + if (monitor.isCanceled() && srcFileOrFolders.length > 1) + { + //ISystemViewElementAdapter adapter = fromSet.getViewAdapter(); + for (int i = 0; i < srcFileOrFolders.length; i++) + { + IRemoteFile thisCopiedFile = null; + try + { + thisCopiedFile = targetFS.getRemoteFileObject(targetFolder, srcFileOrFolders[i].getName(), monitor); + } + catch (SystemMessageException thsiException) + { + thsiException.printStackTrace(); + thisCopiedFile = null; + } + if (thisCopiedFile != null && thisCopiedFile.exists()) + { + //This object has been deleted + resultSet.addResource(thisCopiedFile); + } + } + if (resultSet.size() > 0) + { + //Get the copied file names + Object thisObject = resultSet.get(0); + String copiedFileNames = null; + copiedFileNames = ((IRemoteFile)thisObject).getName(); + for (int i=1; i<(resultSet.size()); i++) + { + thisObject = resultSet.get(i); + copiedFileNames = copiedFileNames + "\n" + ((IRemoteFile)resultSet.get(i)).getName(); //$NON-NLS-1$ + } + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_COPY_INTERRUPTED); + thisMessage.makeSubstitution(copiedFileNames); + SystemMessageDialog.displayErrorMessage(shell, thisMessage); + } + } + else + { + SystemMessageDialog.displayMessage(e); + } } catch (Exception e) { @@ -2563,13 +2636,12 @@ public class SystemViewRemoteFileAdapter /** * Perform the rename action. Defers request to the remote file subsystem */ - public boolean doRename(Shell shell, Object element, String newName) throws Exception + public boolean doRename(Shell shell, Object element, String newName, IProgressMonitor monitor) throws Exception { boolean ok = true; IRemoteFile file = (IRemoteFile) element; IRemoteFileSubSystem ss = file.getParentRemoteFileSubSystem(); - try - { + String newRemotePath = file.getParentPath() + "/" + newName; //$NON-NLS-1$ IResource localResource = null; @@ -2578,7 +2650,7 @@ public class SystemViewRemoteFileAdapter localResource = UniversalFileTransferUtility.getTempFileFor(file); } - ss.rename(file, newName, new NullProgressMonitor()); + ok = ss.rename(file, newName, monitor); if (localResource != null && localResource.exists()) { @@ -2601,14 +2673,8 @@ public class SystemViewRemoteFileAdapter // //sr.fireRemoteResourceChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_RENAMED, file, file.getParentRemoteFile(), file.getParentRemoteFileSubSystem(), null, null); // } // file.markStale(true); - - } - catch (Exception exc) - { - ok = false; - SystemMessageDialog.displayErrorMessage(shell, RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_RENAME_FILE_FAILED).makeSubstitution(file.toString())); - } - return ok; + return ok; + } /** diff --git a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteSearchResultAdapter.java b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteSearchResultAdapter.java index 3158ddf2e40..b21bcfaa570 100644 --- a/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteSearchResultAdapter.java +++ b/rse/plugins/org.eclipse.rse.files.ui/src/org/eclipse/rse/internal/files/ui/view/SystemViewRemoteSearchResultAdapter.java @@ -640,7 +640,7 @@ public class SystemViewRemoteSearchResultAdapter extends AbstractSystemViewAdapt * Return true if this was successful. Return false if it failed and you issued a msg. * Throw an exception if it failed and you want to use the generic msg. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { return false; } diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalByteStreamHandler.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalByteStreamHandler.java index 0cd45032a97..4b3393ad726 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalByteStreamHandler.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalByteStreamHandler.java @@ -13,6 +13,7 @@ * * Contributors: * {Name} (company) - description of contribution. + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.dstore.universal.miners; @@ -127,7 +128,7 @@ public class UniversalByteStreamHandler extends ByteStreamHandler String filePath = virtualFileName.substring(0, virtualIndex); handler = mgr.getRegisteredHandler(new File(filePath)); } - boolean success = handler != null && handler.add(newFile, child.path, child.name); + boolean success = handler != null && handler.add(newFile, child.path, child.name, null); if (!success) { if (status == null) return; @@ -241,7 +242,7 @@ public class UniversalByteStreamHandler extends ByteStreamHandler String filePath = virtualFileName.substring(0, virtualIndex); handler = mgr.getRegisteredHandler(new File(filePath)); } - success = handler != null && handler.add(newFile, child.path, child.name); + success = handler != null && handler.add(newFile, child.path, child.name, null); } else @@ -317,7 +318,7 @@ public class UniversalByteStreamHandler extends ByteStreamHandler String filePath = virtualFileName.substring(0, virtualIndex); handler = mgr.getRegisteredHandler(new File(filePath)); } - success = handler != null && handler.add(newFile, child.path, child.name); + success = handler != null && handler.add(newFile, child.path, child.name, null); } diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java index c32c5afd783..9a605382ef5 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/dstore/universal/miners/UniversalFileSystemMiner.java @@ -24,6 +24,7 @@ * Martin Oberhuber (Wind River) - [199548] Avoid touching files on setReadOnly() if unnecessary * Kevin Doyle (IBM) - [191548] Deleting Read-Only directory removes it from view and displays no error * Xuan Chen (IBM) - [202949] [archives] copy a folder from one connection to an archive file in a different connection does not work + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.dstore.universal.miners; @@ -275,7 +276,7 @@ public class UniversalFileSystemMiner extends Miner { return statusDone(status); } - VirtualChild child = shandler.getVirtualFile(svpath.getVirtualPart()); + VirtualChild child = shandler.getVirtualFile(svpath.getVirtualPart(), null); srcFile = child.getExtractedFile(); } else { @@ -290,7 +291,7 @@ public class UniversalFileSystemMiner extends Miner { //call ISystemArchiveHandler#add(File[] ...) to add them in batch. if (srcFile.isDirectory()) { - result = handler.add(srcFile, virtualContainer, srcName); + result = handler.add(srcFile, virtualContainer, srcName, null); if (!result) { status.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED); return statusDone(status); @@ -308,7 +309,7 @@ public class UniversalFileSystemMiner extends Miner { File[] resultFiles = (File[])nonDirectoryArrayList.toArray(new File[nonDirectoryArrayList.size()]); String[] resultNames = (String[])nonDirectoryNamesArrayList.toArray(new String[nonDirectoryNamesArrayList.size()]); //we need to add those files into the archive file as well. - result = handler.add(resultFiles, virtualContainer, resultNames); + result = handler.add(resultFiles, virtualContainer, resultNames, null); } if (result) @@ -345,18 +346,18 @@ public class UniversalFileSystemMiner extends Miner { return statusDone(status); } - VirtualChild child = shandler.getVirtualFile(svpath.getVirtualPart()); + VirtualChild child = shandler.getVirtualFile(svpath.getVirtualPart(), null); File parentDir = getFileFor(targetFolder); File destination = new File(parentDir, sourceFile.getName()); if (child.isDirectory) { - shandler.extractVirtualDirectory(svpath.getVirtualPart(), parentDir, destination); + shandler.extractVirtualDirectory(svpath.getVirtualPart(), parentDir, destination, null); } else { - shandler.extractVirtualFile(svpath.getVirtualPart(), destination); + shandler.extractVirtualFile(svpath.getVirtualPart(), destination, null); } } else // source is regular file or folder @@ -1025,11 +1026,11 @@ public class UniversalFileSystemMiner extends Miner { .getContainingArchiveString())); boolean success = !(handler == null) && handler.fullRename(oldAbsPath.getVirtualPart(), - newAbsPath.getVirtualPart()); + newAbsPath.getVirtualPart(), null); if (success && handler != null) { subject.setAttribute(DE.A_NAME, filerename.getName()); subject.setAttribute(DE.A_SOURCE, setProperties(handler - .getVirtualFile(newAbsPath.getVirtualPart()))); + .getVirtualFile(newAbsPath.getVirtualPart(), null))); status.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS); _dataStore.update(subject); } else { @@ -1429,7 +1430,7 @@ public class UniversalFileSystemMiner extends Miner { status.setAttribute(DE.A_SOURCE, "false"); //$NON-NLS-1$ return statusDone(status); } - VirtualChild child = handler.getVirtualFile(vpath.getVirtualPart()); + VirtualChild child = handler.getVirtualFile(vpath.getVirtualPart(), null); if (child.exists()) { status.setAttribute(DE.A_SOURCE, "true"); //$NON-NLS-1$ return statusDone(status); @@ -2129,7 +2130,7 @@ public class UniversalFileSystemMiner extends Miner { ISystemArchiveHandler handler = _archiveHandlerManager .getRegisteredHandler(new File(vpath .getContainingArchiveString())); - if (handler == null || !handler.delete(vpath.getVirtualPart())) { + if (handler == null || !handler.delete(vpath.getVirtualPart(), null)) { status.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + vpath.toString()); //$NON-NLS-1$ _dataStore.refresh(subject); return statusDone(status); @@ -2187,8 +2188,8 @@ public class UniversalFileSystemMiner extends Miner { return statusDone(status); } // VirtualChild child = handler.getVirtualFile(vpath.getVirtualPart()); - handler.getVirtualFile(vpath.getVirtualPart()); - handler.createFile(vpath.getVirtualPart()); + handler.getVirtualFile(vpath.getVirtualPart(), null); + handler.createFile(vpath.getVirtualPart(), null); status.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS); if (type.equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)) { @@ -2221,8 +2222,8 @@ public class UniversalFileSystemMiner extends Miner { return statusDone(status); } // VirtualChild child = handler.getVirtualFile(vpath.getVirtualPart()); - handler.getVirtualFile(vpath.getVirtualPart()); - handler.createFolder(vpath.getVirtualPart()); + handler.getVirtualFile(vpath.getVirtualPart(), null); + handler.createFolder(vpath.getVirtualPart(), null); status.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS); if (type.equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)) { @@ -2315,7 +2316,7 @@ public class UniversalFileSystemMiner extends Miner { status.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED); return statusDone(status); } - child = shandler.getVirtualFile(svpath.getVirtualPart()); + child = shandler.getVirtualFile(svpath.getVirtualPart(), null); } else { @@ -2331,7 +2332,7 @@ public class UniversalFileSystemMiner extends Miner { virtualContainer = vpath.getVirtualPart(); } - boolean result = handler.add(srcFile, virtualContainer, newName); + boolean result = handler.add(srcFile, virtualContainer, newName, null); if (result) { status.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS); @@ -2352,7 +2353,7 @@ public class UniversalFileSystemMiner extends Miner { status.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED); return statusDone(status); } - child = shandler.getVirtualFile(svpath.getVirtualPart()); + child = shandler.getVirtualFile(svpath.getVirtualPart(), null); } else { @@ -2365,10 +2366,10 @@ public class UniversalFileSystemMiner extends Miner { File destination = new File(parentDir, newName); if (child.isDirectory) { - shandler.extractVirtualDirectory(svpath.getVirtualPart(), parentDir, destination); + shandler.extractVirtualDirectory(svpath.getVirtualPart(), parentDir, destination, null); } else { - shandler.extractVirtualFile(svpath.getVirtualPart(), destination); + shandler.extractVirtualFile(svpath.getVirtualPart(), destination, null); } } else { diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalDownloadHandler.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalDownloadHandler.java index 038ae276a7c..ebda5e903b6 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalDownloadHandler.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalDownloadHandler.java @@ -13,6 +13,7 @@ * * Contributors: * {Name} (company) - description of contribution. + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.internal.dstore.universal.miners.filesystem; @@ -132,7 +133,7 @@ public class UniversalDownloadHandler extends Thread implements ICancellableHand _dataStore.refresh(arg1); return _miner.statusDone(status); } - VirtualChild vChild = handler.getVirtualFile(vpath.getVirtualPart()); + VirtualChild vChild = handler.getVirtualFile(vpath.getVirtualPart(), null); file = vChild.getExtractedFile(); } diff --git a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalSearchHandler.java b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalSearchHandler.java index 1db45130508..cc5e3dbe1c7 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalSearchHandler.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/miners/org/eclipse/rse/internal/dstore/universal/miners/filesystem/UniversalSearchHandler.java @@ -14,6 +14,7 @@ * Contributors: * Michael Berger (IBM) - Bug 147791 - symbolic links can cause circular search. * David McKnight (IBM) - [190010] cancelling search + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.internal.dstore.universal.miners.filesystem; @@ -218,7 +219,7 @@ public class UniversalSearchHandler extends Thread implements ICancellableHandle // if it's not a file search, call the handler method to search if (!_isFileSearch) { - results = vc.getHandler().search(vc.fullName, _stringMatcher); + results = vc.getHandler().search(vc.fullName, _stringMatcher, null); // if at least one match found, then send back the remote file with matches if (results != null && results.length > 0) { diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java index 3116b2ac749..7643ab7056f 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/files/LocalFileService.java @@ -23,6 +23,7 @@ * Kevin Doyle (IBM) - [199871] LocalFileService needs to implement getMessage() * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems * Kevin Doyle (IBM) - [209355] Retrieving list of FILE_TYPE_FOLDERS should return Archive's + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.services.local.files; @@ -49,8 +50,10 @@ import org.eclipse.rse.internal.services.local.LocalServiceResources; import org.eclipse.rse.services.clientserver.FileTypeMatcher; import org.eclipse.rse.services.clientserver.IMatcher; import org.eclipse.rse.services.clientserver.ISystemFileTypes; +import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.NamePatternMatcher; import org.eclipse.rse.services.clientserver.SystemEncodingUtil; +import org.eclipse.rse.services.clientserver.SystemOperationMonitor; import org.eclipse.rse.services.clientserver.archiveutils.AbsoluteVirtualPath; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; import org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler; @@ -189,6 +192,35 @@ public class LocalFileService extends AbstractFileService implements IFileServic } + private class CheckArchiveOperationStatusThread extends Thread { + + private ISystemOperationMonitor archiveOperationMonitor = null; + private IProgressMonitor monitor = null; + + public CheckArchiveOperationStatusThread(ISystemOperationMonitor archiveOperationMonitor, IProgressMonitor monitor) { + this.archiveOperationMonitor = archiveOperationMonitor; + this.monitor = monitor; + } + + public void run() + { + int a = 0; + while(!monitor.isCanceled() && !archiveOperationMonitor.isDone()) + { + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + } + + //evaluate result + + if(monitor.isCanceled() && !archiveOperationMonitor.isDone()) + { + archiveOperationMonitor.setCanceled(true); + } + } + } + public boolean upload(InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException { boolean isCancelled = false; @@ -209,7 +241,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic if (handler == null) throwCorruptArchiveException(this.getClass() + ".upload()"); //$NON-NLS-1$ else - return handler.add(stream, child.path, remoteFile, SystemEncodingUtil.ENCODING_UTF_8, hostEncoding, !isBinary); + return handler.add(stream, child.path, remoteFile, SystemEncodingUtil.ENCODING_UTF_8, hostEncoding, !isBinary, null); } if (ArchiveHandlerManager.getInstance().isArchive(destinationFile)) { @@ -217,7 +249,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic if (handler == null) throwCorruptArchiveException(this.getClass() + ".copyToArchive()"); //$NON-NLS-1$ else - return handler.add(stream, "", remoteFile, SystemEncodingUtil.ENCODING_UTF_8, hostEncoding, !isBinary); //$NON-NLS-1$ + return handler.add(stream, "", remoteFile, SystemEncodingUtil.ENCODING_UTF_8, hostEncoding, !isBinary, null); //$NON-NLS-1$ } File destinationParent = destinationFile.getParentFile(); @@ -454,48 +486,51 @@ public class LocalFileService extends AbstractFileService implements IFileServic private boolean copyToArchive(File file, File destination, String newName, IProgressMonitor monitor, String sourceEncoding, String targetEncoding, boolean isText) throws SystemMessageException { boolean ok = false; + + ISystemArchiveHandler handler = null; + String path = ""; //$NON-NLS-1$ if (ArchiveHandlerManager.isVirtual(destination.getAbsolutePath())) { VirtualChild virtualChild = ArchiveHandlerManager.getInstance().getVirtualObject(destination.getAbsolutePath()); - String path = virtualChild.fullName; + handler = virtualChild.getHandler(); + path = virtualChild.fullName; if (!virtualChild.isDirectory) { path = virtualChild.path; } - ISystemArchiveHandler handler = virtualChild.getHandler(); - if (handler == null) - throwCorruptArchiveException(this.getClass() + ".copyToArchive()"); //$NON-NLS-1$ - else - { - if (file.isDirectory()) - { - ok = handler.add(file, path, newName, sourceEncoding, targetEncoding, _fileTypeRegistry); - } - else - { - ok = handler.add(file, path, newName, sourceEncoding, targetEncoding, isText); - } - } } else if (ArchiveHandlerManager.getInstance().isArchive(destination)) { - ISystemArchiveHandler handler = ArchiveHandlerManager.getInstance().getRegisteredHandler(destination); - if (handler == null) - throwCorruptArchiveException(this.getClass() + ".copyToArchive()"); //$NON-NLS-1$ - else - { - if (file.isDirectory()) - { - ok = handler.add(file, "", newName, sourceEncoding, targetEncoding, _fileTypeRegistry); //$NON-NLS-1$ - } - else - { - ok = handler.add(file, "", newName, sourceEncoding, targetEncoding, isText); //$NON-NLS-1$ - } - } + handler = ArchiveHandlerManager.getInstance().getRegisteredHandler(destination); } + + if (handler == null) + throwCorruptArchiveException(this.getClass() + ".copyToArchive()"); //$NON-NLS-1$ + + ISystemOperationMonitor archiveOperationMonitor = null; + if (null != monitor) + { + archiveOperationMonitor = new SystemOperationMonitor(); + CheckArchiveOperationStatusThread checkArchiveOperationStatusThread = new CheckArchiveOperationStatusThread(archiveOperationMonitor, monitor); + checkArchiveOperationStatusThread.start(); + } + + if (file.isDirectory()) + { + ok = handler.add(file, path, newName, sourceEncoding, targetEncoding, _fileTypeRegistry, archiveOperationMonitor); + } + else + { + ok = handler.add(file, path, newName, sourceEncoding, targetEncoding, isText, archiveOperationMonitor); + } + if (!ok) { + if (null != monitor && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } // SystemPlugin.logError("LocalFileSubSystemImpl.copyToArchive(): Handler's add() method returned false."); SystemMessage msg = getMessage("RSEF5006"); //$NON-NLS-1$ msg.makeSubstitution(destination.getName(), "localhost"); //$NON-NLS-1$ @@ -872,7 +907,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic throwCorruptArchiveException(this.getClass() + ".createFileInArchive()"); //$NON-NLS-1$ else { - if (!handler.createFile(child.fullName)) + if (!handler.createFile(child.fullName, null)) { //SystemPlugin.logError("LocalFileSubSystemImpl.createFileInArchive(): Archive Handler's createFile method returned false. Couldn't create virtual object."); throw new SystemMessageException(getMessage("RSEG1124").makeSubstitution(newFile)); //$NON-NLS-1$ @@ -928,7 +963,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic ISystemArchiveHandler handler = child.getHandler(); if (handler == null) throwCorruptArchiveException(this.getClass() + ".createFolderInArchive()"); //$NON-NLS-1$ - else if (!handler.createFolder(child.fullName)) + else if (!handler.createFolder(child.fullName, null)) { // SystemPlugin.logError("LocalFileSubSystemImpl.createFolderInArchive(): Archive Handler's createFolder method returned false. Couldn't create virtual object."); throw new SystemMessageException(getMessage("RSEG1124").makeSubstitution(newFolder)); //$NON-NLS-1$ @@ -942,10 +977,15 @@ public class LocalFileService extends AbstractFileService implements IFileServic { fileName = fileName.substring(0, fileName.length() - ArchiveHandlerManager.VIRTUAL_SEPARATOR.length()); } + File remoteParentFile = new File(remoteParent); + if (ArchiveHandlerManager.getInstance().isArchive(remoteParentFile)) + { + remoteParent = remoteParent + ArchiveHandlerManager.VIRTUAL_SEPARATOR; + } File fileToDelete = new File(remoteParent, fileName); if (ArchiveHandlerManager.isVirtual(fileToDelete.getAbsolutePath())) { - return deleteFromArchive(fileToDelete); + return deleteFromArchive(fileToDelete, monitor); } else if (ArchiveHandlerManager.getInstance().isArchive(fileToDelete)) { @@ -989,14 +1029,27 @@ public class LocalFileService extends AbstractFileService implements IFileServic * * @param destination virtual file to delete from archive */ - protected boolean deleteFromArchive(File destination) throws SystemMessageException + protected boolean deleteFromArchive(File destination, IProgressMonitor monitor) throws SystemMessageException { VirtualChild child = ArchiveHandlerManager.getInstance().getVirtualObject(destination.getAbsolutePath()); ISystemArchiveHandler handler = child.getHandler(); if (handler == null) throwCorruptArchiveException(this.getClass() + ".deleteFromArchive()"); //$NON-NLS-1$ - else if (!handler.delete(child.fullName)) + ISystemOperationMonitor archiveOperationMonitor = null; + if (null != monitor) { + archiveOperationMonitor = new SystemOperationMonitor(); + CheckArchiveOperationStatusThread checkArchiveOperationStatusThread = new CheckArchiveOperationStatusThread(archiveOperationMonitor, monitor); + checkArchiveOperationStatusThread.start(); + } + boolean returnValue = handler.delete(child.fullName, archiveOperationMonitor); + if (!returnValue) + { + if (monitor != null && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } // SystemPlugin.logError("LocalFileSubSystemImpl.deleteFromArchive(): Archive Handler's delete method returned false. Couldn't delete virtual object."); throw new SystemMessageException(getMessage("RSEG1125").makeSubstitution(destination)); //$NON-NLS-1$ } @@ -1014,7 +1067,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic File fileToRename = new File(remoteParent, oldName); if (ArchiveHandlerManager.isVirtual(fileToRename.getAbsolutePath())) { - return renameVirtualFile(fileToRename, newName); + return renameVirtualFile(fileToRename, newName, monitor); } File newFile = new File(remoteParent, newName); boolean result = fileToRename.renameTo(newFile); @@ -1041,7 +1094,7 @@ public class LocalFileService extends AbstractFileService implements IFileServic * @param newName the new name of the virtual file * @return whether the operation was successful or not */ - protected boolean renameVirtualFile(File destination, String newName) throws SystemMessageException + protected boolean renameVirtualFile(File destination, String newName, IProgressMonitor monitor) throws SystemMessageException { VirtualChild child = ArchiveHandlerManager.getInstance().getVirtualObject(destination.getAbsolutePath()); ISystemArchiveHandler handler = child.getHandler(); @@ -1051,11 +1104,25 @@ public class LocalFileService extends AbstractFileService implements IFileServic } else { - boolean retval = handler.rename(child.fullName, newName); + ISystemOperationMonitor archiveOperationMonitor = null; + if (null != monitor) + { + archiveOperationMonitor = new SystemOperationMonitor(); + CheckArchiveOperationStatusThread checkArchiveOperationStatusThread = new CheckArchiveOperationStatusThread(archiveOperationMonitor, monitor); + checkArchiveOperationStatusThread.start(); + } + + boolean retval = handler.rename(child.fullName, newName, archiveOperationMonitor); if (!retval) { + if (null != monitor && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } // SystemPlugin.logError("LocalFileSubSystemImpl.renameVirtualFile(): Archive Handler's rename method returned false. Couldn't rename virtual object."); - throw new SystemMessageException(getMessage("RSEG1127").makeSubstitution(child.fullName)); //$NON-NLS-1$ + //SystemMessageDialog.displayErrorMessage(shell, RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_RENAME_FILE_FAILED).makeSubstitution(file.toString())); + throw new SystemMessageException(getMessage("RSEF1301").makeSubstitution(child.fullName)); //$NON-NLS-1$ } return retval; } @@ -1086,7 +1153,21 @@ public class LocalFileService extends AbstractFileService implements IFileServic { if (copy(srcParent, srcName, tgtParent, tgtName, monitor)) { - movedOk = delete(srcParent, srcName, monitor); + try + { + movedOk = delete(srcParent, srcName, monitor); + } + catch (SystemMessageException exc) + { + if (monitor.isCanceled()) + { + //This mean the copy operation is ok, but delete operation has been canceled by user. + //The delete() call will take care of recovered from the cancel operation. + //So we need to make sure to remove the already copied file/folder. + delete(tgtParent, tgtName, null); + } + throw exc; + } } } return movedOk; @@ -1261,16 +1342,58 @@ public class LocalFileService extends AbstractFileService implements IFileServic boolean folderCopy = sourceFolderOrFile.isDirectory(); String src = sourceFolderOrFile.getAbsolutePath(); VirtualChild child = ArchiveHandlerManager.getInstance().getVirtualObject(sourceFolderOrFile.getAbsolutePath()); + ISystemOperationMonitor archiveOperationMonitor = null; + CheckArchiveOperationStatusThread checkArchiveOperationStatusThread = null; + if (null != monitor) + { + archiveOperationMonitor = new SystemOperationMonitor(); + checkArchiveOperationStatusThread = new CheckArchiveOperationStatusThread(archiveOperationMonitor, monitor); + } if (!(ArchiveHandlerManager.isVirtual(targetFolder.getAbsolutePath())) && !ArchiveHandlerManager.getInstance().isArchive(targetFolder)) { // this is an optimization to speed up extractions from large zips. Instead of // extracting to a temp location and then copying the temp files to the target location // we simply instruct the handler to extract to the target location. - return child.getExtractedFile(new File(targetFolder, child.name), sourceEncoding, isText); + if (null != monitor) + { + checkArchiveOperationStatusThread.start(); + } + File destinationFile = new File(targetFolder, child.name); + boolean returnValue = child.getExtractedFile(destinationFile, sourceEncoding, isText, archiveOperationMonitor); + if (!returnValue) + { + if (destinationFile.isDirectory()) + { + deleteContents(destinationFile, monitor); + } + else + { + destinationFile.delete(); + } + + if (monitor != null && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } + // SystemPlugin.logError("LocalFileSubSystemImpl.renameVirtualFile(): Archive Handler's rename method returned false. Couldn't rename virtual object."); + //SystemMessageDialog.displayErrorMessage(shell, RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_RENAME_FILE_FAILED).makeSubstitution(file.toString())); + throw new SystemMessageException(getMessage("RSEF1301").makeSubstitution(child.fullName)); //$NON-NLS-1$ + } + return returnValue; } - src = child.getExtractedFile(sourceEncoding, isText).getAbsolutePath(); - + if (null != monitor) + { + checkArchiveOperationStatusThread.start(); + } + + src = child.getExtractedFile(sourceEncoding, isText, archiveOperationMonitor).getAbsolutePath(); + if (monitor != null && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } if (child.isDirectory) { File tempSource = null; @@ -1294,15 +1417,25 @@ public class LocalFileService extends AbstractFileService implements IFileServic if (handler == null) throwCorruptArchiveException(this.getClass() + ".copy()"); //$NON-NLS-1$ else - handler.extractVirtualDirectory(child.fullName, tempSource, sourceEncoding, isText); + handler.extractVirtualDirectory(child.fullName, tempSource, sourceEncoding, isText, archiveOperationMonitor); src = tempSource.getAbsolutePath() + File.separatorChar + child.name; } if (ArchiveHandlerManager.isVirtual(targetFolder.getAbsolutePath()) || ArchiveHandlerManager.getInstance().isArchive(targetFolder)) { File source = new File(src); - return copyToArchive(source, targetFolder, newName, monitor, SystemEncodingUtil.ENCODING_UTF_8, targetEncoding, isText); + boolean returnValue = copyToArchive(source, targetFolder, newName, monitor, SystemEncodingUtil.ENCODING_UTF_8, targetEncoding, isText); + if (!returnValue) + { + if (monitor != null && monitor.isCanceled()) + { + //This operation has been canceled by the user. + throw new SystemMessageException(getMessage("RSEG1067")); //$NON-NLS-1$ + } + } + return returnValue; } - + + //Don't think the code below here ever got executed, since it scenario has been covered by extract directly to the destination archive file. String target = targetFolder.getAbsolutePath() + java.io.File.separator + newName; // handle embedded blanks of from or to name... if (src.indexOf(' ') >= 0) @@ -1359,9 +1492,14 @@ public class LocalFileService extends AbstractFileService implements IFileServic public boolean copyBatch(String[] srcParents, String[] srcNames, String tgtParent, IProgressMonitor monitor) throws SystemMessageException { boolean ok = true; + SystemMessage msg = getMessage("RSEG1117"); //$NON-NLS-1$ + String deletingMessage = msg.makeSubstitution("").getLevelOneText(); //$NON-NLS-1$ + monitor.beginTask(deletingMessage, srcParents.length); for (int i = 0; i < srcParents.length; i++) { + monitor.subTask(msg.makeSubstitution(srcNames[i]).getLevelOneText()); ok = ok && copy(srcParents[i], srcNames[i], tgtParent, srcNames[i], monitor); + monitor.worked(1); } return ok; } diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java index a2913206647..29d87fb6ba0 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/search/LocalSearchHandler.java @@ -13,6 +13,7 @@ * * Contributors: * Michael Berger (IBM) - Bug 147791 - symbolic links can cause circular search. + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.internal.services.local.search; @@ -236,7 +237,7 @@ public class LocalSearchHandler implements ISearchHandler // method if (!_isFileSearch && vc != null) { - matches = vc.getHandler().search(vc.fullName, _stringMatcher); + matches = vc.getHandler().search(vc.fullName, _stringMatcher, null); IHostSearchResult[] results = convert(file, matches); /** TODO - how to store search results related to files diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/ISystemOperationMonitor.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/ISystemOperationMonitor.java new file mode 100644 index 00000000000..d1a5dad2891 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/ISystemOperationMonitor.java @@ -0,0 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2007, 2007 IBM Corporation. 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 + * + * Contributors: + * {Name} (company) - description of contribution. + * + * Xuan Chen (IBM) - initial API and implementation + ********************************************************************************/ + +package org.eclipse.rse.services.clientserver; + + + +/** + * + */ +public interface ISystemOperationMonitor +{ + /** + * Notifies that the work is done; that is, either the main task is completed + * or the user canceled it. This method may be called more than once + * (implementations should be prepared to handle this case). + */ + public boolean isDone(); + + /** + * Sets the done state to the given value. + * + * @param value true indicates that this operation has finished + * false clears this flag + * @see #isDone() + */ + public void setDone(boolean value); + /** + * Returns whether cancelation of current operation has been requested. + * Long-running operations should poll to see if cancelation + * has been requested. + * + * @return true if cancellation has been requested, + * and false otherwise + * @see #setCanceled(boolean) + */ + public boolean isCanceled(); + + + /** + * Sets the cancel state to the given value. + * + * @param value true indicates that cancelation has + * been requested (but not necessarily acknowledged); + * false clears this flag + * @see #isCanceled() + */ + public void setCanceled(boolean value); + +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemOperationMonitor.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemOperationMonitor.java new file mode 100644 index 00000000000..eee45b13cab --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemOperationMonitor.java @@ -0,0 +1,43 @@ +/******************************************************************************** + * Copyright (c) 2007, 2007 IBM Corporation. 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 + * + * Contributors: + * {Name} (company) - description of contribution. + * + * Xuan Chen (IBM) - initial API and implementation + ********************************************************************************/ + + +package org.eclipse.rse.services.clientserver; + +public class SystemOperationMonitor implements ISystemOperationMonitor +{ + private boolean canceled = false; + private boolean done = false; + + + public boolean isDone() + { + return done; + } + + public void setDone(boolean value) + { + done = value; + } + + public boolean isCanceled() + { + return canceled; + } + + + + public void setCanceled(boolean value) + { + canceled = value; + } +} diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemReentrantMutex.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemReentrantMutex.java new file mode 100644 index 00000000000..da194625209 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/SystemReentrantMutex.java @@ -0,0 +1,210 @@ +/******************************************************************************** + * Copyright (c) 2007, 2007 IBM Corporation. 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 + * + * Contributors: + * {Name} (company) - description of contribution. + * + * Xuan Chen (IBM) - initial API and implementation + ********************************************************************************/ + +package org.eclipse.rse.services.clientserver; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * A SystemMutex Exclusion Lock for Threads that need to access a resource + * in a serialized manner. + * If the request for the lock is running on the same thread who is currently holding the lock, + * it will "borrow" the lock, and the call to waitForLock() will go through. + * An SystemOperationMonitor is accepted + * in order to support cancellation when waiting for the SystemMutex. + * This is a clone for org.eclipse.rse.services.Mutex with some modification to make sure the + * sequential calls to waitForLock() method in the same thread will not be blocked. + * + * Usage Example: + * + * private SystemMutex fooMutex = new SystemMutex(); + * boolean doFooSerialized()(ISystemOperationMonitor monitor) { + * int mutexLockStatus = SystemMutex.LOCK_STATUS_NOLOCK; + * mutexLockStatus = fooMutex.waitForLock(monitor, 1000); + * if (SystemMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { + * try { + * return doFoo(); + * } finally { + * //We only release the mutex if we acquire it, not borrowed it. + * if (SystemMutex.LOCK_STATUS_AQUIRED == mutexLockStatus) + * { + * fooMutex.release(); + * } + * } + * } + * return false; + * } + * + * + */ +public class SystemReentrantMutex { + + private boolean fLocked = false; + private List fWaitQueue = new LinkedList(); + private Thread threadLockThisMutex = null; + public static final int LOCK_STATUS_NOLOCK = 0; //No lock acquired or borrowed + public static final int LOCK_STATUS_AQUIRED = 1; //Lock is acquired + public static final int LOCK_STATUS_BORROWED = 2; //Lock is borrowed, since it is running + //on the same thread as the one holding the lock + + /** + * Creates an instance of SystemMutex. + */ + public SystemReentrantMutex() { + } + + /** + * Try to acquire the lock maintained by this mutex. + * + * If the thread needs to wait before it can acquire the mutex, it + * will wait in a first-come-first-serve fashion. In case a progress + * monitor was given, it will be updated and checked for cancel every + * second. + * + * @param monitor SystemOperationMonitor. May be null. + * @param timeout Maximum wait time given in milliseconds. + * @return LOCK_STATUS_AQUIRED if the lock was acquired successfully. + * LOCK_STATUS_BORROWED if the lock was borrowed. + * LOCK_STATUS_NOLOCK if otherwise. + */ + public int waitForLock(ISystemOperationMonitor monitor, long timeout) { + if (Thread.interrupted()) { + return LOCK_STATUS_NOLOCK; + } + if (monitor!=null && monitor.isCanceled()) { + return LOCK_STATUS_NOLOCK; + } + final Thread myself = Thread.currentThread(); + synchronized(fWaitQueue) { + if (!fLocked) { + //acquire the lock immediately. + fLocked = true; + threadLockThisMutex = myself; + return LOCK_STATUS_AQUIRED; + } else { + fWaitQueue.add(myself); + } + } + //need to wait for the lock. + int lockStatus = LOCK_STATUS_NOLOCK; + try { + long start = System.currentTimeMillis(); + long timeLeft = timeout; + //It could be possible this function is called with null as monitor + //And we don't want to wait forever here + long pollTime = (timeLeft > 1000) ? 1000 : timeLeft; + long nextProgressUpdate = start+500; + boolean canceled = false; + while (timeLeft>0 && !canceled && lockStatus == LOCK_STATUS_NOLOCK) { + //is it my turn yet? Check wait queue and wait + synchronized(fWaitQueue) { + if (!fLocked && fWaitQueue.get(0) == myself) { + fWaitQueue.remove(0); + fLocked = true; + lockStatus = LOCK_STATUS_AQUIRED; + threadLockThisMutex = myself; + } else + { + if (threadLockThisMutex == myself && fWaitQueue.contains(myself)) + { + fWaitQueue.remove(myself); + fLocked = true; + lockStatus = LOCK_STATUS_BORROWED; + } + else + { + long waitTime = timeLeft > pollTime ? pollTime : timeLeft; + fWaitQueue.wait(waitTime); + Object firstInQueue = fWaitQueue.get(0); + boolean amIFirstInQueue = false; + if (firstInQueue == null || firstInQueue == myself) + { + amIFirstInQueue = true; + } + if (!fLocked && amIFirstInQueue) { + fWaitQueue.remove(0); + fLocked = true; + lockStatus = LOCK_STATUS_AQUIRED; + threadLockThisMutex = myself; + } + } + } + } + if (lockStatus == LOCK_STATUS_NOLOCK) { + //Need to continue waiting + long curTime = System.currentTimeMillis(); + timeLeft = start + timeout - curTime; + if (monitor!=null) { + canceled = monitor.isCanceled(); + if (!canceled && (curTime>nextProgressUpdate)) { + nextProgressUpdate+=1000; + } + } + } + } + } catch(InterruptedException e) { + //canceled waiting -> no lock acquired + } finally { + if (lockStatus == LOCK_STATUS_NOLOCK) { + synchronized(fWaitQueue) { + fWaitQueue.remove(myself); + } + } + } + return lockStatus; + } + + /** + * Release this mutex's lock. + * + * May only be called by the same thread that originally acquired + * the SystemMutex. + */ + public void release() { + synchronized(fWaitQueue) { + fLocked=false; + if (!fWaitQueue.isEmpty()) { + fWaitQueue.notifyAll(); + } + } + } + + /** + * Return this Mutex's lock status. + * @return true if this mutex is currently acquired by a thread. + */ + public boolean isLocked() { + synchronized(fWaitQueue) { + return fLocked; + } + } + + /** + * Interrupt all threads waiting for the Lock, causing their + * {@link #waitForLock(ISystemOperationMonitor, long)} method to return + * false. + * This should be called if the resource that the Threads are + * contending for, becomes unavailable for some other reason. + */ + public void interruptAll() { + synchronized(fWaitQueue) { + Iterator it = fWaitQueue.iterator(); + while (it.hasNext()) { + Thread aThread = (Thread)it.next(); + aThread.interrupt(); + } + } + } + +} diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ArchiveHandlerManager.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ArchiveHandlerManager.java index 87a168c62fb..0a9b599b1b8 100644 --- a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ArchiveHandlerManager.java +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ArchiveHandlerManager.java @@ -15,6 +15,7 @@ * {Name} (company) - description of contribution. * Xuan Chen (IBM) - [194293] [Local][Archives] Saving file second time in an Archive Errors * Xuan Chen (IBM) - [202949] [archives] copy a folder from one connection to an archive file in a different connection does not work + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.services.clientserver.archiveutils; @@ -79,7 +80,7 @@ public class ArchiveHandlerManager if (virtualpath == null) virtualpath = ""; //$NON-NLS-1$ ISystemArchiveHandler handler = getRegisteredHandler(file); if (handler == null || !handler.exists()) throw new IOException(); - return handler.getVirtualChildren(virtualpath); + return handler.getVirtualChildren(virtualpath, null); } /** @@ -97,7 +98,7 @@ public class ArchiveHandlerManager if (virtualpath == null) virtualpath = ""; //$NON-NLS-1$ ISystemArchiveHandler handler = getRegisteredHandler(file); if (handler == null) return null; - return handler.getVirtualChildFolders(virtualpath); + return handler.getVirtualChildFolders(virtualpath, null); } /** @@ -187,7 +188,7 @@ public class ArchiveHandlerManager File file = new File(zipfile); ISystemArchiveHandler handler = getRegisteredHandler(file); if (handler == null) return new VirtualChild(avp.getVirtualPart(), new File(avp.getContainingArchiveString())); - VirtualChild vc = handler.getVirtualFile(avp.getVirtualPart()); + VirtualChild vc = handler.getVirtualFile(avp.getVirtualPart(), null); return vc; } @@ -484,7 +485,7 @@ public class ArchiveHandlerManager { ISystemArchiveHandler handler = getRegisteredHandler(archive); if (handler == null || !handler.exists()) return 0; - VirtualChild[] allEntries = handler.getVirtualChildrenList(); + VirtualChild[] allEntries = handler.getVirtualChildrenList(null); int total = 0; for (int i = 0; i < allEntries.length; i++) { diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ISystemArchiveHandler.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ISystemArchiveHandler.java index f7ae942d198..24b28d34821 100644 --- a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ISystemArchiveHandler.java +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/ISystemArchiveHandler.java @@ -12,6 +12,7 @@ * * Contributors: * {Name} (company) - description of contribution. + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.services.clientserver.archiveutils; @@ -20,6 +21,7 @@ import java.io.File; import java.io.InputStream; import org.eclipse.rse.services.clientserver.ISystemFileTypes; +import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.search.SystemSearchLineMatch; import org.eclipse.rse.services.clientserver.search.SystemSearchStringMatcher; @@ -45,23 +47,28 @@ public interface ISystemArchiveHandler * in a flat format, where the entries' filenames are prepended by * the path to the entry within the virtual file system. If there * are no entries in the file, returns an array of size 0. + * @param archiveOperationMonitor the operation progress monitor */ - public VirtualChild[] getVirtualChildrenList(); + public VirtualChild[] getVirtualChildrenList(ISystemOperationMonitor archiveOperationMonitor); /** * @return an array containing all the entries in the archive file * in a flat format, whose full paths begin with the String parent. * Returns an array of length 0 if there are no such entries. + * @param parent full path of the parent + * @param archiveOperationMonitor the operation progress monitor */ - public VirtualChild[] getVirtualChildrenList(String parent); + public VirtualChild[] getVirtualChildrenList(String parent, ISystemOperationMonitor archiveOperationMonitor); /** * @return an array containing the virtual children of the virtual * directory named fullVirtualName. If fullVirtualName is "", * returns the top level in the virtual file system tree. If there are no * values to return, returns null. + * @param fullVirtualName full virtual path of the parent + * @param archiveOperationMonitor the operation progress monitor */ - public VirtualChild[] getVirtualChildren(String fullVirtualName); + public VirtualChild[] getVirtualChildren(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * @return an array containing the virtual children of the virtual @@ -69,22 +76,28 @@ public interface ISystemArchiveHandler * If fullVirtualName is "", * returns the top level of directories in the virtual file system tree. * If there are no values to return, returns null. + * @param fullVirtualName full virtual path of the parent + * @param archiveOperationMonitor the operation progress monitor */ - public VirtualChild[] getVirtualChildFolders(String fullVirtualName); + public VirtualChild[] getVirtualChildFolders(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * @return the virtual File or Folder referred to by fullVirtualName. * This method never returns null. In cases where the VirtualChild does not * physically exist in the archive, this method returns a new VirtualChild object * whose exists() method returns false. + * @param fullVirtualName full virtual path of the object to retrieve + * @param archiveOperationMonitor the operation progress monitor */ - public VirtualChild getVirtualFile(String fullVirtualName); + public VirtualChild getVirtualFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * @return Whether or not the virtual file or folder named fullVirtualName * exists in the archive (physically). + * @param fullVirtualName full virtual path of the object + * @param archiveOperationMonitor the operation progress monitor */ - public boolean exists(String fullVirtualName); + public boolean exists(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * @return Whether or not the handler exists. Usually false if the archive @@ -114,9 +127,10 @@ public interface ISystemArchiveHandler * placing the results in destination. * @param fullVirtualName The full path and name of the virtual file in the archive. * @param destination The destination file for the extracted virtual file. + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualFile(String fullVirtualName, File destination); + public boolean extractVirtualFile(String fullVirtualName, File destination, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts the virtual file named fullVirtualName from the archive, @@ -126,9 +140,10 @@ public interface ISystemArchiveHandler * @param destination The destination file for the extracted virtual file. * @param sourceEncoding The encoding of the file in the archive. * @param isText Whether or not the virtual file is a text file. + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualFile(String fullVirtualName, File destination, String sourceEncoding, boolean isText); + public boolean extractVirtualFile(String fullVirtualName, File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts the directory dir (and its children) from @@ -136,9 +151,10 @@ public interface ISystemArchiveHandler * @param dir The full name of the virtual directory to extract * @param destinationParent A handle to the directory in which the extracted * directory will be placed as a subdirectory. + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualDirectory(String dir, File destinationParent); + public boolean extractVirtualDirectory(String dir, File destinationParent, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts the directory dir (and its children) from @@ -150,9 +166,10 @@ public interface ISystemArchiveHandler * directory will be placed as a subdirectory. * @param sourceEncoding The encoding of the files in the archive. * @param isText Whether or not the files in the directory are text files + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualDirectory(String dir, File destinationParent, String sourceEncoding, boolean isText); + public boolean extractVirtualDirectory(String dir, File destinationParent, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts the directory dir (and its children) from @@ -164,9 +181,10 @@ public interface ISystemArchiveHandler * @param destination A handle to the directory that will be created. Whatever * contents are in that directory will be replaced with what is extracted from * the archive. + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualDirectory(String dir, File destinationParent, File destination); + public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts the directory dir (and its children) from @@ -182,9 +200,10 @@ public interface ISystemArchiveHandler * the archive. * @param sourceEncoding The encoding of the files in the archive. * @param isText Whether or not the files to be extracted in the directory are all text files + * @param archiveOperationMonitor the operation progress monitor * @return true iff the extraction is successful */ - public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, String sourceEncoding, boolean isText); + public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Compresses the file file and adds it to the archive, @@ -192,9 +211,13 @@ public interface ISystemArchiveHandler * name as the parameter name. If the virtual path does not exist * in the archive, create it. If file is a directory, copy it and * its contents into the archive, maintaining the tree structure. + * @param file the file to be added to the archive + * @param virtualPath the destination of the file + * @param name the name of the result virtual file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(File file, String virtualPath, String name); + public boolean add(File file, String virtualPath, String name, ISystemOperationMonitor archiveOperationMonitor); /** * Compresses the file file and adds it to the archive, @@ -203,9 +226,16 @@ public interface ISystemArchiveHandler * name as the parameter name. If the virtual path does not exist * in the archive, create it. If file is a directory, copy it and * its contents into the archive, maintaining the tree structure. + * @param file the file to be added to the archive + * @param virtualPath the destination of the file + * @param name the name of the result virtual file + * @param sourceEncoding the encoding of the source file + * @param targetEncoding the encoding of the result file + * @param isText is the file a text file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText); + public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Compresses the bytes in the InputStream stream and adds them as an entry to the archive, @@ -213,9 +243,16 @@ public interface ISystemArchiveHandler * placing it in the virtual directory virtualPath. Pass the * name as the parameter name. If the virtual path does not exist * in the archive, create it. + * @param stream the InputStream to be added as an entry to the archive + * @param virtualPath the destination of the stream + * @param name the name of the result virtual file + * @param sourceEncoding the encoding of the source stream + * @param targetEncoding the encoding of the result file + * @param isText is the file a text file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText); + public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Compresses the file file and adds it to the archive, @@ -224,9 +261,16 @@ public interface ISystemArchiveHandler * name as the parameter name. If the virtual path does not exist * in the archive, create it. If file is a directory, copy it and * its contents into the archive, maintaining the tree structure. + * @param file the file to be added to the archive + * @param virtualPath the destination of the file + * @param name the name of the result virtual file + * @param sourceEncoding the encoding of the source file + * @param targetEncoding the encoding of the result file + * @param typeRegistery file transfer mode (binary or text) of this file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes typeRegistery); + public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes typeRegistery, ISystemOperationMonitor archiveOperationMonitor); /** * A generalization of the add method. @@ -234,9 +278,13 @@ public interface ISystemArchiveHandler * in the virtual directory virtualPath. Pass the names of the files * as the parameter names, where files[i] has the name names[i]. * If the virtual path does not exist in the archive, create it. + * @param files the list of files to be added to the archive + * @param virtualPath the destination of the file + * @param names the names of the result virtual files + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(File[] files, String virtualPath, String[] names); + public boolean add(File[] files, String virtualPath, String[] names, ISystemOperationMonitor archiveOperationMonitor); /** * A generalization of the add method. @@ -245,17 +293,28 @@ public interface ISystemArchiveHandler * specified by encodings. Pass the names of the files * as the parameter names, where files[i] has the name names[i]. * If the virtual path does not exist in the archive, create it. + * @param files the list of files to be added to the archive + * @param virtualPath the destination of the files + * @param names the names of the result virtual files + * @param sourceEncodings the encoding of the source files + * @param targetEncodings the encoding of the result files + * @param isText file transfer mode (binary or text) of the files + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the add was successful */ - public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText); + public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText, ISystemOperationMonitor archiveOperationMonitor); /** * Compress the file file and replace the virtual file * referred to by fullVirtualName with the compressed file. * Pass the name of the file as the parameter name. + * @param fullVirtualName the path of the file to be replaced + * @param file the file to be added to the archive + * @param name the name of the file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the replace was successful */ - public boolean replace(String fullVirtualName, File file, String name); + public boolean replace(String fullVirtualName, File file, String name, ISystemOperationMonitor archiveOperationMonitor); /** * Compress the InputStream stream and replace the virtual file @@ -263,58 +322,81 @@ public interface ISystemArchiveHandler * Pass the name of the new entry as the parameter name, the * encoding of the entry as encoding and whether or not the entry * isText or not. + * @param fullVirtualName the path of the file to be replaced + * @param stream the InputStream to be added as an entry to the archive + * @param name the name of the result virtual file + * @param sourceEncoding the encoding of the source stream + * @param targetEncoding the encoding of the result file + * @param isText is the file a text file + * @param archiveOperationMonitor the operation progress monitor * @return true if and only if the replace was successful */ - public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText); + public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor); /** * Deletes the entry fullVirtualName from the archive, and returns * whether or not the deletion was successful. + * @param fullVirtualName the path of the file to be deleted + * @param archiveOperationMonitor the operation progress monitor + * @return true if and only if the replace was successful */ - public boolean delete(String fullVirtualName); + public boolean delete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * Renames the entry fullVirtualName to the new name * newName while still leaving the entry in the same virtual - * directory. Returns true if and only if the rename was successfull. + * directory. Returns true if and only if the rename was successful. + * @param fullVirtualName the path of the file to be renamed + * @param archiveOperationMonitor the operation progress monitor + * @return true if and only if the replace was successful */ - public boolean rename(String fullVirtualName, String newName); + public boolean rename(String fullVirtualName, String newName, ISystemOperationMonitor archiveOperationMonitor); /** * Moves the entry fullVirtualName to the location * specified by destinationVirtualPath, while leaving the entry with - * the same name as before. Returns true if and only if the move was successfull. + * the same name as before. + * @param fullVirtualName the path of the file to be renamed + * @param destinationVirtualPath the destination of the file to move to + * @param archiveOperationMonitor the operation progress monitor + * @return true if and only if the replace was successful */ - public boolean move(String fullVirtualName, String destinationVirtualPath); - + public boolean move(String fullVirtualName, String destinationVirtualPath, ISystemOperationMonitor archiveOperationMonitor); + /** * Replaces the full name and path of the entry fullVirtualName * with the new full name and path newFullVirtualName. - * Returns true if and only if the operation was successfull. + * @param fullVirtualName the path of the file to be renamed + * @param newFullVirtualName the full path of the virtual file name + * @param archiveOperationMonitor the operation progress monitor + * @return true if and only if the replace was successful */ - public boolean fullRename(String fullVirtualName, String newFullVirtualName); + public boolean fullRename(String fullVirtualName, String newFullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * Extracts and returns the specified list of virtual files from the archive. * @param fullNames The list of files to return + * @param archiveOperationMonitor the operation progress monitor * @return An array of handles to the extracted files. If fullNames has length 0 * then this method returns an array of length 0. */ - public File[] getFiles(String[] fullNames); + public File[] getFiles(String[] fullNames, ISystemOperationMonitor archiveOperationMonitor); /** * Creates a new, empty folder in the archive. If parent folders do not exist either, creates them. * @param fullVirtualName The full name and path of the new folder within the virtual file system. + * @param archiveOperationMonitor the operation progress monitor * @return Whether or not the creation was successful. */ - public boolean createFolder(String fullVirtualName); + public boolean createFolder(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * Creates a new, empty file in the archive. If parent folders do not exist either, creates them. * @param fullVirtualName The full name and path of the new file within the virtual file system. + * @param archiveOperationMonitor the operation progress monitor * @return Whether or not the creation was successful. */ - public boolean createFile(String fullVirtualName); + public boolean createFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor); /** * Gets the archive-type specific standard name for the VirtualChild @@ -328,10 +410,11 @@ public interface ISystemArchiveHandler * A good implementation will not actually extract the file to disk. * @param fullVirtualName the virtual file to search. * @param matcher the pattern matcher to use. + * @param archiveOperationMonitor the operation progress monitor * @return an array of match objects corresponding to lines where matches were found. * Returns an empty array if there are no results. */ - public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher); + public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher, ISystemOperationMonitor archiveOperationMonitor); /** * Gets the user-defined comment for a specific entry in the archive. diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemTarHandler.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemTarHandler.java index 6339f3f99b7..2bb76f6a1ab 100644 --- a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemTarHandler.java +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemTarHandler.java @@ -15,6 +15,7 @@ * {Name} (company) - description of contribution. * Xuan Chen (IBM) - [194293] [Local][Archives] Saving file second time in an Archive Errors * Xuan Chen (IBM) - [199132] [Archives-TAR][Local-Windows] Can't open files in tar archives + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.services.clientserver.archiveutils; @@ -41,6 +42,7 @@ import org.eclipse.rse.internal.services.clientserver.archiveutils.TarEntry; import org.eclipse.rse.internal.services.clientserver.archiveutils.TarFile; import org.eclipse.rse.internal.services.clientserver.archiveutils.TarOutputStream; import org.eclipse.rse.services.clientserver.ISystemFileTypes; +import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.java.BasicClassFileParser; import org.eclipse.rse.services.clientserver.search.SystemSearchLineMatch; import org.eclipse.rse.services.clientserver.search.SystemSearchStringMatchLocator; @@ -212,7 +214,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { /** * Returns an array of children of the entry with the given path. - * @param the path of the parent entry, or "" to indicate the root entry. + * @param path of the parent entry, or "" to indicate the root entry. * @return an array of children, or an empty array if none exists, or if the entry is not a directory. */ public VirtualChild[] getChildren(String path) { @@ -234,7 +236,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { /** * Returns an array of children folders of the entry with the given path. - * @param the path of the parent entry, or "" to indicate the root entry. + * @param path of the parent entry, or "" to indicate the root entry. * @return an array of children, or an empty array if none exists, or if the entry is not a directory. */ public VirtualChild[] getChildrenFolders(String path) { @@ -625,9 +627,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList() + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList(ISystemOperationMonitor archiveOperationMonitor) */ - public VirtualChild[] getVirtualChildrenList() { + public VirtualChild[] getVirtualChildrenList(ISystemOperationMonitor archiveOperationMonitor) { // this method does not read from cache Vector v = new Vector(); @@ -654,9 +656,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList(java.lang.String, ISystemOperationMonitor) */ - public VirtualChild[] getVirtualChildrenList(String parent) { + public VirtualChild[] getVirtualChildrenList(String parent, ISystemOperationMonitor archiveOperationMonitor) { parent = ArchiveHandlerManager.cleanUpVirtualPath(parent); // this method does not read from cache @@ -690,9 +692,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildren(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildren(java.lang.String, ISystemOperationMonitor) */ - public VirtualChild[] getVirtualChildren(String fullVirtualName) { + public VirtualChild[] getVirtualChildren(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { try { updateCache(); @@ -707,9 +709,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildFolders(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildFolders(java.lang.String, ISystemOperationMonitor) */ - public VirtualChild[] getVirtualChildFolders(String fullVirtualName) { + public VirtualChild[] getVirtualChildFolders(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { try { updateCache(); @@ -724,9 +726,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualFile(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualFile(java.lang.String, ISystemOperationMonitor) */ - public VirtualChild getVirtualFile(String fullVirtualName) { + public VirtualChild getVirtualFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); @@ -754,9 +756,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#exists(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#exists(java.lang.String, ISystemOperationMonitor) */ - public boolean exists(String fullVirtualName) { + public boolean exists(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); @@ -832,7 +834,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualFile(java.lang.String, java.io.File) */ - public boolean extractVirtualFile(String fullVirtualName, File destination) { + public boolean extractVirtualFile(String fullVirtualName, File destination, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); TarEntry entry = getTarFile().getEntry(fullVirtualName); @@ -918,16 +920,16 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, ISystemOperationMonitor) */ - public boolean extractVirtualDirectory(String fullVirtualName, File destinationParent) { - return extractVirtualDirectory(fullVirtualName, destinationParent, (File) null); + public boolean extractVirtualDirectory(String fullVirtualName, File destinationParent, ISystemOperationMonitor archiveOperationMonitor) { + return extractVirtualDirectory(fullVirtualName, destinationParent, (File) null, archiveOperationMonitor); } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.io.File) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.io.File, ISystemOperationMonitor) */ - public boolean extractVirtualDirectory(String fullVirtualName, File destinationParent, File destination) { + public boolean extractVirtualDirectory(String fullVirtualName, File destinationParent, File destination, ISystemOperationMonitor archiveOperationMonitor) { // if the destination directory doesn't exist, create it if (!destinationParent.exists()) { @@ -988,7 +990,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { return false; // log error and quit if we fail to create the directory } else { - extractVirtualFile(fullVirtualName, topDir); + extractVirtualFile(fullVirtualName, topDir, archiveOperationMonitor); } // get the children of this directory @@ -1003,11 +1005,11 @@ public class SystemTarHandler implements ISystemArchiveHandler { if (tempChild.isDirectory) { // and now extract its children - extractVirtualDirectory(tempChild.fullName, childFile, (File) null); + extractVirtualDirectory(tempChild.fullName, childFile, (File) null, archiveOperationMonitor); } // otherwise if the child is a file, simply extract it else { - extractVirtualFile(tempChild.fullName, childFile); + extractVirtualFile(tempChild.fullName, childFile, archiveOperationMonitor); } } @@ -1015,24 +1017,24 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File, java.lang.String, java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File, java.lang.String, java.lang.String, ISystemOperationMonitor) */ - public boolean add(File file, String virtualPath, String name) { + public boolean add(File file, String virtualPath, String name, ISystemOperationMonitor archiveOperationMonitor ) { virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); if (!file.isDirectory()) { // if it exists, call replace String fullVirtualName = getFullVirtualName(virtualPath, name); - if (exists(fullVirtualName)) { - return replace(fullVirtualName, file, name); + if (exists(fullVirtualName, archiveOperationMonitor)) { + return replace(fullVirtualName, file, name, archiveOperationMonitor); } else { File[] files = new File[1]; files[0] = file; String[] names = new String[1]; names[0] = name; - return add(files, virtualPath, names); + return add(files, virtualPath, names, archiveOperationMonitor); } } else { @@ -1060,7 +1062,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { newNames[numOfChildren] = newNames[numOfChildren] + "/"; //$NON-NLS-1$ } - return add(sources, virtualPath, newNames); + return add(sources, virtualPath, newNames, archiveOperationMonitor); } } @@ -1084,9 +1086,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File[], java.lang.String, java.lang.String[]) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File[], java.lang.String, java.lang.String[], ISystemOperationMonitor) */ - public boolean add(File[] files, String virtualPath, String[] names) { + public boolean add(File[] files, String virtualPath, String[] names, ISystemOperationMonitor archiveOperationMonitor) { // update our cache before accessing cache try { @@ -1111,8 +1113,8 @@ public class SystemTarHandler implements ISystemArchiveHandler { // TODO (KM): should we simply replace and return? // I think we should check each entry and replace or create for each one String fullVirtualName = getFullVirtualName(virtualPath, names[i]); - if (exists(fullVirtualName)) { - return replace(fullVirtualName, files[i], names[i]); + if (exists(fullVirtualName, archiveOperationMonitor)) { + return replace(fullVirtualName, files[i], names[i], archiveOperationMonitor); } } @@ -1123,7 +1125,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); // get all the entries in the current tar - VirtualChild[] children = getVirtualChildrenList(); + VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); // if it is an empty temp file, no need to recreate it if (children.length != 0) { @@ -1457,7 +1459,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { /** * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#replace(java.lang.String, java.io.File, java.lang.String) */ - public boolean replace(String fullVirtualName, File file, String name) { + public boolean replace(String fullVirtualName, File file, String name, ISystemOperationMonitor archiveOperationMonitor) { // update our cache before accessing cache try { @@ -1475,8 +1477,8 @@ public class SystemTarHandler implements ISystemArchiveHandler { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); // if the virtual file does not exist, we actually want to add - if (!exists(fullVirtualName)) { - return add(file, fullVirtualName, name); + if (!exists(fullVirtualName, archiveOperationMonitor)) { + return add(file, fullVirtualName, name, archiveOperationMonitor); } try { @@ -1487,7 +1489,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); // get all the entries - VirtualChild[] children = getVirtualChildrenList(); + VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); // create a set of omissions HashSet omissions = new HashSet(); @@ -1548,9 +1550,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#delete(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#delete(java.lang.String, ISystemOperationMonitor) */ - public boolean delete(String fullVirtualName) { + public boolean delete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { // update our cache before accessing cache try { @@ -1562,7 +1564,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { } fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - VirtualChild child = getVirtualFile(fullVirtualName); + VirtualChild child = getVirtualFile(fullVirtualName, archiveOperationMonitor); VirtualChild[] omitArray = new VirtualChild[0]; // child does not exist, so quit @@ -1572,7 +1574,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { // child is a directory, so get its children since we need to delete them as well if (child.isDirectory) { - omitArray = getVirtualChildrenList(fullVirtualName); + omitArray = getVirtualChildrenList(fullVirtualName, archiveOperationMonitor); } try { @@ -1582,7 +1584,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); // get all the entries in the current tar - VirtualChild[] children = getVirtualChildrenList(); + VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); // create a set to hold omissions HashSet omissions = new HashSet(); @@ -1619,27 +1621,27 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#rename(java.lang.String, java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#rename(java.lang.String, java.lang.String, ISystemOperationMonitor) */ - public boolean rename(String fullVirtualName, String newName) { + public boolean rename(String fullVirtualName, String newName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ // if the original does not have any separator, simply rename it. if (i == -1) { - return fullRename(fullVirtualName, newName); + return fullRename(fullVirtualName, newName, archiveOperationMonitor); } // otherwise, get the parent path and append the new name to it. else { String fullNewName = fullVirtualName.substring(0, i+1) + newName; - return fullRename(fullVirtualName, fullNewName); + return fullRename(fullVirtualName, fullNewName, archiveOperationMonitor); } } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#move(java.lang.String, java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#move(java.lang.String, java.lang.String, ISystemOperationMonitor) */ - public boolean move(String fullVirtualName, String destinationVirtualPath) { + public boolean move(String fullVirtualName, String destinationVirtualPath, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); destinationVirtualPath = ArchiveHandlerManager.cleanUpVirtualPath(destinationVirtualPath); @@ -1647,19 +1649,19 @@ public class SystemTarHandler implements ISystemArchiveHandler { // if the original does not have any separator, simply append it to the destination path. if (i == -1) { - return fullRename(fullVirtualName, destinationVirtualPath + "/" + fullVirtualName); //$NON-NLS-1$ + return fullRename(fullVirtualName, destinationVirtualPath + "/" + fullVirtualName, archiveOperationMonitor); //$NON-NLS-1$ } // otherwise, get the last segment (the name) and append that to the destination path. else { String name = fullVirtualName.substring(i); - return fullRename(fullVirtualName, destinationVirtualPath + name); + return fullRename(fullVirtualName, destinationVirtualPath + name, archiveOperationMonitor); } } /** * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#fullRename(java.lang.String, java.lang.String) */ - public boolean fullRename(String fullVirtualName, String newFullVirtualName) { + public boolean fullRename(String fullVirtualName, String newFullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { // update our cache before accessing cache try { @@ -1672,7 +1674,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); newFullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(newFullVirtualName); - VirtualChild child = getVirtualFile(fullVirtualName); + VirtualChild child = getVirtualFile(fullVirtualName, archiveOperationMonitor); // if the virtual file to be renamed does not exist, then quit if (!child.exists()) { @@ -1686,7 +1688,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); // get all the entries - VirtualChild[] children = getVirtualChildrenList(); + VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); // the rename list // a hashmap containing old name, new name associations for each @@ -1702,7 +1704,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { names.put(fullVirtualName + "/", newFullVirtualName + "/"); //$NON-NLS-1$ //$NON-NLS-2$ // get all the children of the entry to be renamed - VirtualChild[] childrenArray = getVirtualChildrenList(fullVirtualName); + VirtualChild[] childrenArray = getVirtualChildrenList(fullVirtualName, archiveOperationMonitor); // now we need to get the relative path of each child with respect to the virtual name // and append the relative path to the new virtual name @@ -1732,8 +1734,12 @@ public class SystemTarHandler implements ISystemArchiveHandler { } // create tar with renamed entries - createTar(children, outStream, names); + boolean isCanceled = createTar(children, outStream, names, archiveOperationMonitor); + if (true == isCanceled) + { + return false; + } // close the output stream outStream.close(); @@ -1760,13 +1766,18 @@ public class SystemTarHandler implements ISystemArchiveHandler { * in the map, and the values are the new names. * @throws IOException if an I/O exception occurs. */ - protected void createTar(VirtualChild[] children, TarOutputStream outStream, HashMap renameMap) throws IOException { + protected boolean createTar(VirtualChild[] children, TarOutputStream outStream, HashMap renameMap, ISystemOperationMonitor archiveOperationMonitor) throws IOException { TarFile tarFile = getTarFile(); // go through each child for (int i = 0; i < children.length; i++) { + if (archiveOperationMonitor.isCanceled()) + { + return true; + } + VirtualChild child = children[i]; String oldPath = child.getArchiveStandardName(); String newPath = oldPath; @@ -1829,6 +1840,8 @@ public class SystemTarHandler implements ISystemArchiveHandler { outStream.closeEntry(); } } + + return false; } /** @@ -1849,9 +1862,9 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getFiles(java.lang.String[]) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getFiles(java.lang.String[], ISystemOperationMonitor) */ - public File[] getFiles(String[] fullNames) { + public File[] getFiles(String[] fullNames, ISystemOperationMonitor archiveOperationMonitor) { File[] files = new File[fullNames.length]; @@ -1871,7 +1884,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { try { files[i] = File.createTempFile(name, "virtual"); //$NON-NLS-1$ files[i].deleteOnExit(); - extractVirtualFile(fullNames[i], files[i]); + extractVirtualFile(fullNames[i], files[i], archiveOperationMonitor); } catch (IOException e) { // TODO: log error @@ -1883,20 +1896,20 @@ public class SystemTarHandler implements ISystemArchiveHandler { } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFolder(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFolder(java.lang.String, ISystemOperationMonitor) */ - public boolean createFolder(String fullVirtualName) { + public boolean createFolder(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = fullVirtualName + "/"; //$NON-NLS-1$ - return createVirtualObject(fullVirtualName); + return createVirtualObject(fullVirtualName, archiveOperationMonitor); } /** - * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFile(java.lang.String) + * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFile(java.lang.String, ISystemOperationMonitor) */ - public boolean createFile(String fullVirtualName) { + public boolean createFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - return createVirtualObject(fullVirtualName); + return createVirtualObject(fullVirtualName, archiveOperationMonitor); } /** @@ -1905,7 +1918,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { * @param name the name of the virtual object. * @return true if the object was created successfully, false otherwise. */ - protected boolean createVirtualObject(String name) { + protected boolean createVirtualObject(String name, ISystemOperationMonitor archiveOperationMonitor) { // update our cache before accessing cache try { @@ -1917,7 +1930,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { } // if the object already exists, return false - if (exists(name)) { + if (exists(name, archiveOperationMonitor)) { return false; } @@ -1928,7 +1941,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); // get all the entries - VirtualChild[] children = getVirtualChildrenList(); + VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); // if it is an empty temp file, no need to recreate it if (children.length != 0) { @@ -2062,7 +2075,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { return true; } - public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher) { + public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher, ISystemOperationMonitor archiveOperationMonitor) { // if the search string is empty or if it is "*", then return no matches // since it is a file search if (matcher.isSearchStringEmpty() || matcher.isSearchStringAsterisk()) { @@ -2071,7 +2084,7 @@ public class SystemTarHandler implements ISystemArchiveHandler { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - VirtualChild vc = getVirtualFile(fullVirtualName); + VirtualChild vc = getVirtualFile(fullVirtualName, archiveOperationMonitor); if (!vc.exists() || vc.isDirectory) { return new SystemSearchLineMatch[0]; @@ -2153,44 +2166,44 @@ public class SystemTarHandler implements ISystemArchiveHandler { * @return whether the add was successful */ public boolean add(File file, String virtualPath, String name, - String encoding, ISystemFileTypes registry) { - return add(file, virtualPath, name); + String encoding, ISystemFileTypes registry, ISystemOperationMonitor archiveOperationMonitor) { + return add(file, virtualPath, name, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File, java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean) */ public boolean add(File file, String virtualPath, String name, - String sourceEncoding, String targetEncoding, boolean isText) { - return add(file, virtualPath, name); + String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { + return add(file, virtualPath, name, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File[], java.lang.String, java.lang.String[], java.lang.String[], java.lang.String[], boolean[]) */ public boolean add(File[] files, String virtualPath, String[] names, - String[] sourceEncodings, String[] targetEncodings, boolean[] isTexts) { - return add(files, virtualPath, names); + String[] sourceEncodings, String[] targetEncodings, boolean[] isTexts, ISystemOperationMonitor archiveOperationMonitor) { + return add(files, virtualPath, names, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.io.File, java.lang.String, boolean) */ public boolean extractVirtualDirectory(String dir, File destinationParent, - File destination, String sourceEncoding, boolean isText) { - return extractVirtualDirectory(dir, destinationParent, destination); + File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { + return extractVirtualDirectory(dir, destinationParent, destination, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.lang.String, boolean) */ public boolean extractVirtualDirectory(String dir, File destinationParent, - String sourceEncoding, boolean isText) { - return extractVirtualDirectory(dir, destinationParent); + String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { + return extractVirtualDirectory(dir, destinationParent, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualFile(java.lang.String, java.io.File, java.lang.String, boolean) */ public boolean extractVirtualFile(String fullVirtualName, File destination, - String sourceEncoding, boolean isText) { - return extractVirtualFile(fullVirtualName, destination); + String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { + return extractVirtualFile(fullVirtualName, destination, archiveOperationMonitor); } /** @@ -2251,16 +2264,16 @@ public class SystemTarHandler implements ISystemArchiveHandler { return type; } - public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText) { + public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { // TODO Auto-generated method stub return false; } - public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes typeRegistery) { - return add(file, virtualPath, name); + public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes typeRegistery, ISystemOperationMonitor archiveOperationMonitor) { + return add(file, virtualPath, name, archiveOperationMonitor); } - public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText) { + public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { // TODO Auto-generated method stub return false; } diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemZipHandler.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemZipHandler.java index d65abd23271..3dcae0d313a 100644 --- a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemZipHandler.java +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/SystemZipHandler.java @@ -16,6 +16,7 @@ * Xuan Chen (IBM) - [192741] [Archives] Move a folder from within an Archive doesn't work if > 1 level deep * Xuan Chen (IBM) - [194293] [Local][Archives] Saving file second time in an Archive Errors * Xuan Chen (IBM) - [181784] [archivehandlers] zipped text files have unexpected contents + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.services.clientserver.archiveutils; @@ -40,7 +41,9 @@ import java.util.zip.ZipOutputStream; import org.eclipse.rse.internal.services.clientserver.archiveutils.SystemArchiveUtil; import org.eclipse.rse.internal.services.clientserver.archiveutils.SystemUniversalZipEntry; import org.eclipse.rse.services.clientserver.ISystemFileTypes; +import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.SystemEncodingUtil; +import org.eclipse.rse.services.clientserver.SystemReentrantMutex; import org.eclipse.rse.services.clientserver.java.BasicClassFileParser; import org.eclipse.rse.services.clientserver.search.SystemSearchLineMatch; import org.eclipse.rse.services.clientserver.search.SystemSearchStringMatchLocator; @@ -96,6 +99,7 @@ public class SystemZipHandler implements ISystemArchiveHandler protected File _file; // The underlying file associated with this handler. protected long _vfsLastModified; // The timestamp of the file that the virtual file system reflects. protected boolean _exists; // Whether or not the zipfile "exists" (in order to exist, must be uncorrupted too) + protected SystemReentrantMutex _mutex; /** * Creates a new SystemZipHandler and associates it with file. @@ -116,6 +120,7 @@ public class SystemZipHandler implements ISystemArchiveHandler { _exists = false; } + _mutex = new SystemReentrantMutex(); } /** @@ -162,6 +167,14 @@ public class SystemZipHandler implements ISystemArchiveHandler } } + //Now, update other properties + nextChild.setComment(next.getComment()); + nextChild.setCompressedSize(next.getCompressedSize()); + Integer methodIntValue = new Integer(next.getMethod()); + nextChild.setCompressionMethod(methodIntValue.toString()); + nextChild.setSize(next.getSize()); + nextChild.setTimeStamp(next.getTime()); + // key has not been encountered before, create a new // element in the virtualFS. if (!_virtualFS.containsKey(nextChild.path)) @@ -228,95 +241,135 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList() */ - public VirtualChild[] getVirtualChildrenList() + public VirtualChild[] getVirtualChildrenList(ISystemOperationMonitor archiveOperationMonitor) { - return getVirtualChildrenList(true); + return getVirtualChildrenList(true, archiveOperationMonitor); } /** * Same as getVirtualChildrenList(), but you can choose whether * to leave the zip file open or closed upon return. */ - public VirtualChild[] getVirtualChildrenList(boolean closeZipFile) + public VirtualChild[] getVirtualChildrenList(boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return new VirtualChild[0]; - if (!updateVirtualFSIfNecessary()) return new VirtualChild[0]; - - if (openZipFile()) + if (!updateVirtualFSIfNecessary(archiveOperationMonitor)) return new VirtualChild[0]; + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - Vector children = new Vector(); - Enumeration entries = _zipfile.entries(); - while (entries.hasMoreElements()) + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - ZipEntry next = (ZipEntry) entries.nextElement(); - SystemUniversalZipEntry nextEntry = new SystemUniversalZipEntry(next); - VirtualChild nextChild = new VirtualChild(this, nextEntry.getFullName()); - nextChild.isDirectory = next.isDirectory(); - children.add(nextChild); + if (openZipFile()) + { + Vector children = new Vector(); + Enumeration entries = _zipfile.entries(); + while (entries.hasMoreElements()) + { + ZipEntry next = (ZipEntry) entries.nextElement(); + SystemUniversalZipEntry nextEntry = new SystemUniversalZipEntry(next); + VirtualChild nextChild = new VirtualChild(this, nextEntry.getFullName()); + nextChild.isDirectory = next.isDirectory(); + children.add(nextChild); + } + VirtualChild[] retVal = new VirtualChild[children.size()]; + for (int i = 0; i < children.size(); i++) + { + retVal[i] = (VirtualChild) children.get(i); + } + if (closeZipFile) closeZipFile(); + return retVal; + } } - VirtualChild[] retVal = new VirtualChild[children.size()]; - for (int i = 0; i < children.size(); i++) - { - retVal[i] = (VirtualChild) children.get(i); - } - if (closeZipFile) closeZipFile(); - return retVal; } - else return new VirtualChild[0]; + catch (Exception e) + { + e.printStackTrace(); + if (closeZipFile) closeZipFile(); + } + finally + { + releaseMutex(mutexLockStatus); + } + + return new VirtualChild[0]; } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildrenList(java.lang.String) */ - public VirtualChild[] getVirtualChildrenList(String parent) + public VirtualChild[] getVirtualChildrenList(String parent, ISystemOperationMonitor archiveOperationMonitor) { - return getVirtualChildrenList(parent, true); + return getVirtualChildrenList(parent, true, archiveOperationMonitor); } /** * Same as getVirtualChildrenList(String parent) but you can choose whether * or not you want to leave the zipfile open after return. */ - public VirtualChild[] getVirtualChildrenList(String parent, boolean closeZipFile) + public VirtualChild[] getVirtualChildrenList(String parent, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return new VirtualChild[0]; - if (!updateVirtualFSIfNecessary()) return new VirtualChild[0]; - - if (openZipFile()) + if (!updateVirtualFSIfNecessary(archiveOperationMonitor)) return new VirtualChild[0]; + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - parent = ArchiveHandlerManager.cleanUpVirtualPath(parent); - Vector children = new Vector(); - Enumeration entries = _zipfile.entries(); - while (entries.hasMoreElements()) + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - ZipEntry next = (ZipEntry) entries.nextElement(); - String nextName = ArchiveHandlerManager.cleanUpVirtualPath(next.getName()); - if (nextName.startsWith(parent) && !nextName.equals(parent+"/")) //$NON-NLS-1$ + if (openZipFile()) { - SystemUniversalZipEntry nextEntry = new SystemUniversalZipEntry(next); - VirtualChild nextChild = new VirtualChild(this, nextEntry.getFullName()); - nextChild.isDirectory = next.isDirectory(); - children.add(nextChild); + parent = ArchiveHandlerManager.cleanUpVirtualPath(parent); + Vector children = new Vector(); + Enumeration entries = _zipfile.entries(); + while (entries.hasMoreElements()) + { + ZipEntry next = (ZipEntry) entries.nextElement(); + String nextName = ArchiveHandlerManager.cleanUpVirtualPath(next.getName()); + if (nextName.startsWith(parent) && !nextName.equals(parent+"/")) //$NON-NLS-1$ + { + SystemUniversalZipEntry nextEntry = new SystemUniversalZipEntry(next); + VirtualChild nextChild = new VirtualChild(this, nextEntry.getFullName()); + nextChild.isDirectory = next.isDirectory(); + children.add(nextChild); + } + } + VirtualChild[] retVal = new VirtualChild[children.size()]; + for (int i = 0; i < children.size(); i++) + { + retVal[i] = (VirtualChild) children.get(i); + } + if (closeZipFile) closeZipFile(); + return retVal; } + else return new VirtualChild[0]; } - VirtualChild[] retVal = new VirtualChild[children.size()]; - for (int i = 0; i < children.size(); i++) + else { - retVal[i] = (VirtualChild) children.get(i); + return new VirtualChild[0]; } - if (closeZipFile) closeZipFile(); - return retVal; } - else return new VirtualChild[0]; + catch (Exception e) + { + e.printStackTrace(); + if (closeZipFile) closeZipFile(); + } + finally + { + releaseMutex(mutexLockStatus); + } + + return new VirtualChild[0]; + } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildren(java.lang.String) */ - public VirtualChild[] getVirtualChildren(String fullVirtualName) + public VirtualChild[] getVirtualChildren(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return null; - if (!updateVirtualFSIfNecessary()) return null; + if (!updateVirtualFSIfNecessary(archiveOperationMonitor)) return null; fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); VirtualChild[] values = null; @@ -337,10 +390,10 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualChildFolders(java.lang.String) */ - public VirtualChild[] getVirtualChildFolders(String fullVirtualName) + public VirtualChild[] getVirtualChildFolders(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return null; - if (!updateVirtualFSIfNecessary()) return null; + if (!updateVirtualFSIfNecessary(archiveOperationMonitor)) return null; fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); Vector folders = new Vector(); VirtualChild[] values = null; @@ -364,10 +417,10 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getVirtualFile(java.lang.String) */ - public VirtualChild getVirtualFile(String fullVirtualName) + public VirtualChild getVirtualFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return new VirtualChild(this, fullVirtualName); - if (!updateVirtualFSIfNecessary()) return new VirtualChild(this, fullVirtualName); + if (!updateVirtualFSIfNecessary(archiveOperationMonitor)) return new VirtualChild(this, fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); if (fullVirtualName == "" || fullVirtualName == null) return new VirtualChild(this); //$NON-NLS-1$ @@ -394,7 +447,7 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#exists(java.lang.String) */ - public boolean exists(String fullVirtualName) + public boolean exists(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; @@ -534,128 +587,140 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualFile(java.lang.String, java.io.File) */ - public boolean extractVirtualFile(String fullVirtualName, File destination) + public boolean extractVirtualFile(String fullVirtualName, File destination, ISystemOperationMonitor archiveOperationMonitor) { - return extractVirtualFile(fullVirtualName, destination, true, SystemEncodingUtil.ENCODING_UTF_8, false); + return extractVirtualFile(fullVirtualName, destination, true, SystemEncodingUtil.ENCODING_UTF_8, false, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualFile(java.lang.String, java.io.File, java.lang.String, boolean) */ - public boolean extractVirtualFile(String fullVirtualName, File destination, String sourceEncoding, boolean isText) + public boolean extractVirtualFile(String fullVirtualName, File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { - return extractVirtualFile(fullVirtualName, destination, true, sourceEncoding, isText); + return extractVirtualFile(fullVirtualName, destination, true, sourceEncoding, isText, archiveOperationMonitor); } /** * Same as extractVirtualFile(String fullVirtualName, File destination) but you can choose whether * or not you want to leave the zipfile open after return. */ - public boolean extractVirtualFile(String fullVirtualName, File destination, boolean closeZipFile, String sourceEncoding, boolean isText) + public boolean extractVirtualFile(String fullVirtualName, File destination, boolean closeZipFile, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; - - if (openZipFile()) + int mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); ZipEntry entry = null; try { - entry = safeGetEntry(fullVirtualName); - if (entry.isDirectory()) + if (openZipFile()) { - destination.delete(); - destination.mkdirs(); - destination.setLastModified(entry.getTime()); - if (closeZipFile) closeZipFile(); - return true; - } - InputStream is = _zipfile.getInputStream(entry); - if (is == null) - { - destination.setLastModified(entry.getTime()); - if (closeZipFile) closeZipFile(); - return true; - } - BufferedInputStream reader = new BufferedInputStream(is); + fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); + + entry = safeGetEntry(fullVirtualName); + if (entry.isDirectory()) + { + destination.delete(); + destination.mkdirs(); + destination.setLastModified(entry.getTime()); + if (closeZipFile) closeZipFile(); + return true; + } + InputStream is = _zipfile.getInputStream(entry); + if (is == null) + { + destination.setLastModified(entry.getTime()); + if (closeZipFile) closeZipFile(); + return true; + } + BufferedInputStream reader = new BufferedInputStream(is); + + if (!destination.exists()) + { + File parentFile = destination.getParentFile(); + if (!parentFile.exists()) + parentFile.mkdirs(); + destination.createNewFile(); + } + BufferedOutputStream writer = new BufferedOutputStream( + new FileOutputStream(destination)); - if (!destination.exists()) - { - File parentFile = destination.getParentFile(); - if (!parentFile.exists()) - parentFile.mkdirs(); - destination.createNewFile(); - } - BufferedOutputStream writer = new BufferedOutputStream( - new FileOutputStream(destination)); - - byte[] buf = new byte[1024]; - int numRead = reader.read(buf); - - while (numRead > 0) - { - if (isText) + byte[] buf = new byte[1024]; + int numRead = reader.read(buf); + + while (numRead > 0) { - String bufString = new String(buf, 0, numRead, sourceEncoding); - byte[] convertedBuf = bufString.getBytes(); - int newSize = convertedBuf.length; - writer.write(convertedBuf, 0, newSize); + if (isText) + { + String bufString = new String(buf, 0, numRead, sourceEncoding); + byte[] convertedBuf = bufString.getBytes(); + int newSize = convertedBuf.length; + writer.write(convertedBuf, 0, newSize); + } + else + { + writer.write(buf, 0, numRead); + } + numRead = reader.read(buf); } - else - { - writer.write(buf, 0, numRead); + writer.close(); + reader.close(); } - numRead = reader.read(buf); - } - writer.close(); - reader.close(); - } - catch (IOException e) - { - if (_virtualFS.containsKey(fullVirtualName)) - { - destination.delete(); - destination.mkdirs(); - destination.setLastModified(_file.lastModified()); + destination.setLastModified(entry.getTime()); if (closeZipFile) closeZipFile(); return true; } - System.out.println(e.getMessage()); - if (closeZipFile) closeZipFile(); - return false; - } - destination.setLastModified(entry.getTime()); - if (closeZipFile) closeZipFile(); - return true; + catch (IOException e) + { + if (_virtualFS.containsKey(fullVirtualName)) + { + destination.delete(); + destination.mkdirs(); + destination.setLastModified(_file.lastModified()); + if (closeZipFile) closeZipFile(); + return true; + } + System.out.println(e.getMessage()); + if (closeZipFile) closeZipFile(); + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } + + } + else + { + return false; } - else return false; } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File) */ - public boolean extractVirtualDirectory(String dir, File destinationParent) + public boolean extractVirtualDirectory(String dir, File destinationParent, ISystemOperationMonitor archiveOperationMonitor) { - return extractVirtualDirectory(dir, destinationParent, (File) null, SystemEncodingUtil.ENCODING_UTF_8, false); + return extractVirtualDirectory(dir, destinationParent, (File) null, SystemEncodingUtil.ENCODING_UTF_8, false, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.lang.String, boolean) */ - public boolean extractVirtualDirectory(String dir, File destinationParent, String sourceEncoding, boolean isText) + public boolean extractVirtualDirectory(String dir, File destinationParent, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { - return extractVirtualDirectory(dir, destinationParent, (File) null, sourceEncoding, isText); + return extractVirtualDirectory(dir, destinationParent, (File) null, sourceEncoding, isText, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#extractVirtualDirectory(java.lang.String, java.io.File, java.io.File) */ - public boolean extractVirtualDirectory(String dir, File destinationParent, File destination) + public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, ISystemOperationMonitor archiveOperationMonitor) { - return extractVirtualDirectory(dir, destinationParent, destination, SystemEncodingUtil.ENCODING_UTF_8, false); + return extractVirtualDirectory(dir, destinationParent, destination, SystemEncodingUtil.ENCODING_UTF_8, false, archiveOperationMonitor); } - public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, String sourceEncoding, boolean isText) + public boolean extractVirtualDirectory(String dir, File destinationParent, File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; @@ -727,13 +792,17 @@ public class SystemZipHandler implements ISystemArchiveHandler } if (!topFilePath.endsWith(lastPortionOfDir)) { - rename(dir, topFile.getName()); + rename(dir, topFile.getName(), archiveOperationMonitor); dir = topFile.getName(); } - VirtualChild[] newChildren = getVirtualChildrenList(dir); + VirtualChild[] newChildren = getVirtualChildrenList(dir, archiveOperationMonitor); - - extractVirtualFile(dir + '/', topFile, sourceEncoding, isText); + if (newChildren.length == 0) + { + //it is a error situation, or the operation has been canceled. + return false; + } + extractVirtualFile(dir + '/', topFile, sourceEncoding, isText, archiveOperationMonitor); for (int i = 0; i < newChildren.length; i++) { @@ -768,11 +837,11 @@ public class SystemZipHandler implements ISystemArchiveHandler boolean success = false; if (newChildren[i].isDirectory) { - success = extractVirtualFile(newChildren[i].fullName + '/', nextFile, sourceEncoding, isText); + success = extractVirtualFile(newChildren[i].fullName + '/', nextFile, sourceEncoding, isText, archiveOperationMonitor); } else { - success = extractVirtualFile(newChildren[i].fullName, nextFile, sourceEncoding, isText); + success = extractVirtualFile(newChildren[i].fullName, nextFile, sourceEncoding, isText, archiveOperationMonitor); } if (!success) return false; } @@ -811,73 +880,96 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File, java.lang.String, java.lang.String) */ - public boolean add(File file, String virtualPath, String name) + public boolean add(File file, String virtualPath, String name, ISystemOperationMonitor archiveOperationMonitor) { - return add(file, virtualPath, name, SystemEncodingUtil.ENCODING_UTF_8, SystemEncodingUtil.ENCODING_UTF_8, false); + return add(file, virtualPath, name, SystemEncodingUtil.ENCODING_UTF_8, SystemEncodingUtil.ENCODING_UTF_8, false, archiveOperationMonitor); } - public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText) + public boolean add(InputStream stream, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); - if (exists(virtualPath + "/" + name)) //$NON-NLS-1$ + if (exists(virtualPath + "/" + name, archiveOperationMonitor)) //$NON-NLS-1$ { // wrong method - return replace(virtualPath + "/" + name, stream, name, sourceEncoding, targetEncoding, isText); //$NON-NLS-1$ + return replace(virtualPath + "/" + name, stream, name, sourceEncoding, targetEncoding, isText, archiveOperationMonitor); //$NON-NLS-1$ } - else + + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - if (openZipFile()) + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); - File outputTempFile; - try + if (openZipFile()) { - // Open a new tempfile which will be our destination for the new zip - outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ - ZipOutputStream dest = new ZipOutputStream( - new FileOutputStream(outputTempFile)); - - dest.setMethod(ZipOutputStream.DEFLATED); - // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); - - // if it is an empty zip file, no need to recreate it - if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ + virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); + File outputTempFile; + try { - recreateZipDeleteEntries(vcList, dest, null); + // Open a new tempfile which will be our destination for the new zip + outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ + ZipOutputStream dest = new ZipOutputStream( + new FileOutputStream(outputTempFile)); + + dest.setMethod(ZipOutputStream.DEFLATED); + // get all the entries in the old zip + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); + + // if it is an empty zip file, no need to recreate it + if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ + { + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, null, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + closeZipFile(); + return false; + } + } + + // append the additional entry to the zip file. + ZipEntry newEntry = appendBytes(stream, dest, virtualPath, name, sourceEncoding, targetEncoding, isText); + // Add the new entry to the virtual file system in memory + fillBranch(newEntry); + + dest.close(); + + // Now replace the old zip file with the new one + replaceOldZip(outputTempFile); + + } + catch (IOException e) + { + System.out.println("Could not add a file."); //$NON-NLS-1$ + System.out.println(e.getMessage()); + closeZipFile(); + return false; } - - // append the additional entry to the zip file. - ZipEntry newEntry = appendBytes(stream, dest, virtualPath, name, sourceEncoding, targetEncoding, isText); - // Add the new entry to the virtual file system in memory - fillBranch(newEntry); - - dest.close(); - - // Now replace the old zip file with the new one - replaceOldZip(outputTempFile); - - } - catch (IOException e) - { - System.out.println("Could not add a file."); //$NON-NLS-1$ - System.out.println(e.getMessage()); closeZipFile(); - return false; + return true; } - closeZipFile(); - return true; } - else return false; + } + catch(Exception e) + { + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } + + return false; } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#add(java.io.File[], java.lang.String, java.lang.String[]) */ - public boolean add(File[] files, String virtualPath, String[] names) + public boolean add(File[] files, String virtualPath, String[] names, ISystemOperationMonitor archiveOperationMonitor) { String[] encodings = new String[files.length]; boolean[] isTexts = new boolean[files.length]; @@ -886,12 +978,12 @@ public class SystemZipHandler implements ISystemArchiveHandler encodings[i] = SystemEncodingUtil.ENCODING_UTF_8; isTexts[i] = false; } - return add(files, virtualPath, names, encodings, encodings, isTexts, true); + return add(files, virtualPath, names, encodings, encodings, isTexts, true, archiveOperationMonitor); } - public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText) + public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText, ISystemOperationMonitor archiveOperationMonitor) { - return add(files, virtualPath, names, sourceEncodings, targetEncodings, isText, true); + return add(files, virtualPath, names, sourceEncodings, targetEncodings, isText, true, archiveOperationMonitor); } @@ -899,66 +991,85 @@ public class SystemZipHandler implements ISystemArchiveHandler * Same as add(File[] files, String virtualPath, String[] names, String[] encodings) but you can choose whether * or not you want to leave the zipfile open after return. */ - public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText, boolean closeZipFile) + public boolean add(File[] files, String virtualPath, String[] names, String[] sourceEncodings, String[] targetEncodings, boolean[] isText, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; - if (openZipFile()) + + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); - int numFiles = files.length; - for (int i = 0; i < numFiles; i++) - { - if (!files[i].exists() || !files[i].canRead()) return false; - String fullVirtualName = getFullVirtualName(virtualPath, names[i]); - if (exists(fullVirtualName)) - { - // sorry, wrong method buddy - return replace(fullVirtualName, files[i], names[i]); - } - } - File outputTempFile; - try + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - // Open a new tempfile which will be our destination for the new zip - outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ - ZipOutputStream dest = new ZipOutputStream( - new FileOutputStream(outputTempFile)); + if (openZipFile()) + { + virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); + int numFiles = files.length; + for (int i = 0; i < numFiles; i++) + { + if (!files[i].exists() || !files[i].canRead()) return false; + String fullVirtualName = getFullVirtualName(virtualPath, names[i]); + if (exists(fullVirtualName, archiveOperationMonitor)) + { + // sorry, wrong method buddy + return replace(fullVirtualName, files[i], names[i], archiveOperationMonitor); + } + } + File outputTempFile; - dest.setMethod(ZipOutputStream.DEFLATED); - // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); + // Open a new tempfile which will be our destination for the new zip + outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ + ZipOutputStream dest = new ZipOutputStream( + new FileOutputStream(outputTempFile)); + + dest.setMethod(ZipOutputStream.DEFLATED); + // get all the entries in the old zip + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); + + // if it is an empty zip file, no need to recreate it + if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ + { + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, null, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + } + + // Now for each new file to add + for (int i = 0; i < numFiles; i++) + { + // append the additional entry to the zip file. + ZipEntry newEntry = appendFile(files[i], dest, virtualPath, names[i], sourceEncodings[i], targetEncodings[i], isText[i]); + // Add the new entry to the virtual file system in memory + fillBranch(newEntry); + } + + dest.close(); + + // Now replace the old zip file with the new one + replaceOldZip(outputTempFile); + - // if it is an empty zip file, no need to recreate it - if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ - { - recreateZipDeleteEntries(vcList, dest, null); + if (closeZipFile) closeZipFile(); + return true; } - - // Now for each new file to add - for (int i = 0; i < numFiles; i++) - { - // append the additional entry to the zip file. - ZipEntry newEntry = appendFile(files[i], dest, virtualPath, names[i], sourceEncodings[i], targetEncodings[i], isText[i]); - // Add the new entry to the virtual file system in memory - fillBranch(newEntry); - } - dest.close(); - - // Now replace the old zip file with the new one - replaceOldZip(outputTempFile); - } - catch (IOException e) - { - System.out.println("Could not add a file."); //$NON-NLS-1$ - System.out.println(e.getMessage()); - if (closeZipFile) closeZipFile(); - return false; - } - if (closeZipFile) closeZipFile(); - return true; } - else return false; + catch(Exception e) + { + if (closeZipFile) closeZipFile(); + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } + + return false; } /** @@ -966,16 +1077,21 @@ public class SystemZipHandler implements ISystemArchiveHandler * collapsed list of all nodes in the subtree * of the file system rooted at parent. */ - public static void listAllFiles(File parent, HashSet found) + public static boolean listAllFiles(File parent, HashSet found, ISystemOperationMonitor archiveOperationMonitor) { File[] children = parent.listFiles(); if (children == null) // DKM - 56031, no authority on parent yields null { found.remove(parent); - return; + return false; } for (int i = 0; i < children.length; i++) { + if (archiveOperationMonitor != null && archiveOperationMonitor.isCanceled()) + { + //the operation has been canceled + return true; + } if (!found.contains(children[i])) // prevent infinite loops due to symlinks { if (children[i].canRead()) @@ -983,11 +1099,13 @@ public class SystemZipHandler implements ISystemArchiveHandler found.add(children[i]); if (children[i].isDirectory()) { - listAllFiles(children[i], found); + listAllFiles(children[i], found, archiveOperationMonitor); } } } } + + return false; } /** @@ -1000,7 +1118,7 @@ public class SystemZipHandler implements ISystemArchiveHandler * the zipfile. Null or empty set if there are no ommisions. * @throws IOException */ - protected void recreateZipDeleteEntries(VirtualChild[] vcList, ZipOutputStream dest, HashSet omitChildren) throws IOException + protected boolean recreateZipDeleteEntries(VirtualChild[] vcList, ZipOutputStream dest, HashSet omitChildren, ISystemOperationMonitor archiveOperationMonitor) throws IOException { if (!(omitChildren == null) && vcList.length == omitChildren.size()) { @@ -1009,11 +1127,17 @@ public class SystemZipHandler implements ISystemArchiveHandler ZipEntry entry = new ZipEntry("/"); //$NON-NLS-1$ dest.putNextEntry(entry); dest.closeEntry(); - return; + return false; } //else for (int i = 0; i < vcList.length; i++) { + if (archiveOperationMonitor != null && archiveOperationMonitor.isCanceled()) + { + //the operation has been canceled + return true; + } + // for each entry, append it to the new temp zip // unless it is in the set of omissions if (omitChildren != null && omitChildren.contains(vcList[i].fullName)) continue; @@ -1040,6 +1164,7 @@ public class SystemZipHandler implements ISystemArchiveHandler dest.closeEntry(); source.close(); } + return false; } /** @@ -1048,14 +1173,18 @@ public class SystemZipHandler implements ISystemArchiveHandler * @param vcList The list of virtual children to create the zip from * @param dest The ZipOutputStream representing the zip file where the * children are to be recreated - * @param oldName The name of the virtual child to rename - * @param newName The new name for the renamed virtual child. + * @param names HashMap maps the full path of a virtual file to the entry in the archive file * @throws IOException */ - protected void recreateZipRenameEntries(VirtualChild[] vcList, ZipOutputStream dest, HashMap names) throws IOException + protected boolean recreateZipRenameEntries(VirtualChild[] vcList, ZipOutputStream dest, HashMap names, ISystemOperationMonitor archiveOperationMonitor) throws IOException { for (int i = 0; i < vcList.length; i++) { + if (archiveOperationMonitor != null && archiveOperationMonitor.isCanceled()) + { + //the operation has been canceled + return true; + } // for each entry, append it to the new temp zip ZipEntry nextEntry; ZipEntry newEntry; @@ -1097,6 +1226,7 @@ public class SystemZipHandler implements ISystemArchiveHandler dest.closeEntry(); source.close(); } + return false; } /** @@ -1238,95 +1368,115 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#delete(java.lang.String) */ - public boolean delete(String fullVirtualName) + public boolean delete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { - return delete(fullVirtualName, true); + boolean returnCode = delete(fullVirtualName, true, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; } /** * Same as delete(String fullVirtualName) but you can choose whether * or not you want to leave the zipfile open after return. */ - public boolean delete(String fullVirtualName, boolean closeZipFile) + public boolean delete(String fullVirtualName, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; - - if (openZipFile()) + File outputTempFile = null; + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - VirtualChild vc = getVirtualFile(fullVirtualName); - VirtualChild[] vcList; - VirtualChild[] vcOmmit = new VirtualChild[1]; - if (!vc.exists()) + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - if (closeZipFile) closeZipFile(); - return false; - } // file doesn't exist - - if (vc.isDirectory) // file is a directory, we must delete the contents - { - vcOmmit = getVirtualChildrenList(fullVirtualName, false); - } + if (openZipFile()) + { + fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); + VirtualChild vc = getVirtualFile(fullVirtualName, archiveOperationMonitor); + VirtualChild[] vcList; + VirtualChild[] vcOmmit = new VirtualChild[1]; + if (!vc.exists()) + { + if (closeZipFile) closeZipFile(); + return false; + } // file doesn't exist + + if (vc.isDirectory) // file is a directory, we must delete the contents + { + vcOmmit = getVirtualChildrenList(fullVirtualName, false, archiveOperationMonitor); + } + + // Open a new tempfile which will be our destination for the new zip + outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ + ZipOutputStream dest = new ZipOutputStream( + new FileOutputStream(outputTempFile)); + dest.setMethod(ZipOutputStream.DEFLATED); + + // get all the entries in the old zip + vcList = getVirtualChildrenList(false, archiveOperationMonitor); + + HashSet omissions = new HashSet(); + + if (vc.isDirectory) + { + for (int i = 0; i < vcOmmit.length; i++) + { + omissions.add(vcOmmit[i].fullName); + } + try + { + safeGetEntry(vc.fullName); + omissions.add(vc.fullName); + } + catch (IOException e) {} + } + else + { + omissions.add(fullVirtualName); + } + + // recreate the zip file without the omissions + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, omissions, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + + dest.close(); - File outputTempFile = null; - try - { - // Open a new tempfile which will be our destination for the new zip - outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ - ZipOutputStream dest = new ZipOutputStream( - new FileOutputStream(outputTempFile)); - dest.setMethod(ZipOutputStream.DEFLATED); - - // get all the entries in the old zip - vcList = getVirtualChildrenList(false); - - HashSet omissions = new HashSet(); - - if (vc.isDirectory) - { - for (int i = 0; i < vcOmmit.length; i++) + // Now replace the old zip file with the new one + replaceOldZip(outputTempFile); + + // Now update the tree + HashMap hm = (HashMap) _virtualFS.get(vc.path); + hm.remove(vc.name); + if (vc.isDirectory) { - omissions.add(vcOmmit[i].fullName); + delTree(vc); } - try - { - safeGetEntry(vc.fullName); - omissions.add(vc.fullName); - } - catch (IOException e) {} - } - else - { - omissions.add(fullVirtualName); - } - - // recreate the zip file without the omissions - recreateZipDeleteEntries(vcList, dest, omissions); - dest.close(); - - // Now replace the old zip file with the new one - replaceOldZip(outputTempFile); - - // Now update the tree - HashMap hm = (HashMap) _virtualFS.get(vc.path); - hm.remove(vc.name); - if (vc.isDirectory) - { - delTree(vc); + if (closeZipFile) closeZipFile(); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return true; } } - catch (IOException e) - { - System.out.println(e.getMessage()); - System.out.println("Could not delete " + fullVirtualName); //$NON-NLS-1$ - if (!(outputTempFile == null)) outputTempFile.delete(); - if (closeZipFile) closeZipFile(); - return false; - } - if (closeZipFile) closeZipFile(); - return true; } - else return false; + catch (IOException e) + { + System.out.println(e.getMessage()); + System.out.println("Could not delete " + fullVirtualName); //$NON-NLS-1$ + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return false; } /** @@ -1351,26 +1501,29 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#replace(java.lang.String, java.io.File, java.lang.String) */ - public boolean replace(String fullVirtualName, File file, String name) + public boolean replace(String fullVirtualName, File file, String name, ISystemOperationMonitor archiveOperationMonitor) { - return replace(fullVirtualName, file, name, true); + return replace(fullVirtualName, file, name, true, archiveOperationMonitor); } /** * Same as replace(String fullVirtualName, File file, String name) but you can choose whether * or not you want to leave the zipfile open after return. */ - public boolean replace(String fullVirtualName, File file, String name, boolean closeZipFile) + public boolean replace(String fullVirtualName, File file, String name, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; if (!file.exists() || !file.canRead()) return false; fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - if (!exists(fullVirtualName)) + if (!exists(fullVirtualName, archiveOperationMonitor)) { // sorry, wrong method buddy - return add(file, fullVirtualName, name); + return add(file, fullVirtualName, name, archiveOperationMonitor); } + + + if (openZipFile()) { File outputTempFile = null; @@ -1382,11 +1535,19 @@ public class SystemZipHandler implements ISystemArchiveHandler new FileOutputStream(outputTempFile)); dest.setMethod(ZipOutputStream.DEFLATED); // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); HashSet omissions = new HashSet(); omissions.add(fullVirtualName); - recreateZipDeleteEntries(vcList, dest, omissions); - + + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, omissions, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + // Now append the additional entry to the zip file. int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ String virtualPath; @@ -1400,7 +1561,7 @@ public class SystemZipHandler implements ISystemArchiveHandler } appendFile(file, dest, virtualPath, name, SystemEncodingUtil.ENCODING_UTF_8, SystemEncodingUtil.ENCODING_UTF_8, false); dest.close(); - + // Now replace the old zip file with the new one replaceOldZip(outputTempFile); @@ -1416,18 +1577,20 @@ public class SystemZipHandler implements ISystemArchiveHandler return true; } else return false; + } - public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText) + public boolean replace(String fullVirtualName, InputStream stream, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - if (!exists(fullVirtualName)) + if (!exists(fullVirtualName, archiveOperationMonitor)) { // wrong method - return add(stream, fullVirtualName, name, sourceEncoding, targetEncoding, isText); + return add(stream, fullVirtualName, name, sourceEncoding, targetEncoding, isText, archiveOperationMonitor); } + if (openZipFile()) { File outputTempFile = null; @@ -1439,10 +1602,17 @@ public class SystemZipHandler implements ISystemArchiveHandler new FileOutputStream(outputTempFile)); dest.setMethod(ZipOutputStream.DEFLATED); // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); HashSet omissions = new HashSet(); omissions.add(fullVirtualName); - recreateZipDeleteEntries(vcList, dest, omissions); + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, omissions, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + closeZipFile(); + return false; + } // Now append the additional entry to the zip file. int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ @@ -1475,34 +1645,37 @@ public class SystemZipHandler implements ISystemArchiveHandler else return false; } + /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#fullRename(java.lang.String, java.lang.String) */ - public boolean fullRename(String fullVirtualName, String newFullVirtualName) + public boolean fullRename(String fullVirtualName, String newFullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { - return fullRename(fullVirtualName, newFullVirtualName, true); + return fullRename(fullVirtualName, newFullVirtualName, true, archiveOperationMonitor); } /** * Same as fullRename(String fullVirtualName, String newFullVirtualName) but you can choose whether * or not you want to leave the zipfile open after return. */ - public boolean fullRename(String fullVirtualName, String newFullVirtualName, boolean closeZipFile) + public boolean fullRename(String fullVirtualName, String newFullVirtualName, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); newFullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(newFullVirtualName); - VirtualChild vc = getVirtualFile(fullVirtualName); + VirtualChild vc = getVirtualFile(fullVirtualName, archiveOperationMonitor); if (!vc.exists()) { System.out.println("The virtual file " + fullVirtualName + " does not exist."); //$NON-NLS-1$ //$NON-NLS-2$ return false; } - if (openZipFile()) + File outputTempFile = null; + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - File outputTempFile = null; - try + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { // Open a new tempfile which will be our destination for the new zip outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ @@ -1510,14 +1683,14 @@ public class SystemZipHandler implements ISystemArchiveHandler new FileOutputStream(outputTempFile)); dest.setMethod(ZipOutputStream.DEFLATED); // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); VirtualChild[] renameList; HashMap names = new HashMap(); // if the entry to rename is a directory, we must then rename // all files and directories below it en masse. if (vc.isDirectory) { - renameList = getVirtualChildrenList(fullVirtualName, false); + renameList = getVirtualChildrenList(fullVirtualName, false, archiveOperationMonitor); for (int i = 0; i < renameList.length; i++) { int j = fullVirtualName.length(); @@ -1533,76 +1706,96 @@ public class SystemZipHandler implements ISystemArchiveHandler names.put(renameList[i].fullName, newName); } } + names.put(fullVirtualName + "/", newFullVirtualName + "/"); //$NON-NLS-1$ //$NON-NLS-2$ + /* try { safeGetEntry(fullVirtualName); names.put(fullVirtualName + "/", newFullVirtualName + "/"); //$NON-NLS-1$ //$NON-NLS-2$ } catch (IOException e) {} + */ } else { names.put(fullVirtualName, newFullVirtualName); } // find the entry to rename and rename it - recreateZipRenameEntries(vcList, dest, names); + boolean isCanceled = recreateZipRenameEntries(vcList, dest, names, archiveOperationMonitor); dest.close(); - + + if (isCanceled) + { + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } // Now replace the old zip file with the new one replaceOldZip(outputTempFile); // Now rebuild the tree buildTree(); - } - catch (IOException e) - { - System.out.println("Could not rename " + fullVirtualName); //$NON-NLS-1$ - if (!(outputTempFile == null)) outputTempFile.delete(); if (closeZipFile) closeZipFile(); + return true; + } + else + { return false; } - if (closeZipFile) closeZipFile(); - return true; } - else return false; + catch (IOException e) + { + e.printStackTrace(); + System.out.println("Could not rename " + fullVirtualName); //$NON-NLS-1$ + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#move(java.lang.String, java.lang.String) */ - public boolean move(String fullVirtualName, String destinationVirtualPath) + public boolean move(String fullVirtualName, String destinationVirtualPath, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); destinationVirtualPath = ArchiveHandlerManager.cleanUpVirtualPath(destinationVirtualPath); int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ if (i == -1) { - return fullRename(fullVirtualName, destinationVirtualPath + "/" + fullVirtualName); //$NON-NLS-1$ + return fullRename(fullVirtualName, destinationVirtualPath + "/" + fullVirtualName, archiveOperationMonitor); //$NON-NLS-1$ } String name = fullVirtualName.substring(i); - return fullRename(fullVirtualName, destinationVirtualPath + name); + return fullRename(fullVirtualName, destinationVirtualPath + name, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#rename(java.lang.String, java.lang.String) */ - public boolean rename(String fullVirtualName, String newName) + public boolean rename(String fullVirtualName, String newName, ISystemOperationMonitor archiveOperationMonitor) { fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ if (i == -1) { - return fullRename(fullVirtualName, newName); + return fullRename(fullVirtualName, newName, archiveOperationMonitor); } String fullNewName = fullVirtualName.substring(0, i+1) + newName; - return fullRename(fullVirtualName, fullNewName); + boolean returnValue = fullRename(fullVirtualName, fullNewName, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnValue; } + /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#getFiles(java.lang.String[]) */ - public File[] getFiles(String[] fullNames) + public File[] getFiles(String[] fullNames, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return new File[0]; @@ -1625,7 +1818,7 @@ public class SystemZipHandler implements ISystemArchiveHandler { files[i] = File.createTempFile(name, "virtual"); //$NON-NLS-1$ files[i].deleteOnExit(); - extractVirtualFile(fullNames[i], files[i]); + extractVirtualFile(fullNames[i], files[i], archiveOperationMonitor); } catch (IOException e) { @@ -1640,20 +1833,20 @@ public class SystemZipHandler implements ISystemArchiveHandler /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFolder(java.lang.String) */ - public boolean createFolder(String name) + public boolean createFolder(String name, ISystemOperationMonitor archiveOperationMonitor) { name = ArchiveHandlerManager.cleanUpVirtualPath(name); name = name + "/"; //$NON-NLS-1$ - return createVirtualObject(name, true); + return createVirtualObject(name, true, archiveOperationMonitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#createFile(java.lang.String) */ - public boolean createFile(String name) + public boolean createFile(String name, ISystemOperationMonitor archiveOperationMonitor) { name = ArchiveHandlerManager.cleanUpVirtualPath(name); - return createVirtualObject(name, true); + return createVirtualObject(name, true, archiveOperationMonitor); } /** @@ -1664,56 +1857,73 @@ public class SystemZipHandler implements ISystemArchiveHandler * name ends in a "/". * @return Whether the creation was successful or not. */ - protected boolean createVirtualObject(String name, boolean closeZipFile) + protected boolean createVirtualObject(String name, boolean closeZipFile, ISystemOperationMonitor archiveOperationMonitor) { if (!_exists) return false; - if (exists(name)) + if (exists(name, archiveOperationMonitor)) { // The object already exists. return false; } - if (openZipFile()) + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - File outputTempFile; - try + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - // Open a new tempfile which will be our destination for the new zip - outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ - ZipOutputStream dest = new ZipOutputStream( - new FileOutputStream(outputTempFile)); - dest.setMethod(ZipOutputStream.DEFLATED); - // get all the entries in the old zip - VirtualChild[] vcList = getVirtualChildrenList(false); - - // if it is an empty zip file, no need to recreate it - if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ + if (openZipFile()) { - recreateZipDeleteEntries(vcList, dest, null); - } - - // append the additional entry to the zip file. - ZipEntry newEntry = appendEmptyFile(dest, name); - // Add the new entry to the virtual file system in memory - fillBranch(newEntry); - - dest.close(); - - // Now replace the old zip file with the new one - replaceOldZip(outputTempFile); + File outputTempFile; + + // Open a new tempfile which will be our destination for the new zip + outputTempFile = new File(_file.getAbsolutePath() + "temp"); //$NON-NLS-1$ + ZipOutputStream dest = new ZipOutputStream( + new FileOutputStream(outputTempFile)); + dest.setMethod(ZipOutputStream.DEFLATED); + // get all the entries in the old zip + VirtualChild[] vcList = getVirtualChildrenList(false, archiveOperationMonitor); + + // if it is an empty zip file, no need to recreate it + if (!(vcList.length == 1) || !vcList[0].fullName.equals("")) //$NON-NLS-1$ + { + boolean isCanceled = recreateZipDeleteEntries(vcList, dest, null, archiveOperationMonitor); + if (isCanceled) + { + dest.close(); + if (!(outputTempFile == null)) outputTempFile.delete(); + if (closeZipFile) closeZipFile(); + return false; + } + } + + // append the additional entry to the zip file. + ZipEntry newEntry = appendEmptyFile(dest, name); + // Add the new entry to the virtual file system in memory + fillBranch(newEntry); + dest.close(); + + // Now replace the old zip file with the new one + replaceOldZip(outputTempFile); + + if (closeZipFile) closeZipFile(); + return true; + } } - catch (IOException e) - { - System.out.println("Could not add a file."); //$NON-NLS-1$ - System.out.println(e.getMessage()); - if (closeZipFile) closeZipFile(); - return false; - } - if (closeZipFile) closeZipFile(); - return true; } - else return false; + catch (IOException e) + { + System.out.println("Could not add a file."); //$NON-NLS-1$ + System.out.println(e.getMessage()); + if (closeZipFile) closeZipFile(); + return false; + } + finally + { + releaseMutex(mutexLockStatus); + } + return false; } /** @@ -1798,20 +2008,40 @@ public class SystemZipHandler implements ISystemArchiveHandler * create the virtualFS are different, update the virtualFS. * @return whether or not the op was successful. */ - protected boolean updateVirtualFSIfNecessary() + protected boolean updateVirtualFSIfNecessary(ISystemOperationMonitor archiveOperationMonitor) { if (_vfsLastModified != _file.lastModified()) { - if (openZipFile()) + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - buildTree(); - _vfsLastModified = _file.lastModified(); - closeZipFile(); - return true; + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) + { + if (openZipFile()) + { + buildTree(); + _vfsLastModified = _file.lastModified(); + closeZipFile(); + return true; + } + else + { + return false; + } + } + } + catch (Exception e) + { + e.printStackTrace(); + closeZipFile(); + } + finally + { + releaseMutex(mutexLockStatus); } - else return false; } - else return true; + return true; } /** @@ -1841,7 +2071,7 @@ public class SystemZipHandler implements ISystemArchiveHandler HashSet omissions = new HashSet(); // the above two statements force recreateZipDeleteEntries to create a dummy entry - recreateZipDeleteEntries(vcList, dest, omissions); + recreateZipDeleteEntries(vcList, dest, omissions, null); dest.close(); if (openZipFile()) @@ -1863,7 +2093,7 @@ public class SystemZipHandler implements ISystemArchiveHandler return true; } - public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher) + public SystemSearchLineMatch[] search(String fullVirtualName, SystemSearchStringMatcher matcher, ISystemOperationMonitor archiveOperationMonitor) { // if the search string is empty or if it is "*", then return no matches @@ -1874,7 +2104,7 @@ public class SystemZipHandler implements ISystemArchiveHandler fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); - VirtualChild vc = getVirtualFile(fullVirtualName); + VirtualChild vc = getVirtualFile(fullVirtualName, archiveOperationMonitor); if (!vc.exists() || vc.isDirectory) { return new SystemSearchLineMatch[0]; @@ -2119,16 +2349,23 @@ public class SystemZipHandler implements ISystemArchiveHandler return type; } - public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes registry) + public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, ISystemFileTypes registry, ISystemOperationMonitor archiveOperationMonitor) { - if (!_exists) return false; + if (!_exists) + { + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return false; + } + virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); if (!file.isDirectory()) { - if (exists(virtualPath + "/" + name)) //$NON-NLS-1$ + if (exists(virtualPath + "/" + name, archiveOperationMonitor)) //$NON-NLS-1$ { // wrong method - return replace(virtualPath + "/" + name, file, name); //$NON-NLS-1$ + boolean returnCode = replace(virtualPath + "/" + name, file, name, archiveOperationMonitor); //$NON-NLS-1$ + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; } else { @@ -2142,14 +2379,20 @@ public class SystemZipHandler implements ISystemArchiveHandler targetEncodings[0] = targetEncoding; boolean[] isTexts = new boolean[1]; isTexts[0] = registry.isText(file); - return add(files, virtualPath, names, sourceEncodings, targetEncodings, isTexts); + boolean returnCode = add(files, virtualPath, names, sourceEncodings, targetEncodings, isTexts, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; } } else { //String sourceName = name; HashSet children = new HashSet(); - listAllFiles(file, children); + boolean isCanceled = listAllFiles(file, children, archiveOperationMonitor); + if (isCanceled) + { + return false; + } File[] sources = new File[children.size() + 1]; String[] newNames = new String[children.size() + 1]; Object[] kids = children.toArray(); @@ -2177,68 +2420,105 @@ public class SystemZipHandler implements ISystemArchiveHandler isTexts[children.size()] = registry.isText(file); if (!newNames[children.size()].endsWith("/")) newNames[children.size()] = newNames[children.size()] + "/"; //$NON-NLS-1$ //$NON-NLS-2$ - return add(sources, virtualPath, newNames, sourceEncodings, targetEncodings, isTexts); + + boolean returnCode = add(sources, virtualPath, newNames, sourceEncodings, targetEncodings, isTexts, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; } } - public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText) + public boolean add(File file, String virtualPath, String name, String sourceEncoding, String targetEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { - if (!_exists) return false; + if (!_exists) + { + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return false; + } + virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); - if (!file.isDirectory()) + + int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK; + try { - String fullVirtualName = getFullVirtualName(virtualPath, name); - if (exists(fullVirtualName)) + mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE); + if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus) { - return replace(fullVirtualName, file, name); - } - else - { - File[] files = new File[1]; - files[0] = file; - String[] names = new String[1]; - names[0] = name; - String[] sourceEncodings = new String[1]; - sourceEncodings[0] = sourceEncoding; - String[] targetEncodings = new String[1]; - targetEncodings[0] = targetEncoding; - boolean[] isTexts = new boolean[1]; - isTexts[0] = isText; - return add(files, virtualPath, names, sourceEncodings, targetEncodings, isTexts); + if (!file.isDirectory()) + { + String fullVirtualName = getFullVirtualName(virtualPath, name); + if (exists(fullVirtualName, archiveOperationMonitor)) + { + boolean returnCode = replace(fullVirtualName, file, name, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; + } + else + { + File[] files = new File[1]; + files[0] = file; + String[] names = new String[1]; + names[0] = name; + String[] sourceEncodings = new String[1]; + sourceEncodings[0] = sourceEncoding; + String[] targetEncodings = new String[1]; + targetEncodings[0] = targetEncoding; + boolean[] isTexts = new boolean[1]; + isTexts[0] = isText; + boolean returnCode = add(files, virtualPath, names, sourceEncodings, targetEncodings, isTexts, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; + } + } + else + { + HashSet children = new HashSet(); + boolean isCanceled = listAllFiles(file, children, archiveOperationMonitor); + if (isCanceled) + { + return false; + } + File[] sources = new File[children.size() + 1]; + String[] newNames = new String[children.size() + 1]; + Object[] kids = children.toArray(); + String[] sourceEncodings = new String[children.size() + 1]; + String[] targetEncodings = new String[children.size() + 1]; + boolean[] isTexts = new boolean[children.size() + 1]; + int charsToTrim = file.getParentFile().getAbsolutePath().length() + 1; + if (file.getParentFile().getAbsolutePath().endsWith(File.separator)) charsToTrim--; // accounts for root + for (int i = 0; i < children.size(); i++) + { + sources[i] = (File) kids[i]; + newNames[i] = sources[i].getAbsolutePath().substring(charsToTrim); + newNames[i] = newNames[i].replace('\\','/'); + if (sources[i].isDirectory() && !newNames[i].endsWith("/")) newNames[i] = newNames[i] + "/"; //$NON-NLS-1$ //$NON-NLS-2$ + + // this part can be changed to allow different encodings for different files + sourceEncodings[i] = sourceEncoding; + targetEncodings[i] = targetEncoding; + isTexts[i] = isText; + } + sources[children.size()] = file; + newNames[children.size()] = name; + sourceEncodings[children.size()] = sourceEncoding; + targetEncodings[children.size()] = targetEncoding; + isTexts[children.size()] = isText; + if (!newNames[children.size()].endsWith("/")) newNames[children.size()] = newNames[children.size()] + "/"; //$NON-NLS-1$ //$NON-NLS-2$ + boolean returnCode = add(sources, virtualPath, newNames, sourceEncodings, targetEncodings, isTexts, archiveOperationMonitor); + setArchiveOperationMonitorStatusDone(archiveOperationMonitor); + return returnCode; + } } } - else + catch (Exception e) { - HashSet children = new HashSet(); - listAllFiles(file, children); - File[] sources = new File[children.size() + 1]; - String[] newNames = new String[children.size() + 1]; - Object[] kids = children.toArray(); - String[] sourceEncodings = new String[children.size() + 1]; - String[] targetEncodings = new String[children.size() + 1]; - boolean[] isTexts = new boolean[children.size() + 1]; - int charsToTrim = file.getParentFile().getAbsolutePath().length() + 1; - if (file.getParentFile().getAbsolutePath().endsWith(File.separator)) charsToTrim--; // accounts for root - for (int i = 0; i < children.size(); i++) - { - sources[i] = (File) kids[i]; - newNames[i] = sources[i].getAbsolutePath().substring(charsToTrim); - newNames[i] = newNames[i].replace('\\','/'); - if (sources[i].isDirectory() && !newNames[i].endsWith("/")) newNames[i] = newNames[i] + "/"; //$NON-NLS-1$ //$NON-NLS-2$ - - // this part can be changed to allow different encodings for different files - sourceEncodings[i] = sourceEncoding; - targetEncodings[i] = targetEncoding; - isTexts[i] = isText; - } - sources[children.size()] = file; - newNames[children.size()] = name; - sourceEncodings[children.size()] = sourceEncoding; - targetEncodings[children.size()] = targetEncoding; - isTexts[children.size()] = isText; - if (!newNames[children.size()].endsWith("/")) newNames[children.size()] = newNames[children.size()] + "/"; //$NON-NLS-1$ //$NON-NLS-2$ - return add(sources, virtualPath, newNames, sourceEncodings, targetEncodings, isTexts); + } + finally + { + releaseMutex(mutexLockStatus); + } + + return false; } /** @@ -2260,4 +2540,22 @@ public class SystemZipHandler implements ISystemArchiveHandler } return fullVirtualName; } + + private void releaseMutex(int mutexLockStatus) + { + //We only release the mutex if we aquired it, not borrowed it. + if (SystemReentrantMutex.LOCK_STATUS_AQUIRED == mutexLockStatus) + { + _mutex.release(); + } + } + + private void setArchiveOperationMonitorStatusDone(ISystemOperationMonitor archiveOperationMonitor) + { + //We only set the status of the archive operation montor to done if it is not been canceled. + if (null != archiveOperationMonitor && !archiveOperationMonitor.isCanceled()) + { + archiveOperationMonitor.setDone(true); + } + } } diff --git a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/VirtualChild.java b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/VirtualChild.java index b1b8bc20370..c441968f5ef 100644 --- a/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/VirtualChild.java +++ b/rse/plugins/org.eclipse.rse.services/clientserver/org/eclipse/rse/services/clientserver/archiveutils/VirtualChild.java @@ -13,6 +13,7 @@ * * Contributors: * {Name} (company) - description of contribution. + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.services.clientserver.archiveutils; @@ -20,6 +21,7 @@ package org.eclipse.rse.services.clientserver.archiveutils; import java.io.File; import java.io.IOException; +import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.SystemEncodingUtil; @@ -36,6 +38,12 @@ public final class VirtualChild { protected ISystemArchiveHandler _handler; protected File _extractedFile; protected File _containingArchive; + + private String comment; + private long compressedSize; + private String compressionMethod; + private long size; + private long timeStamp; /** * Constructs a new VirtualChild given a reference to its parent archive's @@ -51,6 +59,12 @@ public final class VirtualChild { _handler = handler; _extractedFile = null; _containingArchive = null; + + comment = ""; //$NON-NLS-1$ + compressedSize = -1; + compressionMethod = ""; //$NON-NLS-1$ + size = -1; + timeStamp = -1; } /** @@ -94,8 +108,19 @@ public final class VirtualChild { */ public long getTimeStamp() { + /* if (_handler == null) return 0; return _handler.getTimeStampFor(fullName); + */ + return timeStamp; + } + + /** + * @param value the time stamp value + */ + public void setTimeStamp(long value) + { + timeStamp = value; } /** @@ -104,8 +129,19 @@ public final class VirtualChild { */ public long getSize() { + /* if (_handler == null) return 0; return _handler.getSizeFor(fullName); + */ + return size; + } + + /** + * @param value the size value + */ + public void setSize(long value) + { + size = value; } /** @@ -113,8 +149,19 @@ public final class VirtualChild { */ public String getComment() { + /* if (_handler == null) return ""; //$NON-NLS-1$ return _handler.getCommentFor(fullName); + */ + return comment; + } + + /** + * @param value the comment value + */ + public void setComment(String value) + { + comment = value; } /** @@ -123,8 +170,19 @@ public final class VirtualChild { */ public long getCompressedSize() { + /* if (_handler == null) return 0; return _handler.getCompressedSizeFor(fullName); + */ + return compressedSize; + } + + /** + * @param value the compressedSize value + */ + public void setCompressedSize(long value) + { + compressedSize = value; } /** @@ -132,21 +190,44 @@ public final class VirtualChild { */ public String getCompressionMethod() { + /* if (_handler == null) return ""; //$NON-NLS-1$ return _handler.getCompressionMethodFor(fullName); + */ + return compressionMethod; } + /** + * @param value the compression method value + */ + public void setCompressionMethod(String value) + { + compressionMethod = value; + } + /** * @return The actual minus compressed size of this VirtualChild, divided * by the actual size. */ public double getCompressionRatio() { + /* if (getSize() == 0) { return 1; } else return ((double)getSize() - (double)getCompressedSize()) / getSize(); + */ + if (size <= 0) + { + return 1; + } + if (compressedSize <= 0) + { + return 1; + } + + return ((double)size - (double)compressedSize) / size; } /** @@ -157,7 +238,7 @@ public final class VirtualChild { */ public File getExtractedFile() { - return getExtractedFile(SystemEncodingUtil.ENCODING_UTF_8, false); + return getExtractedFile(SystemEncodingUtil.ENCODING_UTF_8, false, null); } /** @@ -167,8 +248,9 @@ public final class VirtualChild { * timestamps on the cached and archived files do not match, the cached file is erased, * and reextracted from the archive. */ - public File getExtractedFile(String sourceEncoding, boolean isText) + public File getExtractedFile(String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { + File returnedFile = null; if (_extractedFile == null || _extractedFile.lastModified() != getTimeStamp()) { try @@ -193,14 +275,19 @@ public final class VirtualChild { if (!(_extractedFile.delete() && _extractedFile.mkdirs())) { System.out.println("VirtualChild.getExtractedFile(): Could not create temp dir."); //$NON-NLS-1$ + //We only set the status of the archive operation montor to done if it is not been canceled. + if (null != archiveOperationMonitor && !archiveOperationMonitor.isCanceled()) + { + archiveOperationMonitor.setDone(true); + } return null; } } - _handler.extractVirtualDirectory(fullName, _extractedFile, sourceEncoding, isText); + _handler.extractVirtualDirectory(fullName, _extractedFile, sourceEncoding, isText, archiveOperationMonitor); } else { - _handler.extractVirtualFile(fullName, _extractedFile, sourceEncoding, isText); + _handler.extractVirtualFile(fullName, _extractedFile, sourceEncoding, isText, archiveOperationMonitor); } } catch (IOException e) @@ -212,12 +299,20 @@ public final class VirtualChild { if (isDirectory) { - return new File(_extractedFile, name); + returnedFile = new File(_extractedFile, name); } else { - return _extractedFile; + returnedFile = _extractedFile; } + + //We only set the status of the archive operation montor to done if it is not been canceled. + if (null != archiveOperationMonitor && !archiveOperationMonitor.isCanceled()) + { + archiveOperationMonitor.setDone(true); + } + + return returnedFile; } /** @@ -230,9 +325,9 @@ public final class VirtualChild { * what is in the archive. * @return true if and only if the extraction succeeded. */ - public boolean getExtractedFile(File destination) + public boolean getExtractedFile(File destination, ISystemOperationMonitor archiveOperationMonitor) { - return getExtractedFile(destination, SystemEncodingUtil.ENCODING_UTF_8, false); + return getExtractedFile(destination, SystemEncodingUtil.ENCODING_UTF_8, false, archiveOperationMonitor); } /** @@ -245,7 +340,7 @@ public final class VirtualChild { * what is in the archive. * @return true if and only if the extraction succeeded. */ - public boolean getExtractedFile(File destination, String sourceEncoding, boolean isText) + public boolean getExtractedFile(File destination, String sourceEncoding, boolean isText, ISystemOperationMonitor archiveOperationMonitor) { boolean success = true; if (_handler == null) return false; @@ -256,14 +351,19 @@ public final class VirtualChild { { if (isDirectory) { - success = _handler.extractVirtualDirectory(fullName, destination.getParentFile(), destination, sourceEncoding, isText); + success = _handler.extractVirtualDirectory(fullName, destination.getParentFile(), destination, sourceEncoding, isText, archiveOperationMonitor); } else { - success = _handler.extractVirtualFile(fullName, destination, sourceEncoding, isText); + success = _handler.extractVirtualFile(fullName, destination, sourceEncoding, isText, archiveOperationMonitor); } _extractedFile = destination; } + //We only set the status of the archive operation montor to done if it is not been canceled. + if (null != archiveOperationMonitor && !archiveOperationMonitor.isCanceled()) + { + archiveOperationMonitor.setDone(true); + } return success; } @@ -273,7 +373,7 @@ public final class VirtualChild { public boolean exists() { if (_handler == null) return false; - return _handler.exists(fullName); + return _handler.exists(fullName, null); } /** diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java index 6806b0ad93b..b8ed6a72122 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems * David McKnight (IBM) - [162195] new APIs for upload multi and download multi + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.services.files; @@ -125,9 +126,14 @@ public abstract class AbstractFileService implements IFileService public boolean deleteBatch(String[] remoteParents, String[] fileNames, IProgressMonitor monitor) throws SystemMessageException { boolean ok = true; + SystemMessage msg = getMessage("RSEF1315"); //$NON-NLS-1$ + String deletingMessage = msg.makeSubstitution("").getLevelOneText(); //$NON-NLS-1$ + monitor.beginTask(deletingMessage, remoteParents.length); for (int i = 0; i < remoteParents.length; i++) { + monitor.subTask(msg.makeSubstitution(fileNames[i]).getLevelOneText()); ok = ok && delete(remoteParents[i], fileNames[i], monitor); + monitor.worked(1); } return ok; } diff --git a/rse/plugins/org.eclipse.rse.shells.ui/src/org/eclipse/rse/shells/ui/view/SystemViewRemoteOutputAdapter.java b/rse/plugins/org.eclipse.rse.shells.ui/src/org/eclipse/rse/shells/ui/view/SystemViewRemoteOutputAdapter.java index 1fd2e7fc508..cbbc561f508 100644 --- a/rse/plugins/org.eclipse.rse.shells.ui/src/org/eclipse/rse/shells/ui/view/SystemViewRemoteOutputAdapter.java +++ b/rse/plugins/org.eclipse.rse.shells.ui/src/org/eclipse/rse/shells/ui/view/SystemViewRemoteOutputAdapter.java @@ -20,6 +20,7 @@ * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Martin Oberhuber (Wind River) - [189130] Move SystemIFileProperties from UI to Core * David McKnight (IBM) - [196842] Don't have open menu for folders + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.shells.ui.view; @@ -1012,7 +1013,7 @@ implements ISystemViewElementAdapter, ISystemRemoteElementAdapter * Return true if this was successful. Return false if it failed and you issued a msg. * Throw an exception if it failed and you want to use the generic msg. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { return false; } diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.local/src/org/eclipse/rse/internal/subsystems/files/local/model/LocalVirtualFile.java b/rse/plugins/org.eclipse.rse.subsystems.files.local/src/org/eclipse/rse/internal/subsystems/files/local/model/LocalVirtualFile.java index 74efcfc403f..70d325a9b38 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.local/src/org/eclipse/rse/internal/subsystems/files/local/model/LocalVirtualFile.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.local/src/org/eclipse/rse/internal/subsystems/files/local/model/LocalVirtualFile.java @@ -14,6 +14,7 @@ * Contributors: * {Name} (company) - description of contribution. * Xuan Chen (IBM) - [200872] [Archives] Size Property displays size of Archive not of file inside Archive + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.internal.subsystems.files.local.model; @@ -167,7 +168,7 @@ public class LocalVirtualFile extends LocalFile implements IVirtualRemoteFile public Object getFile(String srcEncoding, boolean isText) { - return _node.getChild().getExtractedFile(srcEncoding, isText); + return _node.getChild().getExtractedFile(srcEncoding, isText, null); } public String getContainingArchiveFullName() diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/actions/SystemCommonDeleteAction.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/actions/SystemCommonDeleteAction.java index cab13714f90..9008df9db2c 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/actions/SystemCommonDeleteAction.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/actions/SystemCommonDeleteAction.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Kevin Doyle (IBM) - [188637] Handle the caught exception in DeleteJob.run when file fails to be deleted * Kevin Doyle (IBM) - [196582] ClassCastException when doing copy/paste with Remote Search view open + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.actions; @@ -36,9 +37,11 @@ import org.eclipse.rse.core.events.ISystemResourceChangeEvents; import org.eclipse.rse.core.model.ISystemRegistry; import org.eclipse.rse.core.subsystems.ISubSystem; import org.eclipse.rse.internal.ui.SystemResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.ui.ISystemContextMenuConstants; import org.eclipse.rse.ui.ISystemDeleteTarget; +import org.eclipse.rse.ui.ISystemMessages; import org.eclipse.rse.ui.RSEUIPlugin; import org.eclipse.rse.ui.SystemBasePlugin; import org.eclipse.rse.ui.actions.SystemBaseDialogAction; @@ -106,6 +109,7 @@ public class SystemCommonDeleteAction super(SystemResources.ACTION_DELETE_LABEL); _localResources = localResources; _remoteSets = remoteSets; + setUser(true); } public IStatus run(IProgressMonitor monitor) @@ -152,7 +156,37 @@ public class SystemCommonDeleteAction } catch (SystemMessageException e) { - SystemMessageDialog.displayMessage(e); + if (monitor.isCanceled() && set.size() > 1) + { + for (int i = 0; i < set.size(); i++) + { + Object thisObject = set.get(i); + if (!(adapter.exists(thisObject))) + { + //This object has been deleted + remoteDeletedObjects.add(thisObject); + } + } + if (remoteDeletedObjects.size() > 0) + { + //Get the moved file names + Object thisObject = remoteDeletedObjects.get(0); + String deletedFileNames = null; + deletedFileNames = adapter.getName(thisObject); + for (int i=1; i<(remoteDeletedObjects.size()); i++) + { + thisObject = remoteDeletedObjects.get(i); + deletedFileNames = deletedFileNames + "\n" + adapter.getName(thisObject); //$NON-NLS-1$ + } + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_DELETE_INTERRUPTED); + thisMessage.makeSubstitution(deletedFileNames); + SystemMessageDialog.displayErrorMessage(shell, thisMessage); + } + } + else + { + SystemMessageDialog.displayMessage(e); + } } catch (Exception e) { @@ -160,7 +194,6 @@ public class SystemCommonDeleteAction } } - // start a runnable to do the action refresh events DeleteEventRunnable fireEvents = new DeleteEventRunnable(localDeletedObjects, remoteDeletedObjects); Display.getDefault().asyncExec(fireEvents); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemTableTreeView.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemTableTreeView.java index 14f435a7bf2..6739fe02937 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemTableTreeView.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemTableTreeView.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Kevin Doyle (IBM) - [196582] ClassCastException when doing copy/paste with Search view open + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -1397,7 +1398,7 @@ public class SystemTableTreeView if (remoteAdapter != null) oldFullName = remoteAdapter.getAbsoluteName(element); // pre-rename - ok = adapter.doRename(getShell(), element, newNames[nameIdx++]); + ok = adapter.doRename(getShell(), element, newNames[nameIdx++], null); if (ok) { if (remoteAdapter != null) { diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java index 4373a1ad636..046fdc772a3 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java @@ -44,6 +44,7 @@ * David McKnight (IBM) - [204684] CheckExistsJob used for determining if a remote object exists after a query of it's children * David McKnight (IBM) - [205592] CheckExistsJob should use the context model object to get adapter * David McKnight (IBM) - [205819] Need to use input stream copy when EFS files are the src + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -54,6 +55,7 @@ import java.util.Iterator; import java.util.List; import java.util.Vector; +import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; @@ -130,6 +132,7 @@ import org.eclipse.rse.internal.ui.actions.SystemOpenExplorerPerspectiveAction; import org.eclipse.rse.internal.ui.actions.SystemShowInMonitorAction; import org.eclipse.rse.internal.ui.actions.SystemShowInTableAction; import org.eclipse.rse.internal.ui.actions.SystemSubMenuManager; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.ui.ISystemContextMenuConstants; import org.eclipse.rse.ui.ISystemDeleteTarget; @@ -4990,6 +4993,107 @@ public class SystemView extends SafeTreeViewer // ISYSTEMRENAMETARGET METHODS // --------------------------- + private class RenameJob extends WorkspaceJob + { + String[] newNames = null; + Object[] elements = null; + Object[] elementAdapters = null; + Object parentElement = null; + String renameMessage = null; + + /** + * RenameJob job. + * @param newNames array of new names of all the elements need to be renamed + * @param elements array of all the elements need to be renamed + * @param elementAdapters array of all the view adapters of the elements need to be renamed + * @param parentElement the parent object of the list of objects to be renamed + * @param renameMessage the title of the Rename job. + */ + public RenameJob(String[] newNames, Object[] elements, Object[] elementAdapters, Object parentElement, String renameMessage) + { + super(renameMessage); + this.newNames = newNames; + this.elements = elements; + this.elementAdapters = elementAdapters; + this.parentElement = parentElement; + setUser(true); + } + + public IStatus runInWorkspace(IProgressMonitor monitor) + { + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + Object element = null; + ISystemViewElementAdapter adapter = null; + ISystemRemoteElementAdapter remoteAdapter = null; + String oldFullName = ""; //$NON-NLS-1$ + String oldName = ""; //$NON-NLS-1$ + Vector fileNamesRenamed = new Vector(); + + boolean ok = true; + try { + int steps = elements.length; + monitor.beginTask(renameMessage, steps); + for (int i=0; i < elements.length; i++) + { + element = elements[i]; + adapter = (ISystemViewElementAdapter)elementAdapters[i]; + remoteAdapter = getRemoteAdapter(element); + if (remoteAdapter != null) + { + oldName = remoteAdapter.getName(element); + oldFullName = remoteAdapter.getAbsoluteName(element); // pre-rename + monitor.subTask(getRenamingMessage(oldName).getLevelOneText()); + } + ok = adapter.doRename(null, element, newNames[i], monitor); + if (ok) + { + fileNamesRenamed.add(oldName); + if (remoteAdapter != null) + { + ISubSystem ss = adapter.getSubSystem(element); + sr.fireRemoteResourceChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_RENAMED, element, parentElement, ss, oldFullName, this); + } + + else + sr.fireEvent(new org.eclipse.rse.core.events.SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_RENAME, parentElement)); + } + monitor.worked(1); + } + } + catch (SystemMessageException exc) + { + ok = false; + //If this operation is canceled, need to display a proper message to the user. + if (monitor.isCanceled() && fileNamesRenamed.size() > 0) + { + //Get the renamed file names + String renamedFileNames = (String)(fileNamesRenamed.get(0)); + for (int i=1; i<(fileNamesRenamed.size()); i++) + { + renamedFileNames = renamedFileNames + "\n" + fileNamesRenamed.get(i); //$NON-NLS-1$ + } + //getMessage("RSEG1125").makeSubstitution(movedFileName)); + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_RENAME_INTERRUPTED); + thisMessage.makeSubstitution(renamedFileNames); + SystemMessageDialog.displayErrorMessage(shell, thisMessage); + } + else + { + SystemMessageDialog.displayErrorMessage(shell, exc.getSystemMessage()); + } + } catch (Exception exc) { + //String msg = exc.getMessage(); + //if ((msg == null) || (exc instanceof ClassCastException)) + // msg = exc.getClass().getName(); + exc.printStackTrace(); + SystemMessageDialog.displayErrorMessage(null, RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_EXCEPTION_RENAMING).makeSubstitution(element, exc), //msg), + exc); + ok = false; + } + + return Status.OK_STATUS; + } + } /** * Required method from ISystemRenameTarget. * Decides whether to even show the rename menu item. @@ -5008,53 +5112,39 @@ public class SystemView extends SafeTreeViewer if (!selectionFlagsUpdated) scanSelections("canRename"); //$NON-NLS-1$ return selectionEnableRenameAction; } + + /** + * Get the specific "Renaming %1..." + */ + protected SystemMessage getRenamingMessage(String oldName) + { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_RENAMEGENERIC_PROGRESS); + msg.makeSubstitution(oldName); + return msg; + } /** * Required method from ISystemRenameTarget */ public boolean doRename(String[] newNames) { - ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); IStructuredSelection selection = (IStructuredSelection) getSelection(); Iterator elements = selection.iterator(); - Object element = null; Object parentElement = getSelectedParent(); - ISystemViewElementAdapter adapter = null; - ISystemRemoteElementAdapter remoteAdapter = null; - String oldFullName = null; - boolean ok = true; - try { - int nameIdx = 0; - while (ok && elements.hasNext()) { - element = elements.next(); - adapter = getViewAdapter(element); - remoteAdapter = getRemoteAdapter(element); - if (remoteAdapter != null) - oldFullName = remoteAdapter.getAbsoluteName(element); // pre-rename - ok = adapter.doRename(getShell(), element, newNames[nameIdx++]); - if (ok) - { - if (remoteAdapter != null) - { - ISubSystem ss = adapter.getSubSystem(element); - sr.fireRemoteResourceChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_RENAMED, element, parentElement, ss, oldFullName, this); - } - - else - sr.fireEvent(new org.eclipse.rse.core.events.SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_RENAME, parentElement)); - } - } - } catch (SystemMessageException exc) { - SystemMessageDialog.displayErrorMessage(getShell(), exc.getSystemMessage()); - ok = false; - } catch (Exception exc) { - //String msg = exc.getMessage(); - //if ((msg == null) || (exc instanceof ClassCastException)) - // msg = exc.getClass().getName(); - SystemMessageDialog.displayErrorMessage(getShell(), RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_EXCEPTION_RENAMING).makeSubstitution(element, exc), //msg), - exc); - ok = false; + + Object[] renameElements = new Object[newNames.length]; + Object[] elementAdapters = new Object[newNames.length]; + int i = 0; + while (elements.hasNext()) { + renameElements[i] = elements.next(); + elementAdapters[i] = getViewAdapter(renameElements[i]); + i++; + //remoteAdapter = getRemoteAdapter(element); } - return ok; + SystemMessage renameMessage = getRenamingMessage(""); //$NON-NLS-1$ + String renameMessageText = renameMessage.getLevelOneText(); + RenameJob renameJob = new RenameJob(newNames, renameElements, elementAdapters, parentElement, renameMessageText); + renameJob.schedule(); + return true; } protected void logDebugMsg(String msg) { diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewConnectionAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewConnectionAdapter.java index c5e11fd7976..43e2665cf4a 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewConnectionAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewConnectionAdapter.java @@ -28,6 +28,7 @@ * Martin Oberhuber (Wind River) - [190271] Move ISystemViewInputProvider to Core * David McKnight (IBM) - [191288] Up To Action doesn't go all the way back to the connections * Uwe Stieber (Wind River) - [199032] [api] Remove method acceptContextMenuActionContribution(...) from RSESystemTypeAdapter + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -628,7 +629,7 @@ public class SystemViewConnectionAdapter /** * Perform the rename action. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { boolean ok = true; IHost conn = (IHost)element; diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterAdapter.java index aaab7653ba6..f975981698c 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterAdapter.java @@ -18,6 +18,7 @@ * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Tobias Schwarz (Wind River) - [173267] "empty list" should not be displayed * Martin Oberhuber (Wind River) - [190271] Move ISystemViewInputProvider to Core + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -470,7 +471,7 @@ public class SystemViewFilterAdapter extends AbstractSystemViewAdapter /** * Perform the rename action. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { ISystemFilter filter = getFilter(element); ISystemFilterPoolManager fpMgr = filter.getSystemFilterPoolManager(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolAdapter.java index e7d739834c3..0659d9442ec 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolAdapter.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [182454] improve getAbsoluteName() documentation * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186748] Move ISubSystemConfigurationAdapter from UI/rse.core.subsystems.util + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -251,7 +252,7 @@ public class SystemViewFilterPoolAdapter extends AbstractSystemViewAdapter /** * Perform the rename action. Assumes uniqueness checking was done already. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { ISystemFilterPool fp = (ISystemFilterPool)element; ISystemFilterPoolManager fpMgr = fp.getSystemFilterPoolManager(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolReferenceAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolReferenceAdapter.java index cb940f74457..b2bd2dc89e1 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolReferenceAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterPoolReferenceAdapter.java @@ -15,6 +15,7 @@ * Martin Oberhuber (Wind River) - [182454] improve getAbsoluteName() documentation * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186748] Move ISubSystemConfigurationAdapter from UI/rse.core.subsystems.util + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -314,7 +315,7 @@ public class SystemViewFilterPoolReferenceAdapter /** * Perform the rename action. Assumes uniqueness checking was done already. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { ISystemFilterPool fp = getFilterPool(element); ISystemFilterPoolManager fpMgr = fp.getSystemFilterPoolManager(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterReferenceAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterReferenceAdapter.java index f7fd2db4c4c..95de95fc634 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterReferenceAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterReferenceAdapter.java @@ -22,6 +22,7 @@ * Martin Oberhuber (Wind River) - [190271] Move ISystemViewInputProvider to Core * Kevin Doyle (IBM) - [187707] Added separator between New Folder and New File in context menu * David McKnight (IBM) - [199566] Remove synchronzied from internalGetChildren + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -638,7 +639,7 @@ public class SystemViewFilterReferenceAdapter /** * Perform the rename action. Assumes uniqueness checking was done already. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { ISystemFilter filter = getFilter(element); ISystemFilterPoolManager fpMgr = filter.getSystemFilterPoolManager(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterStringAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterStringAdapter.java index 35d8dea0552..3fc00ccaacc 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterStringAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewFilterStringAdapter.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [182454] improve getAbsoluteName() documentation * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186748] Move ISubSystemConfigurationAdapter from UI/rse.core.subsystems.util + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -256,7 +257,7 @@ public class SystemViewFilterStringAdapter extends AbstractSystemViewAdapter /** * Perform the rename action. */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { return true; } diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewSubSystemAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewSubSystemAdapter.java index c7a92597017..3ff781adf17 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewSubSystemAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemViewSubSystemAdapter.java @@ -16,6 +16,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186748] Move ISubSystemConfigurationAdapter from UI/rse.core.subsystems.util * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view; @@ -682,7 +683,7 @@ public class SystemViewSubSystemAdapter extends AbstractSystemViewAdapter /** * Perform the rename action. Assumes uniqueness checking was done already. */ - public boolean doRename(Shell shell, Object element, String name) + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) { ISubSystem ss = (ISubSystem)element; ISubSystemConfiguration parentSSFactory = ss.getSubSystemConfiguration(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/scratchpad/SystemScratchpadView.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/scratchpad/SystemScratchpadView.java index 6c6e41bf9e1..aa45a513d98 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/scratchpad/SystemScratchpadView.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/scratchpad/SystemScratchpadView.java @@ -21,6 +21,7 @@ * Kevin Doyle (IBM) - [189421] Scratchpad not updated after Rename * David McKnight (IBM) - [197860] drag and drop consistency - no text transfer * Kevin Doyle (IBM) - [197841] "Terminate and Remove" should remove the shell from Scratchpad + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view.scratchpad; @@ -970,7 +971,7 @@ public class SystemScratchpadView if (remoteAdapter != null) oldFullName = remoteAdapter.getAbsoluteName(element); // pre-rename - ok = adapter.doRename(getShell(), element, newNames[nameIdx++]); + ok = adapter.doRename(getShell(), element, newNames[nameIdx++], null); if (ok) { if (remoteAdapter != null) { diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewPart.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewPart.java index 3f4beddb2eb..6864ff79ef4 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewPart.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewPart.java @@ -17,6 +17,7 @@ * David Dykstal (IBM) - [186589] move user types, user actions, and compile commands * API to the user actions plugin * Rupen Mardirossian (IBM) - [187741] Implemented the handleDoubleClick method + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view.team; @@ -1116,7 +1117,7 @@ public class SystemTeamViewPart ISystemProfile profile = (ISystemProfile) elements.next(); try { SystemTeamViewProfileAdapter profileAdapter = getProfileAdapter(profile); - profileAdapter.doRename(getShell(), profile, newNames[idx++]); + profileAdapter.doRename(getShell(), profile, newNames[idx++], null); } catch (SystemMessageException exc) { SystemMessageDialog.displayMessage(getShell(), exc); ok = false; diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewProfileAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewProfileAdapter.java index a3ce48859a7..0582cd2684f 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewProfileAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/team/SystemTeamViewProfileAdapter.java @@ -18,6 +18,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * David Dykstal (IBM) - [191130] use new getRemoteSystemsProject(boolean) call + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.internal.ui.view.team; @@ -370,7 +371,7 @@ public class SystemTeamViewProfileAdapter /** * Perform the rename action. */ - public boolean doRename(Shell shell, Object element, String newName) throws Exception + public boolean doRename(Shell shell, Object element, String newName, IProgressMonitor monitor) throws Exception { boolean ok = true; RSECorePlugin.getTheSystemRegistry().renameSystemProfile((ISystemProfile)element, newName); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/ISystemMessages.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/ISystemMessages.java index c603690a075..d54884b89bc 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/ISystemMessages.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/ISystemMessages.java @@ -15,6 +15,9 @@ * API to the user actions plugin * Kevin Doyle (IBM) - [160769] Added FILEMSG_MOVE_FILTER_NOT_VALID * Kevin Doyle (IBM) - [199324] Added FILEMSG_MOVE_TARGET_EQUALS_PARENT_OF_SRC + * Xuan Chen (IBM) - [160775] Added MSG_RENAMEGENERIC_PROGRESS, FILEMSG_MOVE_INTERRUPTED + * FILEMSG_RENAME_INTERRUPTED, FILEMSG_DELETE_INTERRUPTED + * FILEMSG_COPY_INTERRUPTED ********************************************************************************/ package org.eclipse.rse.ui; @@ -195,6 +198,7 @@ public interface ISystemMessages public static final String MSG_MOVEGENERIC_PROGRESS = "RSEG1116"; //$NON-NLS-1$ public static final String MSG_COPYTHINGGENERIC_PROGRESS = "RSEG1117"; //$NON-NLS-1$ public static final String MSG_MOVETHINGGENERIC_PROGRESS = "RSEG1118"; //$NON-NLS-1$ + public static final String MSG_RENAMEGENERIC_PROGRESS = "RSEG1142"; //$NON-NLS-1$ public static final String MSG_SAVING_PROGRESS = "RSEG1119"; //$NON-NLS-1$ @@ -266,6 +270,10 @@ public interface ISystemMessages public static final String FILEMSG_MOVE_TARGET_DESCENDS_FROM_SOURCE = "RSEF1312"; //$NON-NLS-1$ public static final String FILEMSG_MOVE_FILTER_NOT_VALID = "RSEF1313"; //$NON-NLS-1$ public static final String FILEMSG_DELETING = "RSEF1315"; //$NON-NLS-1$ + public static final String FILEMSG_MOVE_INTERRUPTED = "RSEG1245"; //$NON-NLS-1$ + public static final String FILEMSG_RENAME_INTERRUPTED = "RSEG1246"; //$NON-NLS-1$ + public static final String FILEMSG_DELETE_INTERRUPTED = "RSEG1247"; //$NON-NLS-1$ + public static final String FILEMSG_COPY_INTERRUPTED = "RSEG1248"; //$NON-NLS-1$ // ------------------------- // IMPORT/EXPORT MESSAGES... diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/AbstractSystemViewAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/AbstractSystemViewAdapter.java index 8d5e0cf3287..5349aa57ab8 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/AbstractSystemViewAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/AbstractSystemViewAdapter.java @@ -22,6 +22,7 @@ * Tobias Schwarz (Wind River) - [173267] "empty list" should not be displayed * Martin Oberhuber (Wind River) - [190271] Move ISystemViewInputProvider to Core * David McKnight (IBM) - [208803] add exists() method + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.ui.view; @@ -979,7 +980,7 @@ public abstract class AbstractSystemViewAdapter implements ISystemViewElementAda *

By default, returns true. * @return true if we should show the rename action in the popup for the given element. * @see #canRename(Object) - * @see #doRename(Shell,Object,String) + * @see #doRename(Shell,Object,String, IProgressMonitor) */ public boolean showRename(Object element) { @@ -992,7 +993,7 @@ public abstract class AbstractSystemViewAdapter implements ISystemViewElementAda * By default, returns false. Override if your object is renamable. * @return true if this object is renamable by the user * @see #showRename(Object) - * @see #doRename(Shell,Object,String) + * @see #doRename(Shell,Object,String,IProgressMonitor) * @see #getNameValidator(Object) * @see #getCanonicalNewName(Object,String) * @see #namesAreEqual(Object,String) @@ -1011,7 +1012,7 @@ public abstract class AbstractSystemViewAdapter implements ISystemViewElementAda * @see #showRename(Object) * @see #canRename(Object) */ - public boolean doRename(Shell shell, Object element, String name) throws Exception + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { //org.eclipse.rse.core.ui.SystemMessage.displayErrorMessage("INSIDE DORENAME"); return false; diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java index 67daf9fea1c..9ec821b6321 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java @@ -14,6 +14,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [190271] Move ISystemViewInputProvider to Core * David McKnight (IBM) - [208803] add exists() method + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.ui.view; @@ -329,7 +330,7 @@ public interface ISystemViewElementAdapter extends IPropertySource, ISystemDragD /** * Perform the rename on the given item. */ - public boolean doRename(Shell shell, Object element, String name) + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception; diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/SystemTableView.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/SystemTableView.java index a0252ad56dd..478c40546b7 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/SystemTableView.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/SystemTableView.java @@ -16,6 +16,7 @@ * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry * Xuan Chen (IBM) - [187016] [menus] Remote Systems Details View should have Refresh on context menu * David McKnight (IBM) - [193329] using "Resource" instead of "Name" in the label column + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread ********************************************************************************/ package org.eclipse.rse.ui.view; @@ -26,9 +27,12 @@ import java.util.Iterator; import java.util.List; import java.util.Vector; +import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; @@ -79,6 +83,7 @@ import org.eclipse.rse.internal.ui.view.SystemViewDataDragAdapter; import org.eclipse.rse.internal.ui.view.SystemViewDataDropAdapter; import org.eclipse.rse.internal.ui.view.SystemViewMenuListener; import org.eclipse.rse.services.clientserver.StringCompare; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.ui.ISystemContextMenuConstants; import org.eclipse.rse.ui.ISystemDeleteTarget; @@ -1522,7 +1527,102 @@ public class SystemTableView // ISYSTEMRENAMETARGET METHODS // --------------------------- - + private class RenameJob extends WorkspaceJob + { + String[] newNames = null; + Object[] elements = null; + Object[] elementAdapters = null; + Object parentElement = null; + String renameMessage = null; + /** + * RenameJob job. + * @param newNames array of new names of all the elements need to be renamed + * @param elements array of all the elements need to be renamed + * @param elementAdapters array of all the view adapters of the elements need to be renamed + * @param renameMessage the title of the Rename job. + */ + public RenameJob(String[] newNames, Object[] elements, Object[] elementAdapters, String renameMessage) + { + super(renameMessage); + this.newNames = newNames; + this.elements = elements; + this.elementAdapters = elementAdapters; + setUser(true); + } + + public IStatus runInWorkspace(IProgressMonitor monitor) + { + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + Object element = null; + ISystemViewElementAdapter adapter = null; + ISystemRemoteElementAdapter remoteAdapter = null; + String oldFullName = null; + String oldName = null; + Vector fileNamesRenamed = new Vector(); + boolean ok = true; + + try { + int steps = elements.length; + monitor.beginTask(renameMessage, steps); + for (int i=0; i < elements.length; i++) + { + element = elements[i]; + adapter = (ISystemViewElementAdapter)elementAdapters[i]; + remoteAdapter = getRemoteAdapter(element); + Object parentElement = getParentForContent(element); + if (remoteAdapter != null) + { + oldName = remoteAdapter.getName(element); + oldFullName = remoteAdapter.getAbsoluteName(element); // pre-rename + monitor.subTask(getRenamingMessage(oldName).getLevelOneText()); + } + ok = adapter.doRename(null, element, newNames[i], monitor); + if (ok) + { + fileNamesRenamed.add(oldName); + if (remoteAdapter != null) + { + // Don't think we need to do findItem and updateItem here. + sr.fireRemoteResourceChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_RENAMED, element, parentElement, adapter.getSubSystem(element), oldFullName, this); + + } + + else + sr.fireEvent(new org.eclipse.rse.core.events.SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_RENAME, parentElement)); + } + monitor.worked(1); + } + } + catch (SystemMessageException exc) { + ok = false; + //If this operation is canceled, need to display a proper message to the user. + if (monitor.isCanceled() && fileNamesRenamed.size() > 0) + { + //Get the renamed file names + String renamedFileNames = (String)(fileNamesRenamed.get(0)); + for (int i=1; i<(fileNamesRenamed.size()); i++) + { + renamedFileNames = renamedFileNames + "\n" + fileNamesRenamed.get(i); //$NON-NLS-1$ + } + //getMessage("RSEG1125").makeSubstitution(movedFileName)); + SystemMessage thisMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_RENAME_INTERRUPTED); + thisMessage.makeSubstitution(renamedFileNames); + SystemMessageDialog.displayErrorMessage(null, thisMessage); + } + else + { + SystemMessageDialog.displayErrorMessage(null, exc.getSystemMessage()); + } + } catch (Exception exc) { + exc.printStackTrace(); + SystemMessageDialog.displayErrorMessage(null, RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_EXCEPTION_RENAMING).makeSubstitution(element, exc), //msg), + exc); + ok = false; + } + + return Status.OK_STATUS; + } + } /** * Required method from ISystemRenameTarget. * Decides whether to even show the rename menu item. @@ -1553,68 +1653,42 @@ public class SystemTableView return _objectInput; } + /** + * Get the specific "Renaming %1..." + */ + protected SystemMessage getRenamingMessage(String oldName) + { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_RENAMEGENERIC_PROGRESS); + msg.makeSubstitution(oldName); + return msg; + } + /** * Required method from ISystemRenameTarget */ public boolean doRename(String[] newNames) { - ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + IStructuredSelection selection = (IStructuredSelection) getSelection(); Iterator elements = selection.iterator(); - Object element = null; - - ISystemViewElementAdapter adapter = null; - IRemoteObjectIdentifier remoteAdapter = null; - String oldFullName = null; - boolean ok = true; - try - { - int nameIdx = 0; - while (ok && elements.hasNext()) - { - element = elements.next(); - adapter = getViewAdapter(element); - Object parentElement = getParentForContent(element); - - remoteAdapter = getViewAdapter(element); - if (remoteAdapter != null) - oldFullName = remoteAdapter.getAbsoluteName(element); - // pre-rename - ok = adapter.doRename(getShell(), element, newNames[nameIdx++]); - if (ok) - { - if (remoteAdapter != null) - { - // do rename here - Widget widget = findItem(element); - if (widget != null) - { - updateItem(widget, element); - } - sr.fireRemoteResourceChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_RENAMED, element, parentElement, adapter.getSubSystem(element), oldFullName, this); - - } - else - sr.fireEvent(new org.eclipse.rse.core.events.SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_RENAME, parentElement)); - } - } + + + Object[] renameElements = new Object[newNames.length]; + Object[] elementAdapters = new Object[newNames.length]; + int i = 0; + while (elements.hasNext()) { + renameElements[i] = elements.next(); + elementAdapters[i] = getViewAdapter(renameElements[i]); + i++; + //remoteAdapter = getRemoteAdapter(element); } - catch (SystemMessageException exc) - { - SystemMessageDialog.displayErrorMessage(getShell(), exc.getSystemMessage()); - ok = false; - } - catch (Exception exc) - { - //String msg = exc.getMessage(); - //if ((msg == null) || (exc instanceof ClassCastException)) - // msg = exc.getClass().getName(); - SystemMessageDialog.displayErrorMessage(getShell(), RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_EXCEPTION_RENAMING).makeSubstitution(element, exc), - //msg), - exc); - ok = false; - } - return ok; + SystemMessage renameMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_RENAMEGENERIC_PROGRESS); + renameMessage.makeSubstitution(""); //$NON-NLS-1$ + String renameMessageText = renameMessage.getLevelOneText(); + RenameJob renameJob = new RenameJob(newNames, renameElements, elementAdapters, renameMessageText); + renameJob.schedule(); + return true; + } /** diff --git a/rse/plugins/org.eclipse.rse.ui/model/org/eclipse/rse/ui/internal/model/SystemRegistry.java b/rse/plugins/org.eclipse.rse.ui/model/org/eclipse/rse/ui/internal/model/SystemRegistry.java index 8cff6971280..28e774f3786 100644 --- a/rse/plugins/org.eclipse.rse.ui/model/org/eclipse/rse/ui/internal/model/SystemRegistry.java +++ b/rse/plugins/org.eclipse.rse.ui/model/org/eclipse/rse/ui/internal/model/SystemRegistry.java @@ -2767,7 +2767,7 @@ public class SystemRegistry implements ISystemRegistry // mark stale any filters that reference this object invalidateFiltersFor(resourceParent, subsystem); - if (remoteEvent == null) + //if (remoteEvent == null) remoteEvent = new SystemRemoteChangeEvent(); remoteEvent.setEventType(eventType); remoteEvent.setResource(resource); diff --git a/rse/plugins/org.eclipse.rse.ui/systemmessages.xml b/rse/plugins/org.eclipse.rse.ui/systemmessages.xml index 8978bd90e55..d778beb8630 100644 --- a/rse/plugins/org.eclipse.rse.ui/systemmessages.xml +++ b/rse/plugins/org.eclipse.rse.ui/systemmessages.xml @@ -522,6 +522,10 @@ Kevin Doyle (IBM) - [160769] Added message for invalid filter when moving files The xml file '%1' appears to be corrupted. It has been replaced Expected root tag to be named '%2'. The corrupted file has been renamed to '%3' and a new file created for you + + Rename %1... + + Unable to perform action as the underlying file system folder is in use The file system folder %1 is in use by another task and cannot be removed or modified @@ -674,6 +678,30 @@ Kevin Doyle (IBM) - [160769] Added message for invalid filter when moving files The selected encoding is not supported. + + Operation interrupted. Some objects have been moved. + + The following objects have been moved: +%1 + + + Operation interrupted. Some objects have been renamed. + + The following objects have been renamed: +%1 + + + Operation interrupted. Some objects have been deleted. + + The following objects have been deleted: +%1 + + + Operation interrupted. Some objects have been copied to the destination. + + The following objects have been copied: +%1 + diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/testsubsystem/TestSubSystemNodeAdapter.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/testsubsystem/TestSubSystemNodeAdapter.java index 263ebbcee5e..f7ef5e586c6 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/testsubsystem/TestSubSystemNodeAdapter.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/testsubsystem/TestSubSystemNodeAdapter.java @@ -9,6 +9,7 @@ * Tobias Schwarz (Wind River) - initial API and implementation * Martin Oberhuber (Wind River) - [182454] improve getAbsoluteName() documentation * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API + * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread *******************************************************************************/ package org.eclipse.rse.tests.internal.testsubsystem; @@ -301,9 +302,9 @@ public class TestSubSystemNodeAdapter extends AbstractSystemViewAdapter } /* (non-Javadoc) - * @see org.eclipse.rse.ui.view.AbstractSystemViewAdapter#doRename(org.eclipse.swt.widgets.Shell, java.lang.Object, java.lang.String) + * @see org.eclipse.rse.ui.view.AbstractSystemViewAdapter#doRename(org.eclipse.swt.widgets.Shell, java.lang.Object, java.lang.String, IProgressMonitor) */ - public boolean doRename(Shell shell, Object element, String name) throws Exception { + public boolean doRename(Shell shell, Object element, String name, IProgressMonitor monitor) throws Exception { if (name != null && isTestSubSystemNode(element)) { String oldName = ((ITestSubSystemNode)element).getName(); if (oldName == null || !oldName.equals(name)) {