An abstract base implementation for object representing a generic change
to the workbench. A
Change
object is typically created by
calling
Refactoring#createChange(IProgressMonitor). This class should be
subclassed by clients wishing to provide new changes.
Changes are best executed by using a
PerformChangeOperation. If clients
execute a change directly then the following life cycle has to be honored:
- After a single change or a tree of changes has been created, the
method
initializeValidationData
has to be called.
- The method
isValid
can be used to determine if a change
can still be applied to the workspace. If the method returns a
RefactoringStatus with a severity of FATAL then the change has to be
treated as invalid. Performing an invalid change isn't allowed and
results in an unspecified result. This method can be called multiple
times.
- Then the method
perform
can be called. A disabled change
must not be executed. The perform
method can only be called
once. After a change has been executed, only the method dispose
must be called.
- the method
dispose
has to be called either after the
perform
method
has been called or if a change is no longer needed. The second case
for example occurs when the undo stack gets flushed and all change
objects managed by the undo stack are no longer needed. The method
dispose
is typically implemented to unregister listeners
registered during the
method initializeValidationData
. There is no guarantee
that initializeValidationData
, isValid
,
or perform
has been called before dispose
is called.
Here is a code snippet that can be used to execute a change:
Change change= createChange();
try {
change.initializeValidationData(pm);
....
if (!change.isEnabled())
return;
RefactoringStatus valid= change.isValid(new SubProgressMonitor(pm, 1));
if (valid.hasFatalError())
return;
Change undo= change.perform(new SubProgressMonitor(pm, 1));
if (undo != null) {
undo.initializeValidationData(new SubProgressMonitor(pm, 1));
// do something with the undo object
}
} finally {
change.dispose();
}
It is important that implementors of this abstract class provide an adequate
implementation of isValid
and that they provide an undo change
via the return value of the method perform
. If no undo can be
provided then the perform
method is allowed to return null
. But
implementors should be aware that not providing an undo object for a change
object that is part of a larger change tree will result in the fact that for
the whole change tree no undo object will be present.
Changes which are returned as top-level changes (e.g. by Refactoring.createChange()
)
can optionally return a descriptor object of the refactoring which created this change object.
Clients may subclass this class.