KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ltk > ui > refactoring > history > RefactoringHistoryWizard


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ltk.ui.refactoring.history;
12
13 import com.ibm.icu.text.MessageFormat;
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.text.ChoiceFormat JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.List JavaDoc;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.ISafeRunnable;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.NullProgressMonitor;
26 import org.eclipse.core.runtime.OperationCanceledException;
27 import org.eclipse.core.runtime.SafeRunner;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.core.runtime.SubProgressMonitor;
30
31 import org.eclipse.core.resources.ResourcesPlugin;
32
33 import org.eclipse.ltk.core.refactoring.Change;
34 import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
35 import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
36 import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
37 import org.eclipse.ltk.core.refactoring.PerformRefactoringHistoryOperation;
38 import org.eclipse.ltk.core.refactoring.Refactoring;
39 import org.eclipse.ltk.core.refactoring.RefactoringCore;
40 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
41 import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
42 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
43 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
44 import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService;
45 import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
46
47 import org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryImplementation;
48 import org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryManager;
49 import org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler;
50 import org.eclipse.ltk.internal.ui.refactoring.ExceptionHandler;
51 import org.eclipse.ltk.internal.ui.refactoring.IErrorWizardPage;
52 import org.eclipse.ltk.internal.ui.refactoring.IPreviewWizardPage;
53 import org.eclipse.ltk.internal.ui.refactoring.IRefactoringHelpContextIds;
54 import org.eclipse.ltk.internal.ui.refactoring.Messages;
55 import org.eclipse.ltk.internal.ui.refactoring.RefactoringHistoryPreviewPage;
56 import org.eclipse.ltk.internal.ui.refactoring.RefactoringPluginImages;
57 import org.eclipse.ltk.internal.ui.refactoring.RefactoringPreviewChangeFilter;
58 import org.eclipse.ltk.internal.ui.refactoring.RefactoringStatusEntryFilter;
59 import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
60 import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIPlugin;
61 import org.eclipse.ltk.internal.ui.refactoring.UIPerformChangeOperation;
62 import org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter;
63 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryErrorPage;
64 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryOverviewPage;
65
66 import org.eclipse.swt.SWT;
67 import org.eclipse.swt.layout.GridData;
68 import org.eclipse.swt.layout.GridLayout;
69 import org.eclipse.swt.widgets.Composite;
70 import org.eclipse.swt.widgets.Shell;
71
72 import org.eclipse.jface.action.LegacyActionTools;
73 import org.eclipse.jface.dialogs.Dialog;
74 import org.eclipse.jface.dialogs.IDialogConstants;
75 import org.eclipse.jface.dialogs.MessageDialog;
76 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
77 import org.eclipse.jface.operation.IRunnableWithProgress;
78 import org.eclipse.jface.preference.IPreferenceStore;
79 import org.eclipse.jface.wizard.IWizardContainer;
80 import org.eclipse.jface.wizard.IWizardPage;
81 import org.eclipse.jface.wizard.Wizard;
82 import org.eclipse.jface.wizard.WizardDialog;
83 import org.eclipse.jface.wizard.WizardPage;
84
85 import org.eclipse.ui.PlatformUI;
86
87 /**
88  * A default implementation of a refactoring history wizard. Refactoring history
89  * wizards are used to execute the refactorings described by a refactoring
90  * history. A refactoring history wizard differs from a normal wizard in the
91  * following characteristics:
92  * <ul>
93  * <li>A refactoring history wizard consists of a sequence of one error page to
94  * present the outcome of a refactoring's condition checking and one preview
95  * page to present a preview of the workspace changes.</li>
96  * <li> Refactorings are applied to the workspace as soon as a preview has been
97  * accepted. Additionally, refactoring history wizards support the headless
98  * execution of refactorings. The user guided execution of a refactoring history
99  * triggers a series of error pages and preview pages. Within this sequence of
100  * pages, going back is not supported anymore. However, canceling the
101  * refactoring history wizard will undo the already performed refactorings.</li>
102  * </ul>
103  * <p>
104  * A refactoring history wizard is usually opened using the {@link WizardDialog}.
105  * Clients must ensure that the calling thread holds the workspace lock.
106  * </p>
107  * <p>
108  * Note: this class is intended to be extended by clients.
109  * </p>
110  *
111  * @see org.eclipse.ltk.core.refactoring.Refactoring
112  * @see org.eclipse.ltk.core.refactoring.history.RefactoringHistory
113  *
114  * @since 3.2
115  */

116 public class RefactoringHistoryWizard extends Wizard {
117
118     /** The no overview wizard page */
119     private final class NoOverviewWizardPage extends WizardPage {
120
121         /** The no overview wizard page name */
122         private static final String JavaDoc PAGE_NAME= "NoOverviewWizardPage"; //$NON-NLS-1$
123

124         /**
125          * Creates a new no overview wizard page.
126          */

127         private NoOverviewWizardPage() {
128             super(PAGE_NAME);
129             final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
130             if (proxies.length > 0)
131                 setTitle(proxies[0], 1, proxies.length);
132             else
133                 setTitle(fOverviewTitle);
134             setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_description);
135         }
136
137         /**
138          * {@inheritDoc}
139          */

140         public boolean canFlipToNextPage() {
141             return true;
142         }
143
144         /**
145          * {@inheritDoc}
146          */

147         public void createControl(final Composite parent) {
148             final Composite composite= new Composite(parent, SWT.NULL);
149             composite.setLayout(new GridLayout());
150             composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
151             setControl(composite);
152             Dialog.applyDialogFont(composite);
153             PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IRefactoringHelpContextIds.REFACTORING_PREVIEW_WIZARD_PAGE);
154         }
155
156         /**
157          * {@inheritDoc}
158          */

159         public IWizardPage getNextPage() {
160             return getWizard().getNextPage(this);
161         }
162
163         /**
164          * {@inheritDoc}
165          */

166         public IWizardPage getPreviousPage() {
167             return getWizard().getPreviousPage(this);
168         }
169
170         /**
171          * {@inheritDoc}
172          */

