1 11 package org.eclipse.ui.actions; 12 13 import java.io.File ; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.net.URI ; 16 import com.ibm.icu.text.MessageFormat; 17 import java.util.ArrayList ; 18 import java.util.Arrays ; 19 import java.util.List ; 20 21 import org.eclipse.core.commands.ExecutionException; 22 import org.eclipse.core.filesystem.EFS; 23 import org.eclipse.core.filesystem.IFileInfo; 24 import org.eclipse.core.filesystem.IFileStore; 25 import org.eclipse.core.resources.IContainer; 26 import org.eclipse.core.resources.IFile; 27 import org.eclipse.core.resources.IFolder; 28 import org.eclipse.core.resources.IProject; 29 import org.eclipse.core.resources.IResource; 30 import org.eclipse.core.resources.IWorkspace; 31 import org.eclipse.core.resources.IWorkspaceRoot; 32 import org.eclipse.core.resources.ResourcesPlugin; 33 import org.eclipse.core.resources.WorkspaceJob; 34 import org.eclipse.core.runtime.CoreException; 35 import org.eclipse.core.runtime.IAdaptable; 36 import org.eclipse.core.runtime.IPath; 37 import org.eclipse.core.runtime.IProgressMonitor; 38 import org.eclipse.core.runtime.IStatus; 39 import org.eclipse.core.runtime.MultiStatus; 40 import org.eclipse.core.runtime.OperationCanceledException; 41 import org.eclipse.core.runtime.Path; 42 import org.eclipse.core.runtime.Status; 43 import org.eclipse.core.runtime.SubProgressMonitor; 44 import org.eclipse.jface.dialogs.ErrorDialog; 45 import org.eclipse.jface.dialogs.IDialogConstants; 46 import org.eclipse.jface.dialogs.IInputValidator; 47 import org.eclipse.jface.dialogs.InputDialog; 48 import org.eclipse.jface.dialogs.MessageDialog; 49 import org.eclipse.jface.operation.IRunnableWithProgress; 50 import org.eclipse.jface.window.Window; 51 import org.eclipse.osgi.util.NLS; 52 import org.eclipse.swt.SWT; 53 import org.eclipse.swt.widgets.Display; 54 import org.eclipse.swt.widgets.Shell; 55 import org.eclipse.ui.PlatformUI; 56 import org.eclipse.ui.dialogs.IOverwriteQuery; 57 import org.eclipse.ui.ide.undo.AbstractWorkspaceOperation; 58 import org.eclipse.ui.ide.undo.CopyResourcesOperation; 59 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; 60 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; 61 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; 62 import org.eclipse.ui.internal.ide.StatusUtil; 63 import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils; 64 import org.eclipse.ui.wizards.datatransfer.FileStoreStructureProvider; 65 import org.eclipse.ui.wizards.datatransfer.ImportOperation; 66 67 74 public class CopyFilesAndFoldersOperation { 75 76 80 private MultiStatus errorStatus; 81 82 85 private Shell messageShell; 86 87 90 private boolean canceled = false; 91 92 95 private boolean alwaysOverwrite = false; 96 97 private String [] modelProviderIds; 98 99 109 static IPath getAutoNewNameFor(IPath originalName, IWorkspace workspace) { 110 int counter = 1; 111 String resourceName = originalName.lastSegment(); 112 IPath leadupSegment = originalName.removeLastSegments(1); 113 114 while (true) { 115 String nameSegment; 116 117 if (counter > 1) { 118 nameSegment = NLS 119 .bind( 120 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameTwoArgs, 121 new Integer (counter), resourceName); 122 } else { 123 nameSegment = NLS 124 .bind( 125 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameOneArg, 126 resourceName); 127 } 128 129 IPath pathToTry = leadupSegment.append(nameSegment); 130 131 if (!workspace.getRoot().exists(pathToTry)) { 132 return pathToTry; 133 } 134 135 counter++; 136 } 137 } 138 139 145 public CopyFilesAndFoldersOperation(Shell shell) { 146 messageShell = shell; 147 } 148 149 156 protected boolean canPerformAutoRename() { 157 return true; 158 } 159 160 167 protected String getDeepCheckQuestion(IResource source) { 168 return NLS 169 .bind( 170 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepCopyQuestion, 171 source.getFullPath().makeRelative()); 172 } 173 174 181 IStatus checkExist(IFileStore[] stores) { 182 MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID, 183 IStatus.OK, getProblemsMessage(), null); 184 185 for (int i = 0; i < stores.length; i++) { 186 if (stores[i].fetchInfo().exists() == false) { 187 String message = NLS 188 .bind( 189 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted, 190 stores[i].getName()); 191 IStatus status = new Status(IStatus.ERROR, 192 PlatformUI.PLUGIN_ID, IStatus.OK, message, null); 193 multiStatus.add(status); 194 } 195 } 196 return multiStatus; 197 } 198 199 206 IStatus checkExist(IResource[] resources) { 207 MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID, 208 IStatus.OK, getProblemsMessage(), null); 209 210 for (int i = 0; i < resources.length; i++) { 211 IResource resource = resources[i]; 212 if (resource != null) { 213 URI location = resource.getLocationURI(); 214 String message = null; 215 if (location != null) { 216 IFileInfo info = IDEResourceInfoUtils.getFileInfo(location); 217 if (info == null || info.exists() == false) { 218 if (resource.isLinked()) { 219 message = NLS 220 .bind( 221 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingLinkTarget, 222 resource.getName()); 223 } else { 224 message = NLS 225 .bind( 226 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted, 227 resource.getName()); 228 } 229 } 230 } 231 if (message != null) { 232 IStatus status = new Status(IStatus.ERROR, 233 PlatformUI.PLUGIN_ID, IStatus.OK, message, null); 234 multiStatus.add(status); 235 } 236 } 237 } 238 return multiStatus; 239 } 240 241 254 private int checkOverwrite(final IResource source, 255 final IResource destination) { 256 final int[] result = new int[1]; 257 258 Runnable query = new Runnable () { 260 public void run() { 261 String message; 262 int resultId[] = { IDialogConstants.YES_ID, 263 IDialogConstants.YES_TO_ALL_ID, IDialogConstants.NO_ID, 264 IDialogConstants.CANCEL_ID }; 265 String labels[] = new String [] { IDialogConstants.YES_LABEL, 266 IDialogConstants.YES_TO_ALL_LABEL, 267 IDialogConstants.NO_LABEL, 268 IDialogConstants.CANCEL_LABEL }; 269 270 if (destination.getType() == IResource.FOLDER) { 271 if (homogenousResources(source, destination)) { 272 message = NLS 273 .bind( 274 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteMergeQuestion, 275 destination.getFullPath() 276 .makeRelative()); 277 } else { 278 if (destination.isLinked()) { 279 message = NLS 280 .bind( 281 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeLinkQuestion, 282 destination.getFullPath() 283 .makeRelative()); 284 } else { 285 message = NLS 286 .bind( 287 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeNoLinkQuestion, 288 destination.getFullPath() 289 .makeRelative()); 290 } 291 resultId = new int[] { IDialogConstants.YES_ID, 292 IDialogConstants.NO_ID, 293 IDialogConstants.CANCEL_ID }; 294 labels = new String [] { IDialogConstants.YES_LABEL, 295 IDialogConstants.NO_LABEL, 296 IDialogConstants.CANCEL_LABEL }; 297 } 298 } else { 299 String [] bindings = new String [] { 300 IDEResourceInfoUtils.getLocationText(destination), 301 IDEResourceInfoUtils 302 .getDateStringValue(destination), 303 IDEResourceInfoUtils.getLocationText(source), 304 IDEResourceInfoUtils.getDateStringValue(source) }; 305 message = NLS 306 .bind( 307 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteWithDetailsQuestion, 308 bindings); 309 } 310 MessageDialog dialog = new MessageDialog( 311 messageShell, 312 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceExists, 313 null, message, MessageDialog.QUESTION, labels, 0); 314 dialog.open(); 315 if (dialog.getReturnCode() == SWT.DEFAULT) { 316 result[0] = IDialogConstants.CANCEL_ID; 319 } else { 320 result[0] = resultId[dialog.getReturnCode()]; 321 } 322 } 323 }; 324 messageShell.getDisplay().syncExec(query); 325 return result[0]; 326 } 327 328 338 private void collectExistingReadonlyFiles(IPath destinationPath, 339 IResource[] copyResources, ArrayList existing) { 340 IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 341 342 for (int i = 0; i < copyResources.length; i++) { 343 IResource source = copyResources[i]; 344 IPath newDestinationPath = destinationPath.append(source.getName()); 345 IResource newDestination = workspaceRoot 346 .findMember(newDestinationPath); 347 IFolder folder; 348 349 if (newDestination == null) { 350 continue; 351 } 352 folder = getFolder(newDestination); 353 if (folder != null) { 354 IFolder sourceFolder = getFolder(source); 355 356 if (sourceFolder != null) { 357 try { 358 collectExistingReadonlyFiles(newDestinationPath, 359 sourceFolder.members(), existing); 360 } catch (CoreException exception) { 361 recordError(exception); 362 } 363 } 364 } else { 365 IFile file = getFile(newDestination); 366 367 if (file != null) { 368 if (file.isReadOnly()) { 369 existing.add(file); 370 } 371 if (getValidateConflictSource()) { 372 IFile sourceFile = getFile(source); 373 if (sourceFile != null) { 374 existing.add(sourceFile); 375 } 376 } 377 } 378 } 379 } 380 } 381 382 397 protected void copy(IResource[] resources, IPath destination, 398 IProgressMonitor subMonitor) throws CoreException { 399 400 subMonitor 401 .beginTask( 402 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_CopyResourcesTask, 403 resources.length); 404 405 for (int i = 0; i < resources.length; i++) { 406 IResource source = resources[i]; 407 IPath destinationPath = destination.append(source.getName()); 408 IWorkspace workspace = source.getWorkspace(); 409 IWorkspaceRoot workspaceRoot = workspace.getRoot(); 410 IResource existing = workspaceRoot.findMember(destinationPath); 411 if (source.getType() == IResource.FOLDER && existing != null) { 412 if (homogenousResources(source, existing)) { 416 IResource[] children = ((IContainer) source).members(); 417 copy(children, destinationPath, new SubProgressMonitor( 418 subMonitor, 1)); 419 } else { 420 delete(existing, new SubProgressMonitor(subMonitor, 0)); 423 source.copy(destinationPath, IResource.SHALLOW, 424 new SubProgressMonitor(subMonitor, 1)); 425 } 426 } else { 427 if (existing != null) { 428 if (homogenousResources(source, existing)) { 429 copyExisting(source, existing, new SubProgressMonitor( 430 subMonitor, 1)); 431 } else { 432 delete(existing, new SubProgressMonitor(subMonitor, 0)); 436 source.copy(destinationPath, IResource.SHALLOW, 437 new SubProgressMonitor(subMonitor, 1)); 438 } 439 } else { 440 source.copy(destinationPath, IResource.SHALLOW, 441 new SubProgressMonitor(subMonitor, 1)); 442 443 } 444 445 if (subMonitor.isCanceled()) { 446 throw new OperationCanceledException(); 447 } 448 } 449 } 450 } 451 452 464 private void copyExisting(IResource source, IResource existing, 465 IProgressMonitor subMonitor) throws CoreException { 466 IFile existingFile = getFile(existing); 467 468 if (existingFile != null) { 469 IFile sourceFile = getFile(source); 470 471 if (sourceFile != null) { 472 existingFile.setContents(sourceFile.getContents(), 473 IResource.KEEP_HISTORY, new SubProgressMonitor( 474 subMonitor, 0)); 475 } 476 } 477 } 478 479 493 public IResource[] copyResources(final IResource[] resources, 494 IContainer destination) { 495 return copyResources(resources, destination, true, null); 496 } 497 498 515 public IResource[] copyResourcesInCurrentThread( 516 final IResource[] resources, IContainer destination, 517 IProgressMonitor monitor) { 518 return copyResources(resources, destination, false, monitor); 519 } 520 521 530 private IResource[] copyResources(final IResource[] resources, 531 IContainer destination, boolean fork, IProgressMonitor monitor) { 532 final IPath destinationPath = destination.getFullPath(); 533 final IResource[][] copiedResources = new IResource[1][0]; 534 535 IStatus resourceStatus = checkExist(resources); 539 if (resourceStatus.getSeverity() != IStatus.OK) { 540 displayError(resourceStatus); 541 return copiedResources[0]; 542 } 543 String errorMsg = validateDestination(destination, resources); 544 if (errorMsg != null) { 545 displayError(errorMsg); 546 return copiedResources[0]; 547 } 548 549 IRunnableWithProgress op = new IRunnableWithProgress() { 550 public void run(IProgressMonitor monitor) { 551 copyResources(resources, destinationPath, copiedResources, 552 monitor); 553 } 554 }; 555 556 try { 557 PlatformUI.getWorkbench().getProgressService().run(fork, true, op); 558 } catch (InterruptedException e) { 559 return copiedResources[0]; 560 } catch (InvocationTargetException e) { 561 display(e); 562 } 563 564 if (errorStatus != null) { 566 displayError(errorStatus); 567 errorStatus = null; 568 } 569 570 return copiedResources[0]; 571 } 572 573 579 protected boolean isMove() { 580 return false; 581 } 582 583 private void display(InvocationTargetException e) { 584 IDEWorkbenchPlugin.getDefault().getLog().log( 587 StatusUtil.newStatus(IStatus.ERROR, MessageFormat.format( 588 "Exception in {0}.performCopy(): {1}", new Object [] { getClass().getName(), 590 e.getTargetException() }), null)); 591 displayError(NLS 592 .bind( 593 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError, 594 e.getTargetException().getMessage())); 595 } 596 597 612 public void copyFiles(URI [] uris, IContainer destination) { 613 IFileStore[] stores = buildFileStores(uris); 614 if (stores == null) { 615 return; 616 } 617 618 copyFileStores(destination, stores, true, null); 619 } 620 621 637 public void copyFilesInCurrentThread(URI [] uris, IContainer destination, 638 IProgressMonitor monitor) { 639 IFileStore[] stores = buildFileStores(uris); 640 if (stores == null) { 641 return; 642 } 643 644 copyFileStores(destination, stores, false, monitor); 645 } 646 647 654 private IFileStore[] buildFileStores(URI [] uris) { 655 IFileStore[] stores = new IFileStore[uris.length]; 656 for (int i = 0; i < uris.length; i++) { 657 IFileStore store; 658 try { 659 store = EFS.getStore(uris[i]); 660 } catch (CoreException e) { 661 IDEWorkbenchPlugin.log(e.getMessage(), e); 662 reportFileInfoNotFound(uris[i].toString()); 663 return null; 664 } 665 if (store == null) { 666 reportFileInfoNotFound(uris[i].toString()); 667 return null; 668 } 669 stores[i] = store; 670 } 671 return stores; 672 673 } 674 675 690 public void copyFiles(final String [] fileNames, IContainer destination) { 691 IFileStore[] stores = buildFileStores(fileNames); 692 if (stores == null) { 693 return; 694 } 695 696 copyFileStores(destination, stores, true, null); 697 } 698 699 715 public void copyFilesInCurrentThread(final String [] fileNames, 716 IContainer destination, IProgressMonitor monitor) { 717 IFileStore[] stores = buildFileStores(fileNames); 718 if (stores == null) { 719 return; 720 } 721 722 copyFileStores(destination, stores, false, monitor); 723 } 724 725 732 private IFileStore[] buildFileStores(final String [] fileNames) { 733 IFileStore[] stores = new IFileStore[fileNames.length]; 734 for (int i = 0; i < fileNames.length; i++) { 735 IFileStore store = IDEResourceInfoUtils.getFileStore(fileNames[i]); 736 if (store == null) { 737 reportFileInfoNotFound(fileNames[i]); 738 return null; 739 } 740 stores[i] = store; 741 } 742 return stores; 743 } 744 745 750 private void reportFileInfoNotFound(final String fileName) { 751 752 messageShell.getDisplay().syncExec(new Runnable () { 753 public void run() { 754 ErrorDialog 755 .openError( 756 messageShell, 757 getProblemsTitle(), 758 NLS 759 .bind( 760 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound, 761 fileName), null); 762 } 763 }); 764 } 765 766 774 private void copyFileStores(IContainer destination, 775 final IFileStore[] stores, boolean fork, IProgressMonitor monitor) { 776 IStatus fileStatus = checkExist(stores); 780 if (fileStatus.getSeverity() != IStatus.OK) { 781 displayError(fileStatus); 782 return; 783 } 784 String errorMsg = validateImportDestinationInternal(destination, stores); 785 if (errorMsg != null) { 786 displayError(errorMsg); 787 return; 788 } 789 final IPath destinationPath = destination.getFullPath(); 790 791 if (fork) { 792 WorkspaceModifyOperation op = new WorkspaceModifyOperation() { 793 public void execute(IProgressMonitor monitor) { 794 copyFileStores(stores, destinationPath, monitor); 795 } 796 }; 797 try { 798 PlatformUI.getWorkbench().getProgressService().run(true, true, 799 op); 800 } catch (InterruptedException e) { 801 return; 802 } catch (InvocationTargetException exception) { 803 display(exception); 804 } 805 } else { 806 copyFileStores(stores, destinationPath, monitor); 807 } 808 809 if (errorStatus != null) { 811 displayError(errorStatus); 812 errorStatus = null; 813 } 814 } 815 816 822 private void displayError(final IStatus status) { 823 messageShell.getDisplay().syncExec(new Runnable () { 824 public void run() { 825 ErrorDialog.openError(messageShell, getProblemsTitle(), null, 826 status); 827 } 828 }); 829 } 830 831 841 IResource createLinkedResourceHandle(IContainer destination, 842 IResource source) { 843 IWorkspace workspace = destination.getWorkspace(); 844 IWorkspaceRoot workspaceRoot = workspace.getRoot(); 845 IPath linkPath = destination.getFullPath().append(source.getName()); 846 IResource linkHandle; 847 848 if (source.getType() == IResource.FOLDER) { 849 linkHandle = workspaceRoot.getFolder(linkPath); 850 } else { 851 linkHandle = workspaceRoot.getFile(linkPath); 852 } 853 return linkHandle; 854 } 855 856 866 boolean delete(IResource resource, IProgressMonitor monitor) { 867 boolean force = false; 869 if (resource.getType() == IResource.PROJECT) { 870 IProject project = (IProject) resource; 872 try { 873 project.delete(true, force, monitor); 874 } catch (CoreException e) { 875 recordError(e); return false; 877 } 878 } else { 879 int flags = IResource.KEEP_HISTORY; 881 if (force) { 882 flags = flags | IResource.FORCE; 883 } 884 try { 885 resource.delete(flags, monitor); 886 } catch (CoreException e) { 887 recordError(e); return false; 889 } 890 } 891 return true; 892 } 893 894 900 private void displayError(final String message) { 901 messageShell.getDisplay().syncExec(new Runnable () { 902 public void run() { 903 MessageDialog.openError(messageShell, getProblemsTitle(), 904 message); 905 } 906 }); 907 } 908 909 917 protected IFile getFile(IResource resource) { 918 if (resource instanceof IFile) { 919 return (IFile) resource; 920 } 921 return (IFile) ((IAdaptable) resource).getAdapter(IFile.class); 922 } 923 924 934 protected File [] getFiles(String [] fileNames) { 935 File [] files = new File [fileNames.length]; 936 937 for (int i = 0; i < fileNames.length; i++) { 938 files[i] = new File (fileNames[i]); 939 } 940 return files; 941 } 942 943 951 protected IFolder getFolder(IResource resource) { 952 if (resource instanceof IFolder) { 953 return (IFolder) resource; 954 } 955 return (IFolder) ((IAdaptable) resource).getAdapter(IFolder.class); 956 } 957 958 969 private IPath getNewNameFor(final IPath originalName, 970 final IWorkspace workspace) { 971 final IResource resource = workspace.getRoot().findMember(originalName); 972 final IPath prefix = resource.getFullPath().removeLastSegments(1); 973 final String returnValue[] = { "" }; 975 messageShell.getDisplay().syncExec(new Runnable () { 976 public void run() { 977 IInputValidator validator = new IInputValidator() { 978 public String isValid(String string) { 979 if (resource.getName().equals(string)) { 980 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameMustBeDifferent; 981 } 982 IStatus status = workspace.validateName(string, 983 resource.getType()); 984 if (!status.isOK()) { 985 return status.getMessage(); 986 } 987 if (workspace.getRoot().exists(prefix.append(string))) { 988 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameExists; 989 } 990 return null; 991 } 992 }; 993 994 InputDialog dialog = new InputDialog( 995 messageShell, 996 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogTitle, 997 NLS 998 .bind( 999 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogMessage, 1000 resource.getName()), getAutoNewNameFor( 1001 originalName, workspace).lastSegment() 1002 .toString(), validator); 1003 dialog.setBlockOnOpen(true); 1004 dialog.open(); 1005 if (dialog.getReturnCode() == Window.CANCEL) { 1006 returnValue[0] = null; 1007 } else { 1008 returnValue[0] = dialog.getValue(); 1009 } 1010 } 1011 }); 1012 if (returnValue[0] == null) { 1013 throw new OperationCanceledException(); 1014 } 1015 return prefix.append(returnValue[0]); 1016 } 1017 1018 1023 protected String getOperationTitle() { 1024 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_operationTitle; 1025 } 1026 1027 1032 protected String getProblemsMessage() { 1033 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_problemMessage; 1034 } 1035 1036 1041 protected String getProblemsTitle() { 1042 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyFailedTitle; 1043 } 1044 1045 1054 protected boolean getValidateConflictSource() { 1055 return false; 1056 } 1057 1058 1069 protected boolean homogenousResources(IResource source, 1070 IResource destination) { 1071 boolean isSourceLinked = source.isLinked(); 1072 boolean isDestinationLinked = destination.isLinked(); 1073 1074 return (isSourceLinked && isDestinationLinked || isSourceLinked == false 1075 && isDestinationLinked == false); 1076 } 1077 1078 1087 private boolean isAccessible(IResource resource) { 1088 switch (resource.getType()) { 1089 case IResource.FILE: 1090 return true; 1091 case IResource.FOLDER: 1092 return true; 1093 case IResource.PROJECT: 1094 return ((IProject) resource).isOpen(); 1095 default: 1096 return false; 1097 } 1098 } 1099 1100 1111 boolean isDestinationSameAsSource(IResource[] sourceResources, 1112 IContainer destination) { 1113 IPath destinationLocation = destination.getLocation(); 1114 1115 for (int i = 0; i < sourceResources.length; i++) { 1116 IResource sourceResource = sourceResources[i]; 1117 if (sourceResource.getParent().equals(destination)) { 1118 return true; 1119 } else if (destinationLocation != null) { 1120 IPath sourceLocation = sourceResource.getLocation(); 1122 IPath destinationResource = destinationLocation 1123 .append(sourceResource.getName()); 1124 if (sourceLocation != null 1125 && sourceLocation.isPrefixOf(destinationResource)) { 1126 return true; 1127 } 1128 } 1129 } 1130 return false; 1131 } 1132 1133 1150 private boolean performCopy(IResource[] resources, IPath destination, 1151 IProgressMonitor monitor) { 1152 try { 1153 AbstractWorkspaceOperation op = getUndoableCopyOrMoveOperation( 1154 resources, destination); 1155 op.setModelProviderIds(getModelProviderIds()); 1156 PlatformUI.getWorkbench().getOperationSupport() 1157 .getOperationHistory().execute(op, monitor, 1158 WorkspaceUndoUtil.getUIInfoAdapter(messageShell)); 1159 } catch (ExecutionException e) { 1160 if (e.getCause() instanceof CoreException) { 1161 recordError((CoreException) e.getCause()); 1162 } else { 1163 IDEWorkbenchPlugin.log(e.getMessage(), e); 1164 displayError(e.getMessage()); 1165 } 1166 return false; 1167 } 1168 return true; 1169 } 1170 1171 1187 private boolean performCopyWithAutoRename(IResource[] resources, 1188 IPath destination, IProgressMonitor monitor) { 1189 IWorkspace workspace = resources[0].getWorkspace(); 1190 IPath[] destinationPaths = new IPath[resources.length]; 1191 try { 1192 for (int i = 0; i < resources.length; i++) { 1193 IResource source = resources[i]; 1194 destinationPaths[i] = destination.append(source.getName()); 1195 1196 if (workspace.getRoot().exists(destinationPaths[i])) { 1197 destinationPaths[i] = getNewNameFor(destinationPaths[i], 1198 workspace); 1199 } 1200 } 1201 CopyResourcesOperation op = new CopyResourcesOperation(resources, 1202 destinationPaths, 1203 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle); 1204 op.setModelProviderIds(getModelProviderIds()); 1205 PlatformUI.getWorkbench().getOperationSupport() 1206 .getOperationHistory().execute(op, monitor, 1207 WorkspaceUndoUtil.getUIInfoAdapter(messageShell)); 1208 } catch (ExecutionException e) { 1209 if (e.getCause() instanceof CoreException) { 1210 recordError((CoreException) e.getCause()); 1211 } else { 1212 IDEWorkbenchPlugin.log(e.getMessage(), e); 1213 displayError(e.getMessage()); 1214 } 1215 return false; 1216 } 1217 return true; 1218 } 1219 1220 1231 private void performFileImport(IFileStore[] stores, IContainer target, 1232 IProgressMonitor monitor) { 1233 IOverwriteQuery query = new IOverwriteQuery() { 1234 public String queryOverwrite(String pathString) { 1235 if (alwaysOverwrite) { 1236 return ALL; 1237 } 1238 1239 final String returnCode[] = { CANCEL }; 1240 final String msg = NLS 1241 .bind( 1242 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteQuestion, 1243 pathString); 1244 final String [] options = { IDialogConstants.YES_LABEL, 1245 IDialogConstants.YES_TO_ALL_LABEL, 1246 IDialogConstants.NO_LABEL, 1247 IDialogConstants.CANCEL_LABEL }; 1248 messageShell.getDisplay().syncExec(new Runnable () { 1249 public void run() { 1250 MessageDialog dialog = new MessageDialog( 1251 messageShell, 1252 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_question, 1253 null, msg, MessageDialog.QUESTION, options, 0); 1254 dialog.open(); 1255 int returnVal = dialog.getReturnCode(); 1256 String [] returnCodes = { YES, ALL, NO, CANCEL }; 1257 returnCode[0] = returnVal == -1 ? CANCEL 1258 : returnCodes[returnVal]; 1259 } 1260 }); 1261 if (returnCode[0] == ALL) { 1262 alwaysOverwrite = true; 1263 } else if (returnCode[0] == CANCEL) { 1264 canceled = true; 1265 } 1266 return returnCode[0]; 1267 } 1268 }; 1269 1270 ImportOperation op = new ImportOperation(target.getFullPath(), 1271 stores[0].getParent(), FileStoreStructureProvider.INSTANCE, 1272 query, Arrays.asList(stores)); 1273 op.setContext(messageShell); 1274 op.setCreateContainerStructure(false); 1275 try { 1276 op.run(monitor); 1277 } catch (InterruptedException e) { 1278 return; 1279 } catch (InvocationTargetException e) { 1280 if (e.getTargetException() instanceof CoreException) { 1281 displayError(((CoreException) e.getTargetException()) 1282 .getStatus()); 1283 } else { 1284 display(e); 1285 } 1286 return; 1287 } 1288 IStatus status = op.getStatus(); 1291 if (!status.isOK()) { 1292 if (errorStatus == null) { 1293 errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID, 1294 IStatus.ERROR, getProblemsMessage(), null); 1295 } 1296 errorStatus.merge(status); 1297 } 1298 } 1299 1300 1307 private void recordError(CoreException error) { 1308 if (errorStatus == null) { 1309 errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.ERROR, 1310 getProblemsMessage(), error); 1311 } 1312 1313 errorStatus.merge(error.getStatus()); 1314 } 1315 1316 1328 public String validateDestination(IContainer destination, 1329 IResource[] sourceResources) { 1330 if (!isAccessible(destination)) { 1331 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError; 1332 } 1333 IContainer firstParent = null; 1334 URI destinationLocation = destination.getLocationURI(); 1335 for (int i = 0; i < sourceResources.length; i++) { 1336 IResource sourceResource = sourceResources[i]; 1337 if (firstParent == null) { 1338 firstParent = sourceResource.getParent(); 1339 } else if (firstParent.equals(sourceResource.getParent()) == false) { 1340 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_parentNotEqual; 1342 } 1343 1344 URI sourceLocation = sourceResource.getLocationURI(); 1345 if (sourceLocation == null) { 1346 if (sourceResource.isLinked()) { 1347 return NLS 1350 .bind( 1351 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable, 1352 sourceResource.getName()); 1353 } 1354 return NLS 1355 .bind( 1356 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted, 1357 sourceResource.getName()); 1358 1359 } 1360 if (sourceLocation.equals(destinationLocation)) { 1361 return NLS 1362 .bind( 1363 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest, 1364 sourceResource.getName()); 1365 } 1366 if (new Path(sourceLocation.toString()).isPrefixOf(new Path( 1368 destinationLocation.toString()))) { 1369 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError; 1370 } 1371 1372 String linkedResourceMessage = validateLinkedResource(destination, 1373 sourceResource); 1374 if (linkedResourceMessage != null) { 1375 return linkedResourceMessage; 1376 } 1377 } 1378 return null; 1379 } 1380 1381 1393 private boolean validateEdit(IContainer destination, 1394 IResource[] sourceResources) { 1395 ArrayList copyFiles = new ArrayList (); 1396 1397 collectExistingReadonlyFiles(destination.getFullPath(), 1398 sourceResources, copyFiles); 1399 if (copyFiles.size() > 0) { 1400 IFile[] files = (IFile[]) copyFiles.toArray(new IFile[copyFiles 1401 .size()]); 1402 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 1403 IStatus status = workspace.validateEdit(files, messageShell); 1404 1405 canceled = status.isOK() == false; 1406 return status.isOK(); 1407 } 1408 return true; 1409 } 1410 1411 1423 public String validateImportDestination(IContainer destination, 1424 String [] sourceNames) { 1425 1426 IFileStore[] stores = new IFileStore[sourceNames.length]; 1427 for (int i = 0; i < sourceNames.length; i++) { 1428 IFileStore store = IDEResourceInfoUtils 1429 .getFileStore(sourceNames[i]); 1430 if (store == null) { 1431 return NLS 1432 .bind( 1433 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound, 1434 sourceNames[i]); 1435 } 1436 stores[i] = store; 1437 } 1438 return validateImportDestinationInternal(destination, stores); 1439 1440 } 1441 1442 1460 private String validateImportDestinationInternal(IContainer destination, 1461 IFileStore[] sourceStores) { 1462 if (!isAccessible(destination)) 1463 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError; 1464 1465 IFileStore destinationStore; 1466 try { 1467 destinationStore = EFS.getStore(destination.getLocationURI()); 1468 } catch (CoreException exception) { 1469 IDEWorkbenchPlugin.log(exception.getLocalizedMessage(), exception); 1470 return NLS 1471 .bind( 1472 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError, 1473 exception.getLocalizedMessage()); 1474 } 1475 for (int i = 0; i < sourceStores.length; i++) { 1476 IFileStore sourceStore = sourceStores[i]; 1477 IFileStore sourceParentStore = sourceStore.getParent(); 1478 1479 if (sourceStore != null) { 1480 if (destinationStore.equals(sourceStore) 1481 || (sourceParentStore != null && destinationStore 1482 .equals(sourceParentStore))) { 1483 return NLS 1484 .bind( 1485 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_importSameSourceAndDest, 1486 sourceStore.getName()); 1487 } 1488 IFileStore destinationParent = destinationStore.getParent(); 1491 if (sourceStore.isParentOf(destinationParent)) { 1492 return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError; 1493 } 1494 1495 } 1496 } 1497 return null; 1498 } 1499 1500 1509 private String validateLinkedResource(IContainer destination, 1510 IResource source) { 1511 if (source.isLinked() == false) { 1512 return null; 1513 } 1514 IWorkspace workspace = destination.getWorkspace(); 1515 IResource linkHandle = createLinkedResourceHandle(destination, source); 1516 IStatus locationStatus = workspace.validateLinkLocation(linkHandle, 1517 source.getRawLocation()); 1518 1519 if (locationStatus.getSeverity() == IStatus.ERROR) { 1520 return locationStatus.getMessage(); 1521 } 1522 IPath sourceLocation = source.getLocation(); 1523 if (source.getProject().equals(destination.getProject()) == false 1524 && source.getType() == IResource.FOLDER 1525 && sourceLocation != null) { 1526 try { 1529 IResource[] members = destination.members(); 1530 for (int j = 0; j < members.length; j++) { 1531 if (sourceLocation.equals(members[j].getLocation()) 1532 && source.getName().equals(members[j].getName())) { 1533 return NLS 1534 .bind( 1535 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest, 1536 source.getName()); 1537 } 1538 } 1539 } catch (CoreException exception) { 1540 displayError(NLS 1541 .bind( 1542 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError, 1543 exception.getMessage())); 1544 } 1545 } 1546 return null; 1547 } 1548 1549 1560 private IResource[] validateNoNameCollisions(IContainer destination, 1561 IResource[] sourceResources) { 1562 List copyItems = new ArrayList (); 1563 IWorkspaceRoot workspaceRoot = destination.getWorkspace().getRoot(); 1564 int overwrite = IDialogConstants.NO_ID; 1565 1566 for (int i = 0; i < sourceResources.length; i++) { 1569 final IResource sourceResource = sourceResources[i]; 1570 final IPath destinationPath = destination.getFullPath().append( 1571 sourceResource.getName()); 1572 final IPath sourcePath = sourceResource.getFullPath(); 1573 1574 IResource newResource = workspaceRoot.findMember(destinationPath); 1575 if (newResource != null && destinationPath.isPrefixOf(sourcePath)) { 1576 displayError(NLS 1577 .bind( 1578 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteProblem, 1579 destinationPath, sourcePath)); 1580 1581 canceled = true; 1582 return null; 1583 } 1584 } 1585 for (int i = 0; i < sourceResources.length; i++) { 1587 final IResource source = sourceResources[i]; 1588 final IPath destinationPath = destination.getFullPath().append( 1589 source.getName()); 1590 1591 IResource newResource = workspaceRoot.findMember(destinationPath); 1592 if (newResource != null) { 1593 if (overwrite != IDialogConstants.YES_TO_ALL_ID 1594 || (newResource.getType() == IResource.FOLDER && homogenousResources( 1595 source, destination) == false)) { 1596 overwrite = checkOverwrite(source, newResource); 1597 } 1598 if (overwrite == IDialogConstants.YES_ID 1599 || overwrite == IDialogConstants.YES_TO_ALL_ID) { 1600 copyItems.add(source); 1601 } else if (overwrite == IDialogConstants.CANCEL_ID) { 1602 canceled = true; 1603 return null; 1604 } 1605 } else { 1606 copyItems.add(source); 1607 } 1608 } 1609 return (IResource[]) copyItems.toArray(new IResource[copyItems.size()]); 1610 } 1611 1612 private void copyResources(final IResource[] resources, 1613 final IPath destinationPath, final IResource[][] copiedResources, 1614 IProgressMonitor monitor) { 1615 IResource[] copyResources = resources; 1616 1617 monitor.beginTask("", 100); monitor.setTaskName(getOperationTitle()); 1621 monitor.worked(10); 1623 boolean copyWithAutoRename = false; 1625 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 1626 if (root.exists(destinationPath)) { 1627 IContainer container = (IContainer) root 1628 .findMember(destinationPath); 1629 if (isDestinationSameAsSource(copyResources, container) 1632 && canPerformAutoRename()) { 1633 copyWithAutoRename = true; 1634 } else { 1635 copyResources = validateNoNameCollisions(container, 1638 copyResources); 1639 if (copyResources == null) { 1640 if (canceled) { 1641 return; 1642 } 1643 displayError(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameCollision); 1644 return; 1645 } 1646 if (validateEdit(container, copyResources) == false) { 1647 return; 1648 } 1649 } 1650 } 1651 1652 errorStatus = null; 1653 if (copyResources.length > 0) { 1654 if (copyWithAutoRename) { 1655 performCopyWithAutoRename(copyResources, destinationPath, 1656 new SubProgressMonitor(monitor, 90)); 1657 } else { 1658 performCopy(copyResources, destinationPath, new SubProgressMonitor(monitor, 90)); 1659 } 1660 } 1661 monitor.done(); 1662 copiedResources[0] = copyResources; 1663 } 1664 1665 private void copyFileStores(final IFileStore[] stores, 1666 final IPath destinationPath, IProgressMonitor monitor) { 1667 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 1669 if (root.exists(destinationPath)) { 1670 IContainer container = (IContainer) root 1671 .findMember(destinationPath); 1672 1673 performFileImport(stores, container, monitor); 1674 } 1675 } 1676 1677 1685 public String [] getModelProviderIds() { 1686 return modelProviderIds; 1687 } 1688 1689 1699 public void setModelProviderIds(String [] modelProviderIds) { 1700 this.modelProviderIds = modelProviderIds; 1701 } 1702 1703 1715 protected AbstractWorkspaceOperation getUndoableCopyOrMoveOperation( 1716 IResource[] resources, IPath destinationPath) { 1717 return new CopyResourcesOperation(resources, destinationPath, 1718 IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle); 1719 1720 } 1721} 1722 | Popular Tags |