/******************************************************************************* * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ltk.core.refactoring; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService; import org.eclipse.ltk.core.refactoring.history.RefactoringHistory; import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages; import org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService; /** * Operation that, when run, executes a series of refactoring sequentially. * Refactorings are executed using {@link PerformRefactoringOperation}. * <p> * The operation should be executed via the run method offered by * <code>IWorkspace</code> to achieve proper delta batching. * </p> * <p> * Note: this class is not intended to be instantiated or extended outside of * the refactoring framework. * </p> * * @see org.eclipse.core.resources.IWorkspace * @see PerformRefactoringOperation * @see RefactoringHistory * @see RefactoringHistoryService * * @since 3.2 * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. */ public class PerformRefactoringHistoryOperation implements IWorkspaceRunnable { /** The status of the execution */ private RefactoringStatus fExecutionStatus= new RefactoringStatus(); /** The refactoring history */ private final RefactoringHistory fRefactoringHistory; /** * Creates a new perform refactoring history operation. * * @param history * the refactoring history */ public PerformRefactoringHistoryOperation(final RefactoringHistory history) { Assert.isNotNull(history); fRefactoringHistory= history; } /** * Hook method which is called when the specified refactoring is going to be * executed. * * @param refactoring * the refactoring about to be executed * @param descriptor * the refactoring descriptor * @param monitor * the progress monitor to use * @return a status describing the outcome of the initialization */ protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) { Assert.isNotNull(refactoring); Assert.isNotNull(descriptor); return new RefactoringStatus(); } /** * Method which is called to create a refactoring instance from a * refactoring descriptor. The refactoring must be in an initialized state * at the return of the method call. The default implementation delegates * the task to the refactoring descriptor. * * @param descriptor * the refactoring descriptor * @param status * a refactoring status to describe the outcome of the * initialization * @return the refactoring, or <code>null</code> if this refactoring * descriptor represents the unknown refactoring, or if no * refactoring contribution is available for this refactoring * descriptor * @throws CoreException * if an error occurs while creating the refactoring instance * @deprecated since 3.4. Override {@link #createRefactoring(RefactoringDescriptor, RefactoringStatus, IProgressMonitor)} instead */ protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status) throws CoreException { Assert.isNotNull(descriptor); return descriptor.createRefactoring(status); } /** * Method which is called to create a refactoring instance from a * refactoring descriptor. The refactoring must be in an initialized state * at the return of the method call. The default implementation delegates * the task to the refactoring descriptor. * * @param descriptor * the refactoring descriptor * @param status * a refactoring status to describe the outcome of the * initialization * @param monitor * the progress monitor to use * @return the refactoring, or <code>null</code> if this refactoring * descriptor represents the unknown refactoring, or if no * refactoring contribution is available for this refactoring * descriptor * @throws CoreException * if an error occurs while creating the refactoring instance * * @since 3.4 */ protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { try { Assert.isNotNull(descriptor); return createRefactoring(descriptor, status); // call for backward compatibility } finally { if (monitor != null) { monitor.done(); } } } /** * Returns the execution status. Guaranteed not to be <code>null</code>. * * @return the status of the session */ public final RefactoringStatus getExecutionStatus() { return fExecutionStatus; } /** * Hook method which is called when the specified refactoring has been * performed. * * @param refactoring * the refactoring which has been performed * @param monitor * the progress monitor to use */ protected void refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) { Assert.isNotNull(refactoring); Assert.isNotNull(monitor); // Do nothing } /** * {@inheritDoc} */ public void run(final IProgressMonitor monitor) throws CoreException { fExecutionStatus= new RefactoringStatus(); final RefactoringDescriptorProxy[] proxies= fRefactoringHistory.getDescriptors(); monitor.beginTask(RefactoringCoreMessages.PerformRefactoringHistoryOperation_perform_refactorings, 170 * proxies.length); final IRefactoringHistoryService service= RefactoringHistoryService.getInstance(); try { service.connect(); for (int index= 0; index < proxies.length; index++) { final RefactoringDescriptor descriptor= proxies[index].requestDescriptor(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); if (descriptor != null) { Refactoring refactoring= null; RefactoringStatus status= new RefactoringStatus(); try { try { refactoring= createRefactoring(descriptor, status, new SubProgressMonitor(monitor, 30, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); } catch (CoreException exception) { status.merge(RefactoringStatus.create(exception.getStatus())); } if (refactoring != null && !status.hasFatalError()) { final PerformRefactoringOperation operation= new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS); try { status.merge(aboutToPerformRefactoring(refactoring, descriptor, new SubProgressMonitor(monitor, 30, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL))); if (!status.hasFatalError()) { ResourcesPlugin.getWorkspace().run(operation, new SubProgressMonitor(monitor, 90, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); status.merge(operation.getConditionStatus()); if (!status.hasFatalError()) status.merge(operation.getValidationStatus()); } } finally { refactoringPerformed(refactoring, new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); } } } finally { fExecutionStatus.merge(status); } } } } finally { service.disconnect(); monitor.done(); } } }