173         public void setPageComplete(final boolean complete) {
174             super.setPageComplete(true);
175         }
176
177         /**
178          * Sets the title of the page according to the refactoring.
179          *
180          * @param descriptor
181          * the refactoring descriptor, or <code>null</code>
182          * @param current
183          * the non-zero based index of the current refactoring
184          * @param total
185          * the total number of refactorings
186          */

187         public void setTitle(final RefactoringDescriptorProxy descriptor, final int current, final int total) {
188             final String JavaDoc message;
189             if (descriptor != null)
190                 message= descriptor.getDescription();
191             else
192                 message= RefactoringUIMessages.RefactoringHistoryOverviewPage_title;
193             if (total > 1)
194                 setTitle(Messages.format(RefactoringUIMessages.RefactoringHistoryPreviewPage_refactoring_pattern, new String JavaDoc[] { message, String.valueOf(current + 1), String.valueOf(total)}));
195             else
196                 setTitle(message);
197         }
198     }
199
200     /** Preference key for the show apply preference */
201     private static final String JavaDoc PREFERENCE_DO_NOT_SHOW_APPLY_ERROR= RefactoringUIPlugin.getPluginId() + ".do.not.show.apply.refactoring"; //$NON-NLS-1$;
202

203     /** Preference key for the show skip preference */
204     private static final String JavaDoc PREFERENCE_DO_NOT_SHOW_SKIP= RefactoringUIPlugin.getPluginId() + ".do.not.show.skip.refactoring"; //$NON-NLS-1$
205

206     /** Preference key for the warn finish preference */
207     private static final String JavaDoc PREFERENCE_DO_NOT_WARN_FINISH= RefactoringUIPlugin.getPluginId() + ".do.not.warn.finish.wizard"; //$NON-NLS-1$;
208

209     /** Preference key for the warn undo on cancel preference */
210     private static final String JavaDoc PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL= RefactoringUIPlugin.getPluginId() + ".do.not.warn.undo.on.cancel.refactoring"; //$NON-NLS-1$;
211

212     /**
213      * The status code representing an interrupted operation.
214      * <p>
215      * Note: This API must not be used from outside the refactoring framework.
216      * </p>
217      */

218     public static final int STATUS_CODE_INTERRUPTED= 10003;
219
220
221     /** Has the about to perform history event already been fired? */
222     private boolean fAboutToPerformFired= false;
223
224     /** Has an exception occurred while cancelling the wizard? */
225     private boolean fCancelException= false;
226
227     /** The refactoring history control configuration to use */
228     private RefactoringHistoryControlConfiguration fControlConfiguration;
229
230     /** The index of the currently executed refactoring */
231     private int fCurrentRefactoring= 0;
232
233     /**
234      * The refactoring descriptor proxies, in ascending order of their time
235      * stamps, or <code>null</code>
236      */

237     private RefactoringDescriptorProxy[] fDescriptorProxies= null;
238
239     /** The error wizard page */
240     private final RefactoringHistoryErrorPage fErrorPage;
241
242     /** The number of successfully executed refactorings */
243     private int fExecutedRefactorings= 0;
244
245     /** Can the wizard be finished after fatal errors occurred in headless mode? */
246     private boolean fHeadlessErrorStatus= false;
247
248     /** Are we currently in method <code>addPages</code>? */
249     private boolean fInAddPages= false;
250
251     /**
252      * The no overview wizard page, or <code>null</code> if an overview is
253      * desired
254      */

255     private NoOverviewWizardPage fNoOverviewPage;
256
257     /** The description of the overview page */
258     private final String JavaDoc fOverviewDescription;
259
260     /**
261      * The overview wizard page, or <code>null</code> if no overview is
262      * desired
263      */

264     private RefactoringHistoryOverviewPage fOverviewPage;
265
266     /** The title of the overview page */
267     private final String JavaDoc fOverviewTitle;
268
269     /** The preview change filter */
270     private RefactoringPreviewChangeFilter fPreviewChangeFilter= new RefactoringPreviewChangeFilter() {
271
272         /**
273          * {@inheritDoc}
274          */

275         public final boolean select(final Change change) {
276             return selectPreviewChange(change);
277         }
278     };
279
280     /** The preview wizard page */
281     private final RefactoringHistoryPreviewPage fPreviewPage;
282
283     /** The refactoring history to execute */
284     private RefactoringHistory fRefactoringHistory;
285
286     /** Does the wizard show an overview of the refactorings? */
287     private final boolean fShowOverview;
288
289     /** The status entry filter */
290     private RefactoringStatusEntryFilter fStatusEntryFilter= new RefactoringStatusEntryFilter() {
291
292         /**
293          * {@inheritDoc}
294          */

295         public final boolean select(final RefactoringStatusEntry entry) {
296             return selectStatusEntry(entry);
297         }
298     };
299
300     /**
301      * Creates a new refactoring history wizard.
302      * <p>
303      * Clients must ensure that the refactoring history and the refactoring
304      * history control configuration are set before opening the wizard in a
305      * dialog.
306      * </p>
307      *
308      * @param overview
309      * <code>true</code> to show an overview of the refactorings,
310      * <code>false</code> otherwise
311      * @param caption
312      * the caption of the wizard window
313      * @param title
314      * the title of the overview page
315      * @param description
316      * the description of the overview page
317      *
318      * @see #setConfiguration(RefactoringHistoryControlConfiguration)
319      * @see #setInput(RefactoringHistory)
320      */

