1 12 package org.eclipse.ui.wizards.datatransfer; 13 14 import java.io.File ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.util.ArrayList ; 18 import java.util.Arrays ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 22 import org.eclipse.core.resources.IContainer; 23 import org.eclipse.core.resources.IFile; 24 import org.eclipse.core.resources.IFolder; 25 import org.eclipse.core.resources.IResource; 26 import org.eclipse.core.resources.IWorkspace; 27 import org.eclipse.core.resources.IWorkspaceRoot; 28 import org.eclipse.core.resources.ResourceAttributes; 29 import org.eclipse.core.resources.ResourcesPlugin; 30 import org.eclipse.core.runtime.CoreException; 31 import org.eclipse.core.runtime.IAdaptable; 32 import org.eclipse.core.runtime.IPath; 33 import org.eclipse.core.runtime.IProgressMonitor; 34 import org.eclipse.core.runtime.IStatus; 35 import org.eclipse.core.runtime.MultiStatus; 36 import org.eclipse.core.runtime.OperationCanceledException; 37 import org.eclipse.core.runtime.Path; 38 import org.eclipse.core.runtime.Status; 39 import org.eclipse.core.runtime.SubProgressMonitor; 40 import org.eclipse.osgi.util.NLS; 41 import org.eclipse.swt.widgets.Shell; 42 import org.eclipse.ui.PlatformUI; 43 import org.eclipse.ui.actions.WorkspaceModifyOperation; 44 import org.eclipse.ui.dialogs.ContainerGenerator; 45 import org.eclipse.ui.dialogs.IOverwriteQuery; 46 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; 47 import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages; 48 import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider; 49 50 57 public class ImportOperation extends WorkspaceModifyOperation { 58 private static final int POLICY_DEFAULT = 0; 59 60 private static final int POLICY_SKIP_CHILDREN = 1; 61 62 private static final int POLICY_FORCE_OVERWRITE = 2; 63 64 private Object source; 65 66 private IPath destinationPath; 67 68 private IContainer destinationContainer; 69 70 private List selectedFiles; 71 72 private List rejectedFiles; 73 74 private IImportStructureProvider provider; 75 76 private IProgressMonitor monitor; 77 78 protected IOverwriteQuery overwriteCallback; 79 80 private Shell context; 81 82 private List errorTable = new ArrayList (); 83 84 private boolean createContainerStructure = true; 85 86 private static final int OVERWRITE_NOT_SET = 0; 88 89 private static final int OVERWRITE_NONE = 1; 90 91 private static final int OVERWRITE_ALL = 2; 92 93 private int overwriteState = OVERWRITE_NOT_SET; 94 95 121 public ImportOperation(IPath containerPath, Object source, 122 IImportStructureProvider provider, 123 IOverwriteQuery overwriteImplementor) { 124 super(); 125 this.destinationPath = containerPath; 126 this.source = source; 127 this.provider = provider; 128 overwriteCallback = overwriteImplementor; 129 } 130 131 167 public ImportOperation(IPath containerPath, Object source, 168 IImportStructureProvider provider, 169 IOverwriteQuery overwriteImplementor, List filesToImport) { 170 this(containerPath, source, provider, overwriteImplementor); 171 setFilesToImport(filesToImport); 172 } 173 174 199 public ImportOperation(IPath containerPath, 200 IImportStructureProvider provider, 201 IOverwriteQuery overwriteImplementor, List filesToImport) { 202 this(containerPath, null, provider, overwriteImplementor); 203 setFilesToImport(filesToImport); 204 } 205 206 220 void collectExistingReadonlyFiles(IPath sourceStart, List sources, 221 ArrayList noOverwrite, ArrayList overwriteReadonly, int policy) { 222 IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 223 Iterator sourceIter = sources.iterator(); 224 IPath sourceRootPath = null; 225 226 if (this.source != null) { 227 sourceRootPath = new Path(provider.getFullPath(this.source)); 228 } 229 while (sourceIter.hasNext()) { 230 Object nextSource = sourceIter.next(); 231 IPath sourcePath = new Path(provider.getFullPath(nextSource)); 232 IPath newDestinationPath; 233 IResource newDestination; 234 235 if (sourceRootPath == null) { 236 newDestinationPath = sourceStart.append(provider 237 .getLabel(nextSource)); 238 } else { 239 int prefixLength = sourcePath 240 .matchingFirstSegments(sourceRootPath); 241 IPath relativeSourcePath = sourcePath 242 .removeFirstSegments(prefixLength); 243 newDestinationPath = this.destinationPath 244 .append(relativeSourcePath); 245 } 246 newDestination = workspaceRoot.findMember(newDestinationPath); 247 if (newDestination == null) { 248 continue; 249 } 250 251 IFolder folder = getFolder(newDestination); 252 if (folder != null) { 253 if (policy != POLICY_FORCE_OVERWRITE) { 254 if (this.overwriteState == OVERWRITE_NONE 255 || !queryOverwrite(newDestinationPath)) { 256 noOverwrite.add(folder); 257 continue; 258 } 259 } 260 if (provider.isFolder(nextSource)) { 261 collectExistingReadonlyFiles(newDestinationPath, provider 262 .getChildren(nextSource), noOverwrite, 263 overwriteReadonly, POLICY_FORCE_OVERWRITE); 264 } 265 } else { 266 IFile file = getFile(newDestination); 267 268 if (file != null) { 269 if (!queryOverwriteFile(file, policy)) { 270 noOverwrite.add(file.getFullPath()); 271 } else if (file.isReadOnly()) { 272 overwriteReadonly.add(file); 273 } 274 } 275 } 276 } 277 } 278 279 287 IContainer createContainersFor(IPath path) throws CoreException { 288 289 IContainer currentFolder = destinationContainer; 290 291 int segmentCount = path.segmentCount(); 292 293 if (segmentCount == 0) { 295 return currentFolder; 296 } 297 298 if (currentFolder.getType() == IResource.ROOT) { 300 return createFromRoot(path); 301 } 302 303 for (int i = 0; i < segmentCount; i++) { 304 currentFolder = currentFolder.getFolder(new Path(path.segment(i))); 305 if (!currentFolder.exists()) { 306 ((IFolder) currentFolder).create(false, true, null); 307 } 308 } 309 310 return currentFolder; 311 } 312 313 321 private IContainer createFromRoot(IPath path) throws CoreException { 322 323 int segmentCount = path.segmentCount(); 324 325 IContainer currentFolder = ((IWorkspaceRoot) destinationContainer) 327 .getProject(path.segment(0)); 328 329 for (int i = 1; i < segmentCount; i++) { 330 currentFolder = currentFolder.getFolder(new Path(path.segment(i))); 331 if (!currentFolder.exists()) { 332 ((IFolder) currentFolder).create(false, true, null); 333 } 334 } 335 336 return currentFolder; 337 } 338 339 345 void deleteResource(IResource resource) { 346 try { 347 resource.delete(IResource.KEEP_HISTORY, null); 348 } catch (CoreException e) { 349 errorTable.add(e.getStatus()); 350 } 351 } 352 353 357 protected void execute(IProgressMonitor progressMonitor) { 358 359 monitor = progressMonitor; 360 361 try { 362 if (selectedFiles == null) { 363 monitor.beginTask(DataTransferMessages.DataTransfer_importTask, 1000); 365 ContainerGenerator generator = new ContainerGenerator( 366 destinationPath); 367 monitor.worked(30); 368 validateFiles(Arrays.asList(new Object [] { source })); 369 monitor.worked(50); 370 destinationContainer = generator 371 .generateContainer(new SubProgressMonitor(monitor, 50)); 372 importRecursivelyFrom(source, POLICY_DEFAULT); 373 monitor.worked(90); 375 } else { 376 int creationCount = selectedFiles.size(); 378 monitor.beginTask(DataTransferMessages.DataTransfer_importTask, creationCount + 100); 379 ContainerGenerator generator = new ContainerGenerator( 380 destinationPath); 381 monitor.worked(30); 382 validateFiles(selectedFiles); 383 monitor.worked(50); 384 destinationContainer = generator 385 .generateContainer(new SubProgressMonitor(monitor, 50)); 386 importFileSystemObjects(selectedFiles); 387 monitor.done(); 388 } 389 } catch (CoreException e) { 390 errorTable.add(e.getStatus()); 391 } finally { 392 monitor.done(); 393 } 394 } 395 396 405 IContainer getDestinationContainerFor(Object fileSystemObject) 406 throws CoreException { 407 IPath pathname = new Path(provider.getFullPath(fileSystemObject)); 408 409 if (createContainerStructure) { 410 return createContainersFor(pathname.removeLastSegments(1)); 411 } 412 if (source == fileSystemObject) { 413 return null; 414 } 415 IPath sourcePath = new Path(provider.getFullPath(source)); 416 IPath destContainerPath = pathname.removeLastSegments(1); 417 IPath relativePath = destContainerPath.removeFirstSegments( 418 sourcePath.segmentCount()).setDevice(null); 419 return createContainersFor(relativePath); 420 421 } 422 423 430 IFile getFile(IResource resource) { 431 if (resource instanceof IFile) { 432 return (IFile) resource; 433 } 434 Object adapted = ((IAdaptable) resource).getAdapter(IFile.class); 435 if(adapted == null) { 436 return null; 437 } 438 return (IFile) adapted; 439 440 } 441 442 449 IFolder getFolder(IResource resource) { 450 if (resource instanceof IFolder) { 451 return (IFolder) resource; 452 } 453 Object adapted = ((IAdaptable) resource).getAdapter(IFolder.class); 454 if(adapted == null) { 455 return null; 456 } 457 return (IFolder) adapted; 458 } 459 460 467 ArrayList getRejectedFiles(IStatus multiStatus, IFile[] files) { 468 ArrayList filteredFiles = new ArrayList (); 469 470 IStatus[] status = multiStatus.getChildren(); 471 for (int i = 0; i < status.length; i++) { 472 if (status[i].isOK() == false) { 473 errorTable.add(status[i]); 474 filteredFiles.add(files[i].getFullPath()); 475 } 476 } 477 return filteredFiles; 478 } 479 480 488 public IStatus getStatus() { 489 IStatus[] errors = new IStatus[errorTable.size()]; 490 errorTable.toArray(errors); 491 return new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, errors, 492 DataTransferMessages.ImportOperation_importProblems, 493 null); 494 } 495 496 504 void importFile(Object fileObject, int policy) { 505 IContainer containerResource; 506 try { 507 containerResource = getDestinationContainerFor(fileObject); 508 } catch (CoreException e) { 509 IStatus coreStatus = e.getStatus(); 510 String newMessage = NLS.bind(DataTransferMessages.ImportOperation_coreImportError, fileObject, coreStatus.getMessage()); 511 IStatus status = new Status(coreStatus.getSeverity(), coreStatus 512 .getPlugin(), coreStatus.getCode(), newMessage, null); 513 errorTable.add(status); 514 return; 515 } 516 517 String fileObjectPath = provider.getFullPath(fileObject); 518 monitor.subTask(fileObjectPath); 519 IFile targetResource = containerResource.getFile(new Path(provider 520 .getLabel(fileObject))); 521 monitor.worked(1); 522 523 if (rejectedFiles.contains(targetResource.getFullPath())) { 524 return; 525 } 526 527 IPath targetPath = targetResource.getLocation(); 529 if (targetPath != null 531 && (targetPath.toFile().equals(new File (fileObjectPath)))) { 532 errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, 533 NLS.bind(DataTransferMessages.ImportOperation_targetSameAsSourceError, fileObjectPath), null)); 534 return; 535 } 536 537 InputStream contentStream = provider.getContents(fileObject); 538 if (contentStream == null) { 539 errorTable 540 .add(new Status( 541 IStatus.ERROR, 542 PlatformUI.PLUGIN_ID, 543 0, 544 NLS.bind(DataTransferMessages.ImportOperation_openStreamError, fileObjectPath), 545 null)); 546 return; 547 } 548 549 try { 550 if (targetResource.exists()) { 551 targetResource.setContents(contentStream, 552 IResource.KEEP_HISTORY, null); 553 } else { 554 targetResource.create(contentStream, false, null); 555 } 556 setResourceAttributes(targetResource,fileObject); 557 558 if (provider instanceof TarLeveledStructureProvider) { 559 try { 560 targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject)); 561 } catch (CoreException e) { 562 errorTable.add(e.getStatus()); 563 } 564 } 565 } catch (CoreException e) { 566 errorTable.add(e.getStatus()); 567 } finally { 568 try { 569 contentStream.close(); 570 } catch (IOException e) { 571 errorTable 572 .add(new Status( 573 IStatus.ERROR, 574 PlatformUI.PLUGIN_ID, 575 0, 576 NLS.bind(DataTransferMessages.ImportOperation_closeStreamError, fileObjectPath), 577 e)); 578 } 579 } 580 } 581 582 587 private void setResourceAttributes(IFile targetResource, Object fileObject) { 588 589 if(fileObject instanceof File ) { 590 try { 591 targetResource.setResourceAttributes(ResourceAttributes.fromFile((File ) fileObject)); 592 } catch (CoreException e) { 593 IDEWorkbenchPlugin.log(e.getStatus().getMessage(), e); 595 } 596 } 597 598 } 599 600 609 void importFileSystemObjects(List filesToImport) { 610 Iterator filesEnum = filesToImport.iterator(); 611 while (filesEnum.hasNext()) { 612 Object fileSystemObject = filesEnum.next(); 613 if (source == null) { 614 IPath sourcePath = new Path(provider 616 .getFullPath(fileSystemObject)).removeLastSegments(1); 617 if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) { 618 errorTable.add(new Status(IStatus.INFO, 622 PlatformUI.PLUGIN_ID, 0, DataTransferMessages.ImportOperation_cannotCopy, 623 null)); 624 continue; 625 } 626 source = sourcePath.toFile(); 627 } 628 importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT); 629 } 630 } 631 632 641 int importFolder(Object folderObject, int policy) { 642 IContainer containerResource; 643 try { 644 containerResource = getDestinationContainerFor(folderObject); 645 } catch (CoreException e) { 646 errorTable.add(e.getStatus()); 647 return policy; 648 } 649 650 if (containerResource == null) { 651 return policy; 652 } 653 654 monitor.subTask(provider.getFullPath(folderObject)); 655 IWorkspace workspace = destinationContainer.getWorkspace(); 656 IPath containerPath = containerResource.getFullPath(); 657 IPath resourcePath = containerPath.append(provider 658 .getLabel(folderObject)); 659 660 if (resourcePath.equals(containerPath)) { 663 return policy; 664 } 665 666 if (workspace.getRoot().exists(resourcePath)) { 667 if (rejectedFiles.contains(resourcePath)) { 668 return POLICY_SKIP_CHILDREN; 669 } 670 671 return POLICY_FORCE_OVERWRITE; 672 } 673 674 try { 675 workspace.getRoot().getFolder(resourcePath).create(false, true, 676 null); 677 } catch (CoreException e) { 678 errorTable.add(e.getStatus()); 679 } 680 681 return policy; 682 } 683 684 693 void importRecursivelyFrom(Object fileSystemObject, int policy) { 694 if (monitor.isCanceled()) { 695 throw new OperationCanceledException(); 696 } 697 698 if (!provider.isFolder(fileSystemObject)) { 699 importFile(fileSystemObject, policy); 700 return; 701 } 702 703 int childPolicy = importFolder(fileSystemObject, policy); 704 if (childPolicy != POLICY_SKIP_CHILDREN) { 705 Iterator children = provider.getChildren(fileSystemObject) 706 .iterator(); 707 while (children.hasNext()) { 708 importRecursivelyFrom(children.next(), childPolicy); 709 } 710 } 711 } 712 713 721 boolean queryOverwrite(IPath resourcePath) 722 throws OperationCanceledException { 723 String overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath 724 .makeRelative().toString()); 725 726 if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) { 727 throw new OperationCanceledException(DataTransferMessages.DataTransfer_emptyString); 728 } 729 730 if (overwriteAnswer.equals(IOverwriteQuery.NO)) { 731 return false; 732 } 733 734 if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) { 735 this.overwriteState = OVERWRITE_NONE; 736 return false; 737 } 738 739 if (overwriteAnswer.equals(IOverwriteQuery.ALL)) { 740 this.overwriteState = OVERWRITE_ALL; 741 } 742 743 return true; 744 } 745 746 754 boolean queryOverwriteFile(IFile targetFile, int policy) { 755 if (policy != POLICY_FORCE_OVERWRITE) { 757 if (this.overwriteState == OVERWRITE_NOT_SET 758 && !queryOverwrite(targetFile.getFullPath())) { 759 return false; 760 } 761 if (this.overwriteState == OVERWRITE_NONE) { 762 return false; 763 } 764 } 765 return true; 766 } 767 768 777 public void setContext(Shell shell) { 778 context = shell; 779 } 780 781 788 public void setCreateContainerStructure(boolean value) { 789 createContainerStructure = value; 790 } 791 792 798 public void setFilesToImport(List filesToImport) { 799 this.selectedFiles = filesToImport; 800 } 801 802 809 public void setOverwriteResources(boolean value) { 810 if (value) { 811 this.overwriteState = OVERWRITE_ALL; 812 } 813 } 814 815 822 ArrayList validateEdit(List existingFiles) { 823 824 if (existingFiles.size() > 0) { 825 IFile[] files = (IFile[]) existingFiles 826 .toArray(new IFile[existingFiles.size()]); 827 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 828 IStatus status = workspace.validateEdit(files, context); 829 830 if (status.isMultiStatus()) { 832 return getRejectedFiles(status, files); 833 } 834 835 if(!status.isOK()){ 836 errorTable.add(status); 838 ArrayList filteredFiles = new ArrayList (); 839 840 for (int i = 0; i < files.length; i++) { 841 filteredFiles.add(files[i].getFullPath()); 842 } 843 return filteredFiles; 844 } 845 846 } 847 return new ArrayList (); 848 } 849 850 857 void validateFiles(List sourceFiles) { 858 ArrayList noOverwrite = new ArrayList (); 859 ArrayList overwriteReadonly = new ArrayList (); 860 861 collectExistingReadonlyFiles(destinationPath, sourceFiles, noOverwrite, 862 overwriteReadonly, POLICY_DEFAULT); 863 rejectedFiles = validateEdit(overwriteReadonly); 864 rejectedFiles.addAll(noOverwrite); 865 } 866 } 867 | Popular Tags |