## org.eclipse.emf.workspace
Class CompositeEMFOperation

    java.lang.Object
      org.eclipse.core.commands.operations.AbstractOperation
          org.eclipse.emf.workspace.AbstractEMFOperation
              org.eclipse.emf.workspace.CompositeEMFOperation

All Implemented Interfaces:
  IUndoableOperation

    public class CompositeEMFOperation

extends AbstractEMFOperation

An implementation of a composite undoable operation for composition of operations which may include `AbstractEMFOperation`s. The composite ensures that all of the nested operations are executed in a single transaction context. The composite can combine EMF and non-EMF operations freely, and even include nested `CompositeEMFOperation`s.

Although a `CompositeEMFOperation` provides a single root transaction context for all of its children, these children open nested transactions of their own, by default. This can be disabled by turning off the `transactionNestingEnabled` property. This is a hint that child operations should just execute in the transaction that is already open, unless they require a nested transaction. In consequence, child operations would not be able to depend on changes being triggered by previous operations, as triggers will be deferred to the end of the composite (when it commits).

Note that this kind of a composite is different from the `IOperationHistory`'s notion of a `TriggeredOperations`, because the children of a composite are not "triggered" by any primary operation. Rather, it is assumed that the children are explicitly composed by a client. The undo contexts of the composite are a union of the undo contexts of its children.

Note: This class cannot be used with the `IOperationHistory.openOperation(ICompositeOperation, int)` API because it does not implement the `ICompositeOperation` interface. This prevents the possibility of open-ended transactions on the operation history that any listener can contribute additional changes to, on the same editing domain or a different editing domain. The transaction API provides a tightly-regulated triggered change mechanism via the `ResourceSetListener` interface.

This class is intended to be instantiated by clients and supports a limited form of subclassing.

Constructor Summary
`CompositeEMFOperation(TransactionalEditingDomain domain, String label)` Initializes me with the editing domain in which I am making model changes and a label.
`CompositeEMFOperation(TransactionalEditingDomain domain, String label, List<? extends IUndoableOperation> children)` Initializes me with the editing domain, a label, and child operations.
`CompositeEMFOperation(TransactionalEditingDomain domain, String label, List<? extends IUndoableOperation> children, Map<?,?> options)` Initializes me with the editing domain, a label, and child operations, and transaction options.
`CompositeEMFOperation(TransactionalEditingDomain domain, String label, Map<?,?> options)` Initializes me with the editing domain, a label, and transaction options.

Method Summary
`void` `add(IUndoableOperation operation)` Adds a child operation to me.
`protected void` `assertNotExecuted()` Asserts that I have not yet been executed.
`boolean` `canExecute()` I can execute if all of my children can execute.
`boolean` `canRedo()` I can redo if my transaction successfully completed with changes recorded and my children can all be redone.
`boolean` `canUndo()` I can undo if my transaction successfully completed with changes recorded and my children can all be undone.
`protected void` `didCommit(Transaction transaction)` Hook for subclasses to learn that the specified `transaction` has been successfully committed and, if necessary, to extract information from it.
`void` `dispose()` Removes all of my children and disposes them.
`protected IStatus` `doExecute(IProgressMonitor monitor, IAdaptable info)` Implements the execution logic by sequential execution of my children.
`protected IStatus` `doRedo(IProgressMonitor monitor, IAdaptable info)` I undo by asking my children to redo, in forward order.
`protected IStatus` `doUndo(IProgressMonitor monitor, IAdaptable info)` I undo by asking my children to undo, in reverse order.
`protected List<IUndoableOperation>` `getChildren()` Obtains my nested operations.
`boolean` `isTransactionNestingEnabled()` Queries whether nesting of transactions is enabled, meaning that all child operations (recursively) execute in their own (nested) transactions.
`Iterator<IUndoableOperation>` `iterator()` Obtains an iterator to traverse my child operations.
`ListIterator<IUndoableOperation>` `listIterator()` Obtains an iterator to traverse my child operations in either direction.
`ListIterator<IUndoableOperation>` `listIterator(int index)` Obtains an iterator to traverse my child operations in either direction, starting from the specified `index`.
`void` `remove(IUndoableOperation operation)` Removes a child operation from me.
`void` `setTransactionNestingEnabled(boolean enable)` Sets whether nesting of transactions is enabled.
`int` `size()` Queries the number of child operations that I contain.

Methods inherited from class org.eclipse.emf.workspace.AbstractEMFOperation
`aggregateStatuses, didRedo, didUndo, execute, getChange, getEditingDomain, getOptions, redo, undo`