321     public RefactoringHistoryWizard(final boolean overview, final String JavaDoc caption, final String JavaDoc title, final String JavaDoc description) {
322         Assert.isNotNull(caption);
323         Assert.isNotNull(title);
324         Assert.isNotNull(description);
325         fShowOverview= overview;
326         fOverviewTitle= title;
327         fOverviewDescription= description;
328         fErrorPage= new RefactoringHistoryErrorPage();
329         fErrorPage.setFilter(fStatusEntryFilter);
330         fPreviewPage= new RefactoringHistoryPreviewPage();
331         fPreviewPage.setFilter(fPreviewChangeFilter);
332         setNeedsProgressMonitor(true);
333         setWindowTitle(caption);
334         setDefaultPageImageDescriptor(RefactoringPluginImages.DESC_WIZBAN_REFACTOR);
335     }
336
337     /**
338      * Creates a new refactoring history wizard.
339      * <p>
340      * Clients must ensure that the refactoring history and the refactoring
341      * history control configuration are set before opening the wizard in a
342      * dialog.
343      * </p>
344      * <p>
345      * Calling his constructor is equivalent to
346      * {@link #RefactoringHistoryWizard(boolean, String, String, String)} with
347      * the first argument equal to <code>true</code>.
348      * </p>
349      *
350      * @param caption
351      * the caption of the wizard window
352      * @param title
353      * the title of the overview page
354      * @param description
355      * the description of the overview page
356      *
357      * @see #setConfiguration(RefactoringHistoryControlConfiguration)
358      * @see #setInput(RefactoringHistory)
359      */

360     public RefactoringHistoryWizard(final String JavaDoc caption, final String JavaDoc title, final String JavaDoc description) {
361         this(true, caption, title, description);
362     }
363
364     /**
365      * Hook method which is called before the first refactoring of the history
366      * is executed. This method may be called from non-UI threads.
367      * <p>
368      * This method is guaranteed to be called exactly once during the lifetime
369      * of a refactoring history wizard. The default implementation does nothing
370      * and returns a refactoring status of severity {@link RefactoringStatus#OK}.
371      * </p>
372      * <p>
373      * Subclasses may reimplement this method to perform any special processing.
374      * </p>
375      * <p>
376      * Returning a status of severity {@link RefactoringStatus#FATAL} will
377      * terminate the execution of the refactorings.
378      * </p>
379      *
380      * @param monitor
381      * the progress monitor to use
382      *
383      * @return a status describing the outcome of the operation
384      */

385     protected RefactoringStatus aboutToPerformHistory(final IProgressMonitor monitor) {
386         Assert.isNotNull(monitor);
387         fExecutedRefactorings= 0;
388         return new RefactoringStatus();
389     }
390
391     /**
392      * Hook method which is called before the a refactoring of the history is
393      * executed. The refactoring itself is in an initialized state at the time
394      * of the method call. The default implementation does nothing and returns a
395      * status of severity {@link RefactoringStatus#OK}. This method may be
396      * called from non-UI threads.
397      * <p>
398      * Subclasses may extend this method to perform any special processing.
399      * </p>
400      * <p>
401      * Returning a status of severity {@link RefactoringStatus#FATAL} will
402      * terminate the execution of the current refactoring.
403      * </p>
404      *
405      * @param refactoring
406      * the refactoring about to be executed
407      * @param descriptor
408      * the refactoring descriptor
409      * @param monitor
410      * the progress monitor to use
411      * @return a status describing the outcome of the initialization
412      */

413     protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) {
414         Assert.isNotNull(refactoring);
415         Assert.isNotNull(descriptor);
416         return new RefactoringStatus();
417     }
418
419     /**
420      * {@inheritDoc}
421      *
422      * Clients must contribute their wizard pages by re-implementing
423      * {@link #addUserDefinedPages()}.
424      */

425     public final void addPage(final IWizardPage page) {
426         Assert.isTrue(fInAddPages);
427         super.addPage(page);
428     }
429
430     /**
431      * {@inheritDoc}
432      */

433     public final void addPages() {
434         try {
435             fInAddPages= true;
436             addUserDefinedPages();
437             Assert.isNotNull(fRefactoringHistory);
438             Assert.isNotNull(fControlConfiguration);
439             if (fShowOverview) {
440                 fOverviewPage= new RefactoringHistoryOverviewPage(fRefactoringHistory, fOverviewTitle, fOverviewDescription, fControlConfiguration);
441                 addPage(fOverviewPage);
442             } else {
443                 fNoOverviewPage= new NoOverviewWizardPage();
444                 addPage(fNoOverviewPage);
445             }
446             addPage(fErrorPage);
447             addPage(fPreviewPage);
448         } finally {
449             fInAddPages= false;
450         }
451     }
452
453     /**
454      * Adds user defined wizard pages in front of the wizard.
455      * <p>
456      * Clients may extend this method to add custom wizard pages in front of the
457      * wizard.
458      * </p>
459      */

460     protected void addUserDefinedPages() {
461         Assert.isTrue(fInAddPages);
462
463         // Do not add any as default
464
}
465
466     /**
467      * {@inheritDoc}
468      */

469     public boolean canFinish() {
470         final IWizardPage page= getContainer().getCurrentPage();
471         if (page == fErrorPage) {
472             if (fHeadlessErrorStatus)
473                 return true;
474             final RefactoringStatus status= fErrorPage.getStatus();
475             final boolean fatal= status != null && status.hasFatalError();
476             if (isLastRefactoring() && fDescriptorProxies.length > 1) {
477                 if (fatal)
478                     fHeadlessErrorStatus= true;
479                 return true;
480             }
481             return !fatal;
482         }
483         return true;
484     }
485
486     /**
487      * Checks the specified kind of conditions of the refactoring.
488      *
489      * @param refactoring
490      * the refactoring to check its conditions
491      * @param monitor
492      * the progress monitor to use
493      * @param style
494      * the condition checking style
495      * @throws OperationCanceledException
496      * if the operation has been cancelled
497      * @return the resulting status
498      */

499     private RefactoringStatus checkConditions(final Refactoring refactoring, final IProgressMonitor monitor, final int style) throws OperationCanceledException {
500         Assert.isNotNull(refactoring);
501         Assert.isNotNull(monitor);
502         final RefactoringStatus status= new RefactoringStatus();
503         try {
504             final CheckConditionsOperation operation= new CheckConditionsOperation(refactoring, style);
505             operation.run(monitor);
506             status.merge(operation.getStatus());
507         } catch (CoreException exception) {
508             RefactoringUIPlugin.log(exception);
509             status.addFatalError(RefactoringUIMessages.RefactoringWizard_internal_error_1);
510         }
511         return status;
512     }
513
514     /**
515      * Creates the change for the specified refactoring.
516      *
517      * @param refactoring
518      * the refactoring
519      * @param monitor
520      * the progress monitor
521      * @return the created change
522      * @throws OperationCanceledException
523      * if the operation has been cancelled
524      * @throws CoreException
525      * if an error occurs while creating the change
526      */

