Bug 347599: [refactoring] Provide a way to implement refactorings that
depend on resources that have to be explicitly released
diff --git a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
index 1113f4a..b76e89b 100644
--- a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.manipulation; singleton:=true
-Bundle-Version: 1.4.0.qualifier
+Bundle-Version: 1.5.0.qualifier
Bundle-Vendor: %providerName
Bundle-Activator: org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.ltk.core.refactoring;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.8.0,4.0.0)",
org.eclipse.core.expressions;bundle-version="[3.4.100,4.0.0)",
org.eclipse.text;bundle-version="[3.5.0,4.0.0)"
Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.ui.tests/examples/org/eclipse/jdt/ui/examples/TestMoveDescriptorAction.java b/org.eclipse.jdt.ui.tests/examples/org/eclipse/jdt/ui/examples/TestMoveDescriptorAction.java
index 2d8b2c8..1dd1d12 100644
--- a/org.eclipse.jdt.ui.tests/examples/org/eclipse/jdt/ui/examples/TestMoveDescriptorAction.java
+++ b/org.eclipse.jdt.ui.tests/examples/org/eclipse/jdt/ui/examples/TestMoveDescriptorAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -31,7 +31,7 @@
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation;
-import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringContribution;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
@@ -103,14 +103,11 @@
RefactoringStatus status= new RefactoringStatus();
- Refactoring refactoring= moveDes.createRefactoring(status);
- PerformRefactoringOperation op= new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
-
+ RefactoringContext context= moveDes.createRefactoringContext(status);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(context, CheckConditionsOperation.ALL_CONDITIONS);
op.run(monitor);
}
-
-
/* (non-Javadoc)
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
*/
diff --git a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/binary/BinaryRefactoringHistoryWizard.java b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/binary/BinaryRefactoringHistoryWizard.java
index f794e7b..9782f08 100644
--- a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/binary/BinaryRefactoringHistoryWizard.java
+++ b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/binary/BinaryRefactoringHistoryWizard.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
*******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring.binary;
@@ -38,6 +39,7 @@
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringContribution;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
@@ -485,7 +487,7 @@
* {@inheritDoc}
*/
@Override
- protected Refactoring createRefactoring(RefactoringDescriptor descriptor, RefactoringStatus status, IProgressMonitor monitor) throws CoreException {
+ protected RefactoringContext createRefactoringContext(RefactoringDescriptor descriptor, RefactoringStatus status, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(descriptor);
createNecessarySourceCode(monitor);
@@ -523,7 +525,7 @@
return null;
}
}
- return descriptor.createRefactoring(status);
+ return descriptor.createRefactoringContext(status);
}
/**
diff --git a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/AllTests.java b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/AllTests.java
index e523656..8e8e3f1 100644
--- a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/AllTests.java
+++ b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -22,6 +22,9 @@
public static Test suite() {
TestSuite suite= new TestSuite("All LTK Refactoring Core Tests"); //$NON-NLS-1$
+
+ suite.addTestSuite(RefactoringContextTest.class);
+
suite.addTest(ParticipantTests.suite());
suite.addTest(RefactoringHistoryTests.suite());
suite.addTest(RefactoringScriptingTests.suite());
diff --git a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/RefactoringContextTest.java b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/RefactoringContextTest.java
new file mode 100644
index 0000000..d9f6dc6
--- /dev/null
+++ b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/RefactoringContextTest.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ltk.core.refactoring.tests;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
+import org.eclipse.ltk.core.refactoring.NullChange;
+import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+
+
+public class RefactoringContextTest extends TestCase {
+
+ private static class TestRefactoring extends Refactoring {
+ RefactoringStatus fInitialConditionStatus= new RefactoringStatus();
+ RefactoringStatus fFinalConditionStatus= new RefactoringStatus();
+
+ public String getName() {
+ return "test Refactoring";
+ }
+
+ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ return fInitialConditionStatus;
+ }
+
+ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ return fFinalConditionStatus;
+ }
+
+ public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ return new NullChange();
+ }
+ }
+
+ private static class TestRefactoringContext extends RefactoringContext {
+ int fDisposeCalls;
+
+ public TestRefactoringContext(Refactoring refactoring) {
+ super(refactoring);
+ }
+
+ public void dispose() {
+ super.dispose();
+ fDisposeCalls++;
+ }
+ }
+
+
+ public void testDisposeNormal() throws Exception {
+ TestRefactoring ref= new TestRefactoring();
+ TestRefactoringContext context= new TestRefactoringContext(ref);
+
+ new PerformRefactoringOperation(context, CheckConditionsOperation.ALL_CONDITIONS).run(null);
+ assertEquals(1, context.fDisposeCalls);
+
+ try {
+ context.dispose();
+ } catch (IllegalStateException e) {
+ return; //expected
+ }
+ fail("dispose must not be called twice");
+ }
+
+ public void testDisposeInitialFailed() throws Exception {
+ TestRefactoring ref= new TestRefactoring();
+ ref.fInitialConditionStatus.addFatalError("fail");
+ TestRefactoringContext context= new TestRefactoringContext(ref);
+
+ new PerformRefactoringOperation(context, CheckConditionsOperation.ALL_CONDITIONS).run(null);
+ assertEquals(1, context.fDisposeCalls);
+ }
+
+ public void testDisposeFinalFailed() throws Exception {
+ TestRefactoring ref= new TestRefactoring();
+ ref.fFinalConditionStatus.addFatalError("fail");
+ TestRefactoringContext context= new TestRefactoringContext(ref);
+
+ new PerformRefactoringOperation(context, CheckConditionsOperation.ALL_CONDITIONS).run(null);
+ assertEquals(1, context.fDisposeCalls);
+ }
+
+ public void testDisposeChangeFailed() throws Exception {
+ TestRefactoring ref= new TestRefactoring() {
+ public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
+ throw new OperationCanceledException();
+ }
+ };
+ TestRefactoringContext context= new TestRefactoringContext(ref);
+
+ boolean cancelled= false;
+ try {
+ new PerformRefactoringOperation(context, CheckConditionsOperation.ALL_CONDITIONS).run(null);
+ } catch (OperationCanceledException e) {
+ cancelled= true;
+ }
+ assertTrue(cancelled);
+ assertEquals(1, context.fDisposeCalls);
+ }
+}
diff --git a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringTests.java b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringTests.java
index 22993e3..99a042a 100644
--- a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringTests.java
+++ b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringTests.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
*******************************************************************************/
package org.eclipse.ltk.core.refactoring.tests.resource;
@@ -35,6 +36,7 @@
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringContribution;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
@@ -302,14 +304,20 @@
private Change perform(RefactoringDescriptor descriptor) throws CoreException {
RefactoringStatus status= new RefactoringStatus();
- Refactoring refactoring= descriptor.createRefactoring(status);
- assertTrue(status.isOK());
+ final RefactoringContext context= descriptor.createRefactoringContext(status);
+ try {
+ final Refactoring refactoring= context != null ? context.getRefactoring() : null;
+ assertTrue(status.isOK());
- PerformRefactoringOperation op= new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
- op.run(null);
- RefactoringStatus validationStatus= op.getValidationStatus();
- assertTrue(!validationStatus.hasFatalError() && !validationStatus.hasError());
- return op.getUndoChange();
+ PerformRefactoringOperation op= new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
+ op.run(null);
+ RefactoringStatus validationStatus= op.getValidationStatus();
+ assertTrue(!validationStatus.hasFatalError() && !validationStatus.hasError());
+ return op.getUndoChange();
+ } finally {
+ if (context != null)
+ context.dispose();
+ }
}
private IResource assertMove(IResource source, IContainer destination, String content) throws CoreException, IOException {
diff --git a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringUndoTests.java b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringUndoTests.java
index f048c33..a57ab91 100644
--- a/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringUndoTests.java
+++ b/org.eclipse.ltk.core.refactoring.tests/src/org/eclipse/ltk/core/refactoring/tests/resource/ResourceRefactoringUndoTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2011 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
@@ -135,7 +135,7 @@
RenameResourceDescriptor desc= (RenameResourceDescriptor) renameContribution.createDescriptor();
desc.setResourcePath(testFile.getFullPath());
desc.setNewName(TEST_NEWFILE_NAME);
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FileSnapshot snap= new FileSnapshot(testFile);
execute(op);
@@ -160,7 +160,7 @@
RenameResourceDescriptor desc= (RenameResourceDescriptor) renameContribution.createDescriptor();
desc.setResourcePath(testFolder.getFullPath());
desc.setNewName(TEST_NEWFOLDER_NAME);
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FolderSnapshot snap= new FolderSnapshot(testFolder);
execute(op);
@@ -184,7 +184,7 @@
RenameResourceDescriptor desc= (RenameResourceDescriptor) renameContribution.createDescriptor();
desc.setResourcePath(fProject.getProject().getFullPath());
desc.setNewName(TEST_NEWPROJECT_NAME);
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
ProjectSnapshot snap= new ProjectSnapshot(fProject.getProject());
execute(op);
@@ -206,7 +206,7 @@
DeleteResourcesDescriptor desc= (DeleteResourcesDescriptor) renameContribution.createDescriptor();
desc.setResourcePaths(new IPath[] { testFile.getFullPath() });
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FileSnapshot snap= new FileSnapshot(testFile);
@@ -225,7 +225,7 @@
DeleteResourcesDescriptor desc= (DeleteResourcesDescriptor) renameContribution.createDescriptor();
desc.setResourcePaths(new IPath[] { testLinkedFile.getFullPath() });
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FileSnapshot snap= new FileSnapshot(testLinkedFile);
@@ -244,7 +244,7 @@
DeleteResourcesDescriptor desc= (DeleteResourcesDescriptor) renameContribution.createDescriptor();
desc.setResourcePaths(new IPath[] { testSubFolder.getFullPath() });
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FolderSnapshot snap= new FolderSnapshot(testSubFolder);
@@ -263,7 +263,7 @@
DeleteResourcesDescriptor desc= (DeleteResourcesDescriptor) renameContribution.createDescriptor();
desc.setResourcePaths(new IPath[] { testLinkedFolder.getFullPath() });
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
FolderSnapshot snap= new FolderSnapshot(testLinkedFolder);
execute(op);
@@ -280,7 +280,7 @@
DeleteResourcesDescriptor desc= (DeleteResourcesDescriptor) renameContribution.createDescriptor();
desc.setResourcePaths(new IPath[] { fProject.getProject().getFullPath() });
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
execute(op);
assertFalse("Project delete failed", fProject.getProject().exists());
@@ -312,7 +312,7 @@
desc.setResourcePaths(new IPath[] { fProject.getProject().getFullPath() });
desc.setDeleteContents(true);
- PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoring(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
+ PerformRefactoringOperation op= new PerformRefactoringOperation(desc.createRefactoringContext(new RefactoringStatus()), CheckConditionsOperation.ALL_CONDITIONS);
// we don't snapshot since CONTENT will be deleted
execute(op);
diff --git a/org.eclipse.ltk.core.refactoring/META-INF/MANIFEST.MF b/org.eclipse.ltk.core.refactoring/META-INF/MANIFEST.MF
index a1ba3e5..bf5fe3f 100644
--- a/org.eclipse.ltk.core.refactoring/META-INF/MANIFEST.MF
+++ b/org.eclipse.ltk.core.refactoring/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ltk.core.refactoring; singleton:=true
-Bundle-Version: 3.5.300.qualifier
+Bundle-Version: 3.6.0.qualifier
Bundle-Activator: org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringHistoryOperation.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringHistoryOperation.java
index 6adaf4b..ed9d9ec 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringHistoryOperation.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringHistoryOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
*******************************************************************************/
package org.eclipse.ltk.core.refactoring;
@@ -127,6 +128,7 @@
* if an error occurs while creating the refactoring instance
*
* @since 3.4
+ * @deprecated since 3.6. Override {@link #createRefactoringContext(RefactoringDescriptor, RefactoringStatus, IProgressMonitor)} instead
*/
protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
try {
@@ -140,6 +142,43 @@
}
/**
+ * Method which is called to create a refactoring context from a refactoring descriptor.
+ * The refactoring context must contain a refactoring in an initialized state at the return
+ * of the method call.
+ * <p>
+ * A caller of this method must ensure that {@link RefactoringContext#dispose()} is eventually called.
+ * </p>
+ *
+ * <p>
+ * The default implementation delegates the task to the refactoring descriptor.
+ * </p>
+ *
+ * @param descriptor
+ * the refactoring descriptor
+ * @param status
+ * a refactoring status to describe the outcome of the initialization
+ * @param monitor
+ * the progress monitor to use
+ * @return the refactoring context, 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 context
+ * @since 3.6
+ */
+ protected RefactoringContext createRefactoringContext(final RefactoringDescriptor descriptor,
+ final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
+ try {
+ Assert.isNotNull(descriptor);
+ return descriptor.createRefactoringContext(status);
+ } finally {
+ if (monitor != null) {
+ monitor.done();
+ }
+ }
+ }
+
+ /**
* Returns the execution status. Guaranteed not to be <code>null</code>.
*
* @return the status of the session
@@ -177,15 +216,16 @@
for (int index= 0; index < proxies.length; index++) {
final RefactoringDescriptor descriptor= proxies[index].requestDescriptor(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
if (descriptor != null) {
- Refactoring refactoring= null;
+ RefactoringContext context= null;
RefactoringStatus status= new RefactoringStatus();
try {
try {
- refactoring= createRefactoring(descriptor, status, new SubProgressMonitor(monitor, 30, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
+ context= createRefactoringContext(descriptor, status, new SubProgressMonitor(monitor, 30, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
} catch (CoreException exception) {
status.merge(RefactoringStatus.create(exception.getStatus()));
}
- if (refactoring != null && !status.hasFatalError()) {
+ if (context != null && !status.hasFatalError()) {
+ Refactoring refactoring= context.getRefactoring();
final PerformRefactoringOperation operation= new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
try {
status.merge(aboutToPerformRefactoring(refactoring, descriptor, new SubProgressMonitor(monitor, 30, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)));
@@ -201,6 +241,8 @@
}
} finally {
fExecutionStatus.merge(status);
+ if (context != null)
+ context.dispose();
}
}
}
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringOperation.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringOperation.java
index 04bb218..2ce139d 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringOperation.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/PerformRefactoringOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -39,6 +39,7 @@
public class PerformRefactoringOperation implements IWorkspaceRunnable {
private int fStyle;
+ private RefactoringContext fRefactoringContext;
private Refactoring fRefactoring;
private RefactoringStatus fPreconditionStatus;
@@ -53,6 +54,7 @@
* @param refactoring the refactoring to perform
* @param style the condition checking style as defined by
* {@link CheckConditionsOperation}
+ * @see #PerformRefactoringOperation(RefactoringContext, int)
*/
public PerformRefactoringOperation(Refactoring refactoring, int style) {
Assert.isNotNull(refactoring);
@@ -61,6 +63,27 @@
}
/**
+ * Create a new perform refactoring operation. The operation will not
+ * perform the refactoring if the refactoring's condition checking returns
+ * an error of severity {@link RefactoringStatus#FATAL}.
+ * <p>
+ * The caller must ensure that the operation is run exactly once. The implementation
+ * of {@link #run(IProgressMonitor)} will call {@link RefactoringContext#dispose()}.
+ * </p>
+ *
+ * @param refactoringContext the refactoring context to perform
+ * @param style the condition checking style as defined by
+ * {@link CheckConditionsOperation}
+ * @since 3.6
+ */
+ public PerformRefactoringOperation(RefactoringContext refactoringContext, int style) {
+ Assert.isNotNull(refactoringContext);
+ fRefactoringContext= refactoringContext;
+ fRefactoring= fRefactoringContext.getRefactoring();
+ fStyle= style;
+ }
+
+ /**
* Return the refactoring status of the condition checking.
*
* @return the refactoring status of the condition checking or <code>null</code>
@@ -95,23 +118,28 @@
* {@inheritDoc}
*/
public void run(IProgressMonitor monitor) throws CoreException {
- if (monitor == null)
- monitor= new NullProgressMonitor();
- monitor.beginTask("", 10); //$NON-NLS-1$
- final CreateChangeOperation create= new CreateChangeOperation(new CheckConditionsOperation(fRefactoring, fStyle), RefactoringStatus.FATAL);
- create.run(new SubProgressMonitor(monitor, 6));
- fPreconditionStatus= create.getConditionCheckingStatus();
- if (fPreconditionStatus.hasFatalError()) {
- monitor.done();
- return;
- }
- final Change change= create.getChange();
- if (change != null) {
- final PerformChangeOperation perform= new PerformChangeOperation(change);
- perform.setUndoManager(RefactoringCore.getUndoManager(), fRefactoring.getName());
- perform.run(new SubProgressMonitor(monitor, 2));
- fValidationStatus= perform.getValidationStatus();
- fUndo= perform.getUndoChange();
+ try {
+ if (monitor == null)
+ monitor= new NullProgressMonitor();
+ monitor.beginTask("", 10); //$NON-NLS-1$
+ final CreateChangeOperation create= new CreateChangeOperation(new CheckConditionsOperation(fRefactoring, fStyle), RefactoringStatus.FATAL);
+ create.run(new SubProgressMonitor(monitor, 6));
+ fPreconditionStatus= create.getConditionCheckingStatus();
+ if (fPreconditionStatus.hasFatalError()) {
+ monitor.done();
+ return;
+ }
+ final Change change= create.getChange();
+ if (change != null) {
+ final PerformChangeOperation perform= new PerformChangeOperation(change);
+ perform.setUndoManager(RefactoringCore.getUndoManager(), fRefactoring.getName());
+ perform.run(new SubProgressMonitor(monitor, 2));
+ fValidationStatus= perform.getValidationStatus();
+ fUndo= perform.getUndoChange();
+ }
+ } finally {
+ if (fRefactoringContext != null)
+ fRefactoringContext.dispose();
}
}
}
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/Refactoring.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/Refactoring.java
index 2263ac8..fde9a6d 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/Refactoring.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/Refactoring.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 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
@@ -60,6 +60,8 @@
* <p>
* The class should be subclassed by clients wishing to implement new refactorings.
* </p>
+ *
+ * @see RefactoringContext
*
* @since 3.0
*/
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringContext.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringContext.java
new file mode 100644
index 0000000..5b5cc12
--- /dev/null
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringContext.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Google, Inc 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:
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
+ * IBM Corporation - bug fixes
+ *******************************************************************************/
+package org.eclipse.ltk.core.refactoring;
+
+/**
+ * <p>
+ * Refactoring context is a disposable object that can be used by a refactoring to hold resources
+ * that have to be explicitly released. The refactoring context is guaranteed to receive
+ * a {@link #dispose()} call after the associated refactoring has finished or produced an error.
+ * At this point, the refactoring context must release all resources and detach all listeners.
+ * A refactoring context can only be disposed once; it cannot be reused.
+ * </p>
+ * <p>
+ * This class is intended to be subclassed by clients wishing to implement new refactorings that
+ * depend on resources that have to be explicitly released.
+ * </p>
+ * @since 3.6
+ */
+public class RefactoringContext {
+ private Refactoring fRefactoring;
+
+ /**
+ * Creates a context for the given refactoring.
+ *
+ * @param refactoring The refactoring associated with the context. Cannot be <code>null</code>.
+ * @throws NullPointerException if refactoring is <code>null</code>.
+ */
+ public RefactoringContext(Refactoring refactoring) {
+ if (refactoring == null)
+ throw new NullPointerException();
+ fRefactoring= refactoring;
+ }
+
+ /**
+ * Returns the refactoring associated with the context.
+ * <p>
+ * The returned refactoring must be in an initialized state, i.e. ready to
+ * be executed via {@link PerformRefactoringOperation}.
+ * </p>
+ * @return The refactoring associated with the context.
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+ public Refactoring getRefactoring() {
+ return fRefactoring;
+ }
+
+ /**
+ * Disposes of the context. This method will be called exactly once during the life cycle
+ * of the context after the associated refactoring has finished or produced an error.
+ * <p>
+ * Subclasses may extend this method (must call super).
+ * </p>
+ */
+ public void dispose() {
+ if (fRefactoring == null)
+ throw new IllegalStateException("dispose() called more than once."); //$NON-NLS-1$
+ fRefactoring= null;
+ }
+}
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringDescriptor.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringDescriptor.java
index 0491a1b..9f3ccbc 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringDescriptor.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/core/refactoring/RefactoringDescriptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
*******************************************************************************/
package org.eclipse.ltk.core.refactoring;
@@ -229,28 +230,57 @@
/**
* Creates the a new refactoring instance for this refactoring descriptor.
* <p>
- * This method is used by the refactoring framework to instantiate a
- * refactoring from a refactoring descriptor, in order to apply it later on
- * a local or remote workspace.
- * </p>
- * <p>
* The returned refactoring must be in an initialized state, i.e. ready to
* be executed via {@link PerformRefactoringOperation}.
* </p>
+ * <p>
+ * This method is not intended to be called directly from code that does not belong to this
+ * class and its subclasses. External code should call
+ * {@link #createRefactoringContext(RefactoringStatus)} and obtain the refactoring object from
+ * the refactoring context.
+ * </p>
*
* @param status
- * a refactoring status used to describe the outcome of the
- * initialization
+ * a refactoring status used to describe the outcome of the initialization
* @return the refactoring, or <code>null</code> if this refactoring
* descriptor represents the unknown refactoring, or if no
* refactoring contribution is available for this refactoring
* descriptor which is capable to create a refactoring
* @throws CoreException
- * if an error occurs while creating the refactoring instance
+ * if an error occurs while creating the refactoring instance
*/
public abstract Refactoring createRefactoring(RefactoringStatus status) throws CoreException;
/**
+ * Creates the a new refactoring context and the associated refactoring instance for this
+ * refactoring descriptor.
+ * <p>
+ * This method is used by the refactoring framework to instantiate a refactoring
+ * from a refactoring descriptor, in order to apply it later on a local or remote workspace.
+ * </p>
+ * <p>
+ * The default implementation of this method wraps the refactoring in a trivial refactoring
+ * context. Subclasses may override this method to create a custom refactoring context.
+ * </p>
+ *
+ * @param status
+ * a refactoring status used to describe the outcome of the initialization
+ * @return the refactoring context, or <code>null</code> if this refactoring
+ * descriptor represents the unknown refactoring, or if no
+ * refactoring contribution is available for this refactoring
+ * descriptor which is capable to create a refactoring.
+ * @throws CoreException
+ * if an error occurs while creating the refactoring context
+ * @since 3.6
+ */
+ public RefactoringContext createRefactoringContext(RefactoringStatus status) throws CoreException {
+ Refactoring refactoring= createRefactoring(status);
+ if (refactoring == null)
+ return null;
+ return new RefactoringContext(refactoring);
+ }
+
+ /**
* {@inheritDoc}
*/
public final boolean equals(final Object object) {
diff --git a/org.eclipse.ltk.ui.refactoring/META-INF/MANIFEST.MF b/org.eclipse.ltk.ui.refactoring/META-INF/MANIFEST.MF
index 6534a86..319d25f 100644
--- a/org.eclipse.ltk.ui.refactoring/META-INF/MANIFEST.MF
+++ b/org.eclipse.ltk.ui.refactoring/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ltk.ui.refactoring; singleton:=true
-Bundle-Version: 3.6.0.qualifier
+Bundle-Version: 3.7.0.qualifier
Bundle-Activator: org.eclipse.ltk.internal.ui.refactoring.RefactoringUIPlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
@@ -23,7 +23,7 @@
org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.ltk.core.refactoring;bundle-version="[3.6.0,4.0.0)",
org.eclipse.jface.text;bundle-version="[3.5.0,4.0.0)",
org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
org.eclipse.ui.navigator;bundle-version="[3.3.200,4.0.0)",
diff --git a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizard.java b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizard.java
index 5240388..99e122f 100644
--- a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizard.java
+++ b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizard.java
@@ -33,6 +33,7 @@
import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler;
@@ -154,6 +155,7 @@
private static final int LAST= 1 << 8;
private final int fFlags;
+ private final RefactoringContext fRefactoringContext;
private final Refactoring fRefactoring;
private String fDefaultPageTitle;
@@ -180,11 +182,31 @@
* taken as a default.
*/
public RefactoringWizard(Refactoring refactoring, int flags) {
+ this(null, refactoring, flags);
Assert.isNotNull(refactoring);
+ }
+
+ /**
+ * Creates a new refactoring wizard for the given refactoring context.
+ *
+ * @param refactoringContext the refactoringContext the wizard is presenting
+ * @param flags flags specifying the behavior of the wizard. If neither
+ * <code>WIZARD_BASED_USER_INTERFACE</code> nor <code>DIALOG_BASED_UESR_INTERFACE</code>
+ * is specified then <code>WIZARD_BASED_USER_INTERFACE</code> will be
+ * taken as a default.
+ * @since 3.7
+ */
+ public RefactoringWizard(RefactoringContext refactoringContext, int flags) {
+ this(refactoringContext, null, flags);
+ Assert.isNotNull(refactoringContext);
+ }
+
+ private RefactoringWizard(RefactoringContext refactoringContext, Refactoring refactoring, int flags) {
Assert.isTrue(flags < LAST);
if ((flags & DIALOG_BASED_USER_INTERFACE) == 0)
flags |= WIZARD_BASED_USER_INTERFACE;
Assert.isTrue((flags & DIALOG_BASED_USER_INTERFACE) != 0 || (flags & WIZARD_BASED_USER_INTERFACE) != 0);
+ fRefactoringContext= refactoringContext;
fRefactoring= refactoring;
fFlags= flags;
setNeedsProgressMonitor(true);
@@ -200,11 +222,21 @@
*
* @return the wizard's refactoring
*/
- public final Refactoring getRefactoring(){
+ public final Refactoring getRefactoring() {
return fRefactoring;
}
/**
+ * Returns the refactoring context this wizard is associated with, or <code>null</code> if none.
+ *
+ * @return the wizard's refactoring context or <code>null</code>
+ * @since 3.7
+ */
+ public final RefactoringContext getRefactoringContext() {
+ return fRefactoringContext;
+ }
+
+ /**
* Returns the refactoring wizard flags that have been set for this wizard.
* Note that the set of valid flags may grow in the future.
*
diff --git a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizardOpenOperation.java b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizardOpenOperation.java
index 3044fc8..c3a3836 100644
--- a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizardOpenOperation.java
+++ b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/RefactoringWizardOpenOperation.java
@@ -34,6 +34,7 @@
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.internal.ui.refactoring.ExceptionHandler;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
@@ -67,6 +68,11 @@
/**
* Creates a new refactoring wizard starter for the given wizard.
+ * <p>
+ * If the wizard was created via {@link RefactoringWizard#RefactoringWizard(RefactoringContext, int)},
+ * then this operation will also {@link RefactoringContext#dispose() dispose} of the context
+ * at the end of all <code>run</code> methods.
+ * </p>
*
* @param wizard the wizard to open a dialog for
*/
@@ -187,6 +193,9 @@
} finally {
manager.endRule(ResourcesPlugin.getWorkspace().getRoot());
refactoring.setValidationContext(null);
+ RefactoringContext refactoringContext= fWizard.getRefactoringContext();
+ if (refactoringContext != null)
+ refactoringContext.dispose();
}
}
};
diff --git a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/history/RefactoringHistoryWizard.java b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/history/RefactoringHistoryWizard.java
index c00fe40..26cc07f 100644
--- a/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/history/RefactoringHistoryWizard.java
+++ b/org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/ui/refactoring/history/RefactoringHistoryWizard.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Sergey Prigogin <eclipse.sprigogin@gmail.com> - [refactoring] Provide a way to implement refactorings that depend on resources that have to be explicitly released - https://bugs.eclipse.org/347599
*******************************************************************************/
package org.eclipse.ltk.ui.refactoring.history;
@@ -57,6 +58,7 @@
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.RefactoringContext;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
@@ -553,6 +555,7 @@
* descriptor
* @throws CoreException
* if an error occurs while creating the refactoring instance
+ * @deprecated since 3.6. Override {@link #createRefactoringContext(RefactoringDescriptor, RefactoringStatus, IProgressMonitor)} instead
*/
protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status) throws CoreException {
Assert.isNotNull(descriptor);
@@ -581,6 +584,7 @@
* if an error occurs while creating the refactoring instance
*
* @since 3.4
+ * @deprecated since 3.7. Override {@link #createRefactoringContext(RefactoringDescriptor, RefactoringStatus, IProgressMonitor)} instead
*/
protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
final Refactoring refactoring= createRefactoring(descriptor, status);
@@ -594,6 +598,43 @@
}
/**
+ * Creates a refactoring context from the specified refactoring descriptor.
+ * <p>
+ * The default implementation calls
+ * {@link RefactoringDescriptor#createRefactoringContext(RefactoringStatus)} followed by
+ * {@link #aboutToPerformRefactoring(Refactoring, RefactoringDescriptor, IProgressMonitor)}.
+ * Implementors can replace this implementation.
+ * </p>
+ *
+ * @param descriptor
+ * the refactoring descriptor
+ * @param status
+ * the refactoring status
+ * @param monitor
+ * the progress monitor to use
+ * @return the refactoring context, 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 context
+ *
+ * @since 3.7
+ */
+ protected RefactoringContext createRefactoringContext(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
+ Assert.isNotNull(descriptor);
+ final RefactoringContext context= descriptor.createRefactoringContext(status);
+ if (context != null) {
+ final Refactoring refactoring= context.getRefactoring();
+ status.merge(aboutToPerformRefactoring(refactoring, descriptor, monitor));
+ if (!status.hasFatalError())
+ return context;
+ } else {
+ status.addFatalError(Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_error_instantiate_refactoring, descriptor.getDescription()));
+ }
+ return null;
+ }
+
+ /**
* {@inheritDoc}
*/
public void dispose() {
@@ -825,33 +866,39 @@
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));
+ final RefactoringContext context= createRefactoringContext(descriptor, status, new SubProgressMonitor(monitor, 60, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
+ try {
+ if (context != null && status.isOK()) {
+ final Refactoring refactoring= context.getRefactoring();
+ 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 {
- 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;
+ 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 {
- prepareErrorPage(status, proxy, status.hasFatalError(), last);
- result[0]= fErrorPage;
+ } finally {
+ if (context != null)
+ context.dispose();
}
} else {
status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_error_resolving_refactoring));
@@ -1031,8 +1078,8 @@
}
final PerformRefactoringHistoryOperation operation= new PerformRefactoringHistoryOperation(new RefactoringHistoryImplementation(descriptors)) {
- protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus state, IProgressMonitor monitor) throws CoreException {
- return RefactoringHistoryWizard.this.createRefactoring(descriptor, state, monitor);
+ protected RefactoringContext createRefactoringContext(final RefactoringDescriptor descriptor, final RefactoringStatus state, IProgressMonitor monitor) throws CoreException {
+ return RefactoringHistoryWizard.this.createRefactoringContext(descriptor, state, monitor);
}
protected void refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) {