KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > refactoring > RefactoringExecutionHelper


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.jdt.internal.ui.refactoring;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14
15 import org.eclipse.core.runtime.Assert;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.OperationCanceledException;
19 import org.eclipse.core.runtime.SubProgressMonitor;
20 import org.eclipse.core.runtime.jobs.IJobManager;
21 import org.eclipse.core.runtime.jobs.ISchedulingRule;
22 import org.eclipse.core.runtime.jobs.Job;
23
24 import org.eclipse.core.resources.IWorkspaceRunnable;
25 import org.eclipse.core.resources.ResourcesPlugin;
26
27 import org.eclipse.swt.custom.BusyIndicator;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.Shell;
30
31 import org.eclipse.jface.dialogs.Dialog;
32 import org.eclipse.jface.dialogs.IDialogConstants;
33 import org.eclipse.jface.dialogs.MessageDialog;
34 import org.eclipse.jface.operation.IRunnableContext;
35 import org.eclipse.jface.operation.IThreadListener;
36
37 import org.eclipse.ltk.core.refactoring.Change;
38 import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
39 import org.eclipse.ltk.core.refactoring.Refactoring;
40 import org.eclipse.ltk.core.refactoring.RefactoringCore;
41 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
42 import org.eclipse.ltk.ui.refactoring.RefactoringUI;
43
44 import org.eclipse.jdt.internal.corext.util.Messages;
45
46 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
47
48 /**
49  * A helper class to execute a refactoring. The class takes care of pushing the
50  * undo change onto the undo stack and folding editor edits into one editor
51  * undo object.
52  */