527     private Change createChange(final Refactoring refactoring, final IProgressMonitor monitor) throws OperationCanceledException, CoreException {
528         Assert.isNotNull(refactoring);
529         Assert.isNotNull(monitor);
530         final CreateChangeOperation operation= new CreateChangeOperation(refactoring);
531         operation.run(monitor);
532         return operation.getChange();
533     }
534
535     /**
536      * Method which is called to create a refactoring instance from a
537      * refactoring descriptor. The refactoring must be in an initialized state
538      * after the return of the method call. The default implementation delegates
539      * the task to the refactoring descriptor. This method may be called from
540      * non-UI threads.
541      * <p>
542      * Subclasses may reimplement this method to customize the initialization of
543      * a refactoring.
544      * </p>
545      *
546      * @param descriptor
547      * the refactoring descriptor
548      * @param status
549      * a refactoring status describing the outcome of the
550      * initialization
551      * @return the refactoring, or <code>null</code> if this refactoring
552      * descriptor represents the unknown refactoring, or if no
553      * refactoring contribution is available for this refactoring
554      * descriptor
555      * @throws CoreException
556      * if an error occurs while creating the refactoring instance
557      */

558     protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status) throws CoreException {
559         Assert.isNotNull(descriptor);
560         return descriptor.createRefactoring(status);
561     }
562
563     /**
564      * Creates a refactoring from the specified refactoring descriptor.
565      *
566      * @param descriptor
567      * the refactoring descriptor
568      * @param status
569      * the refactoring status
570      * @param monitor
571      * the progress monitor to use
572      * @return the refactoring, or <code>null</code> if this refactoring
573      * descriptor represents the unknown refactoring, or if no
574      * refactoring contribution is available for this refactoring
575      * descriptor
576      * @throws CoreException
577      * if an error occurs while creating the refactoring instance
578      */

579     private Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
580         final Refactoring refactoring= createRefactoring(descriptor, status);
581         if (refactoring != null) {
582             status.merge(aboutToPerformRefactoring(refactoring, descriptor, monitor));
583             if (!status.hasFatalError())
584                 return refactoring;
585         } else
586             status.addFatalError(Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_error_instantiate_refactoring, descriptor.getDescription()));
587         return null;
588     }
589
590     /**
591      * {@inheritDoc}
592      */

593     public void dispose() {
594         SafeRunner.run(new ISafeRunnable() {
595
596             public void handleException(final Throwable JavaDoc exception) {
597                 RefactoringUIPlugin.log(exception);
598             }
599
600             public final void run() throws Exception JavaDoc {
601                 if (fAboutToPerformFired) {
602                     final RefactoringStatusEntry entry= historyPerformed(new NullProgressMonitor()).getEntryWithHighestSeverity();
603                     if (entry != null)
604                         RefactoringUIPlugin.log(entry.toStatus());
605                 }
606             }
607         });
608         super.dispose();
609     }
610
611     /**
612      * Fires the about to perform history event.
613      *
614      * @param monitor
615      * the progress monitor to use
616      *
617      * @return a status describing the outcome of the operation
618      */

619     private RefactoringStatus fireAboutToPerformHistory(final IProgressMonitor monitor) {
620         final RefactoringStatus status= new RefactoringStatus();
621         SafeRunner.run(new ISafeRunnable() {
622
623             public void handleException(final Throwable JavaDoc exception) {
624                 RefactoringUIPlugin.log(exception);
625                 status.addFatalError(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1);
626             }
627
628             public final void run() throws Exception JavaDoc {
629                 status.merge(aboutToPerformHistory(monitor));
630             }
631         });
632         return status;
633     }
634
635     /**
636      * Returns the error wizard page.
637      * <p>
638      * Note: This API must not be called from outside the refactoring framework.
639      * </p>
640      *
641      * @return the error wizard page
642      */

643     public final IErrorWizardPage getErrorPage() {
644         return fErrorPage;
645     }
646
647     /**
648      * {@inheritDoc}
649      */

