1 /*******************************************************************************
2  * Copyright (c) 2005, 2014 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.debug.tests.refactoring;
15 
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IFolder;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.ResourcesPlugin;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.NullProgressMonitor;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.jdt.core.IJavaProject;
26 import org.eclipse.jdt.core.IPackageFragment;
27 import org.eclipse.jdt.core.IPackageFragmentRoot;
28 import org.eclipse.jdt.core.search.IJavaSearchConstants;
29 import org.eclipse.jdt.core.search.IJavaSearchScope;
30 import org.eclipse.jdt.core.search.SearchEngine;
31 import org.eclipse.jdt.core.search.SearchPattern;
32 import org.eclipse.jdt.core.search.TypeNameRequestor;
33 import org.eclipse.jdt.debug.tests.AbstractDebugTest;
34 import org.eclipse.jdt.debug.tests.TestAgainException;
35 import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
36 import org.eclipse.ltk.core.refactoring.PerformRefactoringOperation;
37 import org.eclipse.ltk.core.refactoring.Refactoring;
38 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
39 
40 /**
41  * Common refactoring utils.
42  *
43  * @since 3.2
44  */
45 public class AbstractRefactoringDebugTest extends AbstractDebugTest {
46 
AbstractRefactoringDebugTest(String name)47 	public AbstractRefactoringDebugTest(String name) {
48 		super(name);
49 	}
50 
51 	/* (non-Javadoc)
52 	 * @see org.eclipse.jdt.debug.tests.AbstractDebugTest#setUp()
53 	 */
54 	@Override
setUp()55 	protected void setUp() throws Exception {
56 		super.setUp();
57 		cleanTestFiles();
58 	}
59 
60 	/**
61 	 * Performs the given refactoring. If a {@link CoreException} occurs during the refactoring, we trap it and throw a {@link TestAgainException} to
62 	 * try the test again.
63 	 *
64 	 * @param refactoring
65 	 * @throws Exception
66 	 */
performRefactor(final Refactoring refactoring)67 	public void performRefactor(final Refactoring refactoring) throws Exception {
68 		if(refactoring == null) {
69 			return;
70 		}
71 		PerformRefactoringOperation op = new PerformRefactoringOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
72 		try {
73 			ResourcesPlugin.getWorkspace().run(op, new NullProgressMonitor());
74 			waitForBuild();
75 			RefactoringStatus validationStatus = op.getValidationStatus();
76 			assertTrue(validationStatus.toString(), validationStatus.isOK());
77 			RefactoringStatus conditionStatus = op.getConditionStatus();
78 			assertTrue(conditionStatus.toString(), conditionStatus.isOK());
79 		}
80 		catch(CoreException ce) {
81 			//try the test again - the tests reset the workspace to remove any half-moved / change files
82 			//see https://bugs.eclipse.org/bugs/show_bug.cgi?id=412486
83 			throw new TestAgainException(ce.getLocalizedMessage());
84 		}
85 	}
86 
87 	/**
88 	 * Clean up all the test files
89 	 * @throws CoreException
90 	 */
cleanTestFiles()91 	protected void cleanTestFiles() throws CoreException {
92 		waitUntilIndexesReady();
93 		try {
94 			doClean();
95 			waitForBuild();
96 		} catch (Exception e) {
97 			throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.jdt.debug.tests", 0, "Error", e));
98 		}
99 	}
100 
101 	/**
102 	 * Cleans up refactored files and reverts the source.
103 	 * @throws Exception
104 	 */
doClean()105 	private void doClean() throws Exception {
106 		IJavaProject javaProject = get14Project();
107 		IProject project = javaProject.getProject();
108 		IFolder folder = project.getFolder("src");
109 		folder.refreshLocal(IResource.DEPTH_INFINITE, null);
110 
111 		IPackageFragmentRoot root = getPackageFragmentRoot(javaProject, "src");
112 		IPackageFragment fragment = root.getPackageFragment("renamedPackage");
113 		if (fragment.exists()) {
114 			fragment.delete(true, new NullProgressMonitor());
115 		}
116 		fragment = root.getPackageFragment("a.b.c");
117 		if (!fragment.exists()) {
118 			root.createPackageFragment("a.b.c", true, new NullProgressMonitor());
119 		}
120 
121 	// cleanup MoveeSource / Movee.java
122 		IFile target = project.getFile("src/a/b/Movee.java");
123 		if (target.exists()) {
124 			target.delete(true, false, null);
125 		}
126 		target = project.getFile("src/a/b/c/Movee.java");
127 		if (target.exists()) {
128 			target.delete(true, false, null);
129 		}
130 		IFile source = project.getFile("src/a/MoveeSource");// no .java - it's a bin
131 		source.copy(target.getFullPath(), true, null);
132 
133 	// cleanup MoveeRecipientSource / MoveeRecipient.java
134 		target = project.getFile("src/a/b/MoveeRecipient.java");
135 		if (target.exists()) {
136 			target.delete(true, false, null);
137 		}
138 		source = project.getFile("src/a/MoveeRecipientSource");// no .java - it's a bin
139 		source.copy(target.getFullPath(), true, null);
140 		target = project.getFile("src/a/b/c/RenamedType.java");
141 		if (target.exists()) {
142 			target.delete(true, false, null);
143 		}
144 		target = project.getFile("src/a/b/c/RenamedCompilationUnit.java");// move up a dir
145 		if (target.exists()) {
146 			target.delete(true, false, null);
147 		}
148 
149 	// cleanup MoveeChildSource / MoveeChild.java
150 		target = project.getFile("src/a/b/MoveeChild.java");
151 		if (target.exists()) {
152 			target.delete(true, false, null);
153 		}
154 		target = project.getFile("src/a/b/c/MoveeChild.java");
155 		if (target.exists()) {
156 			target.delete(true, false, null);
157 		}
158 		source = project.getFile("src/a/MoveeChildSource");// no .java - it's a bin
159 		source.copy(target.getFullPath(), true, null);
160 	}
161 
162 	/**
163 	 * Wait until the search index is ready
164 	 */
waitUntilIndexesReady()165 	protected static void waitUntilIndexesReady() {
166 		// dummy query for waiting until the indexes are ready
167 		SearchEngine engine = new SearchEngine();
168 		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
169 		try {
170 			engine.searchAllTypeNames(null,
171 					SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
172 					"!@$#!@".toCharArray(),
173 					SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
174 					IJavaSearchConstants.CLASS,
175 					scope,
176 					new TypeNameRequestor() {},
177 					IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
178 					null);
179 		} catch (CoreException e) {
180 		}
181 	}
182 
183 }
184