Methods inherited from class org.eclipse.core.commands.operations.AbstractOperation
`addContext, getContexts, getLabel, hasContext, removeContext, setLabel, toString`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

Constructor Detail

### CompositeEMFOperation

    public CompositeEMFOperation(TransactionalEditingDomain domain,
                                 String label)

  Initializes me with the editing domain in which I am making model changes and a label.

  Parameters:
    `domain` - my editing domain
    `label` - my user-readable label

### CompositeEMFOperation

    public CompositeEMFOperation(TransactionalEditingDomain domain,
                                 String label,
                                 Map<?,?> options)

  Initializes me with the editing domain, a label, and transaction options.

  Parameters:
    `domain` - my editing domain
    `label` - my user-readable label
    `options` - for the transaction in which I execute myself, or `null` for the default options

### CompositeEMFOperation

    public CompositeEMFOperation(TransactionalEditingDomain domain,
                                 String label,
                                 List<? extends IUndoableOperation> children)

  Initializes me with the editing domain, a label, and child operations.

  Parameters:
    `domain` - my editing domain
    `label` - my user-readable label
    `children` - a list of operations to compose

### CompositeEMFOperation

    public CompositeEMFOperation(TransactionalEditingDomain domain,
                                 String label,
                                 List<? extends IUndoableOperation> children,
                                 Map<?,?> options)

  Initializes me with the editing domain, a label, and child operations, and transaction options.

  Parameters:
    `domain` - my editing domain
    `label` - my user-readable label
    `children` - a list of operations to compose
    `options` - for the transaction in which I execute myself, or `null` for the default options

Method Detail

### doExecute

    protected final IStatus doExecute(IProgressMonitor monitor,
                                      IAdaptable info)
                               throws ExecutionException

  Implements the execution logic by sequential execution of my children. Non-EMF operations are captured in the transaction's recorded changes so that they may be correctly rolled back (in sequence) in the event of rollback, undo, or redo.

  Specified by:
    `doExecute` in class `AbstractEMFOperation`
  Parameters:
    `monitor` - the progress monitor provided by the operation history. Will never be `null` because the `AbstractEMFOperation.execute(IProgressMonitor, IAdaptable)` method would substitute a `NullProgressMonitor` in that case
    `info` - the adaptable provided by the operation history
  Returns:
    the status of the execution
  Throws:
    `ExecutionException` - if, for some reason, I fail to complete the operation

### didCommit

    protected void didCommit(Transaction transaction)

  Description copied from class: `AbstractEMFOperation`

  Hook for subclasses to learn that the specified `transaction` has been successfully committed and, if necessary, to extract information from it.

  Note: subclasses should call this super implementation to get some default behaviours.

  Overrides:
    `didCommit` in class `AbstractEMFOperation`
  Parameters:
    `transaction` - a transaction that has committed, which has recorded our changes

### canExecute

    public boolean canExecute()

  I can execute if all of my children can execute.

  Specified by:
    `canExecute` in interface `IUndoableOperation`
  Overrides:
    `canExecute` in class `AbstractOperation`

### canUndo

    public boolean canUndo()

  I can undo if my transaction successfully completed with changes recorded and my children can all be undone.

  Specified by:
    `canUndo` in interface `IUndoableOperation`
  Overrides:
    `canUndo` in class `AbstractEMFOperation`

### doUndo

    protected final IStatus doUndo(IProgressMonitor monitor,
                                   IAdaptable info)
                            throws ExecutionException

  I undo by asking my children to undo, in reverse order.

  Overrides:
    `doUndo` in class `AbstractEMFOperation`
  Parameters:
    `monitor` - the progress monitor provided by the operation history Will never be `null` because the `AbstractEMFOperation.undo(IProgressMonitor, IAdaptable)` method would substitute a `NullProgressMonitor` in that case
    `info` - the adaptable provided by the operation history
  Returns:
    the status of the undo operation
  Throws:
    `ExecutionException` - on failure to undo

### canRedo

    public boolean canRedo()

  I can redo if my transaction successfully completed with changes recorded and my children can all be redone.

  Specified by:
    `canRedo` in interface `IUndoableOperation`
  Overrides:
    `canRedo` in class `AbstractEMFOperation`