650     public IWizardPage getNextPage(final IWizardPage page) {
651         if (page == fOverviewPage || page == fNoOverviewPage) {
652             fCurrentRefactoring= 0;
653             return getRefactoringPage();
654         } else if (page == fPreviewPage) {
655             fCurrentRefactoring++;
656             return getRefactoringPage();
657         } else if (page == fErrorPage) {
658             final RefactoringStatus status= fErrorPage.getStatus();
659             final IWizardContainer wizard= getContainer();
660             if (status.hasFatalError()) {
661                 final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
662                 String JavaDoc message= null;
663                 String JavaDoc key= null;
664                 if (!RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title.equals(fErrorPage.getTitle())) {
665                     message= Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_fatal_error_message, fErrorPage.getTitle());
666                     key= PREFERENCE_DO_NOT_SHOW_SKIP;
667                 } else {
668                     message= RefactoringUIMessages.RefactoringHistoryWizard_error_applying_changes;
669                     key= PREFERENCE_DO_NOT_SHOW_APPLY_ERROR;
670                 }
671                 if (!store.getBoolean(key)) {
672                     final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), wizard.getShell().getText(), null, message, MessageDialog.INFORMATION, new String JavaDoc[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
673                     dialog.open();
674                     store.setValue(key, dialog.getToggleState());
675                     if (dialog.getReturnCode() == 1)
676                         return null;
677                 }
678                 fCurrentRefactoring++;
679                 return getRefactoringPage();
680             }
681             final Refactoring refactoring= fErrorPage.getRefactoring();
682             if (refactoring != null) {
683                 final IRunnableWithProgress runnable= new IRunnableWithProgress() {
684
685                     public void run(final IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
686                         Assert.isNotNull(monitor);
687                         try {
688                             fPreviewPage.setRefactoring(refactoring);
689                             final Change change= createChange(refactoring, monitor);
690                             getShell().getDisplay().syncExec(new Runnable JavaDoc() {
691
692                                 public final void run() {
693                                     fPreviewPage.setChange(change);
694                                 }
695                             });
696                         } catch (CoreException exception) {
697                             throw new InvocationTargetException JavaDoc(exception);
698                         } catch (OperationCanceledException exception) {
699                             throw new InterruptedException JavaDoc(exception.getLocalizedMessage());
700                         } finally {
701                             monitor.done();
702                         }
703                     }
704                 };
705                 try {
706                     wizard.run(true, false, runnable);
707                 } catch (InvocationTargetException JavaDoc exception) {
708                     final Throwable JavaDoc throwable= exception.getTargetException();
709                     if (throwable != null) {
710                         RefactoringUIPlugin.log(exception);
711                         fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1));
712                         return fErrorPage;
713                     }
714                 } catch (InterruptedException JavaDoc exception) {
715                     return fErrorPage;
716                 }
717             } else {
718                 fPreviewPage.setRefactoring(null);
719                 fPreviewPage.setChange(null);
720             }
721             final RefactoringDescriptorProxy descriptor= getRefactoringDescriptor();
722             if (descriptor != null)
723                 fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
724             else
725                 fPreviewPage.setTitle(RefactoringUIMessages.PreviewWizardPage_changes);
726             fPreviewPage.setStatus(status);
727             fPreviewPage.setNextPageDisabled(isLastRefactoring());
728             return fPreviewPage;
729         }
730         return super.getNextPage(page);
731     }
732
733     /**
734      * Returns the preview wizard page.
735      * <p>
736      * Note: This API must not be called from outside the refactoring framework.
737      * </p>
738      *
739      * @return the preview wizard page
740      */

741     public final IPreviewWizardPage getPreviewPage() {
742         return fPreviewPage;
743     }
744
745     /**
746      * {@inheritDoc}
747      */

748     public IWizardPage getPreviousPage(final IWizardPage page) {
749         if (page == fErrorPage || page == fPreviewPage)
750             return null;
751         return super.getPreviousPage(page);
752     }
753
754     /**
755      * Returns the refactoring descriptor of the current refactoring.
756      *
757      * @return the refactoring descriptor, or <code>null</code>
758      */

759     private RefactoringDescriptorProxy getRefactoringDescriptor() {
760         final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
761         if (fCurrentRefactoring >= 0 && fCurrentRefactoring < proxies.length)
762             return proxies[fCurrentRefactoring];
763         return null;
764     }
765
766     /**
767      * Returns the refactoring descriptors in their order of execution.
768      *
769      * @return the refactoring descriptors
770      */

771     private RefactoringDescriptorProxy[] getRefactoringDescriptors() {
772         if (fDescriptorProxies == null) {
773             final RefactoringDescriptorProxy[] proxies= fRefactoringHistory.getDescriptors();
774             final RefactoringDescriptorProxy[] result= new RefactoringDescriptorProxy[proxies.length];
775             System.arraycopy(proxies, 0, result, 0, proxies.length);
776             RefactoringHistoryManager.sortRefactoringDescriptorsAscending(result);
777             fDescriptorProxies= result;
778         }
779         return fDescriptorProxies;
780     }
781
782     /**
783      * Returns the first page of a refactoring.
784      *
785      * @return the first page, or <code>null</code>
786      */

787     private IWizardPage getRefactoringPage() {
788         final IWizardPage[] result= { null};
789         final RefactoringStatus status= new RefactoringStatus();
790         final IWizardContainer wizard= getContainer();
791         final IRunnableWithProgress runnable= new IRunnableWithProgress() {
792
793             public void run(final IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
794                 Assert.isNotNull(monitor);
795                 try {
796                     monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactoring, 220);
797                     result[0]= null;
798                     if (!fAboutToPerformFired) {
799                         try {
800                             status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)));
801                         } finally {
802                             fAboutToPerformFired= true;
803                         }
804                     }
805                     final boolean last= isLastRefactoring();
806                     final RefactoringDescriptorProxy proxy= getRefactoringDescriptor();
807                     preparePreviewPage(status, proxy, last);
808                     prepareErrorPage(status, proxy, status.hasFatalError(), last || status.hasFatalError());
809                     fErrorPage.setRefactoring(null);
810                     if (!status.isOK()) {
811                         result[0]= fErrorPage;
812                     } else if (proxy != null) {
813                         final IRefactoringHistoryService service= RefactoringCore.getHistoryService();
814                         try {
815                             service.connect();
816                             final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
817                             if (descriptor != null) {
818                                 final Refactoring refactoring= createRefactoring(descriptor, status, new SubProgressMonitor(monitor, 60, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
819                                 if (refactoring != null && status.isOK()) {
820                                     fPreviewPage.setRefactoring(refactoring);
821                                     fErrorPage.setRefactoring(refactoring);
822                                     status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.INITIAL_CONDITONS));
823                                     if (!status.isOK()) {
824                                         prepareErrorPage(status, proxy, status.hasFatalError(), last);
825                                         result[0]= fErrorPage;
826                                     } else {
827                                         status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 65, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.FINAL_CONDITIONS));
828                                         if (!status.isOK()) {
829                                             prepareErrorPage(status, proxy, status.hasFatalError(), last);
830                                             result[0]= fErrorPage;
831                                         } else {
832                                             final Change change= createChange(refactoring, new SubProgressMonitor(monitor, 5, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
833                                             getShell().getDisplay().syncExec(new Runnable JavaDoc() {
834
835                                                 public final void run() {
836                                                     fPreviewPage.setChange(change);
837                                                 }
838                                             });
839                                             result[0]= fPreviewPage;
840                                         }
841                                     }
842                                 } else {
843                                     prepareErrorPage(status, proxy, status.hasFatalError(), last);
844                                     result[0]= fErrorPage;
845                                 }
846                             } else {
847                                 status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_error_resolving_refactoring));
848                                 prepareErrorPage(status, proxy, status.hasFatalError(), last);
849                                 result[0]= fErrorPage;
850                             }
851                         } finally {
852                             service.disconnect();
853                         }
854                     } else {
855                         prepareErrorPage(status, proxy, status.hasFatalError(), last);
856                         result[0]= fErrorPage;
857                     }
858                 } catch (CoreException exception) {
859                     throw new InvocationTargetException JavaDoc(exception);
860                 } catch (OperationCanceledException exception) {
861                     throw new InterruptedException JavaDoc(exception.getLocalizedMessage());
862                 } finally {
863                     monitor.done();
864                 }
865             }
866         };
867         try {
868             wizard.run(true, false, runnable);
869         } catch (InvocationTargetException JavaDoc exception) {
870             RefactoringUIPlugin.log(exception);
871             final Throwable JavaDoc throwable= exception.getTargetException();
872             if (throwable != null) {
873                 fErrorPage.setNextPageDisabled(isLastRefactoring());
874                 fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1));
875                 result[0]= fErrorPage;
876             }
877         } catch (InterruptedException JavaDoc exception) {
878             // Stay on same page
879
result[0]= null;
880         }
881         getContainer().updateButtons();
882         return result[0];
883     }
884
885     /**
886      * Hook method which is called when all refactorings of the history have
887      * been executed. This method may be called from non-UI threads.
888      * <p>
889      * This method is guaranteed to be called exactly once during the lifetime
890      * of a refactoring history wizard. It is not guaranteed that the user
891      * interface has not already been disposed of. The default implementation
892      * does nothing and returns a refactoring status of severity
893      * {@link RefactoringStatus#OK}.
894      * </p>
895      * <p>
896      * Subclasses may reimplement this method to perform any special processing.
897      * </p>
898      *
899      * @param monitor
900      * the progress monitor to use
901      *
902      * @return a status describing the outcome of the operation
903      */

