Copyright (c) 2000, 2008 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Oakland Software (Francis Upton) - Fix for Bug 63149 [ltk] allow changes to be executed after the 'main' change during an undo [refactoring]
/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Oakland Software (Francis Upton) <francisu@ieee.org> - * Fix for Bug 63149 [ltk] allow changes to be executed after the 'main' change during an undo [refactoring] *******************************************************************************/
package org.eclipse.ltk.core.refactoring.participants; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextChange; import org.eclipse.ltk.internal.core.refactoring.ParticipantDescriptor;
A refactoring participant can participate in the condition checking and change creation of a RefactoringProcessor.

If the severity of the condition checking result is RefactoringStatus.FATAL then the whole refactoring will not be carried out.

The changes created by a participant MUST not conflict with any changes provided by other participants or the refactoring itself. To ensure this, a participant is only allowed to manipulate resources belonging to its domain. As of 3.1 this got relaxed for textual resources. A participant can now change a textual resource already manipulated by the processor as long as both are manipulating different regions in the file (see createChange(IProgressMonitor) and getTextChange(Object)). For example a rename type participant updating launch configuration is only allowed to update launch configurations or shared textual resources. If a change conflicts with another change during execution then the participant who created the change will be disabled for the rest of the eclipse session.

A refactoring participant can not assume that all resources are saved before any methods are called on it. Therefore a participant must be able to deal with unsaved resources.

A refactoring participant can implement ISharableParticipant in order to be shared for multiple elements to be refactored by the same processor.

This class should be subclassed by clients wishing to provide special refactoring participants extension points.

Since 3.4, a refactoring participant can also override createPreChange(IProgressMonitor) to add changes that will be executed before the main refactoring changes are executed.

See Also:
Since:3.0
/** * A refactoring participant can participate in the condition checking and * change creation of a {@link RefactoringProcessor}. * <p> * If the severity of the condition checking result is {@link RefactoringStatus#FATAL} * then the whole refactoring will not be carried out. * </p> * <p> * The changes created by a participant <em>MUST</em> not conflict with any changes * provided by other participants or the refactoring itself. To ensure this, a participant * is only allowed to manipulate resources belonging to its domain. As of 3.1 this got * relaxed for textual resources. A participant can now change a textual resource already * manipulated by the processor as long as both are manipulating different regions in the * file (see {@link #createChange(IProgressMonitor)} and {@link #getTextChange(Object)}). * For example a rename type participant updating launch configuration is only allowed to * update launch configurations or shared textual resources. If a change conflicts with * another change during execution then the participant who created the change will be * disabled for the rest of the eclipse session. * </p> * <p> * A refactoring participant can not assume that all resources are saved before any * methods are called on it. Therefore a participant must be able to deal with unsaved * resources. * </p> * <p> * A refactoring participant can implement {@link ISharableParticipant} in order to be * shared for multiple elements to be refactored by the same processor. * </p> * <p> * This class should be subclassed by clients wishing to provide special refactoring * participants extension points. * </p> * <p> * Since 3.4, a refactoring participant can also override {@link #createPreChange(IProgressMonitor)} * to add changes that will be executed <em>before</em> the main refactoring changes * are executed. * </p> * * @see RefactoringProcessor * @see ISharableParticipant * * @since 3.0 */
public abstract class RefactoringParticipant extends PlatformObject { private RefactoringProcessor fProcessor; private ParticipantDescriptor fDescriptor;
Returns the processor that is associated with this participant.
Returns:the processor that is associated with this participant
/** * Returns the processor that is associated with this participant. * * @return the processor that is associated with this participant */
public RefactoringProcessor getProcessor() { return fProcessor; }
Initializes the participant. This method is called by the framework when a participant gets instantiated.

This method isn't intended to be extended or reimplemented by clients.

Params:
  • processor – the processor this participant is associated with
  • element – the element to be refactored
  • arguments – the refactoring arguments
See Also:
Returns:true if the participant could be initialized; otherwise false is returned. If false is returned then the participant will not be added to the refactoring.
/** * Initializes the participant. This method is called by the framework when a * participant gets instantiated. * <p> * This method isn't intended to be extended or reimplemented by clients. * </p> * @param processor the processor this participant is associated with * @param element the element to be refactored * @param arguments the refactoring arguments * * @return <code>true</code> if the participant could be initialized; * otherwise <code>false</code> is returned. If <code>false</code> is * returned then the participant will not be added to the refactoring. * * @see #initialize(Object) */
public boolean initialize(RefactoringProcessor processor, Object element, RefactoringArguments arguments) { Assert.isNotNull(processor); Assert.isNotNull(arguments); fProcessor= processor; initialize(arguments); return initialize(element); }
Initializes the participant with the element to be refactored. If this method returns false then the framework will consider the participant as not being initialized and the participant will be dropped by the framework.
Params:
  • element – the element to be refactored
Returns:true if the participant could be initialized; otherwise false is returned.
/** * Initializes the participant with the element to be refactored. * If this method returns <code>false</code> then the framework * will consider the participant as not being initialized and the * participant will be dropped by the framework. * * @param element the element to be refactored * * @return <code>true</code> if the participant could be initialized; * otherwise <code>false</code> is returned. */
protected abstract boolean initialize(Object element);
Initializes the participant with the refactoring arguments
Params:
  • arguments – the refactoring arguments
/** * Initializes the participant with the refactoring arguments * * @param arguments the refactoring arguments */
protected abstract void initialize(RefactoringArguments arguments);
Returns a human readable name of this participant.
Returns:a human readable name
/** * Returns a human readable name of this participant. * * @return a human readable name */
public abstract String getName();
Checks the conditions of the refactoring participant.

The refactoring is considered as not being executable if the returned status has the severity of RefactoringStatus#FATAL. Note that this blocks the whole refactoring operation!

Clients should use the passed CheckConditionsContext to validate the changes they generate. If the generated changes include workspace resource modifications, clients should call ...

