1 /*******************************************************************************
2  * Copyright (c) 2000, 2020 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.core.tests.model;
15 
16 import java.io.*;
17 import java.net.URL;
18 import java.util.*;
19 import java.util.stream.*;
20 
21 import junit.framework.Test;
22 import junit.framework.TestSuite;
23 
24 import org.eclipse.core.resources.*;
25 import org.eclipse.core.runtime.*;
26 import org.eclipse.core.runtime.jobs.Job;
27 import org.eclipse.jdt.core.*;
28 import org.eclipse.jdt.core.compiler.CharOperation;
29 import org.eclipse.jdt.core.compiler.IProblem;
30 import org.eclipse.jdt.core.dom.AST;
31 import org.eclipse.jdt.core.dom.ASTNode;
32 import org.eclipse.jdt.core.dom.CompilationUnit;
33 import org.eclipse.jdt.core.search.*;
34 import org.eclipse.jdt.core.tests.junit.extension.TestCase;
35 import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
36 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
37 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
38 import org.eclipse.jdt.internal.core.ClasspathAttribute;
39 import org.eclipse.jdt.internal.core.ClasspathEntry;
40 import org.eclipse.jdt.internal.core.JavaCorePreferenceInitializer;
41 import org.eclipse.jdt.internal.core.JavaElement;
42 import org.eclipse.jdt.internal.core.JavaElementDelta;
43 import org.eclipse.jdt.internal.core.JavaModelManager;
44 import org.eclipse.jdt.internal.core.JavaProject;
45 import org.eclipse.jdt.internal.core.NameLookup;
46 import org.eclipse.jdt.internal.core.ResolvedSourceMethod;
47 import org.eclipse.jdt.internal.core.ResolvedSourceType;
48 import org.eclipse.jdt.internal.core.nd.indexer.Indexer;
49 import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
50 import org.eclipse.jdt.internal.core.util.Util;
51 
52 @SuppressWarnings({"rawtypes", "unchecked"})
53 public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
54 
55 	/**
56 	 * The java.io.File path to the directory that contains the external jars.
57 	 */
58 	protected static String EXTERNAL_JAR_DIR_PATH;
59 
60 	/**
61 	 * The java.io.File path to the workspace directory.
62 	 */
63 	protected static String WORKSPACE_DIR_PATH;
64 
65 	// used java project
66 	protected IJavaProject currentProject;
67 
68 	// working copies usage
69 	protected ICompilationUnit[] workingCopies;
70 	protected WorkingCopyOwner wcOwner;
71 
72 	// infos for invalid results
73 	protected int tabs = 2;
74 	protected boolean displayName = false;
75 	protected String endChar = ",";
76 
77 	protected static boolean isJRE9 = false;
78 	protected static boolean isJRE10 = false;
79 	protected static boolean isJRE11 = false;
80 	protected static boolean isJRE12 = false;
81 	protected static boolean isJRE13 = false;
82 	protected static boolean isJRE14 = false;
83 	protected static String DEFAULT_MODULES = null;
84 	static {
85 		String javaVersion = System.getProperty("java.version");
86 		String vmName = System.getProperty("java.vm.name");
87 		int index = -1;
88 		if ( (index = javaVersion.indexOf('-')) != -1) {
89 			javaVersion = javaVersion.substring(0, index);
90 		} else {
91 			if (javaVersion.length() > 3) {
92 				javaVersion = javaVersion.substring(0, 3);
93 			}
94 		}
95 		long jdkLevel = CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion);
96 		if (jdkLevel >= ClassFileConstants.JDK14) {
97 			isJRE14 = true;
98 		}
99 		if (jdkLevel >= ClassFileConstants.JDK12) {
100 			isJRE12 = true;
101 		}
102 		if (jdkLevel >= ClassFileConstants.JDK11) {
103 			isJRE11 = true;
104 		}
105 		if (jdkLevel >= ClassFileConstants.JDK10) {
106 			isJRE10 = true;
107 		}
108 		if (jdkLevel >= ClassFileConstants.JDK9) {
109 			isJRE9 = true;
110 			if (vmName.contains("HotSpot")) {
111 				DEFAULT_MODULES = "java.se," +
112 						"javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media,javafx.swing,javafx.web," + 	// not present in OpenJDK
113 						"jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver," +
114 						"jdk.incubator.httpclient,jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jdi," +
115 						"jdk.jfr," +																						// not present in OpenJDK
116 						"jdk.jshell,jdk.jsobject,jdk.management," +
117 						"jdk.management.cmm,jdk.management.jfr,jdk.management.resource," +									// not present in OpenJDK
118 						"jdk.net," +
119 						"jdk.packager,jdk.packager.services,jdk.plugin.dom," +												// not present in OpenJDK
120 						"jdk.scripting.nashorn,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.xml.dom," +
121 						"oracle.desktop,oracle.net";																		// not present in OpenJDK
122 			} else if (vmName.contains("OpenJDK") || vmName.contains("OpenJ9")) {
123 				DEFAULT_MODULES = "java.se," +
124 						"jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver," +
125 						"jdk.incubator.httpclient,jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jdi," +
126 						"jdk.jshell,jdk.jsobject,jdk.management,jdk.net," +
127 						"jdk.scripting.nashorn,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.xml.dom";
128 			} else {
System.getProperties()129 				System.out.println(System.getProperties());
130 				fail("Unexpected java vm "+javaVersion+" "+vmName);
131 			}
132 			System.out.println("Recognized Java version '"+javaVersion+"' with vm.name '"+vmName+"'");
133 		}
134 	}
135 
136 	/**
137 	 * Internal synonym for constant AST.JSL9
138 	 * to alleviate deprecation warnings once AST.JLS9 is deprecated in future.
139 	 * @deprecated
140 	 */
141 	protected static final int AST_INTERNAL_JLS9 = AST.JLS9;
142 	/**
143 	 * Internal synonym for constant AST.JSL10
144 	 * to alleviate deprecation warnings once AST.JLS10 is deprecated in future.
145 	 * @deprecated
146 	 */
147 	protected static final int AST_INTERNAL_JLS10 = AST.JLS10;
148 
149 	/**
150 	 * Internal synonym for constant AST.JSL12
151 	 * to alleviate deprecation warnings once AST.JLS12 is deprecated in future.
152 	 * @deprecated
153 	 */
154 	protected static final int AST_INTERNAL_JLS12 = AST.JLS12;
155 
156 	/**
157 	 * Internal synonym for constant AST.JSL13
158 	 * to alleviate deprecation warnings once AST.JLS13 is deprecated in future.
159 	 * @deprecated
160 	 */
161 	protected static final int AST_INTERNAL_JLS13 = AST.JLS13;
162 
163 	/**
164 	 * Internal synonym for constant AST.JSL14
165 	 * to alleviate deprecation warnings once AST.JLS14 is deprecated in future.
166 	 */
167 	protected static final int AST_INTERNAL_JLS14 = AST.JLS14;
168 
169 	/**
170 	 * Internal synonym for constant AST.JSL11
171 	 * to alleviate deprecation warnings once AST.JLS11 is deprecated in future.
172 	 * @deprecated
173 	 */
174 	protected static final int AST_INTERNAL_JLS11 = AST.JLS11;
175 
176 	/**
177 	 * Internal synonym for the latest AST level.
178 	 *
179 	 */
180 	protected static final int AST_INTERNAL_LATEST = AST.JLS14;
181 
182 	public static class BasicProblemRequestor implements IProblemRequestor {
acceptProblem(IProblem problem)183 		public void acceptProblem(IProblem problem) {}
beginReporting()184 		public void beginReporting() {}
endReporting()185 		public void endReporting() {}
isActive()186 		public boolean isActive() {
187 			return true;
188 		}
189 	}
190 
191 	public static class ProblemRequestor implements IProblemRequestor {
192 		public StringBuffer problems;
193 		public int problemCount;
194 		protected char[] unitSource;
195 		public boolean isActive = true;
ProblemRequestor()196 		public ProblemRequestor() {
197 			initialize(null);
198 		}
acceptProblem(IProblem problem)199 		public void acceptProblem(IProblem problem) {
200 			org.eclipse.jdt.core.tests.util.Util.appendProblem(this.problems, problem, this.unitSource, ++this.problemCount);
201 			this.problems.append("----------\n");
202 		}
beginReporting()203 		public void beginReporting() {
204 			this.problems.append("----------\n");
205 		}
endReporting()206 		public void endReporting() {
207 			if (this.problemCount == 0)
208 				this.problems.append("----------\n");
209 		}
isActive()210 		public boolean isActive() {
211 			return this.isActive;
212 		}
initialize(char[] source)213 		public void initialize(char[] source) {
214 			reset();
215 			this.unitSource = source;
216 		}
reset()217 		public void reset() {
218 			this.problems = new StringBuffer();
219 			this.problemCount = 0;
220 		}
221 	}
222 
223 	/**
224 	 * Delta listener
225 	 */
226 	protected class DeltaListener implements IElementChangedListener, IResourceChangeListener {
227 		/**
228 		 * Deltas received from the java model. See
229 		 * <code>#startDeltas</code> and
230 		 * <code>#stopDeltas</code>.
231 		 */
232 		private IJavaElementDelta[] deltas;
233 
234 		private int eventType;
235 
236 		private ByteArrayOutputStream stackTraces;
237 
238 		private boolean gotResourceDelta;
239 
DeltaListener()240 		public DeltaListener() {
241 			flush();
242 			this.eventType = -1;
243 		}
DeltaListener(int eventType)244 		public DeltaListener(int eventType) {
245 			flush();
246 			this.eventType = eventType;
247 		}
248 
elementChanged(ElementChangedEvent event)249 		public synchronized void elementChanged(ElementChangedEvent event) {
250 			if (this.eventType == -1 || event.getType() == this.eventType) {
251 				IJavaElementDelta[] copy= new IJavaElementDelta[this.deltas.length + 1];
252 				System.arraycopy(this.deltas, 0, copy, 0, this.deltas.length);
253 				copy[this.deltas.length]= event.getDelta();
254 				this.deltas= copy;
255 
256 				new Throwable("Caller of IElementChangedListener#elementChanged").printStackTrace(new PrintStream(this.stackTraces));
257 			}
258 		}
getCompilationUnitAST(ICompilationUnit workingCopy)259 		public synchronized CompilationUnit getCompilationUnitAST(ICompilationUnit workingCopy) {
260 			for (int i=0, length= this.deltas.length; i<length; i++) {
261 				CompilationUnit result = getCompilationUnitAST(workingCopy, this.deltas[i]);
262 				if (result != null)
263 					return result;
264 			}
265 			return null;
266 		}
getCompilationUnitAST(ICompilationUnit workingCopy, IJavaElementDelta delta)267 		private CompilationUnit getCompilationUnitAST(ICompilationUnit workingCopy, IJavaElementDelta delta) {
268 			if ((delta.getFlags() & IJavaElementDelta.F_AST_AFFECTED) != 0 && workingCopy.equals(delta.getElement()))
269 				return delta.getCompilationUnitAST();
270 			return null;
271 		}
272 
273 		/**
274 		 * Returns the last delta for the given element from the cached delta.
275 		 */
getDeltaFor(IJavaElement element)276 		public IJavaElementDelta getDeltaFor(IJavaElement element) {
277 			return getDeltaFor(element, false);
278 		}
279 
280 		/**
281 		 * Returns the delta for the given element from the cached delta.
282 		 * If the boolean is true returns the first delta found.
283 		 */
getDeltaFor(IJavaElement element, boolean returnFirst)284 		public synchronized IJavaElementDelta getDeltaFor(IJavaElement element, boolean returnFirst) {
285 			if (this.deltas == null) return null;
286 			IJavaElementDelta result = null;
287 			for (int i = 0; i < this.deltas.length; i++) {
288 				IJavaElementDelta delta = searchForDelta(element, this.deltas[i]);
289 				if (delta != null) {
290 					if (returnFirst) {
291 						return delta;
292 					}
293 					result = delta;
294 				}
295 			}
296 			return result;
297 		}
298 
getLastDelta()299 		public synchronized IJavaElementDelta getLastDelta() {
300 			return this.deltas[this.deltas.length - 1];
301 		}
302 
flush()303 		public synchronized void flush() {
304 			this.deltas = new IJavaElementDelta[0];
305 			this.stackTraces = new ByteArrayOutputStream();
306 			this.gotResourceDelta = false;
307 		}
sortDeltas(IJavaElementDelta[] elementDeltas)308 		protected void sortDeltas(IJavaElementDelta[] elementDeltas) {
309         	org.eclipse.jdt.internal.core.util.Util.Comparer comparer = new org.eclipse.jdt.internal.core.util.Util.Comparer() {
310         		public int compare(Object a, Object b) {
311         			IJavaElementDelta deltaA = (IJavaElementDelta)a;
312         			IJavaElementDelta deltaB = (IJavaElementDelta)b;
313         			return toString(deltaA).compareTo(toString(deltaB));
314         		}
315         		private String toString(IJavaElementDelta delta) {
316         			if (delta.getElement().getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
317         				return delta.getElement().getPath().setDevice(null).toString();
318         			}
319         			return delta.toString();
320         		}
321         	};
322         	org.eclipse.jdt.internal.core.util.Util.sort(elementDeltas, comparer);
323         	for (int i = 0, max = elementDeltas.length; i < max; i++) {
324         		IJavaElementDelta delta = elementDeltas[i];
325         		IJavaElementDelta[] children = delta.getAffectedChildren();
326         		if (children != null) {
327         			sortDeltas(children);
328         		}
329         	}
330         }
resourceChanged(IResourceChangeEvent event)331 		public void resourceChanged(IResourceChangeEvent event) {
332 			this.gotResourceDelta = true;
333 		}
334 		/**
335 		 * Returns a delta for the given element in the delta tree
336 		 */
searchForDelta(IJavaElement element, IJavaElementDelta delta)337 		private IJavaElementDelta searchForDelta(IJavaElement element, IJavaElementDelta delta) {
338 			if (delta == null) {
339 				return null;
340 			}
341 			if (delta.getElement().equals(element)) {
342 				return delta;
343 			}
344 			for (int i= 0; i < delta.getAffectedChildren().length; i++) {
345 				IJavaElementDelta child= searchForDelta(element, delta.getAffectedChildren()[i]);
346 				if (child != null) {
347 					return child;
348 				}
349 			}
350 			return null;
351 		}
stackTraces()352 		public synchronized String stackTraces() {
353 			return this.stackTraces.toString();
354 		}
355 
356 		@Override
toString()357 		public synchronized String toString() {
358 			StringBuilder buffer = new StringBuilder();
359 			for (int i = 0, length= this.deltas.length; i < length; i++) {
360 				IJavaElementDelta delta = this.deltas[i];
361 				if (((JavaElementDelta) delta).ignoreFromTests) {
362 					continue;
363 				}
364 				if (buffer.length() != 0) {
365 					buffer.append("\n\n");
366 				}
367 				IJavaElementDelta[] children = delta.getAffectedChildren();
368 				int childrenLength=children.length;
369 				IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
370 				int resourceDeltasLength = resourceDeltas == null ? 0 : resourceDeltas.length;
371 				if (childrenLength == 0 && resourceDeltasLength == 0) {
372 					buffer.append(delta);
373 				} else {
374 					sortDeltas(children);
375 					for (int j = 0; j < childrenLength; j++) {
376 						if (buffer.length() != 0 && buffer.charAt(buffer.length() - 1) != '\n') {
377 							buffer.append('\n');
378 						}
379 						buffer.append(children[j]);
380 					}
381 					for (int j = 0; j < resourceDeltasLength; j++) {
382 						if (buffer.length() != 0 && buffer.charAt(buffer.length() - 1) != '\n') {
383 							buffer.append('\n');
384 						}
385 						buffer.append(resourceDeltas[j]);
386 					}
387 				}
388 			}
389 			return buffer.toString();
390 		}
391 
waitForResourceDelta()392 		public void waitForResourceDelta() {
393 			long start = System.currentTimeMillis();
394 			while (!this.gotResourceDelta) {
395 				try {
396 					Thread.sleep(200);
397 				} catch (InterruptedException e) {
398 				}
399 				if ((System.currentTimeMillis() - start) > 10000/*wait 10 s max*/) {
400 					throw new RuntimeException("Didn't get resource delta after 10 seconds");
401 				}
402 			}
403 		}
404 	}
405 	protected DeltaListener deltaListener = new DeltaListener();
406 
407 	protected ILogListener logListener;
408 	protected ILog log;
409 
410 
AbstractJavaModelTests(String name)411 	public AbstractJavaModelTests(String name) {
412 		super(name);
413 	}
414 
AbstractJavaModelTests(String name, int tabs)415 	public AbstractJavaModelTests(String name, int tabs) {
416 		super(name);
417 		this.tabs = tabs;
418 	}
419 
420 	/**
421 	 * See buildModelTestSuite(Class evaluationTestClass) for more information.
422 	 *
423 	 * @param evaluationTestClass
424 	 * @param minCompliance minimum compliance level required to run this test suite
425 	 * @return a test suite ({@link Test})
426 	 */
buildModelTestSuite(int minCompliance, Class evaluationTestClass)427 	public static Test buildModelTestSuite(int minCompliance, Class evaluationTestClass) {
428 		if (AbstractCompilerTest.getPossibleComplianceLevels() >= minCompliance)
429 			return buildModelTestSuite(evaluationTestClass, ORDERING);
430 		return new Suite(evaluationTestClass.getName());
431 	}
432 
433 	/**
434 	 * Build a test suite with all tests computed from public methods starting with "test"
435 	 * found in the given test class.
436 	 * Test suite name is the name of the given test class.
437 	 *
438 	 * Note that this lis maybe reduced using some mechanisms detailed in {@link #buildTestsList(Class)} method.
439 	 *
440 	 * This test suite differ from this computed in {@link TestCase} in the fact that this is
441 	 * a {@link SuiteOfTestCases.Suite} instead of a simple framework {@link TestSuite}.
442 	 *
443 	 * @param evaluationTestClass
444 	 * @return a test suite ({@link Test})
445 	 */
buildModelTestSuite(Class evaluationTestClass)446 	public static Test buildModelTestSuite(Class evaluationTestClass) {
447 		return buildModelTestSuite(evaluationTestClass, ORDERING);
448 	}
449 
450 	/**
451 	 * Build a test suite with all tests computed from public methods starting with "test"
452 	 * found in the given test class and sorted in alphabetical order.
453 	 * Test suite name is the name of the given test class.
454 	 *
455 	 * Note that this lis maybe reduced using some mechanisms detailed in {@link #buildTestsList(Class)} method.
456 	 *
457 	 * This test suite differ from this computed in {@link TestCase} in the fact that this is
458 	 * a {@link SuiteOfTestCases.Suite} instead of a simple framework {@link TestSuite}.
459 	 *
460 	 * @param evaluationTestClass
461 	 * @param ordering kind of sort use for the list (see {@link #ORDERING} for possible values)
462 	 * @return a test suite ({@link Test})
463 	 */
buildModelTestSuite(Class evaluationTestClass, long ordering)464 	public static Test buildModelTestSuite(Class evaluationTestClass, long ordering) {
465 		TestSuite suite = new Suite(evaluationTestClass.getName());
466 		List tests = buildTestsList(evaluationTestClass, 0, ordering);
467 		for (int index=0, size=tests.size(); index<size; index++) {
468 			suite.addTest((Test)tests.get(index));
469 		}
470 		return suite;
471 	}
472 
addJavaNature(String projectName)473 	protected void addJavaNature(String projectName) throws CoreException {
474 		IProject project = getWorkspaceRoot().getProject(projectName);
475 		IProjectDescription description = project.getDescription();
476 		description.setNatureIds(new String[] {JavaCore.NATURE_ID});
477 		project.setDescription(description, null);
478 	}
assertSearchResults(String expected, Object collector)479 	protected void assertSearchResults(String expected, Object collector) {
480 		assertSearchResults("Unexpected search results", expected, collector);
481 	}
assertSearchResults(String message, String expected, Object collector)482 	protected void assertSearchResults(String message, String expected, Object collector) {
483 		assertSearchResults(message, expected, collector, true /* assertion */);
484 	}
sortLines(String toSplit)485 	private static String sortLines(String toSplit) {
486 		return Arrays.stream(toSplit.split("\n")).sorted().collect(Collectors.joining("\n"));
487 	}
assertSearchResults(String message, String expectedString, Object collector, boolean assertion)488 	protected void assertSearchResults(String message, String expectedString, Object collector, boolean assertion) {
489 		String expected = sortLines(expectedString);
490 		String actual = sortLines(collector.toString());
491 		if (!expected.equals(actual)) {
492 			if (this.displayName) System.out.println(getName()+" actual result is:");
493 			System.out.print(displayString(actual, this.tabs));
494 			System.out.println(",");
495 		}
496 		if (assertion) {
497 			assertEquals(message, expected, actual);
498 		} else {
499 			assumeEquals(message, expected, actual);
500 		}
501 	}
assertScopeEquals(String expected, IJavaSearchScope scope)502 	protected void assertScopeEquals(String expected, IJavaSearchScope scope) {
503 		String actual = scope.toString();
504 		if (!expected.equals(actual)) {
505 			System.out.println(displayString(actual, 3) + ",");
506 		}
507 		assertEquals("Unexpected scope", expected, actual);
508 	}
addClasspathEntry(IJavaProject project, IClasspathEntry entry)509 	protected void addClasspathEntry(IJavaProject project, IClasspathEntry entry) throws JavaModelException{
510 		IClasspathEntry[] entries = project.getRawClasspath();
511 		int length = entries.length;
512 		System.arraycopy(entries, 0, entries = new IClasspathEntry[length + 1], 0, length);
513 		entries[length] = entry;
514 		project.setRawClasspath(entries, null);
515 	}
addClasspathEntry(IJavaProject project, IClasspathEntry entry, int position)516 	protected void addClasspathEntry(IJavaProject project, IClasspathEntry entry, int position) throws JavaModelException{
517 		IClasspathEntry[] entries = project.getRawClasspath();
518 		int length = entries.length;
519 		IClasspathEntry[] newEntries = new IClasspathEntry[length + 1];
520 		for (int srcIdx = 0, tgtIdx = 0; tgtIdx < length+1; tgtIdx++) {
521 			newEntries[tgtIdx] = (tgtIdx == position) ? entry : entries[srcIdx++];
522 		}
523 		project.setRawClasspath(newEntries, null);
524 	}
addClassFolder(IJavaProject javaProject, String folderRelativePath, String[] pathAndContents, String compliance)525 	protected void addClassFolder(IJavaProject javaProject, String folderRelativePath, String[] pathAndContents, String compliance) throws CoreException, IOException {
526 		IProject project = javaProject.getProject();
527 		String projectLocation = project.getLocation().toOSString();
528 		String folderPath = projectLocation + File.separator + folderRelativePath;
529     	org.eclipse.jdt.core.tests.util.Util.createClassFolder(pathAndContents, folderPath, compliance);
530     	project.refreshLocal(IResource.DEPTH_INFINITE, null);
531 		String projectPath = '/' + project.getName() + '/';
532 		addLibraryEntry(
533 			javaProject,
534 			new Path(projectPath + folderRelativePath),
535 			null,
536 			null,
537 			null,
538 			null,
539 			true
540 		);
541 
542 	}
addExternalLibrary(IJavaProject javaProject, String jarPath, String[] pathAndContents, String[] nonJavaResources, String compliance)543 	protected void addExternalLibrary(IJavaProject javaProject, String jarPath, String[] pathAndContents, String[] nonJavaResources, String compliance) throws Exception {
544 		String[] claspath = getJCL15PlusLibraryIfNeeded(compliance);
545 		org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, nonJavaResources, jarPath, claspath, compliance);
546 		addLibraryEntry(javaProject, new Path(jarPath), true/*exported*/);
547 	}
addLibrary(String jarName, String sourceZipName, String[] pathAndContents, String compliance)548 	protected void addLibrary(String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
549 		addLibrary(this.currentProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
550 	}
addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance, Map options)551 	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance, Map options) throws CoreException, IOException {
552 		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, options);
553 	}
addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance)554 	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
555 		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
556 	}
addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance)557 	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance) throws CoreException, IOException {
558 		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, null, null, compliance, null);
559 	}
moduleAttribute()560 	protected IClasspathAttribute[] moduleAttribute() {
561 		return new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
562 	}
newModularLibraryEntry(IPath path, IPath sourceAttachmentPath, IPath sourceAttachmentRootPath)563 	protected IClasspathEntry newModularLibraryEntry(IPath path, IPath sourceAttachmentPath, IPath sourceAttachmentRootPath) {
564 		return JavaCore.newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, null, moduleAttribute(), false);
565 	}
addModularLibraryEntry(IJavaProject project, IPath libraryPath, IPath sourceAttachmentPath)566 	protected void addModularLibraryEntry(IJavaProject project, IPath libraryPath, IPath sourceAttachmentPath) throws JavaModelException {
567 		addClasspathEntry(project, newModularLibraryEntry(libraryPath, sourceAttachmentPath, null));
568 	}
addModularLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance)569 	protected void addModularLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
570 		createLibrary(javaProject, jarName, sourceZipName, pathAndContents, null, compliance);
571 		IPath projectPath = javaProject.getPath();
572 		addModularLibraryEntry(javaProject, projectPath.append(jarName), projectPath.append(sourceZipName));
573 	}
addLibrary( IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String[] librariesInclusionPatterns, String[] librariesExclusionPatterns, String compliance, Map options)574 	protected void addLibrary(
575 			IJavaProject javaProject,
576 			String jarName,
577 			String sourceZipName,
578 			String[] pathAndContents,
579 			String[] nonJavaResources,
580 			String[] librariesInclusionPatterns,
581 			String[] librariesExclusionPatterns,
582 			String compliance,
583 			Map options) throws CoreException, IOException {
584 		IProject project = createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, options);
585 		String projectPath = '/' + project.getName() + '/';
586 		addLibraryEntry(
587 			javaProject,
588 			new Path(projectPath + jarName),
589 			sourceZipName == null ? null : new Path(projectPath + sourceZipName),
590 			null,
591 			toIPathArray(librariesInclusionPatterns),
592 			toIPathArray(librariesExclusionPatterns),
593 			true
594 		);
595 	}
createLibrary( IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance)596 	protected IProject createLibrary(
597 			IJavaProject javaProject,
598 			String jarName,
599 			String sourceZipName,
600 			String[] pathAndContents,
601 			String[] nonJavaResources,
602 			String compliance) throws IOException, CoreException {
603 		return createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, null);
604 	}
605 
createLibrary( IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance, Map options)606 	protected IProject createLibrary(
607 			IJavaProject javaProject,
608 			String jarName,
609 			String sourceZipName,
610 			String[] pathAndContents,
611 			String[] nonJavaResources,
612 			String compliance,
613 			Map options) throws IOException, CoreException {
614 		IProject project = javaProject.getProject();
615 		String projectLocation = project.getLocation().toOSString();
616 		String jarPath = projectLocation + File.separator + jarName;
617 		String[] claspath = getJCL15PlusLibraryIfNeeded(compliance);
618 		org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, nonJavaResources, jarPath, claspath, compliance, options);
619 		if (pathAndContents != null && pathAndContents.length != 0) {
620 			String sourceZipPath = projectLocation + File.separator + sourceZipName;
621 			org.eclipse.jdt.core.tests.util.Util.createSourceZip(pathAndContents, sourceZipPath);
622 		}
623 		project.refreshLocal(IResource.DEPTH_INFINITE, null);
624 		return project;
625 	}
626 
externalAnnotationExtraAttributes(String path)627 	static IClasspathAttribute[] externalAnnotationExtraAttributes(String path) {
628 		return new IClasspathAttribute[] {
629 				new ClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, path)
630 		};
631 	}
632 
addLibraryWithExternalAnnotations( IJavaProject javaProject, String compliance, String jarName, String externalAnnotationPath, String[] pathAndContents, Map options)633 	protected void addLibraryWithExternalAnnotations(
634 			IJavaProject javaProject,
635 			String compliance,
636 			String jarName,
637 			String externalAnnotationPath,
638 			String[] pathAndContents,
639 			Map options) throws CoreException, IOException
640 	{
641 		createLibrary(javaProject, jarName, "src.zip", pathAndContents, null, compliance, options);
642 		String jarPath = '/' + javaProject.getProject().getName() + '/' + jarName;
643 		IClasspathEntry entry = JavaCore.newLibraryEntry(
644 				new Path(jarPath),
645 				new Path('/'+javaProject.getProject().getName()+"/src.zip"),
646 				null/*src attach root*/,
647 				null/*access rules*/,
648 				externalAnnotationExtraAttributes(externalAnnotationPath),
649 				false/*exported*/);
650 		addClasspathEntry(javaProject, entry);
651 	}
652 
addLibraryEntry(String path, boolean exported)653 	protected void addLibraryEntry(String path, boolean exported) throws JavaModelException {
654 		addLibraryEntry(this.currentProject, new Path(path), null, null, null, null, exported);
655 	}
addLibraryEntry(IJavaProject project, String path, boolean exported)656 	protected void addLibraryEntry(IJavaProject project, String path, boolean exported) throws JavaModelException {
657 		addLibraryEntry(project, new Path(path), exported);
658 	}
addLibraryEntry(IJavaProject project, IPath path, boolean exported)659 	protected void addLibraryEntry(IJavaProject project, IPath path, boolean exported) throws JavaModelException {
660 		addLibraryEntry(project, path, null, null, null, null, exported);
661 	}
addLibraryEntry(IJavaProject project, String path, String srcAttachmentPath)662 	protected void addLibraryEntry(IJavaProject project, String path, String srcAttachmentPath) throws JavaModelException{
663 		addLibraryEntry(
664 			project,
665 			new Path(path),
666 			srcAttachmentPath == null ? null : new Path(srcAttachmentPath),
667 			null,
668 			null,
669 			null,
670 			new IClasspathAttribute[0],
671 			false
672 		);
673 	}
addLibraryEntry(IJavaProject project, IPath path, IPath srcAttachmentPath, IPath srcAttachmentPathRoot, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, boolean exported)674 	protected void addLibraryEntry(IJavaProject project, IPath path, IPath srcAttachmentPath, IPath srcAttachmentPathRoot, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, boolean exported) throws JavaModelException{
675 		addLibraryEntry(
676 			project,
677 			path,
678 			srcAttachmentPath,
679 			srcAttachmentPathRoot,
680 			accessibleFiles,
681 			nonAccessibleFiles,
682 			new IClasspathAttribute[0],
683 			exported
684 		);
685 	}
addLibraryEntry(IJavaProject project, IPath path, IPath srcAttachmentPath, IPath srcAttachmentPathRoot, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean exported)686 	protected void addLibraryEntry(IJavaProject project, IPath path, IPath srcAttachmentPath, IPath srcAttachmentPathRoot, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean exported) throws JavaModelException{
687 		IClasspathEntry entry = JavaCore.newLibraryEntry(
688 			path,
689 			srcAttachmentPath,
690 			srcAttachmentPathRoot,
691 			ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles),
692 			extraAttributes,
693 			exported);
694 		addClasspathEntry(project, entry);
695 	}
696 
addModularProjectEntry(IJavaProject project, IJavaProject depProject)697 	protected void addModularProjectEntry(IJavaProject project, IJavaProject depProject) throws JavaModelException {
698 		addClasspathEntry(project, newModularProjectEntry(depProject));
699 	}
700 
newModularProjectEntry(IJavaProject depProject)701 	protected IClasspathEntry newModularProjectEntry(IJavaProject depProject) {
702 		return JavaCore.newProjectEntry(depProject.getPath(), null, false, moduleAttribute(), false);
703 	}
704 
assertSortedElementsEqual(String message, String expected, IJavaElement[] elements)705 	protected void assertSortedElementsEqual(String message, String expected, IJavaElement[] elements) {
706 		sortElements(elements);
707 		assertElementsEqual(message, expected, elements);
708 	}
709 
assertWorkingCopyDeltas(String message, String expected)710 	protected void assertWorkingCopyDeltas(String message, String expected) {
711 		assertDeltas(message, expected, false/*don't wait for resource delta*/);
712 	}
713 
assertResourceEquals(String message, String expected, IResource resource)714 	protected void assertResourceEquals(String message, String expected, IResource resource) {
715 		String actual = resource == null ? "<null>" : resource.getFullPath().toString();
716 		if (!expected.equals(actual)) {
717 			System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(actual));
718 			System.out.println(this.endChar);
719 		}
720 		assertEquals(message, expected, actual);
721 	}
722 
assertResourcesEqual(String message, String expected, Object[] resources)723 	protected void assertResourcesEqual(String message, String expected, Object[] resources) {
724 		sortResources(resources);
725 		StringBuffer buffer = new StringBuffer();
726 		for (int i = 0, length = resources.length; i < length; i++) {
727 			if (resources[i] instanceof IResource) {
728 				buffer.append(((IResource) resources[i]).getFullPath().toString());
729 			} else if (resources[i] instanceof IStorage) {
730 				buffer.append(((IStorage) resources[i]).getFullPath().toString());
731 			} else if (resources[i] == null) {
732 				buffer.append("<null>");
733 			}
734 			if (i != length-1)buffer.append("\n");
735 		}
736 		if (!expected.equals(buffer.toString())) {
737 			System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(buffer.toString(), 2));
738 			System.out.println(this.endChar);
739 		}
740 		assertEquals(
741 			message,
742 			expected,
743 			buffer.toString()
744 		);
745 	}
746 
assertResourceNamesEqual(String message, String expected, Object[] resources)747 	protected void assertResourceNamesEqual(String message, String expected, Object[] resources) {
748 		sortResources(resources);
749 		StringBuffer buffer = new StringBuffer();
750 		for (int i = 0, length = resources.length; i < length; i++) {
751 			if (resources[i] instanceof IResource) {
752 				buffer.append(((IResource)resources[i]).getName());
753 			} else if (resources[i] instanceof IStorage) {
754 				buffer.append(((IStorage) resources[i]).getName());
755 			} else if (resources[i] == null) {
756 				buffer.append("<null>");
757 			}
758 			if (i != length-1)buffer.append("\n");
759 		}
760 		if (!expected.equals(buffer.toString())) {
761 			System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(buffer.toString(), 2));
762 			System.out.println(this.endChar);
763 		}
764 		assertEquals(
765 			message,
766 			expected,
767 			buffer.toString()
768 		);
769 	}
770 
assertResourceTreeEquals(String message, String expected, Object[] resources)771 	protected void assertResourceTreeEquals(String message, String expected, Object[] resources) throws CoreException {
772 		sortResources(resources);
773 		StringBuffer buffer = new StringBuffer();
774 		for (int i = 0, length = resources.length; i < length; i++) {
775 			printResourceTree(resources[i], buffer, 0);
776 			if (i != length-1) buffer.append("\n");
777 		}
778 		if (!expected.equals(buffer.toString())) {
779 			System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(buffer.toString(), 2));
780 			System.out.println(this.endChar);
781 		}
782 		assertEquals(
783 			message,
784 			expected,
785 			buffer.toString()
786 		);
787 	}
788 
printResourceTree(Object resource, StringBuffer buffer, int indent)789 	private void printResourceTree(Object resource, StringBuffer buffer, int indent) throws CoreException {
790 		for (int i = 0; i < indent; i++)
791 			buffer.append("  ");
792 		if (resource instanceof IResource) {
793 			buffer.append(((IResource) resource).getName());
794 			if (resource instanceof IContainer) {
795 				IResource[] children = ((IContainer) resource).members();
796 				int length = children.length;
797 				if (length > 0) buffer.append("\n");
798 				for (int j = 0; j < length; j++) {
799 					printResourceTree(children[j], buffer, indent+1);
800 					if (j != length-1) buffer.append("\n");
801 				}
802 			}
803 		} else if (resource instanceof IJarEntryResource) {
804 			IJarEntryResource jarEntryResource = (IJarEntryResource) resource;
805 			buffer.append(jarEntryResource.getName());
806 			if (!jarEntryResource.isFile()) {
807 				IJarEntryResource[] children = jarEntryResource.getChildren();
808 				int length = children.length;
809 				if (length > 0) buffer.append("\n");
810 				for (int j = 0; j < length; j++) {
811 					printResourceTree(children[j], buffer, indent+1);
812 					if (j != length-1) buffer.append("\n");
813 				}
814 			}
815 		} else if (resource == null) {
816 			buffer.append("<null>");
817 		}
818 
819 	}
820 
assertElementEquals(String message, String expected, IJavaElement element)821 	protected void assertElementEquals(String message, String expected, IJavaElement element) {
822 		String actual = element == null ? "<null>" : ((JavaElement) element).toStringWithAncestors(false/*don't show key*/);
823 		if (!expected.equals(actual)) {
824 			if (this.displayName) System.out.println(getName()+" actual result is:");
825 			System.out.println(displayString(actual, this.tabs) + this.endChar);
826 		}
827 		assertEquals(message, expected, actual);
828 	}
assertElementExists(String message, String expected, IJavaElement element)829 	protected void assertElementExists(String message, String expected, IJavaElement element) {
830 		assertElementEquals(message, expected, element);
831 		if (element != null && !element.exists()) {
832 			fail(((JavaElement) element).toStringWithAncestors(false/*don't show key*/) + " doesn't exist");
833 		}
834 	}
assertElementsEqual(String message, String expected, IJavaElement[] elements)835 	protected void assertElementsEqual(String message, String expected, IJavaElement[] elements) {
836 		assertElementsEqual(message, expected, elements, false/*don't show key*/);
837 	}
assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo)838 	protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo) {
839 		assertElementsEqual(message, expected, elements, showResolvedInfo, false);
840 	}
assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo, boolean sorted)841 	protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo, boolean sorted) {
842 		StringBuffer buffer = new StringBuffer();
843 		if (elements != null) {
844 			for (int i = 0, length = elements.length; i < length; i++){
845 				JavaElement element = (JavaElement)elements[i];
846 				if (element == null) {
847 					buffer.append("<null>");
848 				} else {
849 					buffer.append(element.toStringWithAncestors(showResolvedInfo));
850 				}
851 				if (i != length-1) buffer.append("\n");
852 			}
853 		} else {
854 			buffer.append("<null>");
855 		}
856 		String actual = buffer.toString();
857 		if (sorted) {
858 			actual = sortLines(actual);
859 		}
860 		if (!expected.equals(actual)) {
861 			if (this.displayName) System.out.println(getName()+" actual result is:");
862 			System.out.println(displayString(actual, this.tabs) + this.endChar);
863 		}
864 		assertEquals(message, expected, actual);
865 	}
assertExceptionEquals(String message, String expected, Exception exception)866 	protected void assertExceptionEquals(String message, String expected, Exception exception) {
867 		String actual =
868 			exception == null ?
869 				"<null>" :
870 				(exception instanceof CoreException) ?
871 					((CoreException) exception).getStatus().getMessage() :
872 					exception.toString();
873 		if (!expected.equals(actual)) {
874 			if (this.displayName) System.out.println(getName()+" actual result is:");
875 			System.out.println(displayString(actual, this.tabs) + this.endChar);
876 		}
877 		assertEquals(message, expected, actual);
878 	}
assertHierarchyEquals(String expected, ITypeHierarchy hierarchy)879 	protected void assertHierarchyEquals(String expected, ITypeHierarchy hierarchy) {
880 		String actual = hierarchy.toString();
881 		if (!expected.equals(actual)) {
882 			if (this.displayName) System.out.println(getName()+" actual result is:");
883 			System.out.println(displayString(actual, this.tabs) + this.endChar);
884 		}
885 		assertEquals("Unexpected type hierarchy", expected, actual);
886 	}
assertBuildPathMarkers(String message, String expectedMarkers, IJavaProject project)887 	protected void assertBuildPathMarkers(String message, String expectedMarkers, IJavaProject project) throws CoreException {
888 		waitForAutoBuild();
889 		IMarker[] markers = project.getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
890 		sortMarkers(markers);
891 		assertMarkers(message, expectedMarkers, markers);
892 	}
sortMarkers(IMarker[] markers)893 	protected void sortMarkers(IMarker[] markers) {
894 		org.eclipse.jdt.internal.core.util.Util.Comparer comparer = new org.eclipse.jdt.internal.core.util.Util.Comparer() {
895 			public int compare(Object a, Object b) {
896 				IMarker markerA = (IMarker)a;
897 				IMarker markerB = (IMarker)b;
898 				return markerA.getAttribute(IMarker.MESSAGE, "").compareTo(markerB.getAttribute(IMarker.MESSAGE, "")); //$NON-NLS-1$ //$NON-NLS-2$
899 			}
900 		};
901 		org.eclipse.jdt.internal.core.util.Util.sort(markers, comparer);
902 	}
assertProblemMarkers(String message, String expectedMarkers, IProject project)903 	protected void assertProblemMarkers(String message, String expectedMarkers, IProject project) throws CoreException {
904 		IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
905 		sortMarkers(markers);
906 		assertMarkers(message, expectedMarkers, markers);
907 	}
assertMarkers(String message, String expectedMarkers, IMarker[] markers)908 	protected void assertMarkers(String message, String expectedMarkers, IMarker[] markers) throws CoreException {
909 		StringBuffer buffer = new StringBuffer();
910 		if (markers != null) {
911 			for (int i = 0, length = markers.length; i < length; i++) {
912 				IMarker marker = markers[i];
913 				buffer.append(marker.getAttribute(IMarker.MESSAGE));
914 				if (i != length-1) {
915 					buffer.append("\n");
916 				}
917 			}
918 		}
919 		String actual = buffer.toString();
920 		if (!expectedMarkers.equals(actual)) {
921 		 	System.out.println(displayString(actual, 2));
922 		}
923 		assertEquals(message, expectedMarkers, actual);
924 	}
925 
assertMemberValuePairEquals(String expected, IMemberValuePair member)926 	protected void assertMemberValuePairEquals(String expected, IMemberValuePair member) throws JavaModelException {
927 		StringBuffer buffer = new StringBuffer();
928 		appendAnnotationMember(buffer, member);
929 		String actual = buffer.toString();
930 		if (!expected.equals(actual)) {
931 			System.out.println(displayString(actual, 2) + this.endChar);
932 		}
933 		assertEquals("Unexpected member value pair", expected, actual);
934 	}
935 
assertProblems(String message, String expected, IProblem[] problems, char[] source)936 	protected void assertProblems(String message, String expected, IProblem[] problems, char[] source) {
937 		ProblemRequestor pbRequestor = new ProblemRequestor();
938 		pbRequestor.unitSource = source;
939 		for (int i = 0, length = problems.length; i < length; i++) {
940 			pbRequestor.acceptProblem(problems[i]);
941 		}
942 		assertProblems(message, expected, pbRequestor);
943 	}
assertProblems(String message, String expected, ProblemRequestor problemRequestor)944 	protected void assertProblems(String message, String expected, ProblemRequestor problemRequestor) {
945 		String actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(problemRequestor.problems.toString());
946 		String independantExpectedString = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(expected);
947 		if (!independantExpectedString.equals(actual)){
948 		 	System.out.println(org.eclipse.jdt.core.tests.util.Util.displayString(actual, this.tabs));
949 		}
950 		assertEquals(
951 			message,
952 			independantExpectedString,
953 			actual);
954 	}
955 	/*
956 	 * Asserts that the given actual source (usually coming from a file content) is equal to the expected one.
957 	 * Note that 'expected' is assumed to have the '\n' line separator.
958 	 * The line separators in 'actual' are converted to '\n' before the comparison.
959 	 */
assertSourceEquals(String message, String expected, String actual)960 	protected void assertSourceEquals(String message, String expected, String actual) {
961 		assertSourceEquals(message, expected, actual, true/*convert line delimiter*/);
962 	}
963 	/*
964 	 * Asserts that the given actual source is equal to the expected one.
965 	 * Note that if the line separators in 'actual' are converted to '\n' before the comparison,
966 	 * 'expected' is assumed to have the same '\n' line separator.
967 	 */
assertSourceEquals(String message, String expected, String actual, boolean convert)968 	protected void assertSourceEquals(String message, String expected, String actual, boolean convert) {
969 		if (actual == null) {
970 			assertEquals(message, expected, null);
971 			return;
972 		}
973 		if (convert) {
974 			actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(actual);
975 		}
976 		if (!actual.equals(expected)) {
977 			System.out.println("Expected source in "+getName()+" should be:");
978 			System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(actual.toString(), 2));
979 			System.out.println(this.endChar);
980 		}
981 		assertEquals(message, expected, actual);
982 	}
assertAnnotationsEqual(String expected, IAnnotation[] annotations)983 	protected void assertAnnotationsEqual(String expected, IAnnotation[] annotations) throws JavaModelException {
984 		StringBuffer buffer = new StringBuffer();
985 		for (int i = 0; i < annotations.length; i++) {
986 			IAnnotation annotation = annotations[i];
987 			appendAnnotation(buffer, annotation);
988 			buffer.append("\n");
989 		}
990 		String actual = buffer.toString();
991 		if (!expected.equals(actual)) {
992 			System.out.println(displayString(actual, 2) + this.endChar);
993 		}
994 		assertEquals("Unexpected annotations", expected, actual);
995 	}
996 
appendAnnotation(StringBuffer buffer, IAnnotation annotation)997 	protected void appendAnnotation(StringBuffer buffer, IAnnotation annotation) throws JavaModelException {
998 		buffer.append('@');
999 		buffer.append(annotation.getElementName());
1000 		IMemberValuePair[] members = annotation.getMemberValuePairs();
1001 		int length = members.length;
1002 		if (length > 0) {
1003 			buffer.append('(');
1004 			for (int i = 0; i < length; i++) {
1005 				appendAnnotationMember(buffer, members[i]);
1006 				if (i < length-1)
1007 					buffer.append(", ");
1008 			}
1009 			buffer.append(')');
1010 		}
1011 	}
1012 
appendAnnotationMember(StringBuffer buffer, IMemberValuePair member)1013 	private void appendAnnotationMember(StringBuffer buffer, IMemberValuePair member) throws JavaModelException {
1014 		if (member == null) {
1015 			buffer.append("<null>");
1016 			return;
1017 		}
1018 		String name = member.getMemberName();
1019 		if (!"value".equals(name)) {
1020 			buffer.append(name);
1021 			buffer.append('=');
1022 		}
1023 		int kind = member.getValueKind();
1024 		Object value = member.getValue();
1025 		if (value instanceof Object[]) {
1026 			if (kind == IMemberValuePair.K_UNKNOWN)
1027 				buffer.append("[unknown]");
1028 			buffer.append('{');
1029 			Object[] array = (Object[]) value;
1030 			for (int i = 0, length = array.length; i < length; i++) {
1031 				appendAnnotationMemberValue(buffer, array[i], kind);
1032 				if (i < length-1)
1033 					buffer.append(", ");
1034 			}
1035 			buffer.append('}');
1036 		} else {
1037 			appendAnnotationMemberValue(buffer, value, kind);
1038 		}
1039 	}
1040 
appendAnnotationMemberValue(StringBuffer buffer, Object value, int kind)1041 	private void appendAnnotationMemberValue(StringBuffer buffer, Object value, int kind) throws JavaModelException {
1042 		if (value == null) {
1043 			buffer.append("<null>");
1044 			return;
1045 		}
1046 		switch(kind) {
1047 		case IMemberValuePair.K_INT:
1048 			buffer.append("(int)");
1049 			buffer.append(value);
1050 			break;
1051 		case IMemberValuePair.K_BYTE:
1052 			buffer.append("(byte)");
1053 			buffer.append(value);
1054 			break;
1055 		case IMemberValuePair.K_SHORT:
1056 			buffer.append("(short)");
1057 			buffer.append(value);
1058 			break;
1059 		case IMemberValuePair.K_CHAR:
1060 			buffer.append('\'');
1061 			buffer.append(value);
1062 			buffer.append('\'');
1063 			break;
1064 		case IMemberValuePair.K_FLOAT:
1065 			buffer.append(value);
1066 			buffer.append('f');
1067 			break;
1068 		case IMemberValuePair.K_DOUBLE:
1069 			buffer.append("(double)");
1070 			buffer.append(value);
1071 			break;
1072 		case IMemberValuePair.K_BOOLEAN:
1073 			buffer.append(value);
1074 			break;
1075 		case IMemberValuePair.K_LONG:
1076 			buffer.append(value);
1077 			buffer.append('L');
1078 			break;
1079 		case IMemberValuePair.K_STRING:
1080 			buffer.append('\"');
1081 			buffer.append(value);
1082 			buffer.append('\"');
1083 			break;
1084 		case IMemberValuePair.K_ANNOTATION:
1085 			appendAnnotation(buffer, (IAnnotation) value);
1086 			break;
1087 		case IMemberValuePair.K_CLASS:
1088 			buffer.append(value);
1089 			buffer.append(".class");
1090 			break;
1091 		case IMemberValuePair.K_QUALIFIED_NAME:
1092 			buffer.append(value);
1093 			break;
1094 		case IMemberValuePair.K_SIMPLE_NAME:
1095 			buffer.append(value);
1096 			break;
1097 		case IMemberValuePair.K_UNKNOWN:
1098 			appendAnnotationMemberValue(buffer, value, getValueKind(value));
1099 			break;
1100 		default:
1101 			buffer.append("<Unknown value: (" + (value == null ? "" : value.getClass().getName()) + ") " + value + ">");
1102 			break;
1103 		}
1104 	}
getValueKind(Object value)1105 	private int getValueKind(Object value) {
1106 		if (value instanceof Integer) {
1107 			return IMemberValuePair.K_INT;
1108 		} else if (value instanceof Byte) {
1109 			return IMemberValuePair.K_BYTE;
1110 		} else if (value instanceof Short) {
1111 			return IMemberValuePair.K_SHORT;
1112 		} else if (value instanceof Character) {
1113 			return IMemberValuePair.K_CHAR;
1114 		} else if (value instanceof Float) {
1115 			return IMemberValuePair.K_FLOAT;
1116 		} else if (value instanceof Double) {
1117 			return IMemberValuePair.K_DOUBLE;
1118 		} else if (value instanceof Boolean) {
1119 			return IMemberValuePair.K_BOOLEAN;
1120 		} else if (value instanceof Long) {
1121 			return IMemberValuePair.K_LONG;
1122 		} else if (value instanceof String) {
1123 			return IMemberValuePair.K_STRING;
1124 		}
1125 		return -1;
1126 
1127 	}
1128 	/*
1129 	 * Ensures that the toString() of the given AST node is as expected.
1130 	 */
assertASTNodeEquals(String message, String expected, ASTNode actual)1131 	public void assertASTNodeEquals(String message, String expected, ASTNode actual) {
1132 		String actualString = actual == null ? "null" : actual.toString();
1133 		assertSourceEquals(message, expected, actualString);
1134 	}
1135 	/**
1136 	 * Ensures the elements are present after creation.
1137 	 */
assertCreation(IJavaElement[] newElements)1138 	public void assertCreation(IJavaElement[] newElements) {
1139 		for (int i = 0; i < newElements.length; i++) {
1140 			IJavaElement newElement = newElements[i];
1141 			assertTrue("Element should be present after creation", newElement.exists());
1142 		}
1143 	}
assertClasspathEquals(IClasspathEntry[] classpath, String expected)1144 	protected void assertClasspathEquals(IClasspathEntry[] classpath, String expected) {
1145 		String actual;
1146 		if (classpath == null) {
1147 			actual = "<null>";
1148 		} else {
1149 			StringBuffer buffer = new StringBuffer();
1150 			int length = classpath.length;
1151 			for (int i=0; i<length; i++) {
1152 				buffer.append(classpath[i]);
1153 				if (i < length-1)
1154 					buffer.append('\n');
1155 			}
1156 			actual = buffer.toString();
1157 		}
1158 		if (!actual.equals(expected)) {
1159 		 	System.out.print(displayString(actual, 2));
1160 		}
1161 		assertEquals(expected, actual);
1162 	}
assertPackageFragmentRootsEqual(IPackageFragmentRoot[] roots, String expected)1163 	protected void assertPackageFragmentRootsEqual(IPackageFragmentRoot[] roots, String expected) {
1164 		String actual;
1165 		if (roots == null) {
1166 			actual = "<null>";
1167 		} else {
1168 			StringBuffer buffer = new StringBuffer();
1169 			int length = roots.length;
1170 			for (int i=0; i<length; i++) {
1171 				buffer.append(roots[i]);
1172 				if (i < length-1)
1173 					buffer.append('\n');
1174 			}
1175 			actual = buffer.toString();
1176 		}
1177 		if (!actual.equals(expected)) {
1178 		 	System.out.print(displayString(actual, 2));
1179 		}
1180 		assertEquals(expected, actual);
1181 	}
1182 	/**
1183 	 * Ensures the element is present after creation.
1184 	 */
assertCreation(IJavaElement newElement)1185 	public void assertCreation(IJavaElement newElement) {
1186 		assertCreation(new IJavaElement[] {newElement});
1187 	}
1188 	/**
1189 	 * Creates an operation to delete the given elements, asserts
1190 	 * the operation is successful, and ensures the elements are no
1191 	 * longer present in the model.
1192 	 */
assertDeletion(IJavaElement[] elementsToDelete)1193 	public void assertDeletion(IJavaElement[] elementsToDelete) throws JavaModelException {
1194 		IJavaElement elementToDelete = null;
1195 		for (int i = 0; i < elementsToDelete.length; i++) {
1196 			elementToDelete = elementsToDelete[i];
1197 			assertTrue("Element must be present to be deleted", elementToDelete.exists());
1198 		}
1199 
1200 		getJavaModel().delete(elementsToDelete, false, null);
1201 
1202 		for (int i = 0; i < elementsToDelete.length; i++) {
1203 			elementToDelete = elementsToDelete[i];
1204 			assertTrue("Element should not be present after deletion: " + elementToDelete, !elementToDelete.exists());
1205 		}
1206 	}
assertDeltas(String message, String expected, DeltaListener listener)1207 	protected void assertDeltas(String message, String expected, DeltaListener listener) {
1208 		assertDeltas(message, expected, expected.length() > 0/*wait for resource delta iff a delta is expected*/, listener);
1209 	}
assertDeltas(String message, String expected, boolean waitForResourceDelta, DeltaListener listener)1210 	protected void assertDeltas(String message, String expected, boolean waitForResourceDelta, DeltaListener listener) {
1211 		if (waitForResourceDelta)
1212 			listener.waitForResourceDelta();
1213 		String actual = listener.toString();
1214 		if (!expected.equals(actual)) {
1215 			System.out.println(displayString(actual, 2));
1216 			System.err.println(listener.stackTraces());
1217 		}
1218 		assertEquals(
1219 			message,
1220 			expected,
1221 			actual);
1222 	}
assertDeltas(String message, String expected)1223 	protected void assertDeltas(String message, String expected) {
1224 		assertDeltas(message, expected, expected.length() > 0/*wait for resource delta iff a delta is expected*/);
1225 	}
assertDeltas(String message, String expected, boolean waitForResourceDelta)1226 	protected void assertDeltas(String message, String expected, boolean waitForResourceDelta) {
1227 		if (waitForResourceDelta)
1228 			this.deltaListener.waitForResourceDelta();
1229 		String actual = this.deltaListener.toString();
1230 		if (!expected.equals(actual)) {
1231 			System.out.println(displayString(actual, 2));
1232 			System.err.println(this.deltaListener.stackTraces());
1233 		}
1234 		assertEquals(
1235 			message,
1236 			expected,
1237 			actual);
1238 	}
assertDeltasSortingModules(String message, String expected, boolean waitForResourceDelta)1239 	protected void assertDeltasSortingModules(String message, String expected, boolean waitForResourceDelta) {
1240 		if (waitForResourceDelta)
1241 			this.deltaListener.waitForResourceDelta();
1242 		String actual = this.deltaListener.toString();
1243 		actual = sortModules(actual);
1244 		expected = sortModules(expected);
1245 		if (!expected.equals(actual)) {
1246 			System.out.println(displayString(actual, 2));
1247 			System.err.println(this.deltaListener.stackTraces());
1248 		}
1249 		assertEquals(
1250 			message,
1251 			expected,
1252 			actual);
1253 	}
sortModules(String text)1254 	private String sortModules(String text) {
1255 		StringBuilder buf = new StringBuilder();
1256 		String[] lines = text.split("\n");
1257 		int idx = 0;
1258 
1259 		// prefix before first module:
1260 		while (idx < lines.length) {
1261 			String line = lines[idx];
1262 			if (!line.trim().startsWith("<module:")) {
1263 				buf.append(line).append('\n');
1264 				idx++;
1265 			} else {
1266 				break;
1267 			}
1268 		}
1269 
1270 		// extract & sort modules:
1271 		String[] modules = new String[lines.length-idx];
1272 		int m = 0;
1273 		while (idx < lines.length) {
1274 			String line = lines[idx];
1275 			if (line.trim().startsWith("<module:")) {
1276 				modules[m++] = line;
1277 				idx++;
1278 			} else {
1279 				break;
1280 			}
1281 		}
1282 		if (m > 0) {
1283 			if (m < modules.length)
1284 				modules = Arrays.copyOf(modules, m);
1285 			Arrays.sort(modules);
1286 			for (String module : modules) {
1287 				buf.append(module).append('\n');
1288 			}
1289 
1290 			// suffix:
1291 			while (idx < lines.length) {
1292 				buf.append(lines[idx++]).append('\n');
1293 			}
1294 		}
1295 		return buf.toString();
1296 	}
1297 
assertDeltas(String message, String expected, IJavaElementDelta delta)1298 	protected void assertDeltas(String message, String expected, IJavaElementDelta delta) {
1299 		String actual = delta == null ? "<null>" : delta.toString();
1300 		if (!expected.equals(actual)) {
1301 			System.out.println(displayString(actual, 2));
1302 			System.err.println(this.deltaListener.stackTraces());
1303 		}
1304 		assertEquals(
1305 			message,
1306 			expected,
1307 			actual);
1308 	}
assertTypesEqual(String message, String expected, IType[] types)1309 	protected void assertTypesEqual(String message, String expected, IType[] types) {
1310 		assertTypesEqual(message, expected, types, true);
1311 	}
assertTypesEqual(String message, String expected, IType[] types, boolean sort)1312 	protected void assertTypesEqual(String message, String expected, IType[] types, boolean sort) {
1313 		if (sort) sortTypes(types);
1314 		StringBuffer buffer = new StringBuffer();
1315 		for (int i = 0; i < types.length; i++){
1316 			if (types[i] == null)
1317 				buffer.append("<null>");
1318 			else
1319 				buffer.append(types[i].getFullyQualifiedName());
1320 			buffer.append("\n");
1321 		}
1322 		String actual = buffer.toString();
1323 		if (!expected.equals(actual)) {
1324 			System.out.println(displayString(actual, 2) +  this.endChar);
1325 		}
1326 		assertEquals(message, expected, actual);
1327 	}
assertTypeParametersEqual(String expected, ITypeParameter[] typeParameters)1328 	protected void assertTypeParametersEqual(String expected, ITypeParameter[] typeParameters) throws JavaModelException {
1329 		StringBuffer buffer = new StringBuffer();
1330 		for (int i = 0; i < typeParameters.length; i++) {
1331 			ITypeParameter typeParameter = typeParameters[i];
1332 			buffer.append(typeParameter.getElementName());
1333 			String[] bounds = typeParameter.getBounds();
1334 			int length = bounds.length;
1335 			if (length > 0)
1336 				buffer.append(" extends ");
1337 			for (int j = 0; j < length; j++) {
1338 				buffer.append(bounds[j]);
1339 				if (j != length -1) {
1340 					buffer.append(" & ");
1341 				}
1342 			}
1343 			buffer.append("\n");
1344 		}
1345 		String actual = buffer.toString();
1346 		if (!expected.equals(actual)) {
1347 			System.out.println(displayString(actual, 3) + this.endChar);
1348 		}
1349 		assertEquals("Unexpected type parameters", expected, actual);
1350 	}
assertSortedStringsEqual(String message, String expected, String[] strings)1351 	protected void assertSortedStringsEqual(String message, String expected, String[] strings) {
1352 		Util.sort(strings);
1353 		assertStringsEqual(message, expected, strings);
1354 	}
assertStringsEqual(String message, String expected, String[] strings)1355 	protected void assertStringsEqual(String message, String expected, String[] strings) {
1356 		String actual = org.eclipse.jdt.core.tests.util.Util.toString(strings, true/*add extra new lines*/);
1357 		if (!expected.equals(actual)) {
1358 			System.out.println(displayString(actual, this.tabs) + this.endChar);
1359 		}
1360 		assertEquals(message, expected, actual);
1361 	}
assertStringsEqual(String message, String[] expectedStrings, String[] actualStrings)1362 	protected void assertStringsEqual(String message, String[] expectedStrings, String[] actualStrings) {
1363 		String expected = org.eclipse.jdt.core.tests.util.Util.toString(expectedStrings, false/*don't add extra new lines*/);
1364 		String actual = org.eclipse.jdt.core.tests.util.Util.toString(actualStrings, false/*don't add extra new lines*/);
1365 		if (!expected.equals(actual)) {
1366 			System.out.println(displayString(actual, this.tabs) + this.endChar);
1367 		}
1368 		assertEquals(message, expected, actual);
1369 	}
1370 	/**
1371 	 * Attaches a source zip to the given jar package fragment root.
1372 	 */
attachSource(IPackageFragmentRoot root, String sourcePath, String sourceRoot)1373 	protected void attachSource(IPackageFragmentRoot root, String sourcePath, String sourceRoot) throws JavaModelException {
1374 		IJavaProject javaProject = root.getJavaProject();
1375 		IClasspathEntry[] entries = javaProject.getRawClasspath().clone();
1376 		for (int i = 0; i < entries.length; i++){
1377 			IClasspathEntry entry = entries[i];
1378 			if (entry.getPath().toOSString().toLowerCase().equals(root.getPath().toOSString().toLowerCase())) {
1379 				entries[i] = JavaCore.newLibraryEntry(
1380 					root.getPath(),
1381 					sourcePath == null ? null : new Path(sourcePath),
1382 					sourceRoot == null ? null : new Path(sourceRoot),
1383 					false);
1384 				break;
1385 			}
1386 		}
1387 		javaProject.setRawClasspath(entries, null);
1388 	}
1389 	/**
1390 	 * Creates an operation to delete the given element, asserts
1391 	 * the operation is successful, and ensures the element is no
1392 	 * longer present in the model.
1393 	 */
assertDeletion(IJavaElement elementToDelete)1394 	public void assertDeletion(IJavaElement elementToDelete) throws JavaModelException {
1395 		assertDeletion(new IJavaElement[] {elementToDelete});
1396 	}
1397 	/**
1398 	 * Empties the current deltas.
1399 	 */
clearDeltas(DeltaListener listener)1400 	public void clearDeltas(DeltaListener listener) {
1401 		listener.flush();
1402 	}
clearDeltas()1403 	public void clearDeltas() {
1404 		this.deltaListener.flush();
1405 	}
codeSelect(ISourceReference sourceReference, String selectAt, String selection)1406 	protected IJavaElement[] codeSelect(ISourceReference sourceReference, String selectAt, String selection) throws JavaModelException {
1407 		String str = sourceReference.getSource();
1408 		int start = str.indexOf(selectAt);
1409 		int length = selection.length();
1410 		return ((ICodeAssist)sourceReference).codeSelect(start, length);
1411 	}
codeSelectAt(ISourceReference sourceReference, String selectAt)1412 	protected IJavaElement[] codeSelectAt(ISourceReference sourceReference, String selectAt) throws JavaModelException {
1413 		String str = sourceReference.getSource();
1414 		int start = str.indexOf(selectAt) + selectAt.length();
1415 		int length = 0;
1416 		return ((ICodeAssist)sourceReference).codeSelect(start, length);
1417 	}
1418 	/**
1419 	 * Copy file from src (path to the original file) to dest (path to the destination file).
1420 	 */
copy(File src, File dest)1421 	public void copy(File src, File dest) throws IOException {
1422 		// read source bytes
1423 		byte[] srcBytes = read(src);
1424 
1425 		if (convertToIndependantLineDelimiter(src)) {
1426 			String contents = new String(srcBytes);
1427 			contents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(contents);
1428 			srcBytes = contents.getBytes();
1429 		}
1430 
1431 		// write bytes to dest
1432 		FileOutputStream out = new FileOutputStream(dest);
1433 		try {
1434 			out.write(srcBytes);
1435 		} finally {
1436 			out.close();
1437 		}
1438 	}
1439 
convertToIndependantLineDelimiter(File file)1440 	public boolean convertToIndependantLineDelimiter(File file) {
1441 		return file.getName().endsWith(".java");
1442 	}
1443 
1444 	/**
1445 	 * Copy the given source directory (and all its contents) to the given target directory.
1446 	 */
copyDirectory(File source, File target)1447 	protected void copyDirectory(File source, File target) throws IOException {
1448 		if (!target.exists()) {
1449 			target.mkdirs();
1450 		}
1451 		File[] files = source.listFiles();
1452 		if (files == null) return;
1453 		for (int i = 0; i < files.length; i++) {
1454 			File sourceChild = files[i];
1455 			String name =  sourceChild.getName();
1456 			if (name.equals("CVS") || name.equals(".svn")) continue;
1457 			File targetChild = new File(target, name);
1458 			if (sourceChild.isDirectory()) {
1459 				copyDirectory(sourceChild, targetChild);
1460 			} else {
1461 				copy(sourceChild, targetChild);
1462 			}
1463 		}
1464 	}
createFile(String path, InputStream content)1465 	protected IFile createFile(String path, InputStream content) throws CoreException {
1466 		IFile file = getFile(path);
1467 		file.create(content, true, null);
1468 		try {
1469 			content.close();
1470 		} catch (IOException e) {
1471 			e.printStackTrace();
1472 		}
1473 		return file;
1474 	}
1475 
createFile(String path, byte[] content)1476 	protected IFile createFile(String path, byte[] content) throws CoreException {
1477 		return createFile(path, new ByteArrayInputStream(content));
1478 	}
1479 
createFile(String path, String content)1480 	protected IFile createFile(String path, String content) throws CoreException {
1481 		return createFile(path, content.getBytes());
1482 	}
createFolder(String path)1483 	protected IFolder createFolder(String path) throws CoreException {
1484 		return createFolder(new Path(path));
1485 	}
createFolder(IPath path)1486 	protected IFolder createFolder(IPath path) throws CoreException {
1487 		final IFolder folder = getWorkspaceRoot().getFolder(path);
1488 		getWorkspace().run(new IWorkspaceRunnable() {
1489 			public void run(IProgressMonitor monitor) throws CoreException {
1490 				IContainer parent = folder.getParent();
1491 				if (parent instanceof IFolder && !parent.exists()) {
1492 					createFolder(parent.getFullPath());
1493 				}
1494 				folder.create(true, true, null);
1495 			}
1496 		},
1497 		null);
1498 
1499 		return folder;
1500 	}
createJar(String[] javaPathsAndContents, String jarPath)1501 	protected void createJar(String[] javaPathsAndContents, String jarPath) throws IOException {
1502 		org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, jarPath, "1.4");
1503 	}
1504 
createJar(String[] javaPathsAndContents, String jarPath, Map options)1505 	protected void createJar(String[] javaPathsAndContents, String jarPath, Map options) throws IOException {
1506 		org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, null, jarPath, null, "1.4", options);
1507 	}
1508 
createJar(String[] javaPathsAndContents, String jarPath, String[] classpath, String compliance)1509 	protected void createJar(String[] javaPathsAndContents, String jarPath, String[] classpath, String compliance) throws IOException {
1510 		org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, null,jarPath, classpath, compliance);
1511 	}
1512 
createJar(String[] javaPathsAndContents, String jarPath, String[] classpath, String compliance, Map options)1513 	protected void createJar(String[] javaPathsAndContents, String jarPath, String[] classpath, String compliance, Map options) throws IOException {
1514 		org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, null, jarPath, classpath, compliance, options);
1515 	}
1516 
createJava9Project(String name)1517 	protected IJavaProject createJava9Project(String name) throws CoreException {
1518 		return createJava9ProjectWithJREAttributes(name, new String[]{"src"}, null, "9");
1519 	}
createJava9Project(String name, String compliance)1520 	protected IJavaProject createJava9Project(String name, String compliance) throws CoreException {
1521 		return createJava9ProjectWithJREAttributes(name, new String[]{"src"}, null, compliance);
1522 	}
createJava9Project(String name, String[] srcFolders)1523 	protected IJavaProject createJava9Project(String name, String[] srcFolders) throws CoreException {
1524 		return createJava9ProjectWithJREAttributes(name, srcFolders, null, "9");
1525 	}
createJava10Project(String name, String[] srcFolders)1526 	protected IJavaProject createJava10Project(String name, String[] srcFolders) throws CoreException {
1527 		return createJava9ProjectWithJREAttributes(name, srcFolders, null, "10");
1528 	}
createJava11Project(String name, String[] srcFolders)1529 	protected IJavaProject createJava11Project(String name, String[] srcFolders) throws CoreException {
1530 		return createJava9ProjectWithJREAttributes(name, srcFolders, null, "11");
1531 	}
createJava14Project(String name, String[] srcFolders)1532 	protected IJavaProject createJava14Project(String name, String[] srcFolders) throws CoreException {
1533 		return createJava9ProjectWithJREAttributes(name, srcFolders, null, "14");
1534 	}
createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes)1535 	protected IJavaProject createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes) throws CoreException {
1536 		return createJava9ProjectWithJREAttributes(name, srcFolders, attributes, "9");
1537 	}
createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes, String compliance)1538 	protected IJavaProject createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes, String compliance) throws CoreException {
1539 		String javaHome = System.getProperty("java.home") + File.separator;
1540 		Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar");
1541 		Path sourceAttachment = new Path(javaHome +"/lib/src.zip");
1542 		IClasspathEntry jrtEntry;
1543 		String javaVersion = System.getProperty("java.version"); //$NON-NLS-1$
1544 		if (javaVersion != null && javaVersion.startsWith("1.8")) { //$NON-NLS-1$
1545 			// fall back to a regular JCL to provide access via the unnamed module:
1546 			jrtEntry = JavaCore.newVariableEntry(new Path("JCL18_LIB"), sourceAttachment, null);
1547 			try {
1548 				setUpJCLClasspathVariables("1.8");
1549 			} catch (IOException e) {
1550 				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, e.getMessage(), e));
1551 			}
1552 		} else {
1553 			if (attributes == null)
1554 				attributes = new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
1555 			jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, attributes, false);
1556 		}
1557 		IJavaProject project = this.createJavaProject(name, srcFolders, new String[0],
1558 				new String[0], "bin", compliance);
1559 		IClasspathEntry[] old = project.getRawClasspath();
1560 		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
1561 		System.arraycopy(old, 0, newPath, 0, old.length);
1562 		newPath[old.length] = jrtEntry;
1563 		project.setRawClasspath(newPath, null);
1564 		return project;
1565 	}
getJRTLibraryEntry()1566 	protected IClasspathEntry getJRTLibraryEntry() {
1567 		if (!isJRE9) return null;
1568 		String javaHome = System.getProperty("java.home") + File.separator;
1569 		Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar");
1570 		Path sourceAttachment = new Path(javaHome +"/lib/src.zip");
1571 		return JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, null, false);
1572 	}
1573 	/*
1574 	}
1575 	 * Creates a Java project where prj=src=bin and with JCL_LIB on its classpath.
1576 	 */
createJavaProject(String projectName)1577 	protected IJavaProject createJavaProject(String projectName) throws CoreException {
1578 		return this.createJavaProject(projectName, new String[] {""}, new String[] {"JCL_LIB"}, "");
1579 	}
1580 	/*
1581 	 * Creates a Java project with the given source folders an output location.
1582 	 * Add those on the project's classpath.
1583 	 */
createJavaProject(String projectName, String[] sourceFolders, String output)1584 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String output) throws CoreException {
1585 		return
1586 			this.createJavaProject(
1587 				projectName,
1588 				sourceFolders,
1589 				null/*no lib*/,
1590 				null/*no inclusion pattern*/,
1591 				null/*no exclusion pattern*/,
1592 				null/*no project*/,
1593 				null/*no inclusion pattern*/,
1594 				null/*no exclusion pattern*/,
1595 				null/*no exported project*/,
1596 				output,
1597 				null/*no source outputs*/,
1598 				null/*no inclusion pattern*/,
1599 				null/*no exclusion pattern*/,
1600 				""
1601 			);
1602 	}
1603 	/*
1604 	 * Creates a Java project with the given source folders an output location.
1605 	 * Add those on the project's classpath.
1606 	 */
createJavaProject(String projectName, String[] sourceFolders, String output, String[] sourceOutputs)1607 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String output, String[] sourceOutputs) throws CoreException {
1608 		return
1609 			this.createJavaProject(
1610 				projectName,
1611 				sourceFolders,
1612 				null/*no lib*/,
1613 				null/*no inclusion pattern*/,
1614 				null/*no exclusion pattern*/,
1615 				null/*no project*/,
1616 				null/*no inclusion pattern*/,
1617 				null/*no exclusion pattern*/,
1618 				null/*no exported project*/,
1619 				output,
1620 				sourceOutputs,
1621 				null/*no inclusion pattern*/,
1622 				null/*no exclusion pattern*/,
1623 				""
1624 			);
1625 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output)1626 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output) throws CoreException {
1627 		return
1628 			this.createJavaProject(
1629 				projectName,
1630 				sourceFolders,
1631 				libraries,
1632 				null/*no inclusion pattern*/,
1633 				null/*no exclusion pattern*/,
1634 				null/*no project*/,
1635 				null/*no inclusion pattern*/,
1636 				null/*no exclusion pattern*/,
1637 				true/*combine access restrictions by default*/,
1638 				null/*no exported project*/,
1639 				output,
1640 				null/*no source outputs*/,
1641 				null/*no inclusion pattern*/,
1642 				null/*no exclusion pattern*/,
1643 				"",
1644 				false/*don't import*/
1645 			);
1646 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output, String compliance, boolean useFullJCL)1647 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output, String compliance, boolean useFullJCL) throws CoreException {
1648 		return
1649 				this.createJavaProject(
1650 					projectName,
1651 					sourceFolders,
1652 					libraries,
1653 					null/*no inclusion pattern*/,
1654 					null/*no exclusion pattern*/,
1655 					null/*no project*/,
1656 					null/*no inclusion pattern*/,
1657 					null/*no exclusion pattern*/,
1658 					true,
1659 					null/*no exported project*/,
1660 					output,
1661 					null/*no source outputs*/,
1662 					null/*no inclusion pattern*/,
1663 					null/*no exclusion pattern*/,
1664 					compliance,
1665 					useFullJCL,
1666 					false
1667 				);
1668 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output, String compliance)1669 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output, String compliance) throws CoreException {
1670 		return
1671 			this.createJavaProject(
1672 				projectName,
1673 				sourceFolders,
1674 				libraries,
1675 				null/*no inclusion pattern*/,
1676 				null/*no exclusion pattern*/,
1677 				null/*no project*/,
1678 				null/*no inclusion pattern*/,
1679 				null/*no exclusion pattern*/,
1680 				null/*no exported project*/,
1681 				output,
1682 				null/*no source outputs*/,
1683 				null/*no inclusion pattern*/,
1684 				null/*no exclusion pattern*/,
1685 				compliance
1686 			);
1687 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, String projectOutput)1688 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, String projectOutput) throws CoreException {
1689 		return
1690 			this.createJavaProject(
1691 				projectName,
1692 				sourceFolders,
1693 				libraries,
1694 				null/*no inclusion pattern*/,
1695 				null/*no exclusion pattern*/,
1696 				projects,
1697 				null/*no inclusion pattern*/,
1698 				null/*no exclusion pattern*/,
1699 				null/*no exported project*/,
1700 				projectOutput,
1701 				null/*no source outputs*/,
1702 				null/*no inclusion pattern*/,
1703 				null/*no exclusion pattern*/,
1704 				""
1705 			);
1706 	}
createPattern(IJavaElement element, int limitTo)1707 	protected SearchPattern createPattern(IJavaElement element, int limitTo) {
1708 		return SearchPattern.createPattern(element, limitTo);
1709 	}
createPattern(String stringPattern, int searchFor, int limitTo, boolean isCaseSensitive)1710 	protected SearchPattern createPattern(String stringPattern, int searchFor, int limitTo, boolean isCaseSensitive) {
1711 		int matchMode = stringPattern.indexOf('*') != -1 || stringPattern.indexOf('?') != -1
1712 			? SearchPattern.R_PATTERN_MATCH
1713 			: SearchPattern.R_EXACT_MATCH;
1714 		int matchRule = isCaseSensitive ? matchMode | SearchPattern.R_CASE_SENSITIVE : matchMode;
1715 		return SearchPattern.createPattern(stringPattern, searchFor, limitTo, matchRule);
1716 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, boolean[] exportedProject, String projectOutput)1717 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, boolean[] exportedProject, String projectOutput) throws CoreException {
1718 		return
1719 			this.createJavaProject(
1720 				projectName,
1721 				sourceFolders,
1722 				libraries,
1723 				null/*no inclusion pattern*/,
1724 				null/*no exclusion pattern*/,
1725 				projects,
1726 				null/*no inclusion pattern*/,
1727 				null/*no exclusion pattern*/,
1728 				exportedProject,
1729 				projectOutput,
1730 				null/*no source outputs*/,
1731 				null/*no inclusion pattern*/,
1732 				null/*no exclusion pattern*/,
1733 				""
1734 			);
1735 	}
createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, String projectOutput, String compliance)1736 	protected IJavaProject createJavaProject(String projectName, String[] sourceFolders, String[] libraries, String[] projects, String projectOutput, String compliance) throws CoreException {
1737 		return
1738 			createJavaProject(
1739 				projectName,
1740 				sourceFolders,
1741 				libraries,
1742 				null/*no inclusion pattern*/,
1743 				null/*no exclusion pattern*/,
1744 				projects,
1745 				null/*no inclusion pattern*/,
1746 				null/*no exclusion pattern*/,
1747 				null/*no exported project*/,
1748 				projectOutput,
1749 				null/*no source outputs*/,
1750 				null/*no inclusion pattern*/,
1751 				null/*no exclusion pattern*/,
1752 				compliance
1753 			);
1754 		}
createJavaProject(final String projectName, final String[] sourceFolders, final String[] libraries, final String[] projects, final boolean[] exportedProjects, final String projectOutput, final String[] sourceOutputs, final String[][] inclusionPatterns, final String[][] exclusionPatterns, final String compliance)1755 	protected IJavaProject createJavaProject(final String projectName, final String[] sourceFolders, final String[] libraries, final String[] projects, final boolean[] exportedProjects, final String projectOutput, final String[] sourceOutputs, final String[][] inclusionPatterns, final String[][] exclusionPatterns, final String compliance) throws CoreException {
1756 		return
1757 		this.createJavaProject(
1758 			projectName,
1759 			sourceFolders,
1760 			libraries,
1761 			null/*no inclusion pattern*/,
1762 			null/*no exclusion pattern*/,
1763 			projects,
1764 			null/*no inclusion pattern*/,
1765 			null/*no exclusion pattern*/,
1766 			exportedProjects,
1767 			projectOutput,
1768 			sourceOutputs,
1769 			inclusionPatterns,
1770 			exclusionPatterns,
1771 			compliance
1772 		);
1773 	}
createJavaProject( final String projectName, final String[] sourceFolders, final String[] libraries, final String[][] librariesInclusionPatterns, final String[][] librariesExclusionPatterns, final String[] projects, final String[][] projectsInclusionPatterns, final String[][] projectsExclusionPatterns, final boolean[] exportedProjects, final String projectOutput, final String[] sourceOutputs, final String[][] inclusionPatterns, final String[][] exclusionPatterns, final String compliance)1774 	protected IJavaProject createJavaProject(
1775 			final String projectName,
1776 			final String[] sourceFolders,
1777 			final String[] libraries,
1778 			final String[][] librariesInclusionPatterns,
1779 			final String[][] librariesExclusionPatterns,
1780 			final String[] projects,
1781 			final String[][] projectsInclusionPatterns,
1782 			final String[][] projectsExclusionPatterns,
1783 			final boolean[] exportedProjects,
1784 			final String projectOutput,
1785 			final String[] sourceOutputs,
1786 			final String[][] inclusionPatterns,
1787 			final String[][] exclusionPatterns,
1788 			final String compliance) throws CoreException {
1789 		return createJavaProject(
1790 			projectName,
1791 			sourceFolders,
1792 			libraries,
1793 			librariesInclusionPatterns,
1794 			librariesExclusionPatterns,
1795 			projects,
1796 			projectsInclusionPatterns,
1797 			projectsExclusionPatterns,
1798 			true, // combine access restrictions by default
1799 			exportedProjects,
1800 			projectOutput,
1801 			sourceOutputs,
1802 			inclusionPatterns,
1803 			exclusionPatterns,
1804 			compliance,
1805 			false/*don't import*/);
1806 	}
createJavaProject( final String projectName, final String[] sourceFolders, final String[] libraries, final String[][] librariesInclusionPatterns, final String[][] librariesExclusionPatterns, final String[] projects, final String[][] projectsInclusionPatterns, final String[][] projectsExclusionPatterns, final boolean combineAccessRestrictions, final boolean[] exportedProjects, final String projectOutput, final String[] sourceOutputs, final String[][] inclusionPatterns, final String[][] exclusionPatterns, final String compliance, final boolean simulateImport)1807 	protected IJavaProject createJavaProject(
1808 			final String projectName,
1809 			final String[] sourceFolders,
1810 			final String[] libraries,
1811 			final String[][] librariesInclusionPatterns,
1812 			final String[][] librariesExclusionPatterns,
1813 			final String[] projects,
1814 			final String[][] projectsInclusionPatterns,
1815 			final String[][] projectsExclusionPatterns,
1816 			final boolean combineAccessRestrictions,
1817 			final boolean[] exportedProjects,
1818 			final String projectOutput,
1819 			final String[] sourceOutputs,
1820 			final String[][] inclusionPatterns,
1821 			final String[][] exclusionPatterns,
1822 			final String compliance,
1823 			final boolean simulateImport) throws CoreException {
1824 		return createJavaProject(
1825 				projectName,
1826 				sourceFolders,
1827 				libraries,
1828 				librariesInclusionPatterns,
1829 				librariesExclusionPatterns,
1830 				projects,
1831 				projectsInclusionPatterns,
1832 				projectsExclusionPatterns,
1833 				combineAccessRestrictions,
1834 				exportedProjects,
1835 				projectOutput,
1836 				sourceOutputs,
1837 				inclusionPatterns,
1838 				exclusionPatterns,
1839 				compliance,
1840 				false,
1841 				simulateImport);
1842 	}
createJavaProject( final String projectName, final String[] sourceFolders, final String[] libraries, final String[][] librariesInclusionPatterns, final String[][] librariesExclusionPatterns, final String[] projects, final String[][] projectsInclusionPatterns, final String[][] projectsExclusionPatterns, final boolean combineAccessRestrictions, final boolean[] exportedProjects, final String projectOutput, final String[] sourceOutputs, final String[][] inclusionPatterns, final String[][] exclusionPatterns, final String compliance, final boolean fullJCL, final boolean simulateImport)1843 	protected IJavaProject createJavaProject(
1844 			final String projectName,
1845 			final String[] sourceFolders,
1846 			final String[] libraries,
1847 			final String[][] librariesInclusionPatterns,
1848 			final String[][] librariesExclusionPatterns,
1849 			final String[] projects,
1850 			final String[][] projectsInclusionPatterns,
1851 			final String[][] projectsExclusionPatterns,
1852 			final boolean combineAccessRestrictions,
1853 			final boolean[] exportedProjects,
1854 			final String projectOutput,
1855 			final String[] sourceOutputs,
1856 			final String[][] inclusionPatterns,
1857 			final String[][] exclusionPatterns,
1858 			final String compliance,
1859 			final boolean fullJCL,
1860 			final boolean simulateImport) throws CoreException {
1861 		final IJavaProject[] result = new IJavaProject[1];
1862 		IWorkspaceRunnable create = new IWorkspaceRunnable() {
1863 			public void run(IProgressMonitor monitor) throws CoreException {
1864 				// create project
1865 				createProject(projectName);
1866 
1867 				// set java nature
1868 				addJavaNature(projectName);
1869 
1870 				// create classpath entries
1871 				IProject project = getWorkspaceRoot().getProject(projectName);
1872 				IPath projectPath = project.getFullPath();
1873 				int sourceLength = sourceFolders == null ? 0 : sourceFolders.length;
1874 				int libLength = libraries == null ? 0 : libraries.length;
1875 				int projectLength = projects == null ? 0 : projects.length;
1876 				IClasspathEntry[] entries = new IClasspathEntry[sourceLength+libLength+projectLength];
1877 				for (int i= 0; i < sourceLength; i++) {
1878 					IPath sourcePath = new Path(sourceFolders[i]);
1879 					int segmentCount = sourcePath.segmentCount();
1880 					if (segmentCount > 0) {
1881 						// create folder and its parents
1882 						IContainer container = project;
1883 						for (int j = 0; j < segmentCount; j++) {
1884 							IFolder folder = container.getFolder(new Path(sourcePath.segment(j)));
1885 							if (!folder.exists()) {
1886 								folder.create(true, true, null);
1887 							}
1888 							container = folder;
1889 						}
1890 					}
1891 					IPath outputPath = null;
1892 					if (sourceOutputs != null) {
1893 						// create out folder for source entry
1894 						outputPath = sourceOutputs[i] == null ? null : new Path(sourceOutputs[i]);
1895 						if (outputPath != null && outputPath.segmentCount() > 0) {
1896 							IFolder output = project.getFolder(outputPath);
1897 							if (!output.exists()) {
1898 								output.create(true, true, null);
1899 							}
1900 						}
1901 					}
1902 					// inclusion patterns
1903 					IPath[] inclusionPaths;
1904 					if (inclusionPatterns == null) {
1905 						inclusionPaths = new IPath[0];
1906 					} else {
1907 						String[] patterns = inclusionPatterns[i];
1908 						int length = patterns.length;
1909 						inclusionPaths = new IPath[length];
1910 						for (int j = 0; j < length; j++) {
1911 							String inclusionPattern = patterns[j];
1912 							inclusionPaths[j] = new Path(inclusionPattern);
1913 						}
1914 					}
1915 					// exclusion patterns
1916 					IPath[] exclusionPaths;
1917 					if (exclusionPatterns == null) {
1918 						exclusionPaths = new IPath[0];
1919 					} else {
1920 						String[] patterns = exclusionPatterns[i];
1921 						int length = patterns.length;
1922 						exclusionPaths = new IPath[length];
1923 						for (int j = 0; j < length; j++) {
1924 							String exclusionPattern = patterns[j];
1925 							exclusionPaths[j] = new Path(exclusionPattern);
1926 						}
1927 					}
1928 					// create source entry
1929 					entries[i] =
1930 						JavaCore.newSourceEntry(
1931 							projectPath.append(sourcePath),
1932 							inclusionPaths,
1933 							exclusionPaths,
1934 							outputPath == null ? null : projectPath.append(outputPath)
1935 						);
1936 				}
1937 				for (int i= 0; i < libLength; i++) {
1938 					String lib = libraries[i];
1939 					if (lib.startsWith("JCL")) {
1940 						try {
1941 							// ensure JCL variables are set
1942 							setUpJCLClasspathVariables(compliance, fullJCL);
1943 						} catch (IOException e) {
1944 							e.printStackTrace();
1945 						}
1946 					}
1947 
1948 					// accessible files
1949 					IPath[] accessibleFiles;
1950 					if (librariesInclusionPatterns == null) {
1951 						accessibleFiles = new IPath[0];
1952 					} else {
1953 						String[] patterns = librariesInclusionPatterns[i];
1954 						int length = patterns.length;
1955 						accessibleFiles = new IPath[length];
1956 						for (int j = 0; j < length; j++) {
1957 							String inclusionPattern = patterns[j];
1958 							accessibleFiles[j] = new Path(inclusionPattern);
1959 						}
1960 					}
1961 					// non accessible files
1962 					IPath[] nonAccessibleFiles;
1963 					if (librariesExclusionPatterns == null) {
1964 						nonAccessibleFiles = new IPath[0];
1965 					} else {
1966 						String[] patterns = librariesExclusionPatterns[i];
1967 						int length = patterns.length;
1968 						nonAccessibleFiles = new IPath[length];
1969 						for (int j = 0; j < length; j++) {
1970 							String exclusionPattern = patterns[j];
1971 							nonAccessibleFiles[j] = new Path(exclusionPattern);
1972 						}
1973 					}
1974 					if (lib.indexOf(File.separatorChar) == -1 && lib.charAt(0) != '/' && lib.equals(lib.toUpperCase())) { // all upper case is a var
1975 						char[][] vars = CharOperation.splitOn(',', lib.toCharArray());
1976 						IClasspathAttribute[] extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
1977 						if (CompilerOptions.versionToJdkLevel(compliance) >= ClassFileConstants.JDK9
1978 								&& (lib.startsWith("JCL") || lib.startsWith("CONVERTER_JCL"))) {
1979 							extraAttributes = new IClasspathAttribute[] {
1980 								JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true")
1981 							};
1982 						}
1983 						entries[sourceLength+i] = JavaCore.newVariableEntry(
1984 							new Path(new String(vars[0])),
1985 							vars.length > 1 ? new Path(new String(vars[1])) : null,
1986 							vars.length > 2 ? new Path(new String(vars[2])) : null,
1987 							ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles), // ClasspathEntry.NO_ACCESS_RULES,
1988 							extraAttributes,
1989 							false);
1990 					} else if (lib.startsWith("org.eclipse.jdt.core.tests.model.")) { // container
1991 						entries[sourceLength+i] = JavaCore.newContainerEntry(
1992 								new Path(lib),
1993 								ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles),
1994 								new IClasspathAttribute[0],
1995 								false);
1996 					} else {
1997 						IPath libPath = new Path(lib);
1998 						if (!libPath.isAbsolute() && libPath.segmentCount() > 0 && libPath.getFileExtension() == null) {
1999 							project.getFolder(libPath).create(true, true, null);
2000 							libPath = projectPath.append(libPath);
2001 						}
2002 						entries[sourceLength+i] = JavaCore.newLibraryEntry(
2003 								libPath,
2004 								null,
2005 								null,
2006 								ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles),
2007 								new IClasspathAttribute[0],
2008 								false);
2009 					}
2010 				}
2011 				for  (int i= 0; i < projectLength; i++) {
2012 					boolean isExported = exportedProjects != null && exportedProjects.length > i && exportedProjects[i];
2013 
2014 					// accessible files
2015 					IPath[] accessibleFiles;
2016 					if (projectsInclusionPatterns == null) {
2017 						accessibleFiles = new IPath[0];
2018 					} else {
2019 						String[] patterns = projectsInclusionPatterns[i];
2020 						int length = patterns.length;
2021 						accessibleFiles = new IPath[length];
2022 						for (int j = 0; j < length; j++) {
2023 							String inclusionPattern = patterns[j];
2024 							accessibleFiles[j] = new Path(inclusionPattern);
2025 						}
2026 					}
2027 					// non accessible files
2028 					IPath[] nonAccessibleFiles;
2029 					if (projectsExclusionPatterns == null) {
2030 						nonAccessibleFiles = new IPath[0];
2031 					} else {
2032 						String[] patterns = projectsExclusionPatterns[i];
2033 						int length = patterns.length;
2034 						nonAccessibleFiles = new IPath[length];
2035 						for (int j = 0; j < length; j++) {
2036 							String exclusionPattern = patterns[j];
2037 							nonAccessibleFiles[j] = new Path(exclusionPattern);
2038 						}
2039 					}
2040 
2041 					entries[sourceLength+libLength+i] =
2042 						JavaCore.newProjectEntry(
2043 								new Path(projects[i]),
2044 								ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles),
2045 								combineAccessRestrictions,
2046 								new IClasspathAttribute[0],
2047 								isExported);
2048 				}
2049 
2050 				// create project's output folder
2051 				IPath outputPath = new Path(projectOutput);
2052 				if (outputPath.segmentCount() > 0) {
2053 					IFolder output = project.getFolder(outputPath);
2054 					if (!output.exists()) {
2055 						output.create(true, true, monitor);
2056 					}
2057 				}
2058 
2059 				// set classpath and output location
2060 				JavaProject javaProject = (JavaProject) JavaCore.create(project);
2061 				if (simulateImport)
2062 					javaProject.writeFileEntries(entries, projectPath.append(outputPath));
2063 				else
2064 					javaProject.setRawClasspath(entries, projectPath.append(outputPath), monitor);
2065 
2066 				// set compliance level options
2067 				if ("1.4".equals(compliance)) {
2068 					Map options = new HashMap();
2069 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
2070 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
2071 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
2072 					javaProject.setOptions(options);
2073 				} else if ("1.5".equals(compliance)) {
2074 					Map options = new HashMap();
2075 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
2076 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
2077 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
2078 					javaProject.setOptions(options);
2079 				} else if ("1.6".equals(compliance)) {
2080 					Map options = new HashMap();
2081 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
2082 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
2083 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
2084 					javaProject.setOptions(options);
2085 				} else if ("1.7".equals(compliance)) {
2086 					Map options = new HashMap();
2087 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
2088 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
2089 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
2090 					javaProject.setOptions(options);
2091 				} else if ("1.8".equals(compliance)) {
2092 					Map options = new HashMap();
2093 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
2094 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
2095 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
2096 					javaProject.setOptions(options);
2097 				} else if ("9".equals(compliance)) {
2098 					Map options = new HashMap();
2099 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9);
2100 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9);
2101 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
2102 					javaProject.setOptions(options);
2103 				} else if ("10".equals(compliance)) {
2104 					Map options = new HashMap();
2105 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
2106 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
2107 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
2108 					javaProject.setOptions(options);
2109 				} else if ("11".equals(compliance)) {
2110 					Map options = new HashMap();
2111 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
2112 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
2113 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
2114 					javaProject.setOptions(options);
2115 				} else if ("12".equals(compliance)) {
2116 					Map options = new HashMap();
2117 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
2118 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
2119 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
2120 					javaProject.setOptions(options);
2121 				} else if ("13".equals(compliance)) {
2122 					Map options = new HashMap();
2123 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
2124 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
2125 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
2126 					javaProject.setOptions(options);
2127 				} else if ("14".equals(compliance)) {
2128 					Map options = new HashMap();
2129 					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_14);
2130 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_14);
2131 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_14);
2132 					javaProject.setOptions(options);
2133 				}
2134 				result[0] = javaProject;
2135 			}
2136 		};
2137 		getWorkspace().run(create, null);
2138 		return result[0];
2139 	}
importJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output)2140 	protected IJavaProject importJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output) throws CoreException {
2141 		return
2142 			createJavaProject(
2143 				projectName,
2144 				sourceFolders,
2145 				libraries,
2146 				null/*no inclusion pattern*/,
2147 				null/*no exclusion pattern*/,
2148 				null/*no project*/,
2149 				null/*no inclusion pattern*/,
2150 				null/*no exclusion pattern*/,
2151 				true/*combine access restrictions by default*/,
2152 				null/*no exported project*/,
2153 				output,
2154 				null/*no source outputs*/,
2155 				null/*no inclusion pattern*/,
2156 				null/*no exclusion pattern*/,
2157 				"1.4",
2158 				true/*import*/
2159 			);
2160 	}
2161 	/*
2162 	 * Create simple project.
2163 	 */
createProject(final String projectName)2164 	protected IProject createProject(final String projectName) throws CoreException {
2165 		final IProject project = getProject(projectName);
2166 		IWorkspaceRunnable create = new IWorkspaceRunnable() {
2167 			public void run(IProgressMonitor monitor) throws CoreException {
2168 				project.create(null);
2169 				project.open(null);
2170 			}
2171 		};
2172 		getWorkspace().run(create, null);
2173 		return project;
2174 	}
createSourceZip(String[] pathsAndContents, String zipPath)2175 	public void createSourceZip(String[] pathsAndContents, String zipPath) throws IOException {
2176 		org.eclipse.jdt.core.tests.util.Util.createSourceZip(pathsAndContents, zipPath);
2177 	}
deleteResource(File resource)2178 	public void deleteResource(File resource) {
2179 		int retryCount = 0;
2180 		while (++retryCount <= 60) { // wait 1 minute at most
2181 			if (org.eclipse.jdt.core.tests.util.Util.delete(resource)) {
2182 				break;
2183 			}
2184 		}
2185 	}
deleteFolder(IPath folderPath)2186 	protected void deleteFolder(IPath folderPath) throws CoreException {
2187 		deleteResource(getFolder(folderPath));
2188 	}
deleteProject(String projectName)2189 	protected void deleteProject(String projectName) throws CoreException {
2190 		IProject project = getProject(projectName);
2191 		if (project.exists() && !project.isOpen()) { // force opening so that project can be deleted without logging (see bug 23629)
2192 			project.open(null);
2193 		}
2194 		deleteResource(project);
2195 	}
deleteProject(IJavaProject project)2196 	protected void deleteProject(IJavaProject project) throws CoreException {
2197 		if (project.exists() && !project.isOpen()) { // force opening so that project can be deleted without logging (see bug 23629)
2198 			project.open(null);
2199 		}
2200 		deleteResource(project.getProject());
2201 	}
2202 
2203 	/**
2204 	 * Batch deletion of projects
2205 	 */
deleteProjects(final String[] projectNames)2206 	protected void deleteProjects(final String[] projectNames) throws CoreException {
2207 		ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
2208 			public void run(IProgressMonitor monitor) throws CoreException {
2209 				if (projectNames != null){
2210 					for (int i = 0, max = projectNames.length; i < max; i++){
2211 						if (projectNames[i] != null)
2212 							deleteProject(projectNames[i]);
2213 					}
2214 				}
2215 			}
2216 		},
2217 		null);
2218 	}
2219 	/**
2220 	 * Delete this resource.
2221 	 */
deleteResource(IResource resource)2222 	public void deleteResource(IResource resource) throws CoreException {
2223 		int retryCount = 0; // wait 1 minute at most
2224 		IStatus status = null;
2225 		while (++retryCount <= 6) {
2226 			status = org.eclipse.jdt.core.tests.util.Util.delete(resource);
2227 			if (status.isOK()) {
2228 				return;
2229 			}
2230 			System.gc();
2231 		}
2232 		throw new CoreException(status);
2233 	}
2234 	/**
2235 	 * Returns true if this delta is flagged as having changed children.
2236 	 */
deltaChildrenChanged(IJavaElementDelta delta)2237 	protected boolean deltaChildrenChanged(IJavaElementDelta delta) {
2238 		return delta.getKind() == IJavaElementDelta.CHANGED &&
2239 			(delta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0;
2240 	}
2241 	/**
2242 	 * Returns true if this delta is flagged as having had a content change
2243 	 */
deltaContentChanged(IJavaElementDelta delta)2244 	protected boolean deltaContentChanged(IJavaElementDelta delta) {
2245 		return delta.getKind() == IJavaElementDelta.CHANGED &&
2246 			(delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0;
2247 	}
2248 	/**
2249 	 * Returns true if this delta is flagged as having moved from a location
2250 	 */
deltaMovedFrom(IJavaElementDelta delta)2251 	protected boolean deltaMovedFrom(IJavaElementDelta delta) {
2252 		return delta.getKind() == IJavaElementDelta.ADDED &&
2253 			(delta.getFlags() & IJavaElementDelta.F_MOVED_FROM) != 0;
2254 	}
2255 	/**
2256 	 * Returns true if this delta is flagged as having moved to a location
2257 	 */
deltaMovedTo(IJavaElementDelta delta)2258 	protected boolean deltaMovedTo(IJavaElementDelta delta) {
2259 		return delta.getKind() == IJavaElementDelta.REMOVED &&
2260 			(delta.getFlags() & IJavaElementDelta.F_MOVED_TO) != 0;
2261 	}
2262 	/**
2263 	 * Ensure that the positioned element is in the correct position within the parent.
2264 	 */
ensureCorrectPositioning(IParent container, IJavaElement sibling, IJavaElement positioned)2265 	public void ensureCorrectPositioning(IParent container, IJavaElement sibling, IJavaElement positioned) throws JavaModelException {
2266 		IJavaElement[] children = container.getChildren();
2267 		if (sibling != null) {
2268 			// find the sibling
2269 			boolean found = false;
2270 			for (int i = 0; i < children.length; i++) {
2271 				if (children[i].equals(sibling)) {
2272 					assertTrue("element should be before sibling", i > 0 && children[i - 1].equals(positioned));
2273 					found = true;
2274 					break;
2275 				}
2276 			}
2277 			assertTrue("Did not find sibling", found);
2278 		}
2279 	}
getJCL15PlusLibraryIfNeeded(String compliance)2280 	protected String[] getJCL15PlusLibraryIfNeeded(String compliance) throws JavaModelException, IOException {
2281 		if (compliance.charAt(compliance.length()-1) >= '8' && (AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_8) != 0) {
2282 			// ensure that the JCL 18 lib is setup (i.e. that the jclMin18.jar is copied)
2283 			setUpJCLClasspathVariables("1.8");
2284 			return new String[] {getExternalJCLPathString("1.8")};
2285 		}
2286 		if (compliance.charAt(compliance.length()-1) >= '5' && (AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_5) != 0) {
2287 			// ensure that the JCL 15 lib is setup (i.e. that the jclMin15.jar is copied)
2288 			setUpJCLClasspathVariables("1.5");
2289 			return new String[] {getExternalJCLPathString("1.5")};
2290 		}
2291 		return null;
2292 	}
2293 	/**
2294 	 * Returns the specified compilation unit in the given project, root, and
2295 	 * package fragment or <code>null</code> if it does not exist.
2296 	 */
getClassFile(String projectName, String rootPath, String packageName, String className)2297 	public IOrdinaryClassFile getClassFile(String projectName, String rootPath, String packageName, String className) throws JavaModelException {
2298 		IPackageFragment pkg= getPackageFragment(projectName, rootPath, packageName);
2299 		if (pkg == null) {
2300 			return null;
2301 		}
2302 		return pkg.getOrdinaryClassFile(className);
2303 	}
getCompilationUnit(String path)2304 	protected ICompilationUnit getCompilationUnit(String path) {
2305 		return (ICompilationUnit)JavaCore.create(getFile(path));
2306 	}
2307 	/**
2308 	 * Returns the specified compilation unit in the given project, root, and
2309 	 * package fragment or <code>null</code> if it does not exist.
2310 	 */
getCompilationUnit(String projectName, String rootPath, String packageName, String cuName)2311 	public ICompilationUnit getCompilationUnit(String projectName, String rootPath, String packageName, String cuName) throws JavaModelException {
2312 		IPackageFragment pkg= getPackageFragment(projectName, rootPath, packageName);
2313 		if (pkg == null) {
2314 			return null;
2315 		}
2316 		return pkg.getCompilationUnit(cuName);
2317 	}
2318 	/**
2319 	 * Returns the specified compilation unit in the given project, root, and
2320 	 * package fragment or <code>null</code> if it does not exist.
2321 	 */
getCompilationUnits(String projectName, String rootPath, String packageName)2322 	public ICompilationUnit[] getCompilationUnits(String projectName, String rootPath, String packageName) throws JavaModelException {
2323 		IPackageFragment pkg= getPackageFragment(projectName, rootPath, packageName);
2324 		if (pkg == null) {
2325 			return null;
2326 		}
2327 		return pkg.getCompilationUnits();
2328 	}
getCompilationUnitFor(IJavaElement element)2329 	protected ICompilationUnit getCompilationUnitFor(IJavaElement element) {
2330 
2331 		if (element instanceof ICompilationUnit) {
2332 			return (ICompilationUnit)element;
2333 		}
2334 
2335 		if (element instanceof IMember) {
2336 			return ((IMember)element).getCompilationUnit();
2337 		}
2338 
2339 		if (element instanceof IPackageDeclaration ||
2340 			element instanceof IImportDeclaration) {
2341 				return (ICompilationUnit)element.getParent();
2342 			}
2343 
2344 		return null;
2345 
2346 	}
getExternalFile(String relativePath)2347 	protected File getExternalFile(String relativePath) {
2348 		return new File(getExternalPath(), relativePath);
2349 	}
2350 
getExternalResourcePath(String relativePath)2351 	protected String getExternalResourcePath(String relativePath) {
2352 		return getExternalPath() + relativePath;
2353 	}
2354 
2355 	/**
2356 	 * Returns the IPath to the external java class library (e.g. jclMin.jar)
2357 	 */
getExternalJCLPath()2358 	protected IPath getExternalJCLPath() {
2359 		return new Path(getExternalJCLPathString(""));
2360 	}
2361 	/**
2362 	 * Returns the IPath to the external java class library (e.g. jclMin.jar)
2363 	 */
getExternalJCLPath(String compliance)2364 	protected IPath getExternalJCLPath(String compliance) {
2365 		return new Path(getExternalJCLPathString(compliance));
2366 	}
2367 	/**
2368 	 * Returns the java.io path to the external java class library (e.g. jclMin.jar)
2369 	 */
getExternalJCLPathString()2370 	protected String getExternalJCLPathString() {
2371 		return getExternalJCLPathString("");
2372 	}
2373 	/**
2374 	 * Returns the java.io path to the external java class library (e.g. jclMin.jar)
2375 	 */
getExternalJCLPathString(String compliance)2376 	protected String getExternalJCLPathString(String compliance) {
2377 		return getExternalPath() + "jclMin" + compliance + ".jar";
2378 	}
getExternalJCLPathString(String compliance, boolean useFullJCL)2379 	protected String getExternalJCLPathString(String compliance, boolean useFullJCL) {
2380 		if (useFullJCL) {
2381 			return getExternalPath() + "jclFull" + compliance + ".jar";
2382 		} else {
2383 			return getExternalJCLPathString(compliance);
2384 		}
2385 	}
2386 	/**
2387 	 * Returns the IPath to the root source of the external java class library (e.g. "src")
2388 	 */
getExternalJCLRootSourcePath()2389 	protected IPath getExternalJCLRootSourcePath() {
2390 		return new Path("src");
2391 	}
2392 	/**
2393 	 * Returns the IPath to the source of the external java class library (e.g. jclMinsrc.zip)
2394 	 */
getExternalJCLSourcePath()2395 	protected IPath getExternalJCLSourcePath() {
2396 		return new Path(getExternalJCLSourcePathString(""));
2397 	}
2398 	/**
2399 	 * Returns the IPath to the source of the external java class library (e.g. jclMinsrc.zip)
2400 	 */
getExternalJCLSourcePath(String compliance)2401 	protected IPath getExternalJCLSourcePath(String compliance) {
2402 		return new Path(getExternalJCLSourcePathString(compliance));
2403 	}
2404 	/**
2405 	 * Returns the java.io path to the source of the external java class library (e.g. jclMinsrc.zip)
2406 	 */
getExternalJCLSourcePathString()2407 	protected String getExternalJCLSourcePathString() {
2408 		return getExternalJCLSourcePathString("");
2409 	}
2410 	/**
2411 	 * Returns the java.io path to the source of the external java class library (e.g. jclMinsrc.zip)
2412 	 */
getExternalJCLSourcePathString(String compliance)2413 	protected String getExternalJCLSourcePathString(String compliance) {
2414 		return getExternalPath() + "jclMin" + compliance + "src.zip";
2415 	}
2416 	/*
2417 	 * Returns the OS path to the external directory that contains external jar files.
2418 	 * This path ends with a File.separatorChar.
2419 	 */
getExternalPath()2420 	protected String getExternalPath() {
2421 		if (EXTERNAL_JAR_DIR_PATH == null)
2422 			try {
2423 				String path = getWorkspaceRoot().getLocation().toFile().getParentFile().getCanonicalPath();
2424 				if (path.charAt(path.length()-1) != File.separatorChar)
2425 					path += File.separatorChar;
2426 				EXTERNAL_JAR_DIR_PATH = path;
2427 			} catch (IOException e) {
2428 				e.printStackTrace();
2429 			}
2430 		return EXTERNAL_JAR_DIR_PATH;
2431 	}
2432 	/*
2433 	 * Returns the OS path to the workspace directory.
2434 	 * This path ends with a File.separatorChar.
2435 	 */
getWorkspacePath()2436 	protected String getWorkspacePath() {
2437 		if (WORKSPACE_DIR_PATH == null)
2438 			try {
2439 				String path = getWorkspaceRoot().getLocation().toFile().getCanonicalPath();
2440 				if (path.charAt(path.length()-1) != File.separatorChar)
2441 					path += File.separatorChar;
2442 				WORKSPACE_DIR_PATH = path;
2443 			} catch (IOException e) {
2444 				e.printStackTrace();
2445 			}
2446 		return WORKSPACE_DIR_PATH;
2447 	}
getFile(String path)2448 	protected IFile getFile(String path) {
2449 		return getWorkspaceRoot().getFile(new Path(path));
2450 	}
getFolder(IPath path)2451 	protected IFolder getFolder(IPath path) {
2452 		return getWorkspaceRoot().getFolder(path);
2453 	}
2454 	/**
2455 	 * Returns the Java Model this test suite is running on.
2456 	 */
getJavaModel()2457 	public IJavaModel getJavaModel() {
2458 		return JavaCore.create(getWorkspaceRoot());
2459 	}
2460 	/**
2461 	 * Returns the Java Project with the given name in this test
2462 	 * suite's model. This is a convenience method.
2463 	 */
getJavaProject(String name)2464 	public IJavaProject getJavaProject(String name) {
2465 		IProject project = getProject(name);
2466 		return JavaCore.create(project);
2467 	}
getLocalVariable(ISourceReference cu, String selectAt, String selection)2468 	protected ILocalVariable getLocalVariable(ISourceReference cu, String selectAt, String selection) throws JavaModelException {
2469 		IJavaElement[] elements = codeSelect(cu, selectAt, selection);
2470 		if (elements.length == 0) return null;
2471 		if (elements[0] instanceof ILocalVariable) {
2472 			return (ILocalVariable)elements[0];
2473 		}
2474 		return null;
2475 	}
getLocalVariable(String cuPath, String selectAt, String selection)2476 	protected ILocalVariable getLocalVariable(String cuPath, String selectAt, String selection) throws JavaModelException {
2477 		ISourceReference cu = getCompilationUnit(cuPath);
2478 		return getLocalVariable(cu, selectAt, selection);
2479 	}
getNameSource(String cuSource, IJavaElement element)2480 	protected String getNameSource(String cuSource, IJavaElement element) throws JavaModelException {
2481 		ISourceRange nameRange;
2482 		switch (element.getElementType()) {
2483 			case IJavaElement.TYPE_PARAMETER:
2484 				nameRange = ((ITypeParameter) element).getNameRange();
2485 				break;
2486 			case IJavaElement.ANNOTATION:
2487 				nameRange = ((IAnnotation) element).getNameRange();
2488 				break;
2489 			case IJavaElement.PACKAGE_DECLARATION :
2490 				nameRange = ((IPackageDeclaration) element).getNameRange();
2491 				break;
2492 			case IJavaElement.IMPORT_DECLARATION :
2493 				nameRange = ((IImportDeclaration) element).getNameRange();
2494 				break;
2495 			default:
2496 				nameRange = ((IMember) element).getNameRange();
2497 				break;
2498 		}
2499 		return getSource(cuSource, nameRange);
2500 	}
getSource(String cuSource, ISourceRange sourceRange)2501 	protected String getSource(String cuSource, ISourceRange sourceRange) throws JavaModelException {
2502 		int start = sourceRange.getOffset();
2503 		int end = start+sourceRange.getLength();
2504 		String actualSource = start >= 0 && end >= start ? cuSource.substring(start, end) : "";
2505 		return actualSource;
2506 	}
2507 	/**
2508 	 * Returns the specified package fragment in the given project and root, or
2509 	 * <code>null</code> if it does not exist.
2510 	 * The rootPath must be specified as a project relative path. The empty
2511 	 * path refers to the default package fragment.
2512 	 */
getPackageFragment(String projectName, String rootPath, String packageName)2513 	public IPackageFragment getPackageFragment(String projectName, String rootPath, String packageName) throws JavaModelException {
2514 		IPackageFragmentRoot root= getPackageFragmentRoot(projectName, rootPath);
2515 		if (root == null) {
2516 			return null;
2517 		}
2518 		return root.getPackageFragment(packageName);
2519 	}
2520 	/**
2521 	 * Returns the specified package fragment root in the given project, or
2522 	 * <code>null</code> if it does not exist.
2523 	 * If relative, the rootPath must be specified as a project relative path.
2524 	 * The empty path refers to the package fragment root that is the project
2525 	 * folder itself.
2526 	 * If absolute, the rootPath refers to either an external jar, or a resource
2527 	 * internal to the workspace
2528 	 */
getPackageFragmentRoot( String projectName, String rootPath)2529 	public IPackageFragmentRoot getPackageFragmentRoot(
2530 		String projectName,
2531 		String rootPath)
2532 		throws JavaModelException {
2533 
2534 		IJavaProject project = getJavaProject(projectName);
2535 		if (project == null) {
2536 			return null;
2537 		}
2538 		IPath path = new Path(rootPath);
2539 		if (path.isAbsolute()) {
2540 			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
2541 			IResource resource = workspaceRoot.findMember(path);
2542 			IPackageFragmentRoot root;
2543 			if (resource == null) {
2544 				// external jar
2545 				root = project.getPackageFragmentRoot(rootPath);
2546 			} else {
2547 				// resource in the workspace
2548 				root = project.getPackageFragmentRoot(resource);
2549 			}
2550 			return root;
2551 		} else {
2552 			IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
2553 			if (roots == null || roots.length == 0) {
2554 				return null;
2555 			}
2556 			for (int i = 0; i < roots.length; i++) {
2557 				IPackageFragmentRoot root = roots[i];
2558 				if (!root.isExternal()
2559 					&& root.getUnderlyingResource().getProjectRelativePath().equals(path)) {
2560 					return root;
2561 				}
2562 			}
2563 		}
2564 		return null;
2565 	}
getProject(String project)2566 	protected IProject getProject(String project) {
2567 		return getWorkspaceRoot().getProject(project);
2568 	}
2569 	/**
2570 	 * Returns the OS path to the directory that contains this plugin.
2571 	 */
getPluginDirectoryPath()2572 	protected String getPluginDirectoryPath() {
2573 		try {
2574 			URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.model").getEntry("/");
2575 			return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath();
2576 		} catch (IOException e) {
2577 			e.printStackTrace();
2578 		}
2579 		return null;
2580 	}
getSourceWorkspacePath()2581 	public String getSourceWorkspacePath() {
2582 		return getPluginDirectoryPath() +  java.io.File.separator + "workspace";
2583 	}
getWorkingCopy(String path, boolean computeProblems)2584 	public ICompilationUnit getWorkingCopy(String path, boolean computeProblems) throws JavaModelException {
2585 		return getWorkingCopy(path, "", computeProblems);
2586 	}
getWorkingCopy(String path, String source)2587 	public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
2588 		return getWorkingCopy(path, source, false);
2589 	}
getWorkingCopy(String path, String source, boolean computeProblems)2590 	public ICompilationUnit getWorkingCopy(String path, String source, boolean computeProblems) throws JavaModelException {
2591 		if (this.wcOwner == null) {
2592 			this.wcOwner = newWorkingCopyOwner(computeProblems ? new BasicProblemRequestor() : null);
2593 			return getWorkingCopy(path, source, this.wcOwner);
2594 		}
2595 		ICompilationUnit wc = getWorkingCopy(path, source, this.wcOwner);
2596 		// Verify that compute problem parameter is compatible with working copy problem requestor
2597 		if (computeProblems) {
2598 			assertNotNull("Cannot compute problems if the problem requestor of the working copy owner is set to null!", this.wcOwner.getProblemRequestor(wc));
2599 		} else {
2600 			assertNull("Cannot ignore problems if the problem requestor of the working copy owner is not set to null!", this.wcOwner.getProblemRequestor(wc));
2601 		}
2602 		return wc;
2603 	}
getWorkingCopy(String path, String source, WorkingCopyOwner owner)2604 	public ICompilationUnit getWorkingCopy(String path, String source, WorkingCopyOwner owner) throws JavaModelException {
2605 		ICompilationUnit workingCopy = getCompilationUnit(path);
2606 		if (owner != null)
2607 			workingCopy = workingCopy.getWorkingCopy(owner, null/*no progress monitor*/);
2608 		else
2609 			workingCopy.becomeWorkingCopy(null/*no progress monitor*/);
2610 		workingCopy.getBuffer().setContents(source);
2611 		if (owner != null) {
2612 			IProblemRequestor problemRequestor = owner.getProblemRequestor(workingCopy);
2613 			if (problemRequestor instanceof ProblemRequestor) {
2614 				((ProblemRequestor) problemRequestor).initialize(source.toCharArray());
2615 			}
2616 		}
2617 		workingCopy.makeConsistent(null/*no progress monitor*/);
2618 		return workingCopy;
2619 	}
2620 	/**
2621 	 * This method is still necessary when we need to use an owner and a specific problem requestor
2622 	 * (typically while using primary owner).
2623 	 * @deprecated
2624 	 */
getWorkingCopy(String path, String source, WorkingCopyOwner owner, IProblemRequestor problemRequestor)2625 	public ICompilationUnit getWorkingCopy(String path, String source, WorkingCopyOwner owner, IProblemRequestor problemRequestor) throws JavaModelException {
2626 		ICompilationUnit workingCopy = getCompilationUnit(path);
2627 		if (owner != null)
2628 			workingCopy = workingCopy.getWorkingCopy(owner, problemRequestor, null/*no progress monitor*/);
2629 		else
2630 			workingCopy.becomeWorkingCopy(problemRequestor, null/*no progress monitor*/);
2631 		workingCopy.getBuffer().setContents(source);
2632 		if (problemRequestor instanceof ProblemRequestor)
2633 			((ProblemRequestor) problemRequestor).initialize(source.toCharArray());
2634 		workingCopy.makeConsistent(null/*no progress monitor*/);
2635 		return workingCopy;
2636 	}
2637 	/**
2638 	 * Returns the IWorkspace this test suite is running on.
2639 	 */
getWorkspace()2640 	public IWorkspace getWorkspace() {
2641 		return ResourcesPlugin.getWorkspace();
2642 	}
getWorkspaceRoot()2643 	public IWorkspaceRoot getWorkspaceRoot() {
2644 		return getWorkspace().getRoot();
2645 	}
discardWorkingCopies(ICompilationUnit[] units)2646 	protected void discardWorkingCopies(ICompilationUnit[] units) throws JavaModelException {
2647 		if (units == null) return;
2648 		for (int i = 0, length = units.length; i < length; i++)
2649 			if (units[i] != null)
2650 				units[i].discardWorkingCopy();
2651 	}
2652 
displayString(String toPrint, int indent)2653 	protected String displayString(String toPrint, int indent) {
2654     	char[] toDisplay = toPrint.toCharArray();
2655     	toDisplay =
2656     		CharOperation.replace(
2657     			toDisplay,
2658     			getWorkspacePath().toCharArray(),
2659     			"getWorkspacePath()".toCharArray());
2660     	toDisplay =
2661     		CharOperation.replace(
2662     			toDisplay,
2663     			getExternalJCLPathString().toCharArray(),
2664     			"getExternalJCLPathString()".toCharArray());
2665 		toDisplay =
2666     		CharOperation.replace(
2667     			toDisplay,
2668     			getExternalJCLPathString("1.5").toCharArray(),
2669     			"getExternalJCLPathString(\"1.5\")".toCharArray());
2670 		toDisplay =
2671     		CharOperation.replace(
2672     			toDisplay,
2673     			getExternalPath().toCharArray(),
2674     			"getExternalPath()".toCharArray());
2675 
2676 		toDisplay =
2677     		CharOperation.replace(
2678     			toDisplay,
2679     			org.eclipse.jdt.core.tests.util.Util.displayString(getExternalJCLSourcePathString(), 0).toCharArray(),
2680     			"getExternalJCLSourcePathString()".toCharArray());
2681 		toDisplay =
2682     		CharOperation.replace(
2683     			toDisplay,
2684     			org.eclipse.jdt.core.tests.util.Util.displayString(getExternalJCLSourcePathString("1.5"), 0).toCharArray(),
2685     			"getExternalJCLSourcePathString(\"1.5\")".toCharArray());
2686 
2687     	toDisplay = org.eclipse.jdt.core.tests.util.Util.displayString(new String(toDisplay), indent).toCharArray();
2688 
2689     	toDisplay =
2690     		CharOperation.replace(
2691     			toDisplay,
2692     			"getWorkspacePath()".toCharArray(),
2693     			("\"+ getWorkspacePath() + \"").toCharArray());
2694     	toDisplay =
2695     		CharOperation.replace(
2696     			toDisplay,
2697     			"getExternalJCLPathString()".toCharArray(),
2698     			("\"+ getExternalJCLPathString() + \"").toCharArray());
2699     	toDisplay =
2700     		CharOperation.replace(
2701     			toDisplay,
2702     			"getExternalJCLPathString(\\\"1.5\\\")".toCharArray(),
2703     			("\"+ getExternalJCLPathString(\"1.5\") + \"").toCharArray());
2704     	toDisplay =
2705     		CharOperation.replace(
2706     			toDisplay,
2707     			"getExternalJCLSourcePathString()".toCharArray(),
2708     			("\"+ getExternalJCLSourcePathString() + \"").toCharArray());
2709     	toDisplay =
2710     		CharOperation.replace(
2711     			toDisplay,
2712     			"getExternalJCLSourcePathString(\\\"1.5\\\")".toCharArray(),
2713     			("\"+ getExternalJCLSourcePathString(\"1.5\") + \"").toCharArray());
2714     	toDisplay =
2715     		CharOperation.replace(
2716     			toDisplay,
2717     			"getExternalPath()".toCharArray(),
2718     			("\"+ getExternalPath() + \"").toCharArray());
2719     	return new String(toDisplay);
2720     }
2721 
newExternalWorkingCopy(String name, final String contents)2722 	protected ICompilationUnit newExternalWorkingCopy(String name, final String contents) throws JavaModelException {
2723 		return newExternalWorkingCopy(name, null/*no classpath*/, null/*no problem requestor*/, contents);
2724 	}
newExternalWorkingCopy(String name, IClasspathEntry[] classpath, final IProblemRequestor problemRequestor, final String contents)2725 	protected ICompilationUnit newExternalWorkingCopy(String name, IClasspathEntry[] classpath, final IProblemRequestor problemRequestor, final String contents) throws JavaModelException {
2726 		WorkingCopyOwner owner = new WorkingCopyOwner() {
2727 			public IBuffer createBuffer(ICompilationUnit wc) {
2728 				IBuffer buffer = super.createBuffer(wc);
2729 				buffer.setContents(contents);
2730 				return buffer;
2731 			}
2732 			public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
2733 				return problemRequestor;
2734 			}
2735 		};
2736 		return owner.newWorkingCopy(name, classpath, null/*no progress monitor*/);
2737 	}
2738 
2739 	/**
2740 	 * Create a new working copy owner using given problem requestor
2741 	 * to report problem.
2742 	 *
2743 	 * @param problemRequestor The requestor used to report problems
2744 	 * @return The created working copy owner
2745 	 */
newWorkingCopyOwner(final IProblemRequestor problemRequestor)2746 	protected WorkingCopyOwner newWorkingCopyOwner(final IProblemRequestor problemRequestor) {
2747 		return new WorkingCopyOwner() {
2748 			public IProblemRequestor getProblemRequestor(ICompilationUnit unit) {
2749 				return problemRequestor;
2750 			}
2751 		};
2752 	}
2753 
2754 	public byte[] read(java.io.File file) throws java.io.IOException {
2755 		int fileLength;
2756 		byte[] fileBytes = new byte[fileLength = (int) file.length()];
2757 		java.io.FileInputStream stream = new java.io.FileInputStream(file);
2758 		int bytesRead = 0;
2759 		int lastReadSize = 0;
2760 		try {
2761 			while ((lastReadSize != -1) && (bytesRead != fileLength)) {
2762 				lastReadSize = stream.read(fileBytes, bytesRead, fileLength - bytesRead);
2763 				bytesRead += lastReadSize;
2764 			}
2765 			return fileBytes;
2766 		} finally {
2767 			stream.close();
2768 		}
2769 	}
2770 
2771 	public void refresh(final IJavaProject javaProject) throws CoreException {
2772 		javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
2773 		waitForManualRefresh();
2774 	}
2775 
2776 	protected void refreshExternalArchives(IJavaProject p) throws JavaModelException {
2777 		waitForAutoBuild(); // ensure that the auto-build job doesn't interfere with external jar refreshing
2778 		getJavaModel().refreshExternalArchives(new IJavaElement[] {p}, null);
2779 		Indexer.getInstance().waitForIndex(null);
2780 	}
2781 
2782 	protected void removeJavaNature(String projectName) throws CoreException {
2783 		IProject project = getProject(projectName);
2784 		IProjectDescription description = project.getDescription();
2785 		description.setNatureIds(new String[] {});
2786 		project.setDescription(description, null);
2787 	}
2788 	protected void removeLibrary(IJavaProject javaProject, String jarName, String sourceZipName) throws CoreException, IOException {
2789 		IProject project = javaProject.getProject();
2790 		String projectPath = '/' + project.getName() + '/';
2791 		removeClasspathEntry(javaProject, new Path(projectPath + jarName));
2792 		org.eclipse.jdt.core.tests.util.Util.delete(project.getFile(jarName));
2793 		if (sourceZipName != null && sourceZipName.length() != 0) {
2794 			org.eclipse.jdt.core.tests.util.Util.delete(project.getFile(sourceZipName));
2795 		}
2796 	}
2797 	protected void removeClasspathEntry(IPath path) throws JavaModelException {
2798 		removeClasspathEntry(this.currentProject, path);
2799 	}
2800 	protected void removeClasspathEntry(IJavaProject project, IPath path) throws JavaModelException {
2801 		IClasspathEntry[] entries = project.getRawClasspath();
2802 		int length = entries.length;
2803 		IClasspathEntry[] newEntries = null;
2804 		for (int i = 0; i < length; i++) {
2805 			IClasspathEntry entry = entries[i];
2806 			if (entry.getPath().equals(path)) {
2807 				newEntries = new IClasspathEntry[length-1];
2808 				if (i > 0)
2809 					System.arraycopy(entries, 0, newEntries, 0, i);
2810 				if (i < length-1)
2811 				System.arraycopy(entries, i+1, newEntries, i, length-1-i);
2812 				break;
2813 			}
2814 		}
2815 		if (newEntries != null)
2816 			project.setRawClasspath(newEntries, null);
2817 	}
2818 
2819 	protected void search(IJavaElement element, int limitTo, IJavaSearchScope scope, SearchRequestor requestor) throws CoreException {
2820 		search(element, limitTo, SearchPattern.R_EXACT_MATCH|SearchPattern.R_CASE_SENSITIVE, scope, requestor);
2821 	}
2822 	protected void search(IJavaElement element, int limitTo, int matchRule, IJavaSearchScope scope, SearchRequestor requestor) throws CoreException {
2823 		SearchPattern pattern = SearchPattern.createPattern(element, limitTo, matchRule);
2824 		assertNotNull("Pattern should not be null", pattern);
2825 		new SearchEngine().search(
2826 			pattern,
2827 			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
2828 			scope,
2829 			requestor,
2830 			null
2831 		);
2832 	}
2833 	protected void search(String patternString, int searchFor, int limitTo, IJavaSearchScope scope, SearchRequestor requestor) throws CoreException {
2834 		search(patternString, searchFor, limitTo, SearchPattern.R_EXACT_MATCH|SearchPattern.R_CASE_SENSITIVE, scope, requestor);
2835 	}
2836 	protected void search(String patternString, int searchFor, int limitTo, int matchRule, IJavaSearchScope scope, SearchRequestor requestor) throws CoreException {
2837 		if (patternString.indexOf('*') != -1 || patternString.indexOf('?') != -1)
2838 			matchRule |= SearchPattern.R_PATTERN_MATCH;
2839 		SearchPattern pattern = SearchPattern.createPattern(
2840 			patternString,
2841 			searchFor,
2842 			limitTo,
2843 			matchRule);
2844 		assertNotNull("Pattern should not be null", pattern);
2845 		new SearchEngine().search(
2846 			pattern,
2847 			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
2848 			scope,
2849 			requestor,
2850 			null);
2851 	}
2852 
2853 	/*
2854 	 * Selection of java elements.
2855 	 */
2856 
2857 	/*
2858 	 * Search several occurences of a selection in a compilation unit source and returns its start and length.
2859 	 * If occurence is negative, then perform a backward search from the end of file.
2860 	 * If selection starts or ends with a comment (to help identification in source), it is removed from returned selection info.
2861 	 */
2862 	int[] selectionInfo(ICompilationUnit cu, String selection, int occurences) throws JavaModelException {
2863 		String source = cu.getSource();
2864 		int index = occurences < 0 ? source.lastIndexOf(selection) : source.indexOf(selection);
2865 		int max = Math.abs(occurences)-1;
2866 		for (int n=0; index >= 0 && n<max; n++) {
2867 			index = occurences < 0 ? source.lastIndexOf(selection, index) : source.indexOf(selection, index+selection.length());
2868 		}
2869 		StringBuffer msg = new StringBuffer("Selection '");
2870 		msg.append(selection);
2871 		if (index >= 0) {
2872 			if (selection.startsWith("/**")) { // comment is before
2873 				int start = source.indexOf("*/", index);
2874 				if (start >=0) {
2875 					return new int[] { start+2, selection.length()-(start+2-index) };
2876 				} else {
2877 					msg.append("' starts with an unterminated comment");
2878 				}
2879 			} else if (selection.endsWith("*/")) { // comment is after
2880 				int end = source.lastIndexOf("/**", index+selection.length());
2881 				if (end >=0) {
2882 					return new int[] { index, index-end };
2883 				} else {
2884 					msg.append("' ends with an unstartted comment");
2885 				}
2886 			} else { // no comment => use whole selection
2887 				return new int[] { index, selection.length() };
2888 			}
2889 		} else {
2890 			msg.append("' was not found in ");
2891 		}
2892 		msg.append(cu.getElementName());
2893 		msg.append(":\n");
2894 		msg.append(source);
2895 		assertTrue(msg.toString(), false);
2896 		return null;
2897 	}
2898 
2899 	/**
2900 	 * Select a field in a compilation unit identified with the first occurence in the source of a given selection.
2901 	 * @param unit
2902 	 * @param selection
2903 	 * @return IField
2904 	 * @throws JavaModelException
2905 	 */
2906 	protected IField selectField(ICompilationUnit unit, String selection) throws JavaModelException {
2907 		return selectField(unit, selection, 1);
2908 	}
2909 
2910 	/**
2911 	 * Select a field in a compilation unit identified with the nth occurence in the source of a given selection.
2912 	 * @param unit
2913 	 * @param selection
2914 	 * @param occurences
2915 	 * @return IField
2916 	 * @throws JavaModelException
2917 	 */
2918 	protected IField selectField(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
2919 		return (IField) selectJavaElement(unit, selection, occurences, IJavaElement.FIELD);
2920 	}
2921 
2922 	/**
2923 	 * Select a local variable in a compilation unit identified with the first occurence in the source of a given selection.
2924 	 * @param unit
2925 	 * @param selection
2926 	 * @return IType
2927 	 * @throws JavaModelException
2928 	 */
2929 	protected ILocalVariable selectLocalVariable(ICompilationUnit unit, String selection) throws JavaModelException {
2930 		return selectLocalVariable(unit, selection, 1);
2931 	}
2932 
2933 	/**
2934 	 * Select a local variable in a compilation unit identified with the nth occurence in the source of a given selection.
2935 	 * @param unit
2936 	 * @param selection
2937 	 * @param occurences
2938 	 * @return IType
2939 	 * @throws JavaModelException
2940 	 */
2941 	protected ILocalVariable selectLocalVariable(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
2942 		return (ILocalVariable) selectJavaElement(unit, selection, occurences, IJavaElement.LOCAL_VARIABLE);
2943 	}
2944 
2945 	/**
2946 	 * Select a method in a compilation unit identified with the first occurence in the source of a given selection.
2947 	 * @param unit
2948 	 * @param selection
2949 	 * @return IMethod
2950 	 * @throws JavaModelException
2951 	 */
2952 	protected IMethod selectMethod(ICompilationUnit unit, String selection) throws JavaModelException {
2953 		return selectMethod(unit, selection, 1);
2954 	}
2955 
2956 	/**
2957 	 * Select a method in a compilation unit identified with the nth occurence in the source of a given selection.
2958 	 * @param unit
2959 	 * @param selection
2960 	 * @param occurences
2961 	 * @return IMethod
2962 	 * @throws JavaModelException
2963 	 */
2964 	protected IMethod selectMethod(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
2965 		return (IMethod) selectJavaElement(unit, selection, occurences, IJavaElement.METHOD);
2966 	}
2967 
2968 	/**
2969 	 * Select a parameterized source method in a compilation unit identified with the first occurence in the source of a given selection.
2970 	 * @param unit
2971 	 * @param selection
2972 	 * @return ParameterizedSourceMethod
2973 	 * @throws JavaModelException
2974 	 */
2975 	protected ResolvedSourceMethod selectParameterizedMethod(ICompilationUnit unit, String selection) throws JavaModelException {
2976 		return selectParameterizedMethod(unit, selection, 1);
2977 	}
2978 
2979 	/**
2980 	 * Select a parameterized source method in a compilation unit identified with the nth occurence in the source of a given selection.
2981 	 * @param unit
2982 	 * @param selection
2983 	 * @param occurences
2984 	 * @return ParameterizedSourceMethod
2985 	 * @throws JavaModelException
2986 	 */
2987 	protected ResolvedSourceMethod selectParameterizedMethod(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
2988 		IMethod type = selectMethod(unit, selection, occurences);
2989 		assertTrue("Not a parameterized source type: "+type.getElementName(), type instanceof ResolvedSourceMethod);
2990 		return (ResolvedSourceMethod) type;
2991 	}
2992 
2993 	/**
2994 	 * Select a parameterized source type in a compilation unit identified with the first occurence in the source of a given selection.
2995 	 * @param unit
2996 	 * @param selection
2997 	 * @return ParameterizedSourceType
2998 	 * @throws JavaModelException
2999 	 */
3000 	protected ResolvedSourceType selectParameterizedType(ICompilationUnit unit, String selection) throws JavaModelException {
3001 		return selectParameterizedType(unit, selection, 1);
3002 	}
3003 
3004 	/**
3005 	 * Select a parameterized source type in a compilation unit identified with the nth occurence in the source of a given selection.
3006 	 * @param unit
3007 	 * @param selection
3008 	 * @param occurences
3009 	 * @return ParameterizedSourceType
3010 	 * @throws JavaModelException
3011 	 */
3012 	protected ResolvedSourceType selectParameterizedType(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
3013 		IType type = selectType(unit, selection, occurences);
3014 		assertTrue("Not a parameterized source type: "+type.getElementName(), type instanceof ResolvedSourceType);
3015 		return (ResolvedSourceType) type;
3016 	}
3017 
3018 	/**
3019 	 * Select a type in a compilation unit identified with the first occurence in the source of a given selection.
3020 	 * @param unit
3021 	 * @param selection
3022 	 * @return IType
3023 	 * @throws JavaModelException
3024 	 */
3025 	protected IType selectType(ICompilationUnit unit, String selection) throws JavaModelException {
3026 		return selectType(unit, selection, 1);
3027 	}
3028 
3029 	/**
3030 	 * Select a type in a compilation unit identified with the nth occurence in the source of a given selection.
3031 	 * @param unit
3032 	 * @param selection
3033 	 * @param occurences
3034 	 * @return IType
3035 	 * @throws JavaModelException
3036 	 */
3037 	protected IType selectType(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
3038 		return (IType) selectJavaElement(unit, selection, occurences, IJavaElement.TYPE);
3039 	}
3040 
3041 	/**
3042 	 * Select a type parameter in a compilation unit identified with the first occurence in the source of a given selection.
3043 	 * @param unit
3044 	 * @param selection
3045 	 * @return IType
3046 	 * @throws JavaModelException
3047 	 */
3048 	protected ITypeParameter selectTypeParameter(ICompilationUnit unit, String selection) throws JavaModelException {
3049 		return selectTypeParameter(unit, selection, 1);
3050 	}
3051 
3052 	/**
3053 	 * Select a type parameter in a compilation unit identified with the nth occurence in the source of a given selection.
3054 	 * @param unit
3055 	 * @param selection
3056 	 * @param occurences
3057 	 * @return IType
3058 	 * @throws JavaModelException
3059 	 */
3060 	protected ITypeParameter selectTypeParameter(ICompilationUnit unit, String selection, int occurences) throws JavaModelException {
3061 		return (ITypeParameter) selectJavaElement(unit, selection, occurences, IJavaElement.TYPE_PARAMETER);
3062 	}
3063 
3064 	/**
3065 	 * Select a java element in a compilation unit identified with the nth occurence in the source of a given selection.
3066 	 * Do not allow subclasses to call this method as we want to verify IJavaElement kind.
3067 	 */
3068 	IJavaElement selectJavaElement(ICompilationUnit unit, String selection, int occurences, int elementType) throws JavaModelException {
3069 		int[] selectionPositions = selectionInfo(unit, selection, occurences);
3070 		IJavaElement[] elements = null;
3071 		if (this.wcOwner == null) {
3072 			elements = unit.codeSelect(selectionPositions[0], selectionPositions[1]);
3073 		} else {
3074 			elements = unit.codeSelect(selectionPositions[0], selectionPositions[1], this.wcOwner);
3075 		}
3076 		assertEquals("Invalid selection number", 1, elements.length);
3077 		assertEquals("Invalid java element type: "+elements[0].getElementName(), elements[0].getElementType(), elementType);
3078 		return elements[0];
3079 	}
3080 
3081 	/* ************
3082 	 * Suite set-ups *
3083 	 *************/
3084 	/**
3085 	 * Sets the class path of the Java project.
3086 	 */
3087 	public void setClasspath(IJavaProject javaProject, IClasspathEntry[] classpath) {
3088 		try {
3089 			javaProject.setRawClasspath(classpath, null);
3090 		} catch (JavaModelException e) {
3091 			e.printStackTrace();
3092 			assertTrue("failed to set classpath", false);
3093 		}
3094 	}
3095 	protected IJavaProject setupModuleProject(String name, String[] sources) throws CoreException {
3096 		return setupModuleProject(name, sources, false);
3097 	}
3098 	protected IJavaProject setupModuleProject(String name, String[] sources, boolean addModulePathContainer) throws CoreException {
3099 		IClasspathEntry[] deps = null;
3100 		if (addModulePathContainer) {
3101 			IClasspathEntry containerEntry = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
3102 			deps = new IClasspathEntry[] {containerEntry};
3103 		}
3104 		return setupModuleProject(name, sources, deps);
3105 	}
3106 	protected IJavaProject setupModuleProject(String name, String[] sources, IClasspathEntry[] deps) throws CoreException {
3107 		return setupModuleProject(name, new String[]{"src"}, sources, deps);
3108 	}
3109 	protected IJavaProject setupModuleProject(String name, String[] srcFolders, String[] sources, IClasspathEntry[] deps) throws CoreException {
3110 		IJavaProject project = createJava9Project(name, srcFolders);
3111 		createSourceFiles(project, sources);
3112 		if (deps != null) {
3113 			IClasspathEntry[] old = project.getRawClasspath();
3114 			IClasspathEntry[] newPath = new IClasspathEntry[old.length + deps.length];
3115 			System.arraycopy(old, 0, newPath, 0, old.length);
3116 			System.arraycopy(deps, 0, newPath, old.length, deps.length);
3117 			project.setRawClasspath(newPath, null);
3118 		}
3119 		return project;
3120 	}
3121 
3122 	protected void createSourceFiles(IJavaProject project, String[] sources) throws CoreException {
3123 		IProgressMonitor monitor = new NullProgressMonitor();
3124 		for (int i = 0; i < sources.length; i+= 2) {
3125 			IPath path = new Path(sources[i]);
3126 			IPath parentPath = path.removeLastSegments(1);
3127 			IFolder folder = project.getProject().getFolder(parentPath);
3128 			if (!folder.exists())
3129 				this.createFolder(folder.getFullPath());
3130 			IFile file = project.getProject().getFile(new Path(sources[i]));
3131 			file.create(new ByteArrayInputStream(sources[i+1].getBytes()), true, monitor);
3132 		}
3133 	}
3134 
3135 	/**
3136 	 * Check locally for the required JCL files, <jclName>.jar and <jclName>src.zip.
3137 	 * If not available, copy from the project resources.
3138 	 */
3139 	public void setupExternalJCL(String jclName) throws IOException {
3140 		String externalPath = getExternalPath();
3141 		String separator = java.io.File.separator;
3142 		String resourceJCLDir = getPluginDirectoryPath() + separator + "JCL";
3143 		java.io.File jclDir = new java.io.File(externalPath);
3144 		java.io.File jclMin =
3145 			new java.io.File(externalPath + jclName + ".jar");
3146 		java.io.File jclMinsrc = new java.io.File(externalPath + jclName + "src.zip");
3147 		if (!jclDir.exists()) {
3148 			if (!jclDir.mkdir()) {
3149 				//mkdir failed
3150 				throw new IOException("Could not create the directory " + jclDir);
3151 			}
3152 			//copy the two files to the JCL directory
3153 			java.io.File resourceJCLMin =
3154 				new java.io.File(resourceJCLDir + separator + jclName + ".jar");
3155 			copy(resourceJCLMin, jclMin);
3156 			java.io.File resourceJCLMinsrc =
3157 				new java.io.File(resourceJCLDir + separator + jclName + "src.zip");
3158 			copy(resourceJCLMinsrc, jclMinsrc);
3159 		} else {
3160 			//check that the two files, jclMin.jar and jclMinsrc.zip are present
3161 			//copy either file that is missing or less recent than the one in workspace
3162 			java.io.File resourceJCLMin =
3163 				new java.io.File(resourceJCLDir + separator + jclName + ".jar");
3164 			if ((jclMin.lastModified() < resourceJCLMin.lastModified())
3165                     || (jclMin.length() != resourceJCLMin.length())) {
3166 				copy(resourceJCLMin, jclMin);
3167 			}
3168 			java.io.File resourceJCLMinsrc =
3169 				new java.io.File(resourceJCLDir + separator + jclName + "src.zip");
3170 			if ((jclMinsrc.lastModified() < resourceJCLMinsrc.lastModified())
3171                     || (jclMinsrc.length() != resourceJCLMinsrc.length())) {
3172 				copy(resourceJCLMinsrc, jclMinsrc);
3173 			}
3174 		}
3175 	}
3176 	protected IJavaProject setUpJavaProject(final String projectName) throws CoreException, IOException {
3177 		this.currentProject = setUpJavaProject(projectName, "1.4");
3178 		return this.currentProject;
3179 	}
3180 	protected IJavaProject setUpJavaProject(final String projectName, String compliance) throws CoreException, IOException {
3181 		this.currentProject =  setUpJavaProject(projectName, compliance, false);
3182 		return this.currentProject;
3183 	}
3184 	protected IJavaProject setUpJavaProject(final String projectName, String compliance, boolean useFullJCL) throws CoreException, IOException {
3185 		// copy files in project from source workspace to target workspace
3186 		String sourceWorkspacePath = getSourceWorkspacePath();
3187 		String targetWorkspacePath = getWorkspaceRoot().getLocation().toFile().getCanonicalPath();
3188 		copyDirectory(new File(sourceWorkspacePath, projectName), new File(targetWorkspacePath, projectName));
3189 
3190 		// ensure variables are set
3191 		setUpJCLClasspathVariables(compliance, useFullJCL);
3192 
3193 		// create project
3194 		final IProject project = getWorkspaceRoot().getProject(projectName);
3195 		IWorkspaceRunnable populate = new IWorkspaceRunnable() {
3196 			public void run(IProgressMonitor monitor) throws CoreException {
3197 				project.create(null);
3198 				project.open(null);
3199 			}
3200 		};
3201 		getWorkspace().run(populate, null);
3202 		IJavaProject javaProject = JavaCore.create(project);
3203 		setUpProjectCompliance(javaProject, compliance, useFullJCL);
3204 		javaProject.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.IGNORE);
3205 		javaProject.setOption(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER, JavaCore.IGNORE);
3206 		javaProject.setOption(JavaCore.COMPILER_PB_FIELD_HIDING, JavaCore.IGNORE);
3207 		javaProject.setOption(JavaCore.COMPILER_PB_LOCAL_VARIABLE_HIDING, JavaCore.IGNORE);
3208 		javaProject.setOption(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING, JavaCore.IGNORE);
3209 		return javaProject;
3210 	}
3211 	protected void setUpProjectCompliance(IJavaProject javaProject, String compliance) throws JavaModelException, IOException {
3212 		setUpProjectCompliance(javaProject, compliance, false);
3213 	}
3214 	protected void setUpProjectCompliance(IJavaProject javaProject, String compliance, boolean useFullJCL) throws JavaModelException, IOException {
3215 		// Look for version to set and return if that's already done
3216 		String version = compliance; // assume that the values of CompilerOptions.VERSION_* are used
3217 		if (version.equals(javaProject.getOption(CompilerOptions.OPTION_Compliance, false))) {
3218 			return;
3219 		}
3220 		String newJclLibString;
3221 		String newJclSrcString;
3222 		if (useFullJCL) {
3223 			if (compliance.equals("10")) {
3224 				newJclLibString = "JCL10_LIB"; // TODO: have no full variant yet
3225 				newJclSrcString = "JCL10_SRC";
3226 			} else {
3227 				newJclLibString = "JCL18_FULL";
3228 				newJclSrcString = "JCL18_SRC"; // Use the same source
3229 			}
3230 		} else {
3231 			if (compliance.equals("14")) {
3232 				newJclLibString = "JCL14_LIB";
3233 				newJclSrcString = "JCL14_SRC";
3234 			} else if (compliance.equals("13")) {
3235 				newJclLibString = "JCL13_LIB";
3236 				newJclSrcString = "JCL13_SRC";
3237 			} else if (compliance.equals("12")) {
3238 				newJclLibString = "JCL12_LIB";
3239 				newJclSrcString = "JCL12_SRC";
3240 			} else if (compliance.equals("11")) {
3241 				newJclLibString = "JCL11_LIB";
3242 				newJclSrcString = "JCL11_SRC";
3243 			} else if (compliance.equals("10")) {
3244 				newJclLibString = "JCL10_LIB";
3245 				newJclSrcString = "JCL10_SRC";
3246 			} else if (compliance.length() < 3) {
3247 					newJclLibString = "JCL19_LIB";
3248 					newJclSrcString = "JCL19_SRC";
3249 			} else if (compliance.charAt(2) > '7') {
3250 				newJclLibString = "JCL18_LIB";
3251 				newJclSrcString = "JCL18_SRC";
3252 			} else if (compliance.charAt(2) > '4') {
3253 				newJclLibString = "JCL15_LIB";
3254 				newJclSrcString = "JCL15_SRC";
3255 			} else {
3256 				newJclLibString = "JCL_LIB";
3257 				newJclSrcString = "JCL_SRC";
3258 			}
3259 		}
3260 
3261 		// ensure variables are set
3262 		setUpJCLClasspathVariables(compliance, useFullJCL);
3263 
3264 		// set options
3265 		Map options = new HashMap();
3266 		options.put(CompilerOptions.OPTION_Compliance, version);
3267 		options.put(CompilerOptions.OPTION_Source, version);
3268 		options.put(CompilerOptions.OPTION_TargetPlatform, version);
3269 		javaProject.setOptions(options);
3270 
3271 		IClasspathEntry[] classpath = javaProject.getRawClasspath();
3272 
3273 		for (int i = 0, length = classpath.length; i < length; i++) {
3274 			IClasspathEntry entry = classpath[i];
3275 			final IPath path = entry.getPath();
3276 			// Choose the new JCL path only if the current JCL path is different
3277 			if (isJCLPath(path) && !path.toString().equals(newJclLibString)) {
3278 					classpath[i] = JavaCore.newVariableEntry(
3279 							new Path(newJclLibString),
3280 							new Path(newJclSrcString),
3281 							entry.getSourceAttachmentRootPath(),
3282 							entry.getAccessRules(),
3283 							new IClasspathAttribute[0],
3284 							entry.isExported());
3285 					break;
3286 			}
3287 		}
3288 		javaProject.setRawClasspath(classpath, null);
3289 	}
3290 	public boolean isJCLPath(IPath path) {
3291 		IPath jclLib = new Path("JCL_LIB");
3292 		IPath jcl5Lib = new Path("JCL15_LIB");
3293 		IPath jcl8Lib = new Path("JCL18_LIB");
3294 		IPath jcl9Lib = new Path("JCL19_LIB");
3295 		IPath jcl10Lib = new Path("JCL10_LIB");
3296 		IPath jcl11Lib = new Path("JCL11_LIB");
3297 		IPath jcl12Lib = new Path("JCL12_LIB");
3298 		IPath jcl13Lib = new Path("JCL13_LIB");
3299 		IPath jcl14Lib = new Path("JCL14_LIB");
3300 		IPath jclFull = new Path("JCL18_FULL");
3301 
3302 		return path.equals(jclLib) || path.equals(jcl5Lib) || path.equals(jcl8Lib) || path.equals(jcl9Lib)
3303 				|| path.equals(jcl10Lib) ||  path.equals(jcl11Lib) || path.equals(jcl12Lib) || path.equals(jcl13Lib)
3304 				|| path.equals(jcl14Lib) || path.equals(jclFull);
3305 	}
3306 	public void setUpJCLClasspathVariables(String compliance) throws JavaModelException, IOException {
3307 		setUpJCLClasspathVariables(compliance, false);
3308 	}
3309 	public void setUpJCLClasspathVariables(String compliance, boolean useFullJCL) throws JavaModelException, IOException {
3310 		if ("1.5".equals(compliance) || "1.6".equals(compliance)) {
3311 			if (JavaCore.getClasspathVariable("JCL15_LIB") == null) {
3312 				setupExternalJCL("jclMin1.5");
3313 				JavaCore.setClasspathVariables(
3314 					new String[] {"JCL15_LIB", "JCL15_SRC", "JCL_SRCROOT"},
3315 					new IPath[] {getExternalJCLPath("1.5"), getExternalJCLSourcePath("1.5"), getExternalJCLRootSourcePath()},
3316 					null);
3317 			}
3318 		} else if ("1.7".equals(compliance)) {
3319 			if (JavaCore.getClasspathVariable("JCL17_LIB") == null) {
3320 				setupExternalJCL("jclMin1.7");
3321 				JavaCore.setClasspathVariables(
3322 					new String[] {"JCL17_LIB", "JCL17_SRC", "JCL_SRCROOT"},
3323 					new IPath[] {getExternalJCLPath("1.7"), getExternalJCLSourcePath("1.7"), getExternalJCLRootSourcePath()},
3324 					null);
3325 			}
3326 		} else if ("1.8".equals(compliance)) {
3327 			if (useFullJCL) {
3328 				if (JavaCore.getClasspathVariable("JCL18_FULL") == null) {
3329 					setupExternalJCL("jclMin1.8"); // Create the whole mininmal 1.8 set, though we will need only the source zip
3330 					setupExternalJCL("jclFull1.8");
3331 					JavaCore.setClasspathVariables(
3332 						new String[] {"JCL18_FULL", "JCL18_SRC", "JCL_SRCROOT"},
3333 						new IPath[] {new Path(getExternalJCLPathString("1.8", true)), getExternalJCLSourcePath("1.8"), getExternalJCLRootSourcePath()},
3334 						null);
3335 				}
3336 			} else if (JavaCore.getClasspathVariable("JCL18_LIB") == null) {
3337 						setupExternalJCL("jclMin1.8");
3338 						JavaCore.setClasspathVariables(
3339 							new String[] {"JCL18_LIB", "JCL18_SRC", "JCL_SRCROOT"},
3340 							new IPath[] {getExternalJCLPath("1.8"), getExternalJCLSourcePath("1.8"), getExternalJCLRootSourcePath()},
3341 							null);
3342 			}
3343 		} else if ("9".equals(compliance)) {
3344 			if (JavaCore.getClasspathVariable("JCL19_LIB") == null) {
3345 				setupExternalJCL("jclMin9");
3346 				JavaCore.setClasspathVariables(
3347 					new String[] {"JCL19_LIB", "JCL19_SRC", "JCL_SRCROOT"},
3348 					new IPath[] {getExternalJCLPath("9"), getExternalJCLSourcePath("9"), getExternalJCLRootSourcePath()},
3349 					null);
3350 			}
3351 		} else if ("10".equals(compliance)) {
3352 			if (JavaCore.getClasspathVariable("JCL10_LIB") == null) {
3353 				setupExternalJCL("jclMin10");
3354 				JavaCore.setClasspathVariables(
3355 					new String[] {"JCL10_LIB", "JCL10_SRC", "JCL_SRCROOT"},
3356 					new IPath[] {getExternalJCLPath("10"), getExternalJCLSourcePath("10"), getExternalJCLRootSourcePath()},
3357 					null);
3358 			}
3359 		} else if ("11".equals(compliance)) {
3360 			if (JavaCore.getClasspathVariable("JCL11_LIB") == null) {
3361 				setupExternalJCL("jclMin11");
3362 				JavaCore.setClasspathVariables(
3363 					new String[] {"JCL11_LIB", "JCL11_SRC", "JCL_SRCROOT"},
3364 					new IPath[] {getExternalJCLPath("11"), getExternalJCLSourcePath("11"), getExternalJCLRootSourcePath()},
3365 					null);
3366 			}
3367 		} else if ("12".equals(compliance)) {
3368 			if (JavaCore.getClasspathVariable("JCL12_LIB") == null) {
3369 				setupExternalJCL("jclMin12");
3370 				JavaCore.setClasspathVariables(
3371 					new String[] {"JCL12_LIB", "JCL12_SRC", "JCL_SRCROOT"},
3372 					new IPath[] {getExternalJCLPath("12"), getExternalJCLSourcePath("12"), getExternalJCLRootSourcePath()},
3373 					null);
3374 			}
3375 		} else if ("13".equals(compliance)) {
3376 			if (JavaCore.getClasspathVariable("JCL13_LIB") == null) {
3377 				setupExternalJCL("jclMin13"); // No need for an explicit jclmin13, just use the same old one.
3378 				JavaCore.setClasspathVariables(
3379 					new String[] {"JCL13_LIB", "JCL13_SRC", "JCL_SRCROOT"},
3380 					new IPath[] {getExternalJCLPath("13"), getExternalJCLSourcePath("13"), getExternalJCLRootSourcePath()},
3381 					null);
3382 			}
3383 		} else if ("14".equals(compliance)) {
3384 			if (JavaCore.getClasspathVariable("JCL14_LIB") == null) {
3385 				setupExternalJCL("jclMin14");
3386 				JavaCore.setClasspathVariables(
3387 					new String[] {"JCL14_LIB", "JCL14_SRC", "JCL_SRCROOT"},
3388 					new IPath[] {getExternalJCLPath("14"), getExternalJCLSourcePath("14"), getExternalJCLRootSourcePath()},
3389 					null);
3390 			}
3391 		} else {
3392 			if (JavaCore.getClasspathVariable("JCL_LIB") == null) {
3393 				setupExternalJCL("jclMin");
3394 				JavaCore.setClasspathVariables(
3395 					new String[] {"JCL_LIB", "JCL_SRC", "JCL_SRCROOT"},
3396 					new IPath[] {getExternalJCLPath(), getExternalJCLSourcePath(), getExternalJCLRootSourcePath()},
3397 					null);
3398 			}
3399 		}
3400 	}
3401 	@Override
3402 	public void setUpSuite() throws Exception {
3403 		super.setUpSuite();
3404 
3405 		// ensure autobuilding is turned off
3406 		IWorkspaceDescription description = getWorkspace().getDescription();
3407 		if (description.isAutoBuilding()) {
3408 			description.setAutoBuilding(false);
3409 			getWorkspace().setDescription(description);
3410 		}
3411 	}
3412 	@Override
3413 	protected void setUp () throws Exception {
3414 		super.setUp();
3415 
3416 		if (NameLookup.VERBOSE || BasicSearchEngine.VERBOSE || JavaModelManager.VERBOSE) {
3417 			System.out.println("--------------------------------------------------------------------------------");
3418 			System.out.println("Running test "+getName()+"...");
3419 		}
3420 	}
3421 	protected void sortElements(IJavaElement[] elements) {
3422 		Util.Comparer comparer = new Util.Comparer() {
3423 			public int compare(Object a, Object b) {
3424 				JavaElement elementA = (JavaElement)a;
3425 				JavaElement elementB = (JavaElement)b;
3426 				char[] tempJCLPath = "<externalJCLPath>".toCharArray();
3427 	    		String idA = new String(CharOperation.replace(
3428 	    			elementA.toStringWithAncestors().toCharArray(),
3429 	    			getExternalJCLPathString().toCharArray(),
3430 	    			tempJCLPath));
3431 	    		String idB = new String(CharOperation.replace(
3432 	    			elementB.toStringWithAncestors().toCharArray(),
3433 	    			getExternalJCLPathString().toCharArray(),
3434 	    			tempJCLPath));
3435 				return idA.compareTo(idB);
3436 			}
3437 		};
3438 		Util.sort(elements, comparer);
3439 	}
3440 	protected void sortResources(Object[] resources) {
3441 		Util.Comparer comparer = new Util.Comparer() {
3442 			public int compare(Object a, Object b) {
3443 				if (a instanceof IResource) {
3444 					IResource resourceA = (IResource)a;
3445 					IResource resourceB = (IResource)b;
3446 					return resourceA.getFullPath().toString().compareTo(resourceB.getFullPath().toString());
3447 				} else {
3448 					IJarEntryResource resourceA = (IJarEntryResource)a;
3449 					IJarEntryResource resourceB = (IJarEntryResource)b;
3450 					return resourceA.getFullPath().toString().compareTo(resourceB.getFullPath().toString());
3451 				}
3452 			}
3453 		};
3454 		Util.sort(resources, comparer);
3455 	}
3456 	protected void sortTypes(IType[] types) {
3457 		Util.Comparer comparer = new Util.Comparer() {
3458 			public int compare(Object a, Object b) {
3459 				IType typeA = (IType)a;
3460 				IType typeB = (IType)b;
3461 				return typeA.getFullyQualifiedName().compareTo(typeB.getFullyQualifiedName());
3462 			}
3463 		};
3464 		Util.sort(types, comparer);
3465 	}
3466 	/*
3467 	 * Simulate a save/exit of the workspace
3468 	 */
3469 	protected void simulateExit() throws CoreException {
3470 		waitForAutoBuild();
3471 		getWorkspace().save(true/*full save*/, null/*no progress*/);
3472 		JavaModelManager.getJavaModelManager().shutdown();
3473 	}
3474 	/*
3475 	 * Simulate a save/exit/restart of the workspace
3476 	 */
3477 	protected void simulateExitRestart() throws CoreException {
3478 		simulateExit();
3479 		simulateRestart();
3480 	}
3481 	/*
3482 	 * Simulate a restart of the workspace
3483 	 */
3484 	protected void simulateRestart() throws CoreException {
3485 		JavaModelManager.doNotUse(); // reset the MANAGER singleton
3486 		JavaModelManager.getJavaModelManager().startup();
3487 		new JavaCorePreferenceInitializer().initializeDefaultPreferences();
3488 	}
3489 	/**
3490 	 * Starts listening to element deltas, and queues them in fgDeltas.
3491 	 */
3492 	public void startDeltas(DeltaListener listener) {
3493 		clearDeltas(listener);
3494 		JavaCore.addElementChangedListener(listener);
3495 		getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
3496 	}
3497 	/**
3498 	 * Stops listening to element deltas, and clears the current deltas.
3499 	 */
3500 	public void stopDeltas(DeltaListener listener) {
3501 		getWorkspace().removeResourceChangeListener(listener);
3502 		JavaCore.removeElementChangedListener(listener);
3503 		clearDeltas(listener);
3504 	}
3505 	/**
3506 	 * Starts listening to element deltas, and queues them in fgDeltas.
3507 	 */
3508 	public void startDeltas() {
3509 		clearDeltas();
3510 		JavaCore.addElementChangedListener(this.deltaListener);
3511 		getWorkspace().addResourceChangeListener(this.deltaListener, IResourceChangeEvent.POST_CHANGE);
3512 	}
3513 	/**
3514 	 * Stops listening to element deltas, and clears the current deltas.
3515 	 */
3516 	public void stopDeltas() {
3517 		getWorkspace().removeResourceChangeListener(this.deltaListener);
3518 		JavaCore.removeElementChangedListener(this.deltaListener);
3519 		clearDeltas();
3520 	}
3521 	protected void startLogListening() {
3522 		startLogListening(JavaCore.getPlugin().getLog());
3523 	}
3524 	protected void startLogListening(ILog logToListen) {
3525 		stopLogListening(); // cleanup if we forgot to stop listening
3526 		this.log = logToListen;
3527 		this.logListener = new ILogListener(){
3528 			private StringBuffer buffer = new StringBuffer();
3529 			public void logging(IStatus status, String plugin) {
3530 				this.buffer.append(status);
3531 				this.buffer.append('\n');
3532 			}
3533 			public String toString() {
3534 				return this.buffer.toString();
3535 			}
3536 		};
3537 		if (logToListen == null) {
3538 			Platform.addLogListener(this.logListener);
3539 		} else {
3540 			this.log.addLogListener(this.logListener);
3541 		}
3542 	}
3543 	protected void stopLogListening() {
3544 		if (this.logListener == null)
3545 			return;
3546 		if (this.log == null) {
3547 			Platform.removeLogListener(this.logListener);
3548 		} else {
3549 			this.log.removeLogListener(this.logListener);
3550 		}
3551 		this.logListener = null;
3552 		this.log = null;
3553 	}
3554 	protected void assertLogEquals(String expected) {
3555 		String actual = this.logListener == null ? "<null>" : this.logListener.toString();
3556 		assertSourceEquals(
3557 			"Unexpected entry in log",
3558 			expected,
3559 			actual);
3560 	}
3561 	protected IPath[] toIPathArray(String[] paths) {
3562 		if (paths == null) return null;
3563 		int length = paths.length;
3564 		IPath[] result = new IPath[length];
3565 		for (int i = 0; i < length; i++) {
3566 			result[i] = new Path(paths[i]);
3567 		}
3568 		return result;
3569 	}
3570 	protected void touch(File f) {
3571 		final int time = 1000;
3572 		long lastModified = f.lastModified();
3573 		org.eclipse.jdt.core.tests.util.Util.waitAtLeast(time);
3574 		f.setLastModified(lastModified + time);
3575 		// Loop until the last modified time has really changed on the file
3576 		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=295619
3577 		int n = 1;
3578 		while (n < 10) { // retry 9 times more if necessary
3579 			if (f.lastModified() != lastModified) {
3580 				// We can leave the loop as the file has been really touched
3581 				return;
3582 			}
3583 			f.setLastModified(lastModified + n*time);
3584 			org.eclipse.jdt.core.tests.util.Util.waitAtLeast(time);
3585 			n++;
3586 		}
3587 		assertFalse("The file "+f.getAbsolutePath()+" was not touched!", lastModified == f.lastModified());
3588 	}
3589 
3590 	protected String toString(String[] strings) {
3591 		return org.eclipse.jdt.core.tests.util.Util.toString(strings, false/*don't add extra new line*/);
3592 	}
3593 	@Override
3594 	protected void tearDown() throws Exception {
3595 
3596 		super.tearDown();
3597 		if (this.workingCopies != null) {
3598 			discardWorkingCopies(this.workingCopies);
3599 			this.workingCopies = null;
3600 		}
3601 		this.wcOwner = null;
3602 
3603 		// ensure workspace options have been restored to their default
3604 		Hashtable options = JavaCore.getOptions();
3605 		Hashtable defaultOptions = JavaCore.getDefaultOptions();
3606 		assertEquals(
3607 			"Workspace options should be back to their default",
3608 			new CompilerOptions(defaultOptions).toString(),
3609 			new CompilerOptions(options).toString());
3610 	}
3611 
3612 	protected IPath getJRE9Path() {
3613 		return new Path(System.getProperty("java.home") + "/lib/jrt-fs.jar");
3614 	}
3615 
3616 	/**
3617 	 * Wait for autobuild notification to occur
3618 	 */
3619 	public static void waitForAutoBuild() {
3620 		boolean wasInterrupted = false;
3621 		do {
3622 			try {
3623 				Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null);
3624 				Indexer.getInstance().waitForIndex(null);
3625 				wasInterrupted = false;
3626 			} catch (OperationCanceledException e) {
3627 				e.printStackTrace();
3628 			} catch (InterruptedException e) {
3629 				wasInterrupted = true;
3630 			}
3631 		} while (wasInterrupted);
3632 	}
3633 
3634 	public static void waitForManualRefresh() {
3635 		boolean wasInterrupted = false;
3636 		do {
3637 			try {
3638 				Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null);
3639 				Indexer.getInstance().waitForIndex(null);
3640 				wasInterrupted = false;
3641 			} catch (OperationCanceledException e) {
3642 				e.printStackTrace();
3643 			} catch (InterruptedException e) {
3644 				wasInterrupted = true;
3645 			}
3646 		} while (wasInterrupted);
3647 	}
3648 
3649 	public static void waitUntilIndexesReady() {
3650 		// dummy query for waiting until the indexes are ready
3651 		SearchEngine engine = new SearchEngine();
3652 		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
3653 		try {
3654 			Indexer.getInstance().waitForIndex(null);
3655 			engine.searchAllTypeNames(
3656 				null,
3657 				SearchPattern.R_EXACT_MATCH,
3658 				"!@$#!@".toCharArray(),
3659 				SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
3660 				IJavaSearchConstants.CLASS,
3661 				scope,
3662 				new TypeNameRequestor() {
3663 					public void acceptType(
3664 						int modifiers,
3665 						char[] packageName,
3666 						char[] simpleTypeName,
3667 						char[][] enclosingTypeNames,
3668 						String path) {}
3669 				},
3670 				IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
3671 				null);
3672 		} catch (CoreException e) {
3673 			logError("exception occurred while waiting on indexing", e);
3674 		}
3675 	}
3676 
3677 	private static void logError(String errorMessage, CoreException e) {
3678 		Plugin plugin = JavaCore.getPlugin();
3679 		if (plugin != null) {
3680 			ILog log = plugin.getLog();
3681 			Status status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, errorMessage, e);
3682 			log.log(status);
3683 		}
3684 	}
3685 }
3686