904     protected RefactoringStatus historyPerformed(final IProgressMonitor monitor) {
905         Assert.isNotNull(monitor);
906         return new RefactoringStatus();
907     }
908
909     /**
910      * Is the current refactoring the last one?
911      *
912      * @return <code>true</code> if it is the last one, <code>false</code>
913      * otherwise
914      */

915     private boolean isLastRefactoring() {
916         return fCurrentRefactoring >= getRefactoringDescriptors().length - 1;
917     }
918
919     /**
920      * Is the current refactoring the second last one?
921      *
922      * @return <code>true</code> if it is the second last one,
923      * <code>false</code> otherwise
924      */

925     private boolean isSecondLastRefactoring() {
926         return fCurrentRefactoring >= getRefactoringDescriptors().length - 2;
927     }
928
929     /**
930      * {@inheritDoc}
931      */

932     public boolean performCancel() {
933         if (fExecutedRefactorings > 0 && !fCancelException) {
934             final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
935             if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL)) {
936                 final MessageFormat format= new MessageFormat(RefactoringUIMessages.RefactoringHistoryWizard_undo_message_pattern);
937                 final String JavaDoc message= RefactoringUIMessages.RefactoringHistoryWizard_undo_message_explanation;
938                 final String JavaDoc[] messages= { RefactoringUIMessages.RefactoringHistoryWizard_one_refactoring_undone + message, RefactoringUIMessages.RefactoringHistoryWizard_several_refactorings_undone + message};
939                 final ChoiceFormat JavaDoc choice= new ChoiceFormat JavaDoc(new double[] { 1, Double.MAX_VALUE}, messages);
940                 format.setFormatByArgumentIndex(0, choice);
941                 final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), getShell().getText(), null, format.format(new Object JavaDoc[] { new Integer JavaDoc(fExecutedRefactorings)}), MessageDialog.INFORMATION, new String JavaDoc[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
942                 dialog.open();
943                 store.setValue(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL, dialog.getToggleState());
944                 if (dialog.getReturnCode() == 1)
945                     return false;
946             }
947             final IRunnableWithProgress runnable= new IRunnableWithProgress() {
948
949                 public final void run(final IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
950                     for (int index= 0; index < fExecutedRefactorings; index++) {
951                         try {
952                             RefactoringCore.getUndoManager().performUndo(null, new SubProgressMonitor(monitor, 100));
953                             if (fExecutedRefactorings > 0)
954                                 fExecutedRefactorings--;
955                         } catch (CoreException exception) {
956                             throw new InvocationTargetException JavaDoc(exception);
957                         }
958                     }
959                 }
960             };
961             try {
962                 getContainer().run(false, false, runnable);
963             } catch (InvocationTargetException JavaDoc exception) {
964                 RefactoringUIPlugin.log(exception);
965                 fCancelException= true;
966                 fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_internal_error));
967                 fErrorPage.setNextPageDisabled(true);
968                 fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_title);
969                 fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_description);
970                 getContainer().showPage(fErrorPage);
971                 return false;
972             } catch (InterruptedException JavaDoc exception) {
973                 // Does not happen
974
}
975         }
976         return super.performCancel();
977     }
978
979     /**
980      * {@inheritDoc}
981      */