 (ResourceChangeChecker) context.getChecker(ResourceChangeChecker.class);
IResourceChangeDescriptionFactory deltaFactory= checker.getDeltaFactory();

... and use the delta factory to describe all resource modifications in advance.

This method can be called more than once.

Params:
  • pm – a progress monitor to report progress
  • context – a condition checking context to collect shared condition checks
Throws:
See Also:
Returns:a refactoring status. If the status is RefactoringStatus#FATAL the refactoring is considered as not being executable.
/** * Checks the conditions of the refactoring participant. * <p> * The refactoring is considered as not being executable if the returned status * has the severity of <code>RefactoringStatus#FATAL</code>. Note that this blocks * the whole refactoring operation! * </p> * <p> * Clients should use the passed {@link CheckConditionsContext} to validate the changes * they generate. If the generated changes include workspace resource modifications, * clients should call ...</p> * * <pre> (ResourceChangeChecker) context.getChecker(ResourceChangeChecker.class); * IResourceChangeDescriptionFactory deltaFactory= checker.getDeltaFactory();</pre> * <p> * ... and use the delta factory to describe all resource modifications in advance. * </p> * <p> * This method can be called more than once. * </p> * * @param pm a progress monitor to report progress * @param context a condition checking context to collect shared condition checks * * @return a refactoring status. If the status is <code>RefactoringStatus#FATAL</code> * the refactoring is considered as not being executable. * * @throws OperationCanceledException if the condition checking got canceled * * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(IProgressMonitor) * @see RefactoringStatus */
public abstract RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException;
Creates a Change object that contains the workspace modifications of this participant to be executed before the changes from the refactoring are executed. Note that this implies that the undo change of the returned Change object will be executed after the undo changes from the refactoring have been executed.

The changes provided by a participant must not conflict with any change provided by other participants or by the refactoring itself.

If the change conflicts with any change provided by other participants or by the refactoring itself, then change execution will fail and the participant will be disabled for the rest of the eclipse session.

If an exception occurs while creating the change, the refactoring can not be carried out, and the participant will be disabled for the rest of the eclipse session.

A participant can manipulate text resource already manipulated by the processor as long as the textual manipulations don't conflict (e.g. the participant manipulates a different region of the text resource). The method must not return those changes in its change tree since the change is already part of another change tree. If the participant only manipulates shared changes then it can return null to indicate that it didn't create own changes. A shared text change can be accessed via the method getTextChange(Object).

The default implementation returns null. Subclasses can extend or override.

Note that most refactorings will implement createChange(IProgressMonitor) rather than this method.

Params:
  • pm – a progress monitor to report progress
Throws:
See Also:
Returns:the change representing the workspace modifications to be executed before the refactoring change or null if no changes are made
Since:3.4
/** * Creates a {@link Change} object that contains the workspace modifications * of this participant to be executed <em>before</em> the * changes from the refactoring are executed. Note that this implies that the * undo change of the returned Change object will be executed <em>after</em> * the undo changes from the refactoring have been executed. * <p> * The changes provided * by a participant <em>must</em> not conflict with any change provided by other * participants or by the refactoring itself. * <p> * If the change conflicts with any change provided by other participants or * by the refactoring itself, then change execution will fail and the * participant will be disabled for the rest of the eclipse session. * </p> * <p> * If an exception occurs while creating the change, the refactoring can not * be carried out, and the participant will be disabled for the rest of the * eclipse session. * </p> * <p> * A participant can manipulate text resource already manipulated by * the processor as long as the textual manipulations don't conflict (e.g. * the participant manipulates a different region of the text resource). * The method must not return those changes in its change tree since the change * is already part of another change tree. If the participant only manipulates * shared changes then it can return <code>null</code> to indicate that it didn't * create own changes. A shared text change can be accessed via the method * {@link #getTextChange(Object)}. * </p> * <p> * The default implementation returns <code>null</code>. Subclasses can extend or override. * </p> * <p> * Note that most refactorings will implement {@link #createChange(IProgressMonitor)} * rather than this method. * </p> * * @param pm a progress monitor to report progress * * @return the change representing the workspace modifications to be executed * before the refactoring change or <code>null</code> if no changes are made * * @throws CoreException if an error occurred while creating the change * * @throws OperationCanceledException if the change creation got canceled * * @see #createChange(IProgressMonitor) * * @since 3.4 */
public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { return null; }
Creates a Change object that contains the workspace modifications of this participant to be executed after the changes from the refactoring are executed. Note that this implies that the undo change of the returned Change object will be executed before the undo changes from the refactoring have been executed.

The changes provided by a participant must not conflict with any change provided by other participants or by the refactoring itself.

If the change conflicts with any change provided by other participants or by the refactoring itself, then change execution will fail and the participant will be disabled for the rest of the eclipse session.

If an exception occurs while creating the change, the refactoring can not be carried out, and the participant will be disabled for the rest of the eclipse session.

As of 3.1, a participant can manipulate text resources already manipulated by the processor as long as the textual manipulations don't conflict (i.e. the participant manipulates a different region of the text resource). The method must not return those changes in its change tree since the change is already part of another change tree. If the participant only manipulates shared changes, then it can return null to indicate that it didn't create own changes. A shared text change can be accessed via the method getTextChange(Object).

Params:
  • pm – a progress monitor to report progress
Throws:
See Also:
Returns:the change representing the workspace modifications to be executed after the refactoring change or null if no changes are made
/** * Creates a {@link Change} object that contains the workspace modifications * of this participant to be executed <em>after</em> the * changes from the refactoring are executed. Note that this implies that the * undo change of the returned Change object will be executed <em>before</em> * the undo changes from the refactoring have been executed. * <p> * The changes provided by a participant <em>must</em> * not conflict with any change provided by other participants or by the * refactoring itself. * <p> * If the change conflicts with any change provided by other participants or * by the refactoring itself, then change execution will fail and the * participant will be disabled for the rest of the eclipse session. * </p> * <p> * If an exception occurs while creating the change, the refactoring can not * be carried out, and the participant will be disabled for the rest of the * eclipse session. * </p> * <p> * As of 3.1, a participant can manipulate text resources already manipulated by * the processor as long as the textual manipulations don't conflict (i.e. * the participant manipulates a different region of the text resource). * The method must not return those changes in its change tree since the change * is already part of another change tree. If the participant only manipulates * shared changes, then it can return <code>null</code> to indicate that it didn't * create own changes. A shared text change can be accessed via the method * {@link #getTextChange(Object)}. * </p> * * @param pm a progress monitor to report progress * * @return the change representing the workspace modifications to be executed * after the refactoring change or <code>null</code> if no changes are made * * @throws CoreException if an error occurred while creating the change * * @throws OperationCanceledException if the change creation got canceled * * @see #createPreChange(IProgressMonitor) */
public abstract Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException;
Returns the text change for the given element or null if a text change doesn't exist. This method only returns a valid result during change creation. Outside of change creation always null is returned.
Params:
  • element – the element to be modified for which a text change is requested
Returns:the text change or null if no text change exists for the element @since 3.1
/** * Returns the text change for the given element or <code>null</code> * if a text change doesn't exist. This method only returns a valid * result during change creation. Outside of change creation always * <code>null</code> is returned. * * @param element the element to be modified for which a text change * is requested * * @return the text change or <code>null</code> if no text change exists * for the element * * @since 3.1 */
public TextChange getTextChange(Object element) { return getProcessor().getRefactoring().getTextChange(element); } //---- helper method ---------------------------------------------------- /* package */ void setDescriptor(ParticipantDescriptor descriptor) { Assert.isNotNull(descriptor); fDescriptor= descriptor; } /* package */ ParticipantDescriptor getDescriptor() { return fDescriptor; } }