@Override public void closeOperation(boolean operationOK, boolean addToHistory, int mode) { ICompositeOperation endedComposite = null; synchronized (openCompositeLock) { if (DEBUG_OPERATION_HISTORY_UNEXPECTED) { if (openComposite == null) { Tracing.printTrace( "OPERATIONHISTORY", "Attempted to close operation when none was open"); //$NON-NLS-1$//$NON-NLS-2$ return; } } // notifications will occur outside the synchonized block if (openComposite != null) { if (DEBUG_OPERATION_HISTORY_OPENOPERATION) { Tracing.printTrace( "OPERATIONHISTORY", "Closing operation " + openComposite); // $NON-NLS-1$ //$NON-NLS-2$ } endedComposite = openComposite; openComposite = null; } } // any mode other than EXECUTE was triggered by a request to undo or // redo something already in the history, so undo and redo // notification will occur at the end of that sequence. if (endedComposite != null) { if (operationOK) { if (mode == EXECUTE) { notifyDone(endedComposite); } if (addToHistory) { add(endedComposite); } } else { if (mode == EXECUTE) { notifyNotOK(endedComposite); } } } }
@Override public IStatus execute(IUndoableOperation operation, IProgressMonitor monitor, IAdaptable info) throws ExecutionException { Assert.isNotNull(operation); // error if operation is invalid if (!operation.canExecute()) { return IOperationHistory.OPERATION_INVALID_STATUS; } // check with the operation approvers IStatus status = getExecuteApproval(operation, info); if (!status.isOK()) { // not approved. No notifications are sent, just return the status. return status; } /* * If we are in the middle of an open composite, then we will add this * operation to the open operation rather than add the operation to the * history. We will still execute it. */ boolean merging = false; synchronized (openCompositeLock) { if (openComposite != null) { // the composite shouldn't be executed explicitly while it is // still // open if (openComposite == operation) { return IOperationHistory.OPERATION_INVALID_STATUS; } openComposite.add(operation); merging = true; } } /* * Execute the operation */ if (!merging) { notifyAboutToExecute(operation); } try { status = operation.execute(monitor, info); } catch (OperationCanceledException e) { status = Status.CANCEL_STATUS; } catch (ExecutionException e) { notifyNotOK(operation); throw e; } catch (Exception e) { notifyNotOK(operation); throw new ExecutionException( "While executing the operation, an exception occurred", e); // $NON-NLS-1$ } // if successful, the notify listeners are notified and the operation is // added to the history if (!merging) { if (status.isOK()) { notifyDone(operation); add(operation); } else { notifyNotOK(operation, status); // dispose the operation since we did not add it to the stack // and will no longer have a reference to it. operation.dispose(); } } // all other severities are not interpreted. Simply return the status. return status; }