982     public boolean performFinish() {
983         if (fHeadlessErrorStatus)
984             return true;
985         if (fOverviewPage != null)
986             fOverviewPage.performFinish();
987         final IWizardContainer wizard= getContainer();
988         final RefactoringStatus status= new RefactoringStatus();
989         final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
990         final List JavaDoc list= new ArrayList JavaDoc(proxies.length);
991         for (int index= fCurrentRefactoring; index < proxies.length; index++)
992             list.add(proxies[index]);
993         final RefactoringDescriptorProxy[] descriptors= new RefactoringDescriptorProxy[list.size()];
994         list.toArray(descriptors);
995         final boolean last= isLastRefactoring();
996         if (wizard.getCurrentPage() == fPreviewPage && last) {
997             final Refactoring refactoring= fPreviewPage.getRefactoring();
998             final Change change= fPreviewPage.getChange();
999             if (refactoring != null && change != null) {
1000                status.merge(performPreviewChange(change, refactoring));
1001                if (!status.isOK()) {
1002                    final RefactoringStatusEntry entry= status.getEntryWithHighestSeverity();
1003                    if (entry.getSeverity() == RefactoringStatus.INFO && entry.getCode() == RefactoringHistoryWizard.STATUS_CODE_INTERRUPTED)
1004                        return false;
1005                    fErrorPage.setStatus(status);
1006                    fErrorPage.setNextPageDisabled(true);
1007                    fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title);
1008                    fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error);
1009                    wizard.showPage(fErrorPage);
1010                    return false;
1011                }
1012            }
1013        } else {
1014            final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
1015            if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_FINISH) && proxies.length > 0) {
1016                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 JavaDoc[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
1017                dialog.open();
1018                store.setValue(PREFERENCE_DO_NOT_WARN_FINISH, dialog.getToggleState());
1019                if (dialog.getReturnCode() == IDialogConstants.CANCEL_ID)
1020                    return false;
1021            }
1022            final PerformRefactoringHistoryOperation operation= new PerformRefactoringHistoryOperation(new RefactoringHistoryImplementation(descriptors)) {
1023
1024                protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) {
1025                    final RefactoringStatus[] result= { new RefactoringStatus()};
1026                    SafeRunner.run(new ISafeRunnable() {
1027
1028                        public void handleException(final Throwable JavaDoc exception) {
1029                            RefactoringUIPlugin.log(exception);
1030                        }
1031
1032                        public final void run() throws Exception JavaDoc {
1033                            result[0]= RefactoringHistoryWizard.this.aboutToPerformRefactoring(refactoring, descriptor, monitor);
1034                        }
1035                    });
1036                    return result[0];
1037                }
1038
1039                protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus state) throws CoreException {
1040                    return RefactoringHistoryWizard.this.createRefactoring(descriptor, state);
1041                }
1042
1043                protected void refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) {
1044                    SafeRunner.run(new ISafeRunnable() {
1045
1046                        public void handleException(final Throwable JavaDoc exception) {
1047                            RefactoringUIPlugin.log(exception);
1048                        }
1049
1050                        public final void run() throws Exception JavaDoc {
1051                            RefactoringHistoryWizard.this.refactoringPerformed(refactoring, monitor);
1052                        }
1053                    });
1054                }
1055
1056                public void run(final IProgressMonitor monitor) throws CoreException {
1057                    try {
1058                        monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactorings, 100);
1059                        if (!fAboutToPerformFired) {
1060                            try {
1061                                status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)));
1062                            } finally {
1063                                fAboutToPerformFired= true;
1064                            }
1065                        }
1066                        if (!status.isOK()) {
1067                            final int severity= status.getSeverity();
1068                            throw new CoreException(new Status(severity != RefactoringStatus.FATAL ? severity : IStatus.ERROR, RefactoringUIPlugin.getPluginId(), 0, null, null));
1069                        }
1070                        super.run(new SubProgressMonitor(monitor, 80, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
1071                    } finally {
1072                        monitor.done();
1073                    }
1074                }
1075            };
1076            try {
1077                wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot()));
1078            } catch (InvocationTargetException JavaDoc exception) {
1079                RefactoringUIPlugin.log(exception);
1080                final Throwable JavaDoc throwable= exception.getTargetException();
1081                if (throwable != null) {
1082                    final String JavaDoc message= throwable.getLocalizedMessage();
1083                    if (message != null && !"".equals(message)) //$NON-NLS-1$
1084
status.merge(RefactoringStatus.createFatalErrorStatus(message));
1085                    fErrorPage.setStatus(status);
1086                    fErrorPage.setNextPageDisabled(status.hasFatalError());
1087                    fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title);
1088                    fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error);
1089                    wizard.showPage(fErrorPage);
1090                    return false;
1091                }
1092            } catch (InterruptedException JavaDoc exception) {
1093                // Does not happen
1094
}
1095            final RefactoringStatus result= operation.getExecutionStatus();
1096            if (!result.isOK()) {
1097                fHeadlessErrorStatus= true;
1098                fErrorPage.setStatus(result);
1099                fErrorPage.setNextPageDisabled(true);
1100                fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_title);
1101                fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_description);
1102                wizard.showPage(fErrorPage);
1103                return false;
1104            }
1105        }
1106        return true;
1107    }
1108
1109    /**
1110     * Performs the change previously displayed in the preview.
1111     * <p>
1112     * Note: This API must not be called from outside the refactoring framework.
1113     * </p>
1114     *
1115     * @param change
1116     * the change displayed in the preview
1117     * @param refactoring
1118     * the associated refactoring
1119     * @return the status of the operation, already handled by the user
1120     */