53 public class RefactoringExecutionHelper {
54
55     private final Refactoring fRefactoring;
56     private final Shell fParent;
57     private final IRunnableContext fExecContext;
58     private final int fStopSeverity;
59     private final int fSaveMode;
60
61     private class Operation implements IWorkspaceRunnable {
62         public Change fChange;
63         public PerformChangeOperation fPerformChangeOperation;
64         private final boolean fForked;
65         
66         public Operation(boolean forked) {
67             fForked= forked;
68         }
69         
70         public void run(IProgressMonitor pm) throws CoreException {
71             try {
72                 pm.beginTask("", fForked ? 7 : 11); //$NON-NLS-1$
73
pm.subTask(""); //$NON-NLS-1$
74

75                 final RefactoringStatus status= fRefactoring.checkAllConditions(new SubProgressMonitor(pm, 4, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
76                 if (status.getSeverity() >= fStopSeverity) {
77                     final boolean[] canceled= { false };
78                     if (fForked) {
79                         fParent.getDisplay().syncExec(new Runnable JavaDoc() {
80                             public void run() {
81                                 canceled[0]= showStatusDialog(status);
82                             }
83                         });
84                     } else {
85                         canceled[0]= showStatusDialog(status);
86                     }
87                     if (canceled[0]) {
88                         throw new OperationCanceledException();
89                     }
90                 }
91
92                 fChange= fRefactoring.createChange(new SubProgressMonitor(pm, 2, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
93                 fChange.initializeValidationData(new SubProgressMonitor(pm, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
94                 
95                 fPerformChangeOperation= RefactoringUI.createUIAwareChangeOperation(fChange);
96                 fPerformChangeOperation.setUndoManager(RefactoringCore.getUndoManager(), fRefactoring.getName());
97                 if (fRefactoring instanceof IScheduledRefactoring)
98                     fPerformChangeOperation.setSchedulingRule(((IScheduledRefactoring)fRefactoring).getSchedulingRule());
99                 
100                 if (! fForked)
101                     fPerformChangeOperation.run(new SubProgressMonitor(pm, 4, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
102             } finally {
103                 pm.done();
104             }
105         }
106
107         /**
108          * @param status the status to show
109          * @return <code>true</code> iff the operation should be cancelled
110          */

111         private boolean showStatusDialog(RefactoringStatus status) {
112             Dialog dialog= RefactoringUI.createRefactoringStatusDialog(status, fParent, fRefactoring.getName(), false);
113             return dialog.open() == IDialogConstants.CANCEL_ID;
114         }
115     }
116     
117     /**
118      * @param refactoring
119      * @param stopSeverity a refactoring status constant from {@link RefactoringStatus}
120      * @param saveMode a save mode from {@link RefactoringSaveHelper}
121      * @param parent
122      * @param context
123      */

124     public RefactoringExecutionHelper(Refactoring refactoring, int stopSeverity, int saveMode, Shell parent, IRunnableContext context) {
125         super();
126         Assert.isNotNull(refactoring);
127         Assert.isNotNull(parent);
128         Assert.isNotNull(context);
129         fRefactoring= refactoring;
130         fStopSeverity= stopSeverity;
131         fParent= parent;
132         fExecContext= context;
133         fSaveMode= saveMode;
134     }
135     
136     /**
137      * Must be called in the UI thread.
138      * @param fork if set, the operation will be forked
139      * @param cancelable if set, the operation will be cancellable
140      * @throws InterruptedException thrown when the operation is cancelled
141      * @throws InvocationTargetException thrown when the operation failed to execute
142      */

143     public void perform(boolean fork, boolean cancelable) throws InterruptedException JavaDoc, InvocationTargetException JavaDoc {
144         Assert.isTrue(Display.getCurrent() != null);
145         final IJobManager manager= Job.getJobManager();
146         final ISchedulingRule rule;
147         if (fRefactoring instanceof IScheduledRefactoring) {
148             rule= ((IScheduledRefactoring)fRefactoring).getSchedulingRule();
149         } else {
150             rule= ResourcesPlugin.getWorkspace().getRoot();
151         }
152         class OperationRunner extends WorkbenchRunnableAdapter implements IThreadListener {
153             public OperationRunner(IWorkspaceRunnable runnable, ISchedulingRule schedulingRule) {
154                 super(runnable, schedulingRule);
155             }
156             public void threadChange(Thread JavaDoc thread) {
157                 manager.transferRule(getSchedulingRule(), thread);
158             }
159         }
160         try {
161             try {
162                 Runnable JavaDoc r= new Runnable JavaDoc() {
163                     public void run() {
164                         manager.beginRule(rule, null);
165                     }
166                 };
167                 BusyIndicator.showWhile(fParent.getDisplay(), r);
168             } catch (OperationCanceledException e) {
169                 throw new InterruptedException JavaDoc(e.getMessage());
170             }
171             
172             RefactoringSaveHelper saveHelper= new RefactoringSaveHelper(fSaveMode);
173             if (!saveHelper.saveEditors(fParent))
174                 throw new InterruptedException JavaDoc();
175             final Operation op= new Operation(fork);
176             fRefactoring.setValidationContext(fParent);
177             try{
178                 fExecContext.run(fork, cancelable, new OperationRunner(op, rule));
179                 if (fork && op.fPerformChangeOperation != null)
180                     fExecContext.run(false, false, new OperationRunner(op.fPerformChangeOperation, rule));
181
182                 if (op.fPerformChangeOperation != null) {
183                     RefactoringStatus validationStatus= op.fPerformChangeOperation.getValidationStatus();
184                     if (validationStatus != null && validationStatus.hasFatalError()) {
185                         MessageDialog.openError(fParent, fRefactoring.getName(),
186                                 Messages.format(
187                                         RefactoringMessages.RefactoringExecutionHelper_cannot_execute,
188                                         validationStatus.getMessageMatchingSeverity(RefactoringStatus.FATAL)));
189                         return;
190                     }
191                 }
192             } catch (InvocationTargetException JavaDoc e) {
193                 PerformChangeOperation pco= op.fPerformChangeOperation;
194                 if (pco != null && pco.changeExecutionFailed()) {
195                     ChangeExceptionHandler handler= new ChangeExceptionHandler(fParent, fRefactoring);
196                     Throwable JavaDoc inner= e.getTargetException();
197                     if (inner instanceof RuntimeException JavaDoc) {
198                         handler.handle(pco.getChange(), (RuntimeException JavaDoc)inner);
199                     } else if (inner instanceof CoreException) {
200                         handler.handle(pco.getChange(), (CoreException)inner);
201                     } else {
202                         throw e;
203                     }
204                 } else {
205                     throw e;
206                 }
207             } catch (OperationCanceledException e) {
208                 throw new InterruptedException JavaDoc(e.getMessage());
209             } finally {
210                 saveHelper.triggerBuild();
211             }
212         } finally {
213             manager.endRule(rule);
214             fRefactoring.setValidationContext(null);
215         }
216     }
217 }
218
Popular Tags