### doRedo

    protected final IStatus doRedo(IProgressMonitor monitor,
                                   IAdaptable info)
                            throws ExecutionException

  I undo by asking my children to redo, in forward order.

  Overrides:
    `doRedo` in class `AbstractEMFOperation`
  Parameters:
    `monitor` - the progress monitor provided by the operation history Will never be `null` because the `AbstractEMFOperation.redo(IProgressMonitor, IAdaptable)` method would substitute a `NullProgressMonitor` in that case
    `info` - the adaptable provided by the operation history
  Returns:
    the status of the redo operation
  Throws:
    `ExecutionException` - on failure to redo

### dispose

    public void dispose()

  Removes all of my children and disposes them.

  Specified by:
    `dispose` in interface `IUndoableOperation`
  Overrides:
    `dispose` in class `AbstractEMFOperation`

### getChildren

    protected List<IUndoableOperation> getChildren()

  Obtains my nested operations. Note that the return result is mutable and is identical to my child-operation storage, so subclasses should be careful of adding or removing contents. This should ordinarily be done only via the `add(IUndoableOperation)` and `remove(IUndoableOperation)` methods because these maintain the undo contexts (or, equivalently, using the iterators).

  Returns:
    my list of children
  See Also:
    `add(IUndoableOperation)`, `remove(IUndoableOperation)`, `iterator()`, `listIterator(int)`

### add

    public void add(IUndoableOperation operation)

  Adds a child operation to me. This should only be done before I am executed. Has no effect if I already contain this operation as a child.

  Parameters:
    `operation` - a new child operation
  Throws:
    `IllegalStateException` - if I have already been successfully executed

### assertNotExecuted

    protected final void assertNotExecuted()

  Asserts that I have not yet been executed. Changes to my children are not permitted after I have been executed.

### remove

    public void remove(IUndoableOperation operation)

  Removes a child operation from me. This should only be done before I am executed. Has no effect if I do not contain this operation as a child.

  Note that, unlike the `ICompositeOperation` interface (which I do not implement), I do not dispose an operation when it is removed from me. This would not be correct, as I did not create that operation.

  Parameters:
    `operation` - a child operation to remove
  Throws:
    `IllegalStateException` - if I have already been successfully executed

### isTransactionNestingEnabled

    public boolean isTransactionNestingEnabled()

  Queries whether nesting of transactions is enabled, meaning that all child operations (recursively) execute in their own (nested) transactions. Nested transactions are enabled by default.

  Returns:
    `false` if child operations execute in a single (flat) transaction where possible; `false`, otherwise
  See Also:
    `setTransactionNestingEnabled(boolean)`

### setTransactionNestingEnabled

    public void setTransactionNestingEnabled(boolean enable)

  Sets whether nesting of transactions is enabled. Turning this off can improve performance considerably by avoiding the book-keeping overhead of large numbers of small transactions, where a composite operation is a large nested structure. This property is propagated to child composite operations (recursively).

  Note that this is really only a hint: there are exceptions where child operation will still create nested transactions. These are:

  - when the child is not an `AbstractEMFOperation`. Non-EMF operations are given special transactions that capture their changes as change descriptions in the parent transaction
  - when the child has different `transaction options` than the parent composite operation

  Parameters:
    `enable` - whether to force all child operations to create nested transactions
  Throws:
    `IllegalStateException` - if I have already been `executed`, after which time transaction nesting cannot be changed

### size

    public int size()

  Queries the number of child operations that I contain.

  Returns:
    my size

### iterator

    public Iterator<IUndoableOperation> iterator()

  Obtains an iterator to traverse my child operations. Removing children via this iterator correctly maintains my undo contexts.

  Returns:
    an iterator of my children

### listIterator

    public ListIterator<IUndoableOperation> listIterator()

  Obtains an iterator to traverse my child operations in either direction. Adding and removing children via this iterator correctly maintains my undo contexts.

  Note that, unlike list iterators generally, this implementation does not permit the addition of an operation that I already contain (the composite does not permit duplicates). Moreover, only `IUndoableOperation`s may be added, otherwise `ClassCastException`s will result.

  Returns:
    an iterator of my children

### listIterator

    public ListIterator<IUndoableOperation> listIterator(int index)

  Obtains an iterator to traverse my child operations in either direction, starting from the specified `index`. Adding and removing children via this iterator correctly maintains my undo contexts.

  Note that, unlike list iterators generally, this implementation does not permit the addition of an operation that I already contain (the composite does not permit duplicates). Moreover, only `IUndoableOperation`s may be added, otherwise `ClassCastException`s will result.

  Parameters:
    `index` - the index in my children at which to start iterating
  Returns:
    an iterator of my children

Copyright 2002, 2007 IBM Corporation and others. All Rights Reserved.