1121    public final RefactoringStatus performPreviewChange(final Change change, final Refactoring refactoring) {
1122        Assert.isNotNull(change);
1123        Assert.isNotNull(refactoring);
1124        final UIPerformChangeOperation operation= new UIPerformChangeOperation(getShell().getDisplay(), change, getContainer()) {
1125
1126            public void run(final IProgressMonitor monitor) throws CoreException {
1127                try {
1128                    monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_changes, 12);
1129                    super.run(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
1130                    refactoringPerformed(refactoring, new SubProgressMonitor(monitor, 2, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
1131                } finally {
1132                    monitor.done();
1133                }
1134            }
1135        };
1136        final RefactoringStatus status= performPreviewChange(operation, refactoring);
1137        if (status.isOK())
1138            status.merge(operation.getValidationStatus());
1139        return status;
1140    }
1141
1142    /**
1143     * Performs the change previously displayed in the preview using the
1144     * specified change operation.
1145     *
1146     * @param operation
1147     * the change operation
1148     * @param refactoring
1149     * the associated refactoring
1150     * @return the status of the operation, already handled by the user
1151     */

1152    private RefactoringStatus performPreviewChange(final PerformChangeOperation operation, final Refactoring refactoring) {
1153        Assert.isNotNull(operation);
1154        Assert.isNotNull(refactoring);
1155        operation.setUndoManager(RefactoringCore.getUndoManager(), refactoring.getName());
1156        final IWizardContainer wizard= getContainer();
1157        final Shell shell= wizard.getShell();
1158        try {
1159            wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot()));
1160        } catch (InvocationTargetException JavaDoc exception) {
1161            final Throwable JavaDoc throwable= exception.getTargetException();
1162            if (operation.changeExecutionFailed()) {
1163                final Change change= operation.getChange();
1164                final ChangeExceptionHandler handler= new ChangeExceptionHandler(shell, refactoring);
1165                if (throwable instanceof RuntimeException JavaDoc)
1166                    handler.handle(change, (RuntimeException JavaDoc) throwable);
1167                else if (throwable instanceof CoreException)
1168                    handler.handle(change, (CoreException) throwable);
1169            }
1170            ExceptionHandler.handle(exception, shell, RefactoringUIMessages.RefactoringWizard_refactoring, RefactoringUIMessages.RefactoringWizard_unexpected_exception_1);
1171        } catch (InterruptedException JavaDoc exception) {
1172            return RefactoringStatus.create(new Status(IStatus.INFO, RefactoringUIPlugin.getPluginId(), STATUS_CODE_INTERRUPTED, exception.getLocalizedMessage(), exception));
1173        } finally {
1174            fPreviewPage.setNextPageDisabled(isSecondLastRefactoring());
1175            getContainer().updateButtons();
1176        }
1177        return new RefactoringStatus();
1178    }
1179
1180    /**
1181     * Prepares the error page to be displayed.
1182     *
1183     * @param status
1184     * the refactoring status
1185     * @param descriptor
1186     * the refactoring descriptor
1187     * @param fatal
1188     * <code>true</code> if the error is fatal, <code>false</code>
1189     * otherwise
1190     * @param disabled
1191     * <code>true</code> if the next page is disabled,
1192     * <code>false</code> otherwise
1193     */

1194    private void prepareErrorPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean fatal, final boolean disabled) {
1195        getShell().getDisplay().syncExec(new Runnable JavaDoc() {
1196
1197            public final void run() {
1198                fErrorPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
1199                fErrorPage.setNextPageDisabled(disabled && fatal);
1200                fErrorPage.setPageComplete(!fatal);
1201                fErrorPage.setStatus(null);
1202                fErrorPage.setStatus(status);
1203                getContainer().updateButtons();
1204            }
1205        });
1206    }
1207
1208    /**
1209     * Prepares the preview page to be displayed.
1210     *
1211     * @param status
1212     * the refactoring status
1213     * @param descriptor
1214     * the refactoring descriptor
1215     * @param disabled
1216     * <code>true</code> if the next page is disabled,
1217     * <code>false</code> otherwise
1218     */

1219    private void preparePreviewPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean disabled) {
1220        getShell().getDisplay().syncExec(new Runnable JavaDoc() {
1221
1222            public final void run() {
1223                fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
1224                fPreviewPage.setNextPageDisabled(disabled);
1225                fPreviewPage.setPageComplete(!disabled);
1226                fPreviewPage.setStatus(status);
1227                getContainer().updateButtons();
1228            }
1229        });
1230    }
1231
1232    /**
1233     * Hook method which is called when the specified refactoring has been
1234     * performed, e.g. its change object has been successfully applied to the
1235     * workspace. The default implementation does nothing and returns a
1236     * refactoring status of severity {@link RefactoringStatus#OK}. This method
1237     * may be called from non-UI threads.
1238     * <p>
1239     * Subclasses may reimplement this method to perform any special processing.
1240     * </p>
1241     * <p>
1242     * Returning a status of severity {@link RefactoringStatus#FATAL} will
1243     * terminate the execution of the refactorings.
1244     * </p>
1245     *
1246     * @param refactoring
1247     * the refactoring which has been performed
1248     * @param monitor
1249     * the progress monitor to use
1250     * @return a status describing the outcome of the operation
1251     */

1252    protected RefactoringStatus refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) {
1253        Assert.isNotNull(refactoring);
1254        Assert.isNotNull(monitor);
1255        fExecutedRefactorings++;
1256        return new RefactoringStatus();
1257    }
1258
1259    /**
1260     * Hook method which is called for each change before it is displayed in a
1261     * preview page. The default implementation returns <code>true</code>.
1262     * <p>
1263     * Subclasses may reimplement this method to perform any special filtering
1264     * of preview changes.
1265     * </p>
1266     *
1267     * @param change
1268     * the change to select
1269     * @return <code>true</code> if the change passes the filter,
1270     * <code>false</code> otherwise
1271     */

1272    protected boolean selectPreviewChange(final Change change) {
1273        return true;
1274    }
1275
1276    /**
1277     * Hook method which is called for each status entry before it is displayed
1278     * in a wizard page. The default implementation returns <code>true</code>.
1279     * <p>
1280     * Subclasses may reimplement this method to perform any special filtering
1281     * of status entries on error pages.
1282     * </p>
1283     *
1284     * @param entry
1285     * the status entry to select
1286     * @return <code>true</code> if the status entry passes the filter,
1287     * <code>false</code> otherwise
1288     */

1289    protected boolean selectStatusEntry(final RefactoringStatusEntry entry) {
1290        return true;
1291    }
1292
1293    /**
1294     * Sets the refactoring history control configuration.
1295     * <p>
1296     * This method must be called before opening the wizard in a dialog.
1297     * </p>
1298     *
1299     * @param configuration
1300     * the configuration to set
1301     */

1302    public final void setConfiguration(final RefactoringHistoryControlConfiguration configuration) {
1303        Assert.isNotNull(configuration);
1304        fControlConfiguration= configuration;
1305    }
1306
1307    /**
1308     * Sets the refactoring history.
1309     * <p>
1310     * This method must be called before opening the wizard in a dialog.
1311     * </p>
1312     *
1313     * @param history
1314     * the refactoring history
1315     */

1316    public final void setInput(final RefactoringHistory history) {
1317        Assert.isNotNull(history);
1318        fRefactoringHistory= history;
1319    }
1320}
1321
Popular Tags