1 11 12 package org.eclipse.ui.ide.undo; 13 14 import org.eclipse.core.commands.ExecutionException; 15 import org.eclipse.core.commands.operations.AbstractOperation; 16 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation; 17 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation2; 18 import org.eclipse.core.commands.operations.OperationHistoryEvent; 19 import org.eclipse.core.commands.operations.OperationStatus; 20 import org.eclipse.core.resources.IResource; 21 import org.eclipse.core.resources.IResourceRuleFactory; 22 import org.eclipse.core.resources.IWorkspace; 23 import org.eclipse.core.resources.IWorkspaceRunnable; 24 import org.eclipse.core.resources.ResourcesPlugin; 25 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; 26 import org.eclipse.core.resources.mapping.ResourceChangeValidator; 27 import org.eclipse.core.runtime.CoreException; 28 import org.eclipse.core.runtime.IAdaptable; 29 import org.eclipse.core.runtime.IProgressMonitor; 30 import org.eclipse.core.runtime.IStatus; 31 import org.eclipse.core.runtime.Status; 32 import org.eclipse.core.runtime.jobs.ISchedulingRule; 33 import org.eclipse.jface.action.Action; 34 import org.eclipse.osgi.util.NLS; 35 import org.eclipse.swt.widgets.Shell; 36 import org.eclipse.ui.PlatformUI; 37 import org.eclipse.ui.ide.IDE; 38 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; 39 import org.eclipse.ui.internal.ide.undo.UndoMessages; 40 41 54 public abstract class AbstractWorkspaceOperation extends AbstractOperation 55 implements IAdvancedUndoableOperation, IAdvancedUndoableOperation2 { 56 57 private static String ELLIPSIS = "..."; 59 protected static int EXECUTE = 1; 60 61 protected static int UNDO = 2; 62 63 protected static int REDO = 3; 64 65 protected IResource[] resources; 66 67 private boolean isValid = true; 68 69 73 protected boolean quietCompute = false; 74 75 String [] modelProviderIds; 76 77 83 AbstractWorkspaceOperation(String name) { 84 super(Action.removeMnemonics(name)); 87 88 String label = this.getLabel(); 90 if (label.endsWith(ELLIPSIS)) { 91 this.setLabel(label 92 .substring(0, label.length() - ELLIPSIS.length())); 93 } 94 } 95 96 103 public void setModelProviderIds(String [] ids) { 104 modelProviderIds = ids; 105 } 106 107 113 protected void setTargetResources(IResource[] resources) { 114 this.resources = resources; 115 } 116 117 122 protected IWorkspace getWorkspace() { 123 return ResourcesPlugin.getWorkspace(); 124 } 125 126 131 protected IResourceRuleFactory getWorkspaceRuleFactory() { 132 return getWorkspace().getRuleFactory(); 133 } 134 135 140 protected void markInvalid() { 141 isValid = false; 142 } 143 144 151 public boolean canExecute() { 152 return isValid(); 153 } 154 155 162 public boolean canUndo() { 163 return isValid(); 164 } 165 166 173 public boolean canRedo() { 174 return isValid(); 175 } 176 177 201 public IStatus execute(IProgressMonitor monitor, final IAdaptable uiInfo) 202 throws ExecutionException { 203 try { 204 getWorkspace().run(new IWorkspaceRunnable() { 205 public void run(IProgressMonitor monitor) throws CoreException { 206 doExecute(monitor, uiInfo); 207 } 208 }, getExecuteSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor); 209 } catch (final CoreException e) { 210 throw new ExecutionException(NLS.bind( 211 UndoMessages.AbstractWorkspaceOperation_ExecuteErrorTitle, 212 getLabel()), e); 213 } 214 isValid = true; 215 return Status.OK_STATUS; 216 } 217 218 241 public IStatus redo(IProgressMonitor monitor, final IAdaptable uiInfo) 242 throws ExecutionException { 243 try { 244 getWorkspace().run(new IWorkspaceRunnable() { 245 public void run(IProgressMonitor monitor) throws CoreException { 246 doExecute(monitor, uiInfo); 247 } 248 }, getRedoSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor); 249 } catch (final CoreException e) { 250 throw new ExecutionException(NLS.bind( 251 UndoMessages.AbstractWorkspaceOperation_RedoErrorTitle, 252 getLabel()), e); 253 254 } 255 isValid = true; 256 return Status.OK_STATUS; 257 } 258 259 282 public IStatus undo(IProgressMonitor monitor, final IAdaptable uiInfo) 283 throws ExecutionException { 284 try { 285 getWorkspace().run(new IWorkspaceRunnable() { 286 public void run(IProgressMonitor monitor) throws CoreException { 287 doUndo(monitor, uiInfo); 288 } 289 }, getUndoSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor); 290 } catch (final CoreException e) { 291 throw new ExecutionException(NLS.bind( 292 UndoMessages.AbstractWorkspaceOperation_UndoErrorTitle, 293 getLabel()), e); 294 295 } 296 isValid = true; 297 return Status.OK_STATUS; 298 } 299 300 314 protected abstract void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) 315 throws CoreException; 316 317 332 protected abstract void doExecute(IProgressMonitor monitor, 333 IAdaptable uiInfo) throws CoreException; 334 335 342 protected boolean isValid() { 343 return isValid; 344 } 345 346 351 public void aboutToNotify(OperationHistoryEvent event) { 352 } 354 355 360 public Object [] getAffectedObjects() { 361 return resources; 362 } 363 364 399 public IStatus computeExecutionStatus(IProgressMonitor monitor) { 400 IStatus status = Status.OK_STATUS; 401 402 if (quietCompute) { 404 return status; 405 } 406 407 IResourceChangeDescriptionFactory factory = ResourceChangeValidator 408 .getValidator().createDeltaFactory(); 409 if (updateResourceChangeDescriptionFactory(factory, EXECUTE)) { 410 boolean proceed = IDE 411 .promptToConfirm( 412 getShell(null), 413 UndoMessages.AbstractWorkspaceOperation_SideEffectsWarningTitle, 414 NLS 415 .bind( 416 UndoMessages.AbstractWorkspaceOperation_ExecuteSideEffectsWarningMessage, 417 getLabel()), factory.getDelta(), 418 modelProviderIds, true ); 419 if (!proceed) { 420 status = Status.CANCEL_STATUS; 421 } 422 } 423 return status; 424 425 } 426 427 462 public IStatus computeUndoableStatus(IProgressMonitor monitor) { 463 IStatus status = Status.OK_STATUS; 464 if (quietCompute) { 466 return status; 467 } 468 469 IResourceChangeDescriptionFactory factory = ResourceChangeValidator 470 .getValidator().createDeltaFactory(); 471 if (updateResourceChangeDescriptionFactory(factory, UNDO)) { 472 boolean proceed = IDE 473 .promptToConfirm( 474 getShell(null), 475 UndoMessages.AbstractWorkspaceOperation_SideEffectsWarningTitle, 476 NLS 477 .bind( 478 UndoMessages.AbstractWorkspaceOperation_UndoSideEffectsWarningMessage, 479 getLabel()), factory.getDelta(), 480 modelProviderIds, true ); 481 if (!proceed) { 482 status = Status.CANCEL_STATUS; 483 } 484 } 485 return status; 486 487 } 488 489 524 public IStatus computeRedoableStatus(IProgressMonitor monitor) { 525 IStatus status = Status.OK_STATUS; 526 if (quietCompute) { 528 return status; 529 } 530 531 IResourceChangeDescriptionFactory factory = ResourceChangeValidator 532 .getValidator().createDeltaFactory(); 533 if (updateResourceChangeDescriptionFactory(factory, REDO)) { 534 boolean proceed = IDE 535 .promptToConfirm( 536 getShell(null), 537 UndoMessages.AbstractWorkspaceOperation_SideEffectsWarningTitle, 538 NLS 539 .bind( 540 UndoMessages.AbstractWorkspaceOperation_RedoSideEffectsWarningMessage, 541 getLabel()), factory.getDelta(), 542 modelProviderIds, true ); 543 if (!proceed) { 544 status = Status.CANCEL_STATUS; 545 } 546 } 547 return status; 548 } 549 550 565 protected boolean updateResourceChangeDescriptionFactory( 566 IResourceChangeDescriptionFactory factory, int operation) { 567 return false; 568 } 569 570 579 protected IStatus getErrorStatus(String message) { 580 String statusMessage = message; 581 if (statusMessage == null) { 582 statusMessage = NLS 583 .bind( 584 UndoMessages.AbstractWorkspaceOperation_ErrorInvalidMessage, 585 getLabel()); 586 } 587 return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, 588 OperationStatus.OPERATION_INVALID, statusMessage, null); 589 } 590 591 602 protected IStatus getWarningStatus(String message, int code) { 603 String statusMessage = message; 604 if (statusMessage == null) { 605 statusMessage = NLS 606 .bind( 607 UndoMessages.AbstractWorkspaceOperation_GenericWarningMessage, 608 getLabel()); 609 } 610 return new Status(IStatus.WARNING, IDEWorkbenchPlugin.IDE_WORKBENCH, 611 code, statusMessage, null); 612 } 613 614 621 protected boolean resourcesExist() { 622 if (resources == null || resources.length == 0) { 623 return false; 624 } 625 for (int i = 0; i < resources.length; i++) { 626 if (!resources[i].exists()) { 627 return false; 628 } 629 } 630 return true; 631 } 632 633 640 protected boolean resourcesIncludesProjects() { 641 if (resources == null || resources.length == 0) { 642 return false; 643 } 644 for (int i = 0; i < resources.length; i++) { 645 if (resources[i].getType() == IResource.PROJECT) { 646 return true; 647 } 648 } 649 return false; 650 } 651 652 666 protected ISchedulingRule getExecuteSchedulingRule() { 667 return getWorkspace().getRoot(); 668 } 669 670 684 protected ISchedulingRule getUndoSchedulingRule() { 685 return getWorkspace().getRoot(); 686 } 687 688 701 protected ISchedulingRule getRedoSchedulingRule() { 702 return getExecuteSchedulingRule(); 703 } 704 705 710 public void setQuietCompute(boolean quiet) { 711 quietCompute = quiet; 712 } 713 714 717 public String toString() { 718 StringBuffer text = new StringBuffer (super.toString()); 719 text.append("\n"); text.append(this.getClass().getName()); 721 appendDescriptiveText(text); 722 return text.toString(); 723 } 724 725 733 protected void appendDescriptiveText(StringBuffer text) { 734 text.append(" resources: "); text.append(resources); 736 text.append('\''); 737 } 738 739 754 protected Shell getShell(IAdaptable uiInfo) { 755 if (uiInfo != null) { 756 Shell shell = (Shell) uiInfo.getAdapter(Shell.class); 757 if (shell != null) { 758 return shell; 759 } 760 } 761 return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 762 } 763 764 769 public boolean runInBackground() { 770 return true; 771 } 772 } 773 | Popular Tags |