| /******************************************************************************* |
| * Copyright (c) 2005, 2006 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.ui.refactoring.history; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.text.ChoiceFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.ltk.core.refactoring.Change; |
| import org.eclipse.ltk.core.refactoring.CheckConditionsOperation; |
| import org.eclipse.ltk.core.refactoring.CreateChangeOperation; |
| import org.eclipse.ltk.core.refactoring.PerformChangeOperation; |
| import org.eclipse.ltk.core.refactoring.PerformRefactoringHistoryOperation; |
| import org.eclipse.ltk.core.refactoring.Refactoring; |
| import org.eclipse.ltk.core.refactoring.RefactoringCore; |
| import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; |
| import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy; |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; |
| import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService; |
| import org.eclipse.ltk.core.refactoring.history.RefactoringHistory; |
| |
| import org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryImplementation; |
| import org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler; |
| import org.eclipse.ltk.internal.ui.refactoring.ExceptionHandler; |
| import org.eclipse.ltk.internal.ui.refactoring.IErrorWizardPage; |
| import org.eclipse.ltk.internal.ui.refactoring.IPreviewWizardPage; |
| import org.eclipse.ltk.internal.ui.refactoring.IRefactoringHelpContextIds; |
| import org.eclipse.ltk.internal.ui.refactoring.Messages; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringHistoryPreviewPage; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringPluginImages; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringPreviewChangeFilter; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringStatusEntryFilter; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages; |
| import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIPlugin; |
| import org.eclipse.ltk.internal.ui.refactoring.UIPerformChangeOperation; |
| import org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter; |
| import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryErrorPage; |
| import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryOverviewPage; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Shell; |
| |
| import org.eclipse.jface.action.LegacyActionTools; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.MessageDialogWithToggle; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.wizard.IWizardContainer; |
| import org.eclipse.jface.wizard.IWizardPage; |
| import org.eclipse.jface.wizard.Wizard; |
| import org.eclipse.jface.wizard.WizardDialog; |
| import org.eclipse.jface.wizard.WizardPage; |
| |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * A default implementation of a refactoring history wizard. Refactoring history |
| * wizards are used to execute the refactorings described by a refactoring |
| * history. A refactoring history wizard differs from a normal wizard in the |
| * following characteristics: |
| * <ul> |
| * <li>A refactoring history wizard consists of a sequence of one error page to |
| * present the outcome of a refactoring's condition checking and one preview |
| * page to present a preview of the workspace changes.</li> |
| * <li> Refactorings are applied to the workspace as soon as a preview has been |
| * accepted. Additionally, refactoring history wizards support the headless |
| * execution of refactorings. The user guided execution of a refactoring history |
| * triggers a series of error pages and preview pages. Within this sequence of |
| * pages, going back is not supported anymore. However, canceling the |
| * refactoring history wizard will undo the already performed refactorings.</li> |
| * </ul> |
| * <p> |
| * A refactoring history wizard is usually opened using the {@link WizardDialog}. |
| * Clients must ensure that the calling thread holds the workspace lock. |
| * </p> |
| * <p> |
| * Note: this class is intended to be extended by clients. |
| * </p> |
| * |
| * @see org.eclipse.ltk.core.refactoring.Refactoring |
| * @see org.eclipse.ltk.core.refactoring.history.RefactoringHistory |
| * |
| * @since 3.2 |
| */ |
| public class RefactoringHistoryWizard extends Wizard { |
| |
| /** The no overview wizard page */ |
| private final class NoOverviewWizardPage extends WizardPage { |
| |
| /** The no overview wizard page name */ |
| private static final String PAGE_NAME= "NoOverviewWizardPage"; //$NON-NLS-1$ |
| |
| /** |
| * Creates a new no overview wizard page. |
| */ |
| private NoOverviewWizardPage() { |
| super(PAGE_NAME); |
| final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors(); |
| if (proxies.length > 0) |
| setTitle(proxies[0], 1, proxies.length); |
| else |
| setTitle(fOverviewTitle); |
| setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_description); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean canFlipToNextPage() { |
| return true; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void createControl(final Composite parent) { |
| final Composite composite= new Composite(parent, SWT.NULL); |
| composite.setLayout(new GridLayout()); |
| composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); |
| setControl(composite); |
| Dialog.applyDialogFont(composite); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IRefactoringHelpContextIds.REFACTORING_PREVIEW_WIZARD_PAGE); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public IWizardPage getNextPage() { |
| return getWizard().getNextPage(this); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public IWizardPage getPreviousPage() { |
| return getWizard().getPreviousPage(this); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setPageComplete(final boolean complete) { |
| super.setPageComplete(true); |
| } |
| |
| /** |
| * Sets the title of the page according to the refactoring. |
| * |
| * @param descriptor |
| * the refactoring descriptor, or <code>null</code> |
| * @param current |
| * the non-zero based index of the current refactoring |
| * @param total |
| * the total number of refactorings |
| */ |
| public void setTitle(final RefactoringDescriptorProxy descriptor, final int current, final int total) { |
| final String message; |
| if (descriptor != null) |
| message= descriptor.getDescription(); |
| else |
| message= RefactoringUIMessages.RefactoringHistoryOverviewPage_title; |
| if (total > 1) |
| setTitle(Messages.format(RefactoringUIMessages.RefactoringHistoryPreviewPage_refactoring_pattern, new String[] { message, String.valueOf(current + 1), String.valueOf(total)})); |
| else |
| setTitle(message); |
| } |
| } |
| |
| /** Preference key for the show apply preference */ |
| private static final String PREFERENCE_DO_NOT_SHOW_APPLY_ERROR= RefactoringUIPlugin.getPluginId() + ".do.not.show.apply.refactoring"; //$NON-NLS-1$; |
| |
| /** Preference key for the show skip preference */ |
| private static final String PREFERENCE_DO_NOT_SHOW_SKIP= RefactoringUIPlugin.getPluginId() + ".do.not.show.skip.refactoring"; //$NON-NLS-1$ |
| |
| /** Preference key for the warn finish preference */ |
| private static final String PREFERENCE_DO_NOT_WARN_FINISH= RefactoringUIPlugin.getPluginId() + ".do.not.warn.finish.wizard"; //$NON-NLS-1$; |
| |
| /** Preference key for the warn undo on cancel preference */ |
| private static final String PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL= RefactoringUIPlugin.getPluginId() + ".do.not.warn.undo.on.cancel.refactoring"; //$NON-NLS-1$; |
| |
| /** |
| * The status code representing an interrupted operation. |
| * <p> |
| * Note: This API must not be used from outside the refactoring framework. |
| * </p> |
| */ |
| public static final int STATUS_CODE_INTERRUPTED= 10003; |
| |
| |
| /** Has the about to perform history event already been fired? */ |
| private boolean fAboutToPerformFired= false; |
| |
| /** Has an exception occurred while cancelling the wizard? */ |
| private boolean fCancelException= false; |
| |
| /** The refactoring history control configuration to use */ |
| private RefactoringHistoryControlConfiguration fControlConfiguration; |
| |
| /** The index of the currently executed refactoring */ |
| private int fCurrentRefactoring= 0; |
| |
| /** |
| * The refactoring descriptor proxies, in ascending order of their time |
| * stamps, or <code>null</code> |
| */ |
| private RefactoringDescriptorProxy[] fDescriptorProxies= null; |
| |
| /** The error wizard page */ |
| private final RefactoringHistoryErrorPage fErrorPage; |
| |
| /** The number of successfully executed refactorings */ |
| private int fExecutedRefactorings= 0; |
| |
| /** Are we currently in method <code>addPages</code>? */ |
| private boolean fInAddPages= false; |
| |
| /** |
| * The no overview wizard page, or <code>null</code> if an overview is |
| * desired |
| */ |
| private NoOverviewWizardPage fNoOverviewPage; |
| |
| /** The description of the overview page */ |
| private final String fOverviewDescription; |
| |
| /** |
| * The overview wizard page, or <code>null</code> if no overview is |
| * desired |
| */ |
| private RefactoringHistoryOverviewPage fOverviewPage; |
| |
| /** The title of the overview page */ |
| private final String fOverviewTitle; |
| |
| /** The preview change filter */ |
| private RefactoringPreviewChangeFilter fPreviewChangeFilter= new RefactoringPreviewChangeFilter() { |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final boolean select(final Change change) { |
| return selectPreviewChange(change); |
| } |
| }; |
| |
| /** The preview wizard page */ |
| private final RefactoringHistoryPreviewPage fPreviewPage; |
| |
| /** The refactoring history to execute */ |
| private RefactoringHistory fRefactoringHistory; |
| |
| /** Does the wizard show an overview of the refactorings? */ |
| private final boolean fShowOverview; |
| |
| /** The status entry filter */ |
| private RefactoringStatusEntryFilter fStatusEntryFilter= new RefactoringStatusEntryFilter() { |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final boolean select(final RefactoringStatusEntry entry) { |
| return selectStatusEntry(entry); |
| } |
| }; |
| |
| /** |
| * Creates a new refactoring history wizard. |
| * <p> |
| * Clients must ensure that the refactoring history and the refactoring |
| * history control configuration are set before opening the wizard in a |
| * dialog. |
| * </p> |
| * |
| * @param overview |
| * <code>true</code> to show an overview of the refactorings, |
| * <code>false</code> otherwise |
| * @param caption |
| * the caption of the wizard window |
| * @param title |
| * the title of the overview page |
| * @param description |
| * the description of the overview page |
| * |
| * @see #setConfiguration(RefactoringHistoryControlConfiguration) |
| * @see #setInput(RefactoringHistory) |
| */ |
| public RefactoringHistoryWizard(final boolean overview, final String caption, final String title, final String description) { |
| Assert.isNotNull(caption); |
| Assert.isNotNull(title); |
| Assert.isNotNull(description); |
| fShowOverview= overview; |
| fOverviewTitle= title; |
| fOverviewDescription= description; |
| fErrorPage= new RefactoringHistoryErrorPage(); |
| fErrorPage.setFilter(fStatusEntryFilter); |
| fPreviewPage= new RefactoringHistoryPreviewPage(); |
| fPreviewPage.setFilter(fPreviewChangeFilter); |
| setNeedsProgressMonitor(true); |
| setWindowTitle(caption); |
| setDefaultPageImageDescriptor(RefactoringPluginImages.DESC_WIZBAN_REFACTOR); |
| } |
| |
| /** |
| * Creates a new refactoring history wizard. |
| * <p> |
| * Clients must ensure that the refactoring history and the refactoring |
| * history control configuration are set before opening the wizard in a |
| * dialog. |
| * </p> |
| * <p> |
| * Calling his constructor is equivalent to |
| * {@link #RefactoringHistoryWizard(boolean, String, String, String)} with |
| * the first argument equal to <code>true</code>. |
| * </p> |
| * |
| * @param caption |
| * the caption of the wizard window |
| * @param title |
| * the title of the overview page |
| * @param description |
| * the description of the overview page |
| * |
| * @see #setConfiguration(RefactoringHistoryControlConfiguration) |
| * @see #setInput(RefactoringHistory) |
| */ |
| public RefactoringHistoryWizard(final String caption, final String title, final String description) { |
| this(true, caption, title, description); |
| } |
| |
| /** |
| * Hook method which is called before the first refactoring of the history |
| * is executed. This method may be called from non-UI threads. |
| * <p> |
| * This method is guaranteed to be called exactly once during the lifetime |
| * of a refactoring history wizard. The default implementation does nothing |
| * and returns a refactoring status of severity {@link RefactoringStatus#OK}. |
| * </p> |
| * <p> |
| * Subclasses may reimplement this method to perform any special processing. |
| * </p> |
| * <p> |
| * Returning a status of severity {@link RefactoringStatus#FATAL} will |
| * terminate the execution of the refactorings. |
| * </p> |
| * |
| * @param monitor |
| * the progress monitor to use |
| * |
| * @return a status describing the outcome of the operation |
| */ |
| protected RefactoringStatus aboutToPerformHistory(final IProgressMonitor monitor) { |
| Assert.isNotNull(monitor); |
| fExecutedRefactorings= 0; |
| return new RefactoringStatus(); |
| } |
| |
| /** |
| * Hook method which is called before the a refactoring of the history is |
| * executed. The refactoring itself is in an initialized state at the time |
| * of the method call. The default implementation does nothing and returns a |
| * status of severity {@link RefactoringStatus#OK}. This method may be |
| * called from non-UI threads. |
| * <p> |
| * Subclasses may extend this method to perform any special processing. |
| * </p> |
| * <p> |
| * Returning a status of severity {@link RefactoringStatus#FATAL} will |
| * terminate the execution of the current refactoring. |
| * </p> |
| * |
| * @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(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * Clients must contribute their wizard pages by re-implementing |
| * {@link #addUserDefinedPages()}. |
| */ |
| public final void addPage(final IWizardPage page) { |
| Assert.isTrue(fInAddPages); |
| super.addPage(page); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final void addPages() { |
| try { |
| fInAddPages= true; |
| addUserDefinedPages(); |
| Assert.isNotNull(fRefactoringHistory); |
| Assert.isNotNull(fControlConfiguration); |
| if (fShowOverview) { |
| fOverviewPage= new RefactoringHistoryOverviewPage(fRefactoringHistory, fOverviewTitle, fOverviewDescription, fControlConfiguration); |
| addPage(fOverviewPage); |
| } else { |
| fNoOverviewPage= new NoOverviewWizardPage(); |
| addPage(fNoOverviewPage); |
| } |
| addPage(fErrorPage); |
| addPage(fPreviewPage); |
| } finally { |
| fInAddPages= false; |
| } |
| } |
| |
| /** |
| * Adds user defined wizard pages in front of the wizard. |
| * <p> |
| * Clients may extend this method to add custom wizard pages in front of the |
| * wizard. |
| * </p> |
| */ |
| protected void addUserDefinedPages() { |
| Assert.isTrue(fInAddPages); |
| |
| // Do not add any as default |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean canFinish() { |
| final IWizardPage page= getContainer().getCurrentPage(); |
| if (page == fErrorPage) { |
| final RefactoringStatus status= fErrorPage.getStatus(); |
| return status == null || !status.hasFatalError(); |
| } |
| return true; |
| } |
| |
| /** |
| * Checks the specified kind of conditions of the refactoring. |
| * |
| * @param refactoring |
| * the refactoring to check its conditions |
| * @param monitor |
| * the progress monitor to use |
| * @param style |
| * the condition checking style |
| * @throws OperationCanceledException |
| * if the operation has been cancelled |
| * @return the resulting status |
| */ |
| private RefactoringStatus checkConditions(final Refactoring refactoring, final IProgressMonitor monitor, final int style) throws OperationCanceledException { |
| Assert.isNotNull(refactoring); |
| Assert.isNotNull(monitor); |
| final RefactoringStatus status= new RefactoringStatus(); |
| try { |
| final CheckConditionsOperation operation= new CheckConditionsOperation(refactoring, style); |
| operation.run(monitor); |
| status.merge(operation.getStatus()); |
| } catch (CoreException exception) { |
| RefactoringUIPlugin.log(exception); |
| status.addFatalError(RefactoringUIMessages.RefactoringWizard_internal_error_1); |
| } |
| return status; |
| } |
| |
| /** |
| * Creates the change for the specified refactoring. |
| * |
| * @param refactoring |
| * the refactoring |
| * @param monitor |
| * the progress monitor |
| * @return the created change |
| * @throws OperationCanceledException |
| * if the operation has been cancelled |
| * @throws CoreException |
| * if an error occurs while creating the change |
| */ |
| private Change createChange(final Refactoring refactoring, final IProgressMonitor monitor) throws OperationCanceledException, CoreException { |
| Assert.isNotNull(refactoring); |
| Assert.isNotNull(monitor); |
| final CreateChangeOperation operation= new CreateChangeOperation(refactoring); |
| operation.run(monitor); |
| return operation.getChange(); |
| } |
| |
| /** |
| * Method which is called to create a refactoring instance from a |
| * refactoring descriptor. The refactoring must be in an initialized state |
| * after the return of the method call. The default implementation delegates |
| * the task to the refactoring descriptor. This method may be called from |
| * non-UI threads. |
| * <p> |
| * Subclasses may reimplement this method to customize the initialization of |
| * a refactoring. |
| * </p> |
| * |
| * @param descriptor |
| * the refactoring descriptor |
| * @param status |
| * a refactoring status describing 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 |
| */ |
| protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status) throws CoreException { |
| Assert.isNotNull(descriptor); |
| return descriptor.createRefactoring(status); |
| } |
| |
| /** |
| * Creates a refactoring from the specified refactoring descriptor. |
| * |
| * @param descriptor |
| * the refactoring descriptor |
| * @param status |
| * the refactoring status |
| * @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 |
| */ |
| private Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException { |
| final Refactoring refactoring= createRefactoring(descriptor, status); |
| if (refactoring != null) { |
| status.merge(aboutToPerformRefactoring(refactoring, descriptor, monitor)); |
| if (!status.hasFatalError()) |
| return refactoring; |
| } else |
| status.addFatalError(Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_error_instantiate_refactoring, descriptor.getDescription())); |
| return null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void dispose() { |
| SafeRunner.run(new ISafeRunnable() { |
| |
| public void handleException(final Throwable exception) { |
| RefactoringUIPlugin.log(exception); |
| } |
| |
| public final void run() throws Exception { |
| if (fAboutToPerformFired) { |
| final RefactoringStatusEntry entry= historyPerformed(new NullProgressMonitor()).getEntryWithHighestSeverity(); |
| if (entry != null) |
| RefactoringUIPlugin.log(entry.toStatus()); |
| } |
| } |
| }); |
| super.dispose(); |
| } |
| |
| /** |
| * Fires the about to perform history event. |
| * |
| * @param monitor |
| * the progress monitor to use |
| * |
| * @return a status describing the outcome of the operation |
| */ |
| private RefactoringStatus fireAboutToPerformHistory(final IProgressMonitor monitor) { |
| final RefactoringStatus status= new RefactoringStatus(); |
| SafeRunner.run(new ISafeRunnable() { |
| |
| public void handleException(final Throwable exception) { |
| RefactoringUIPlugin.log(exception); |
| status.addFatalError(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1); |
| } |
| |
| public final void run() throws Exception { |
| status.merge(aboutToPerformHistory(monitor)); |
| } |
| }); |
| return status; |
| } |
| |
| /** |
| * Returns the error wizard page. |
| * <p> |
| * Note: This API must not be called from outside the refactoring framework. |
| * </p> |
| * |
| * @return the error wizard page |
| */ |
| public final IErrorWizardPage getErrorPage() { |
| return fErrorPage; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public IWizardPage getNextPage(final IWizardPage page) { |
| if (page == fOverviewPage || page == fNoOverviewPage) { |
| fCurrentRefactoring= 0; |
| return getRefactoringPage(); |
| } else if (page == fPreviewPage) { |
| fCurrentRefactoring++; |
| return getRefactoringPage(); |
| } else if (page == fErrorPage) { |
| final RefactoringStatus status= fErrorPage.getStatus(); |
| final IWizardContainer wizard= getContainer(); |
| if (status.hasFatalError()) { |
| final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore(); |
| String message= null; |
| String key= null; |
| if (!RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title.equals(fErrorPage.getTitle())) { |
| message= Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_fatal_error_message, fErrorPage.getTitle()); |
| key= PREFERENCE_DO_NOT_SHOW_SKIP; |
| } else { |
| message= RefactoringUIMessages.RefactoringHistoryWizard_error_applying_changes; |
| key= PREFERENCE_DO_NOT_SHOW_APPLY_ERROR; |
| } |
| if (!store.getBoolean(key)) { |
| final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), wizard.getShell().getText(), null, message, MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false); |
| dialog.open(); |
| store.setValue(key, dialog.getToggleState()); |
| if (dialog.getReturnCode() == 1) |
| return null; |
| } |
| fCurrentRefactoring++; |
| return getRefactoringPage(); |
| } |
| final Refactoring refactoring= fErrorPage.getRefactoring(); |
| if (refactoring != null) { |
| final IRunnableWithProgress runnable= new IRunnableWithProgress() { |
| |
| public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| Assert.isNotNull(monitor); |
| try { |
| fPreviewPage.setRefactoring(refactoring); |
| final Change change= createChange(refactoring, monitor); |
| getShell().getDisplay().syncExec(new Runnable() { |
| |
| public final void run() { |
| fPreviewPage.setChange(change); |
| } |
| }); |
| } catch (CoreException exception) { |
| throw new InvocationTargetException(exception); |
| } catch (OperationCanceledException exception) { |
| throw new InterruptedException(exception.getLocalizedMessage()); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| try { |
| wizard.run(true, false, runnable); |
| } catch (InvocationTargetException exception) { |
| final Throwable throwable= exception.getTargetException(); |
| if (throwable != null) { |
| RefactoringUIPlugin.log(exception); |
| fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1)); |
| return fErrorPage; |
| } |
| } catch (InterruptedException exception) { |
| return fErrorPage; |
| } |
| } else { |
| fPreviewPage.setRefactoring(null); |
| fPreviewPage.setChange(null); |
| } |
| final RefactoringDescriptorProxy descriptor= getRefactoringDescriptor(); |
| if (descriptor != null) |
| fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length); |
| else |
| fPreviewPage.setTitle(RefactoringUIMessages.PreviewWizardPage_changes); |
| fPreviewPage.setStatus(status); |
| fPreviewPage.setNextPageDisabled(isLastRefactoring()); |
| return fPreviewPage; |
| } |
| return super.getNextPage(page); |
| } |
| |
| /** |
| * Returns the preview wizard page. |
| * <p> |
| * Note: This API must not be called from outside the refactoring framework. |
| * </p> |
| * |
| * @return the preview wizard page |
| */ |
| public final IPreviewWizardPage getPreviewPage() { |
| return fPreviewPage; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public IWizardPage getPreviousPage(final IWizardPage page) { |
| if (page == fErrorPage || page == fPreviewPage) |
| return null; |
| return super.getPreviousPage(page); |
| } |
| |
| /** |
| * Returns the refactoring descriptor of the current refactoring. |
| * |
| * @return the refactoring descriptor, or <code>null</code> |
| */ |
| private RefactoringDescriptorProxy getRefactoringDescriptor() { |
| final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors(); |
| if (fCurrentRefactoring >= 0 && fCurrentRefactoring < proxies.length) |
| return proxies[fCurrentRefactoring]; |
| return null; |
| } |
| |
| /** |
| * Returns the refactoring descriptors in their order of execution. |
| * |
| * @return the refactoring descriptors |
| */ |
| private RefactoringDescriptorProxy[] getRefactoringDescriptors() { |
| if (fDescriptorProxies == null) { |
| final RefactoringDescriptorProxy[] proxies= fRefactoringHistory.getDescriptors(); |
| final RefactoringDescriptorProxy[] result= new RefactoringDescriptorProxy[proxies.length]; |
| System.arraycopy(proxies, 0, result, 0, proxies.length); |
| Arrays.sort(result, new Comparator() { |
| |
| public final int compare(final Object first, final Object second) { |
| final RefactoringDescriptorProxy predecessor= (RefactoringDescriptorProxy) first; |
| final RefactoringDescriptorProxy successor= (RefactoringDescriptorProxy) second; |
| final long delta= predecessor.getTimeStamp() - successor.getTimeStamp(); |
| if (delta > 0) |
| return 1; |
| else if (delta < 0) |
| return -1; |
| return 0; |
| } |
| }); |
| fDescriptorProxies= result; |
| } |
| return fDescriptorProxies; |
| } |
| |
| /** |
| * Returns the first page of a refactoring. |
| * |
| * @return the first page, or <code>null</code> |
| */ |
| private IWizardPage getRefactoringPage() { |
| final IWizardPage[] result= { null}; |
| final RefactoringStatus status= new RefactoringStatus(); |
| final IWizardContainer wizard= getContainer(); |
| final IRunnableWithProgress runnable= new IRunnableWithProgress() { |
| |
| public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| Assert.isNotNull(monitor); |
| try { |
| monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactoring, 220); |
| result[0]= null; |
| if (!fAboutToPerformFired) { |
| try { |
| status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL))); |
| } finally { |
| fAboutToPerformFired= true; |
| } |
| } |
| final boolean last= isLastRefactoring(); |
| final RefactoringDescriptorProxy proxy= getRefactoringDescriptor(); |
| preparePreviewPage(status, proxy, last); |
| prepareErrorPage(status, proxy, status.hasFatalError(), last || status.hasFatalError()); |
| fErrorPage.setRefactoring(null); |
| if (!status.isOK()) { |
| result[0]= fErrorPage; |
| } else if (proxy != null) { |
| final IRefactoringHistoryService service= RefactoringCore.getHistoryService(); |
| try { |
| service.connect(); |
| final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| if (descriptor != null) { |
| final Refactoring refactoring= createRefactoring(descriptor, status, new SubProgressMonitor(monitor, 60, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| if (refactoring != null && status.isOK()) { |
| fPreviewPage.setRefactoring(refactoring); |
| fErrorPage.setRefactoring(refactoring); |
| status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.INITIAL_CONDITONS)); |
| if (!status.isOK()) { |
| prepareErrorPage(status, proxy, status.hasFatalError(), last); |
| result[0]= fErrorPage; |
| } else { |
| status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 65, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.FINAL_CONDITIONS)); |
| if (!status.isOK()) { |
| prepareErrorPage(status, proxy, status.hasFatalError(), last); |
| result[0]= fErrorPage; |
| } else { |
| final Change change= createChange(refactoring, new SubProgressMonitor(monitor, 5, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| getShell().getDisplay().syncExec(new Runnable() { |
| |
| public final void run() { |
| fPreviewPage.setChange(change); |
| } |
| }); |
| result[0]= fPreviewPage; |
| } |
| } |
| } else { |
| prepareErrorPage(status, proxy, status.hasFatalError(), last); |
| result[0]= fErrorPage; |
| } |
| } else { |
| status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_error_resolving_refactoring)); |
| prepareErrorPage(status, proxy, status.hasFatalError(), last); |
| result[0]= fErrorPage; |
| } |
| } finally { |
| service.disconnect(); |
| } |
| } else { |
| prepareErrorPage(status, proxy, status.hasFatalError(), last); |
| result[0]= fErrorPage; |
| } |
| } catch (CoreException exception) { |
| throw new InvocationTargetException(exception); |
| } catch (OperationCanceledException exception) { |
| throw new InterruptedException(exception.getLocalizedMessage()); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| try { |
| wizard.run(true, false, runnable); |
| } catch (InvocationTargetException exception) { |
| RefactoringUIPlugin.log(exception); |
| final Throwable throwable= exception.getTargetException(); |
| if (throwable != null) { |
| fErrorPage.setNextPageDisabled(isLastRefactoring()); |
| fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1)); |
| result[0]= fErrorPage; |
| } |
| } catch (InterruptedException exception) { |
| // Stay on same page |
| result[0]= null; |
| } |
| getContainer().updateButtons(); |
| return result[0]; |
| } |
| |
| /** |
| * Hook method which is called when all refactorings of the history have |
| * been executed. This method may be called from non-UI threads. |
| * <p> |
| * This method is guaranteed to be called exactly once during the lifetime |
| * of a refactoring history wizard. It is not guaranteed that the user |
| * interface has not already been disposed of. The default implementation |
| * does nothing and returns a refactoring status of severity |
| * {@link RefactoringStatus#OK}. |
| * </p> |
| * <p> |
| * Subclasses may reimplement this method to perform any special processing. |
| * </p> |
| * |
| * @param monitor |
| * the progress monitor to use |
| * |
| * @return a status describing the outcome of the operation |
| */ |
| protected RefactoringStatus historyPerformed(final IProgressMonitor monitor) { |
| Assert.isNotNull(monitor); |
| return new RefactoringStatus(); |
| } |
| |
| /** |
| * Is the current refactoring the last one? |
| * |
| * @return <code>true</code> if it is the last one, <code>false</code> |
| * otherwise |
| */ |
| private boolean isLastRefactoring() { |
| return fCurrentRefactoring >= getRefactoringDescriptors().length - 1; |
| } |
| |
| /** |
| * Is the current refactoring the second last one? |
| * |
| * @return <code>true</code> if it is the second last one, |
| * <code>false</code> otherwise |
| */ |
| private boolean isSecondLastRefactoring() { |
| return fCurrentRefactoring >= getRefactoringDescriptors().length - 2; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean performCancel() { |
| if (fExecutedRefactorings > 0 && !fCancelException) { |
| final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore(); |
| if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL)) { |
| final MessageFormat format= new MessageFormat(RefactoringUIMessages.RefactoringHistoryWizard_undo_message_pattern); |
| final String message= RefactoringUIMessages.RefactoringHistoryWizard_undo_message_explanation; |
| final String[] messages= { RefactoringUIMessages.RefactoringHistoryWizard_one_refactoring_undone + message, RefactoringUIMessages.RefactoringHistoryWizard_several_refactorings_undone + message}; |
| final ChoiceFormat choice= new ChoiceFormat(new double[] { 1, Double.MAX_VALUE}, messages); |
| format.setFormatByArgumentIndex(0, choice); |
| final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), getShell().getText(), null, format.format(new Object[] { new Integer(fExecutedRefactorings)}), MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false); |
| dialog.open(); |
| store.setValue(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL, dialog.getToggleState()); |
| if (dialog.getReturnCode() == 1) |
| return false; |
| } |
| final IRunnableWithProgress runnable= new IRunnableWithProgress() { |
| |
| public final void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| for (int index= 0; index < fExecutedRefactorings; index++) { |
| try { |
| RefactoringCore.getUndoManager().performUndo(null, new SubProgressMonitor(monitor, 100)); |
| if (fExecutedRefactorings > 0) |
| fExecutedRefactorings--; |
| } catch (CoreException exception) { |
| throw new InvocationTargetException(exception); |
| } |
| } |
| } |
| }; |
| try { |
| getContainer().run(false, false, runnable); |
| } catch (InvocationTargetException exception) { |
| RefactoringUIPlugin.log(exception); |
| fCancelException= true; |
| fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_internal_error)); |
| fErrorPage.setNextPageDisabled(true); |
| fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_title); |
| fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_description); |
| getContainer().showPage(fErrorPage); |
| return false; |
| } catch (InterruptedException exception) { |
| // Does not happen |
| } |
| } |
| return super.performCancel(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean performFinish() { |
| if (fOverviewPage != null) |
| fOverviewPage.performFinish(); |
| final IWizardContainer wizard= getContainer(); |
| final RefactoringStatus status= new RefactoringStatus(); |
| final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors(); |
| final List list= new ArrayList(proxies.length); |
| for (int index= fCurrentRefactoring; index < proxies.length; index++) |
| list.add(proxies[index]); |
| final RefactoringDescriptorProxy[] descriptors= new RefactoringDescriptorProxy[list.size()]; |
| list.toArray(descriptors); |
| final boolean last= isLastRefactoring(); |
| if (wizard.getCurrentPage() == fPreviewPage && last) { |
| final Refactoring refactoring= fPreviewPage.getRefactoring(); |
| final Change change= fPreviewPage.getChange(); |
| if (refactoring != null && change != null) { |
| status.merge(performPreviewChange(change, refactoring)); |
| if (!status.isOK()) { |
| final RefactoringStatusEntry entry= status.getEntryWithHighestSeverity(); |
| if (entry.getSeverity() == RefactoringStatus.INFO && entry.getCode() == RefactoringHistoryWizard.STATUS_CODE_INTERRUPTED) |
| return false; |
| fErrorPage.setStatus(status); |
| fErrorPage.setNextPageDisabled(true); |
| fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title); |
| fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error); |
| wizard.showPage(fErrorPage); |
| return false; |
| } |
| } |
| } else { |
| final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore(); |
| if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_FINISH) && proxies.length > 0) { |
| final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), wizard.getShell().getText(), null, Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_warning_finish, LegacyActionTools.removeMnemonics(IDialogConstants.FINISH_LABEL)), MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false); |
| dialog.open(); |
| store.setValue(PREFERENCE_DO_NOT_WARN_FINISH, dialog.getToggleState()); |
| if (dialog.getReturnCode() == IDialogConstants.CANCEL_ID) |
| return false; |
| } |
| final PerformRefactoringHistoryOperation operation= new PerformRefactoringHistoryOperation(new RefactoringHistoryImplementation(descriptors)) { |
| |
| protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) { |
| final RefactoringStatus[] result= { new RefactoringStatus()}; |
| SafeRunner.run(new ISafeRunnable() { |
| |
| public void handleException(final Throwable exception) { |
| RefactoringUIPlugin.log(exception); |
| } |
| |
| public final void run() throws Exception { |
| result[0]= RefactoringHistoryWizard.this.aboutToPerformRefactoring(refactoring, descriptor, monitor); |
| } |
| }); |
| return result[0]; |
| } |
| |
| protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus state) throws CoreException { |
| return RefactoringHistoryWizard.this.createRefactoring(descriptor, state); |
| } |
| |
| protected void refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) { |
| SafeRunner.run(new ISafeRunnable() { |
| |
| public void handleException(final Throwable exception) { |
| RefactoringUIPlugin.log(exception); |
| } |
| |
| public final void run() throws Exception { |
| RefactoringHistoryWizard.this.refactoringPerformed(refactoring, monitor); |
| } |
| }); |
| } |
| |
| public void run(final IProgressMonitor monitor) throws CoreException { |
| try { |
| monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactorings, 100); |
| if (!fAboutToPerformFired) { |
| try { |
| status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL))); |
| } finally { |
| fAboutToPerformFired= true; |
| } |
| } |
| if (!status.isOK()) { |
| final int severity= status.getSeverity(); |
| throw new CoreException(new Status(severity != RefactoringStatus.FATAL ? severity : IStatus.ERROR, RefactoringUIPlugin.getPluginId(), 0, null, null)); |
| } |
| super.run(new SubProgressMonitor(monitor, 80, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| try { |
| wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot())); |
| } catch (InvocationTargetException exception) { |
| RefactoringUIPlugin.log(exception); |
| final Throwable throwable= exception.getTargetException(); |
| if (throwable != null) { |
| final String message= throwable.getLocalizedMessage(); |
| if (message != null && !"".equals(message)) //$NON-NLS-1$ |
| status.merge(RefactoringStatus.createFatalErrorStatus(message)); |
| fErrorPage.setStatus(status); |
| fErrorPage.setNextPageDisabled(status.hasFatalError()); |
| fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title); |
| fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error); |
| wizard.showPage(fErrorPage); |
| return false; |
| } |
| } catch (InterruptedException exception) { |
| // Does not happen |
| } |
| final RefactoringStatus result= operation.getExecutionStatus(); |
| if (!result.isOK()) { |
| fErrorPage.setStatus(result); |
| fErrorPage.setNextPageDisabled(true); |
| fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_title); |
| fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_description); |
| wizard.showPage(fErrorPage); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Performs the change previously displayed in the preview. |
| * <p> |
| * Note: This API must not be called from outside the refactoring framework. |
| * </p> |
| * |
| * @param change |
| * the change displayed in the preview |
| * @param refactoring |
| * the associated refactoring |
| * @return the status of the operation, already handled by the user |
| */ |
| public final RefactoringStatus performPreviewChange(final Change change, final Refactoring refactoring) { |
| Assert.isNotNull(change); |
| Assert.isNotNull(refactoring); |
| final UIPerformChangeOperation operation= new UIPerformChangeOperation(getShell().getDisplay(), change, getContainer()) { |
| |
| public void run(final IProgressMonitor monitor) throws CoreException { |
| try { |
| monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_changes, 12); |
| super.run(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| refactoringPerformed(refactoring, new SubProgressMonitor(monitor, 2, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| final RefactoringStatus status= performPreviewChange(operation, refactoring); |
| if (status.isOK()) |
| status.merge(operation.getValidationStatus()); |
| return status; |
| } |
| |
| /** |
| * Performs the change previously displayed in the preview using the |
| * specified change operation. |
| * |
| * @param operation |
| * the change operation |
| * @param refactoring |
| * the associated refactoring |
| * @return the status of the operation, already handled by the user |
| */ |
| private RefactoringStatus performPreviewChange(final PerformChangeOperation operation, final Refactoring refactoring) { |
| Assert.isNotNull(operation); |
| Assert.isNotNull(refactoring); |
| operation.setUndoManager(RefactoringCore.getUndoManager(), refactoring.getName()); |
| final IWizardContainer wizard= getContainer(); |
| final Shell shell= wizard.getShell(); |
| try { |
| wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot())); |
| } catch (InvocationTargetException exception) { |
| final Throwable throwable= exception.getTargetException(); |
| if (operation.changeExecutionFailed()) { |
| final Change change= operation.getChange(); |
| final ChangeExceptionHandler handler= new ChangeExceptionHandler(shell, refactoring); |
| if (throwable instanceof RuntimeException) |
| handler.handle(change, (RuntimeException) throwable); |
| else if (throwable instanceof CoreException) |
| handler.handle(change, (CoreException) throwable); |
| } |
| ExceptionHandler.handle(exception, shell, RefactoringUIMessages.RefactoringWizard_refactoring, RefactoringUIMessages.RefactoringWizard_unexpected_exception_1); |
| } catch (InterruptedException exception) { |
| return RefactoringStatus.create(new Status(IStatus.INFO, RefactoringUIPlugin.getPluginId(), STATUS_CODE_INTERRUPTED, exception.getLocalizedMessage(), exception)); |
| } finally { |
| fPreviewPage.setNextPageDisabled(isSecondLastRefactoring()); |
| getContainer().updateButtons(); |
| } |
| return new RefactoringStatus(); |
| } |
| |
| /** |
| * Prepares the error page to be displayed. |
| * |
| * @param status |
| * the refactoring status |
| * @param descriptor |
| * the refactoring descriptor |
| * @param fatal |
| * <code>true</code> if the error is fatal, <code>false</code> |
| * otherwise |
| * @param disabled |
| * <code>true</code> if the next page is disabled, |
| * <code>false</code> otherwise |
| */ |
| private void prepareErrorPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean fatal, final boolean disabled) { |
| getShell().getDisplay().syncExec(new Runnable() { |
| |
| public final void run() { |
| fErrorPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length); |
| fErrorPage.setNextPageDisabled(disabled && fatal); |
| fErrorPage.setPageComplete(!fatal); |
| fErrorPage.setStatus(null); |
| fErrorPage.setStatus(status); |
| getContainer().updateButtons(); |
| } |
| }); |
| } |
| |
| /** |
| * Prepares the preview page to be displayed. |
| * |
| * @param status |
| * the refactoring status |
| * @param descriptor |
| * the refactoring descriptor |
| * @param disabled |
| * <code>true</code> if the next page is disabled, |
| * <code>false</code> otherwise |
| */ |
| private void preparePreviewPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean disabled) { |
| getShell().getDisplay().syncExec(new Runnable() { |
| |
| public final void run() { |
| fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length); |
| fPreviewPage.setNextPageDisabled(disabled); |
| fPreviewPage.setPageComplete(!disabled); |
| fPreviewPage.setStatus(status); |
| getContainer().updateButtons(); |
| } |
| }); |
| } |
| |
| /** |
| * Hook method which is called when the specified refactoring has been |
| * performed, e.g. its change object has been successfully applied to the |
| * workspace. The default implementation does nothing and returns a |
| * refactoring status of severity {@link RefactoringStatus#OK}. This method |
| * may be called from non-UI threads. |
| * <p> |
| * Subclasses may reimplement this method to perform any special processing. |
| * </p> |
| * <p> |
| * Returning a status of severity {@link RefactoringStatus#FATAL} will |
| * terminate the execution of the refactorings. |
| * </p> |
| * |
| * @param refactoring |
| * the refactoring which has been performed |
| * @param monitor |
| * the progress monitor to use |
| * @return a status describing the outcome of the operation |
| */ |
| protected RefactoringStatus refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) { |
| Assert.isNotNull(refactoring); |
| Assert.isNotNull(monitor); |
| fExecutedRefactorings++; |
| return new RefactoringStatus(); |
| } |
| |
| /** |
| * Hook method which is called for each change before it is displayed in a |
| * preview page. The default implementation returns <code>true</code>. |
| * <p> |
| * Subclasses may reimplement this method to perform any special filtering |
| * of preview changes. |
| * </p> |
| * |
| * @param change |
| * the change to select |
| * @return <code>true</code> if the change passes the filter, |
| * <code>false</code> otherwise |
| */ |
| protected boolean selectPreviewChange(final Change change) { |
| return true; |
| } |
| |
| /** |
| * Hook method which is called for each status entry before it is displayed |
| * in a wizard page. The default implementation returns <code>true</code>. |
| * <p> |
| * Subclasses may reimplement this method to perform any special filtering |
| * of status entries on error pages. |
| * </p> |
| * |
| * @param entry |
| * the status entry to select |
| * @return <code>true</code> if the status entry passes the filter, |
| * <code>false</code> otherwise |
| */ |
| protected boolean selectStatusEntry(final RefactoringStatusEntry entry) { |
| return true; |
| } |
| |
| /** |
| * Sets the refactoring history control configuration. |
| * <p> |
| * This method must be called before opening the wizard in a dialog. |
| * </p> |
| * |
| * @param configuration |
| * the configuration to set |
| */ |
| public final void setConfiguration(final RefactoringHistoryControlConfiguration configuration) { |
| Assert.isNotNull(configuration); |
| fControlConfiguration= configuration; |
| } |
| |
| /** |
| * Sets the refactoring history. |
| * <p> |
| * This method must be called before opening the wizard in a dialog. |
| * </p> |
| * |
| * @param history |
| * the refactoring history |
| */ |
| public final void setInput(final RefactoringHistory history) { |
| Assert.isNotNull(history); |
| fRefactoringHistory= history; |
| } |
| } |