1 /*******************************************************************************
2  * Copyright (c) 2000, 2017 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.File;
17 import java.io.IOException;
18 
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.jdt.core.*;
23 import org.eclipse.jdt.core.tests.util.Util;
24 import org.eclipse.jdt.internal.core.JavaElement;
25 import org.eclipse.jdt.internal.core.LocalVariable;
26 
27 import junit.framework.Test;
28 
29 public class MementoTests extends ModifyingResourceTests {
MementoTests(String name)30 public MementoTests(String name) {
31 	super(name);
32 }
33 // Use this static initializer to specify subset for tests
34 // All specified tests which do not belong to the class are skipped...
35 static {
36 //	TESTS_PREFIX =  "testArray";
37 //	TESTS_NAMES = new String[] { "testPackageFragmentRootMemento8" };
38 //	TESTS_NUMBERS = new int[] { 8 };
39 //	TESTS_RANGE = new int[] { 6, -1 };
40 }
41 
suite()42 public static Test suite() {
43 	return buildModelTestSuite(MementoTests.class);
44 }
assertMemento(String expected, IJavaElement element)45 protected void assertMemento(String expected, IJavaElement element) {
46 	String actual = element.getHandleIdentifier();
47 	if (!expected.equals(actual)){
48 		String escapedExternalJCL = getEscapedExternalJCLPath();
49 		int start = actual.indexOf(escapedExternalJCL);
50 		if (start != -1) {
51 			String firstPart = actual.substring(0, start);
52 		 	System.out.print(Util.displayString(firstPart, 2));
53 		 	System.out.print(" + getEscapedExternalJCLPath() + ");
54 		 	String secondPart = actual.substring(start+escapedExternalJCL.length());
55 		 	System.out.print(Util.displayString(secondPart, 0));
56 		} else {
57 			System.out.print(Util.displayString(actual, 2));
58 		}
59 	 	System.out.println(",");
60 	}
61 	assertEquals(
62 		"Unexpected memento for " + element,
63 		expected,
64 		actual);
65 	IJavaElement restored = JavaCore.create(actual);
66 	assertEquals(
67 		"Unexpected restored element",
68 		element,
69 		restored);
70 	String restoredHandleIdentifier = restored.getHandleIdentifier();
71 	assertEquals(
72 		"Unexpected memento for restored element " + restored,
73 		expected,
74 		restoredHandleIdentifier);
75 }
getEscapedExternalJCLPath()76 protected String getEscapedExternalJCLPath() {
77 	return getEscapedPath(getExternalJCLPath().toString());
78 }
getEscapedJrtJarPath()79 String getEscapedJrtJarPath() {
80 	return getEscapedPath(System.getProperty("java.home")+"/lib/jrt-fs.jar");
81 }
getEscapedPath(String path)82 protected String getEscapedPath(String path) {
83 	StringBuffer buffer = new StringBuffer();
84 	for (int i = 0; i < path.length(); i++) {
85 		char character = path.charAt(i);
86 		if (character == '/') buffer.append('\\');
87 		buffer.append(character);
88 	}
89 	return buffer.toString();
90 }
91 @Override
setUpSuite()92 public void setUpSuite() throws Exception {
93 	super.setUpSuite();
94 
95 	Util.createClassFolder(new String[] {
96 		"X.java",
97 		"public class X {}"
98 		},
99 		getExternalResourcePath("myLib"),
100 		"1.4");
101 	this.createJavaProject(
102 			"P",
103 			new String[] {"src", "!"},
104 			new String[] {
105 				getExternalJCLPathString(),
106 				"/P/lib",
107 				"/P/lib/myLib.jar",
108 				"/OtherProj/lib",
109 				"/OtherProj/lib/myLib.jar",
110 				getExternalResourcePath("myLib")
111 			},
112 			"bin");
113 }
114 @Override
tearDownSuite()115 public void tearDownSuite() throws Exception {
116 	this.deleteProject("P");
117 	deleteExternalResource("myLib");
118 	super.tearDownSuite();
119 }
120 /*
121  * Tests that an annotation can be persisted and restored using its memento.
122  */
testAnnotation1()123 public void testAnnotation1() {
124 	IAnnotation annotation = getCompilationUnit("/P/src/p/X.java").getType("X").getAnnotation("MyAnnot");
125 	assertMemento(
126 		"=P/src<p{X.java[X}MyAnnot",
127 		annotation);
128 }
129 /*
130  * Tests that an annotation can be persisted and restored using its memento.
131  */
testAnnotation2()132 public void testAnnotation2() {
133 	IAnnotation annotation = getCompilationUnit("/P/src/p/X.java").getType("X").getMethod("foo", new String[0]).getAnnotation("MyAnnot");
134 	assertMemento(
135 		"=P/src<p{X.java[X~foo}MyAnnot",
136 		annotation);
137 }
138 /*
139  * Tests that an annotation can be persisted and restored using its memento.
140  */
testAnnotation3()141 public void testAnnotation3() {
142 	IAnnotation annotation = getCompilationUnit("/P/src/p/X.java").getType("X").getField("field").getAnnotation("MyAnnot");
143 	assertMemento(
144 		"=P/src<p{X.java[X^field}MyAnnot",
145 		annotation);
146 }
147 /**
148  * Tests that an anonymous type can be persisted and restored using its memento.
149  */
testAnonymousTypeMemento1()150 public void testAnonymousTypeMemento1() {
151 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
152 
153 	IType anonymous = type.getInitializer(1).getType("", 1);
154 	assertMemento(
155 		"=P/src<p{X.java[X|1[",
156 		anonymous);
157 
158 	anonymous = type.getInitializer(1).getType("", 2);
159 	assertMemento(
160 		"=P/src<p{X.java[X|1[!2",
161 		anonymous);
162 }
163 /**
164  * Tests that an anonymous type can be persisted and restored using its memento.
165  */
testAnonymousTypeMemento2()166 public void testAnonymousTypeMemento2() {
167 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
168 
169 	IType anonymous = type.getField("f").getType("", 1);
170 	assertMemento(
171 		"=P/src<p{X.java[X^f[",
172 		anonymous);
173 
174 	anonymous = type.getField("f").getType("", 3);
175 	assertMemento(
176 		"=P/src<p{X.java[X^f[!3",
177 		anonymous);
178 }
179 /**
180  * Tests that an anonymous type can be persisted and restored using its memento.
181  */
testAnonymousTypeMemento3()182 public void testAnonymousTypeMemento3() {
183 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
184 
185 	IType anonymous = type.getMethod("foo", new String[]{}).getType("", 1);
186 	assertMemento(
187 		"=P/src<p{X.java[X~foo[",
188 		anonymous);
189 
190 	anonymous = type.getMethod("foo", new String[]{}).getType("", 4);
191 	assertMemento(
192 		"=P/src<p{X.java[X~foo[!4",
193 		anonymous);
194 }
195 /**
196  * Tests that a binary field can be persisted and restored using its memento.
197  */
testBinaryFieldMemento()198 public void testBinaryFieldMemento() throws JavaModelException {
199 	IField field = getClassFile("/P/lib/p/X.class").getType().getField("field");
200 	assertMemento(
201 		"=P/lib<p(X.class[X^field",
202 		field);
203 }
204 /**
205  * Tests that an inner type, inner field and inner method can be persisted and restored
206  * using mementos.
207  */
testBinaryInnerTypeMemento()208 public void testBinaryInnerTypeMemento() throws JavaModelException {
209 	IType type = getClassFile("/P/lib/p/X$Inner.class").getType();
210 
211 	assertMemento(
212 		"=P/lib<p(X$Inner.class[Inner",
213 		type);
214 
215 	IField innerField = type.getField("field");
216 	assertMemento(
217 		"=P/lib<p(X$Inner.class[Inner^field",
218 		innerField);
219 
220 	IMethod innerMethod = type.getMethod("foo", new String[] {"I", "Ljava.lang.String;"});
221 	assertMemento(
222 		"=P/lib<p(X$Inner.class[Inner~foo~I~Ljava.lang.String;",
223 		innerMethod);
224 }
225 /**
226  * Tests that a binary method can be persisted and restored using its memento.
227  */
testBinaryMethodMemento1()228 public void testBinaryMethodMemento1() throws JavaModelException {
229 	IType type = getClassFile("/P/lib/p/X.class").getType();
230 	IMethod method = type.getMethod("foo", new String[] {"I", "Ljava.lang.String;"});
231 	assertMemento(
232 		"=P/lib<p(X.class[X~foo~I~Ljava.lang.String;",
233 		method);
234 }
235 /**
236  * Tests that a binary method can be persisted and restored using its memento.
237  */
testBinaryMethodMemento2()238 public void testBinaryMethodMemento2() throws JavaModelException {
239 	IType type = getClassFile("/P/lib/p/X.class").getType();
240 	IMethod method = type.getMethod("bar", new String[] {});
241 	assertMemento(
242 		"=P/lib<p(X.class[X~bar",
243 		method);
244 }
245 /**
246  * Tests that a binary method can be persisted and restored using its memento.
247  */
testBinaryMethodMemento3()248 public void testBinaryMethodMemento3() throws JavaModelException {
249 	IType type = getClassFile("/P/lib/p/X.class").getType();
250 	IMethod method = type.getMethod("fred", new String[] {"[Z"});
251 	assertMemento(
252 		"=P/lib<p(X.class[X~fred~\\[Z",
253 		method);
254 }
255 /**
256  * Tests that a binary method with a parameter with wildcard can be persisted and restored using its memento.
257  * (regression test for bug 75466 [1.5] IAE in JavaElement.exists() for Collection<E>#containsAll(Collection<?>))
258  */
testBinaryMethodMemento4()259 public void testBinaryMethodMemento4() throws JavaModelException {
260 	IType type = getClassFile("/P/lib/p/X.class").getType();
261 	IMethod method = type.getMethod("foo", new String[] {"Ljava.util.Collection<*>;"});
262 	assertMemento(
263 		"=P/lib<p(X.class[X~foo~Ljava.util.Collection\\<*>;",
264 		method);
265 }
266 
267 /**
268  * Tests that a binary type can be persisted and restored using its memento.
269  */
testBinaryTypeMemento()270 public void testBinaryTypeMemento() throws JavaModelException {
271 	IType type = getClassFile("/P/lib/p/X.class").getType();
272 	assertMemento(
273 		"=P/lib<p(X.class[X",
274 		type);
275 }
276 /**
277  * Tests that a class file can be persisted and restored using its memento.
278  */
testClassFileMemento()279 public void testClassFileMemento() {
280 	IClassFile cf =  getClassFile("/P/lib/p/X.class");
281 	assertMemento(
282 		"=P/lib<p(X.class",
283 		cf);
284 
285 	cf = getClassFile("/P/lib/Y.class");
286 	assertMemento(
287 		"=P/lib<(Y.class",
288 		cf);
289 
290 }
291 /**
292  * Tests that a compilation unit can be persisted and restored using its memento.
293  */
testCompilationUnitMemento1()294 public void testCompilationUnitMemento1() {
295 	ICompilationUnit cu = getCompilationUnit("/P/src/p/X.java");
296 	assertMemento(
297 		"=P/src<p{X.java",
298 		cu);
299 
300 	cu = getCompilationUnit("/P/src/Y.java");
301 	assertMemento(
302 		"=P/src<{Y.java",
303 		cu);
304 }
305 /*
306  * Ensure that restoring a compilation unit memento with a null owner doesn't create an
307  * invalid handle
308  * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=205917 )
309  */
testCompilationUnitMemento2()310 public void testCompilationUnitMemento2() throws Exception {
311 	ICompilationUnit cu = getCompilationUnit("/P/src/p/X.java");
312 	String handleIdentifier = cu.getHandleIdentifier();
313 	cu = (ICompilationUnit) JavaCore.create(handleIdentifier, null);
314 	assertEquals(cu, cu); // should not throw an NPE
315 }
316 /**
317  * Tests that a binary field in an external jar can be persisted and restored using its memento.
318  */
testExternalJarBinaryFieldMemento()319 public void testExternalJarBinaryFieldMemento() throws JavaModelException {
320 	IType type = getClassFile("P", getExternalJCLPathString(), "p", "X.class").getType();
321 	IField field = type.getField("field");
322 	assertMemento(
323 		"=P/"+ getEscapedExternalJCLPath() + "<p(X.class[X^field",
324 		field);
325 }
326 /**
327  * Tests that a inner binary type and field in an external jar can be persisted and restored using its memento.
328  */
testExternalJarBinaryInnerTypeMemento()329 public void testExternalJarBinaryInnerTypeMemento() throws JavaModelException {
330 	IType type = getClassFile("P", getExternalJCLPathString(), "p", "X$Inner.class").getType();
331 	assertMemento(
332 		"=P/" + getEscapedExternalJCLPath() + "<p(X$Inner.class[Inner",
333 		type);
334 }
335 /**
336  * Tests that a binary method in an external jar can be persisted and restored using its memento.
337  */
testExternalJarBinaryMethodMemento()338 public void testExternalJarBinaryMethodMemento() throws JavaModelException {
339 	IType type = getClassFile("P", getExternalJCLPathString(), "p", "X.class").getType();
340 	IMethod method = type.getMethod("foo", new String[] {"[Ljava.lang.String;"});
341 	assertMemento(
342 		"=P/" + getEscapedExternalJCLPath() + "<p(X.class[X~foo~\\[Ljava.lang.String;",
343 		method);
344 }
345 /**
346  * Tests that a binary type in an external jar can be persisted and restored using its memento.
347  */
testExternalJarBinaryTypeMemento()348 public void testExternalJarBinaryTypeMemento() throws JavaModelException {
349 	IType type = getClassFile("P", getExternalJCLPathString(), "p", "X.class").getType();
350 	assertMemento(
351 		"=P/" + getEscapedExternalJCLPath() + "<p(X.class[X",
352 		type);
353 }
354 /**
355  * Tests that a class file in an external jar at the root of the file system can be persisted and restored using its memento.
356  */
testExternalJarClassFileMemento()357 public void testExternalJarClassFileMemento() throws JavaModelException {
358 	char separator = File.separatorChar;
359 	String device = separator == '/' ? "" : "C:";
360 	IClassFile classFile = getClassFile("P", device + separator + "lib.jar", "p", "X.class");
361 	assertMemento(
362 		"=P/" + device + "\\/lib.jar<p(X.class",
363 		classFile);
364 }
365 /*
366  * Ensures that a class file in an external library folder can be persisted and restored using its memento.
367  */
testExternalLibraryFolderClassFileMemento()368 public void testExternalLibraryFolderClassFileMemento() throws JavaModelException {
369 	IClassFile classFile = getClassFile("P", getExternalResourcePath("myLib"), "", "X.class");
370 	assertMemento(
371 		"=P/" + getEscapedPath(new Path(getExternalResourcePath("myLib")).toString()) + "<(X.class",
372 		classFile);
373 }
374 /**
375  * Tests that an import declaration can be persisted and restored using its memento.
376  */
testImportContainerMemento()377 public void testImportContainerMemento() {
378 	IImportContainer importContainer = getCompilationUnit("/P/src/p/X.java").getImportContainer();
379 	assertMemento(
380 		"=P/src<p{X.java#",
381 		importContainer);
382 }
383 /**
384  * Tests that an import declaration can be persisted and restored using its memento.
385  */
testImportDeclarationMemento()386 public void testImportDeclarationMemento() {
387 	IImportDeclaration importDecl = getCompilationUnit("/P/src/p/X.java").getImport("java.io.Serializable");
388 	assertMemento(
389 		"=P/src<p{X.java#java.io.Serializable",
390 		importDecl);
391 
392 	importDecl = getCompilationUnit("/P/src/p/X.java").getImport("java.util.*");
393 	assertMemento(
394 		"=P/src<p{X.java#java.util.*",
395 		importDecl);
396 }
397 /*
398  * Ensures that a Java element is returned for an invalid memento.
399  * (regression test for bug 81762 [model] AIOOB in breakpoints view)
400  */
testInvalidMemento()401 public void testInvalidMemento() {
402 	IJavaElement element = JavaCore.create("=P/src<p{");
403 	assertElementEquals("Unexpected element", "p [in src [in P]]", element);
404 }
405 /**
406  * Tests that an initializer can be persisted and restored using its memento.
407  */
testInitializerMemento()408 public void testInitializerMemento() {
409 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
410 
411 	IInitializer initializer = type.getInitializer(1);
412 	assertMemento(
413 		"=P/src<p{X.java[X|1",
414 		initializer);
415 
416 	initializer = type.getInitializer(2);
417 	assertMemento(
418 		"=P/src<p{X.java[X|2",
419 		initializer);
420 }
421 /**
422  * Tests that a binary field in an internal jar can be persisted and restored using its memento.
423  */
testInternalJarBinaryFieldMemento()424 public void testInternalJarBinaryFieldMemento() throws JavaModelException {
425 	IType type = getPackageFragmentRoot("/P/lib/myLib.jar").getPackageFragment("p").getOrdinaryClassFile("X.class").getType();
426 	IField field = type.getField("field");
427 	assertMemento(
428 		"=P/lib\\/myLib.jar<p(X.class[X^field",
429 		field);
430 }
431 /**
432  * Tests that a inner binary type and field in an internal jar can be persisted and restored using its memento.
433  */
testInternalJarBinaryInnerTypeMemento()434 public void testInternalJarBinaryInnerTypeMemento() throws JavaModelException {
435 	IType type = getPackageFragmentRoot("/P/lib/myLib.jar").getPackageFragment("p").getOrdinaryClassFile("X$Inner.class").getType();
436 	assertMemento(
437 		"=P/lib\\/myLib.jar<p(X$Inner.class[Inner",
438 		type);
439 }
440 /**
441  * Tests that a binary method in an internal jar can be persisted and restored using its memento.
442  */
testInternalJarBinaryMethodMemento()443 public void testInternalJarBinaryMethodMemento() throws JavaModelException {
444 	IType type = getPackageFragmentRoot("/P/lib/myLib.jar").getPackageFragment("p").getOrdinaryClassFile("X.class").getType();
445 	IMethod method = type.getMethod("foo", new String[] {"[Ljava.lang.String;"});
446 	assertMemento(
447 		"=P/lib\\/myLib.jar<p(X.class[X~foo~\\[Ljava.lang.String;",
448 		method);
449 }
450 /**
451  * Tests that a binary type in an internal jar can be persisted and restored using its memento.
452  */
testInternalJarBinaryTypeMemento()453 public void testInternalJarBinaryTypeMemento() throws JavaModelException {
454 	IType type = getPackageFragmentRoot("/P/lib/myLib.jar").getPackageFragment("p").getOrdinaryClassFile("X.class").getType();
455 	assertMemento(
456 		"=P/lib\\/myLib.jar<p(X.class[X",
457 		type);
458 }
459 /**
460  * Tests that a local type can be persisted and restored using its memento.
461  */
testLocalTypeMemento1()462 public void testLocalTypeMemento1() {
463 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
464 
465 	IType anonymous = type.getInitializer(1).getType("Y", 1);
466 	assertMemento(
467 		"=P/src<p{X.java[X|1[Y",
468 		anonymous);
469 
470 	anonymous = type.getInitializer(1).getType("Y", 2);
471 	assertMemento(
472 		"=P/src<p{X.java[X|1[Y!2",
473 		anonymous);
474 }
475 /**
476  * Tests that a local type can be persisted and restored using its memento.
477  */
testLocalTypeMemento2()478 public void testLocalTypeMemento2() {
479 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
480 
481 	IType anonymous = type.getMethod("foo", new String[]{}).getType("Y", 1);
482 	assertMemento(
483 		"=P/src<p{X.java[X~foo[Y",
484 		anonymous);
485 
486 	anonymous = type.getMethod("foo", new String[]{}).getType("Y", 3);
487 	assertMemento(
488 		"=P/src<p{X.java[X~foo[Y!3",
489 		anonymous);
490 }
491 /**
492  * Tests that a local variable can be persisted and restored using its memento.
493  */
testLocalVariableMemento1()494 public void testLocalVariableMemento1() {
495 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
496 	IMethod method = type.getMethod("foo", new String[]{});
497 
498 	ILocalVariable localVar = new LocalVariable((JavaElement)method, "var", 1, 2, 3, 4, "Z", null, 0, true);
499 	assertMemento(
500 		"=P/src<p{X.java[X~foo@var!1!2!3!4!Z!0!true",
501 		localVar);
502 }
503 /**
504  * Tests that a local variable can be persisted and restored using its memento.
505  */
testLocalVariableMemento2()506 public void testLocalVariableMemento2() throws JavaModelException {
507 	IType type = getClassFile("/P/src/p/X.class").getType();
508 	IMethod method = type.getMethod("foo", new String[]{"I"});
509 
510 	ILocalVariable localVar = new LocalVariable((JavaElement)method, "var", 1, 2, 3, 4, "Z", null,0, false);
511 	assertMemento(
512 		"=P/src<p(X.class[X~foo~I@var!1!2!3!4!Z!0!false",
513 		localVar);
514 }
515 /**
516  * Tests that a local variable can be persisted and restored using its memento.
517  */
testLocalVariableMemento3()518 public void testLocalVariableMemento3() {
519 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
520 	IInitializer initializer = type.getInitializer(1);
521 
522 	ILocalVariable localVar = new LocalVariable((JavaElement)initializer, "var", 1, 2, 3, 4, "Z", null, 0, false);
523 	assertMemento(
524 		"=P/src<p{X.java[X|1@var!1!2!3!4!Z!0!false",
525 		localVar);
526 }
527 /**
528  * Tests that a local variable can be persisted and restored using its memento.
529  * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=244549 )
530  */
testLocalVariableMemento4()531 public void testLocalVariableMemento4() throws Exception {
532 	try {
533 		createJavaProject("P1", new String[] {"src"}, new String[] {getExternalJCLPathString("1.5")}, "bin", "1.5");
534 		createFile(
535 			"/P1/src/X.java",
536 			"public class X<T> {\n" +
537 			"  void foo() {\n" +
538 			"    X<String> var = null;\n" +
539 			"  }\n" +
540 			"}"
541 		);
542 		ILocalVariable localVar = getLocalVariable(getCompilationUnit("/P1/src/X.java"), "var", "var");
543 		String memento = localVar.getHandleIdentifier();
544 		IJavaElement restored = JavaCore.create(memento);
545 		String restoredMemento = restored.getHandleIdentifier();
546 		assertEquals("Unexpected restored memento", memento, restoredMemento);
547 	} finally {
548 		deleteProject("P1");
549 	}
550 }
551 /**
552  * Tests that a package declaration can be persisted and restored using its memento.
553  */
testPackageDeclarationMemento()554 public void testPackageDeclarationMemento() {
555 	IPackageDeclaration declaration = getCompilationUnit("/P/src/p/X.java").getPackageDeclaration("p");
556 	assertMemento(
557 		"=P/src<p{X.java%p",
558 		declaration);
559 
560 	declaration = getCompilationUnit("/P/src/p1/p2/X.java").getPackageDeclaration("p1.p2");
561 	assertMemento(
562 		"=P/src<p1.p2{X.java%p1.p2",
563 		declaration);
564 }
565 /**
566  * Tests that a package fragment can be persisted and restored using its memento.
567  */
testPackageFragmentMemento()568 public void testPackageFragmentMemento() {
569 	IPackageFragment pkg = getPackage("/P/src/p");
570 	assertMemento(
571 		"=P/src<p",
572 		pkg);
573 
574 	pkg = getPackage("/P/src/p1/p2");
575 	assertMemento(
576 		"=P/src<p1.p2",
577 		pkg);
578 
579 	pkg = getPackage("/P/src");
580 	assertMemento(
581 		"=P/src<",
582 		pkg);
583 }
584 /**
585  * Tests that a package fragment in the default root can be persisted and restored using its memento.
586  */
testPackageFragmentMemento2()587 public void testPackageFragmentMemento2() throws CoreException {
588 	try {
589 		createJavaProject("P1", new String[] {""}, "");
590 		IPackageFragment pkg = getPackage("/P1/p");
591 		assertMemento(
592 			"=P1/<p",
593 			pkg);
594 	} finally {
595 		deleteProject("P1");
596 	}
597 }
598 /**
599  * Tests that a source folder package fragment root can be persisted and restored using its memento.
600  */
testPackageFragmentRootMemento1()601 public void testPackageFragmentRootMemento1() {
602 	IJavaProject project = getJavaProject("P");
603 	IPackageFragmentRoot root = project.getPackageFragmentRoot(project.getProject().getFolder("src"));
604 	assertMemento(
605 		"=P/src",
606 		root);
607 }
608 /**
609  * Tests that a source folder package fragment root corresponding to the project
610  * can be persisted and restored using its memento.
611  */
testPackageFragmentRootMemento2()612 public void testPackageFragmentRootMemento2() throws CoreException {
613 	try {
614 		IJavaProject project = this.createJavaProject("P1", new String[] {""}, "");
615 		IPackageFragmentRoot root = project.getPackageFragmentRoot(project.getProject());
616 		assertMemento(
617 			"=P1/",
618 			root);
619 	} finally {
620 		this.deleteProject("P1");
621 	}
622 }
623 /**
624  * Tests that a library folder package fragment root in the same project
625  * can be persisted and restored using its memento.
626  */
testPackageFragmentRootMemento3()627 public void testPackageFragmentRootMemento3() {
628 	IJavaProject project = getJavaProject("P");
629 	IFolder libFolder = project.getProject().getFolder("lib");
630 	IPackageFragmentRoot root = project.getPackageFragmentRoot(libFolder);
631 	assertMemento(
632 		"=P/lib",
633 		root);
634 }
635 /**
636  * Tests that a library folder package fragment root in another project
637  * can be persisted and restored using its memento.
638  */
testPackageFragmentRootMemento4()639 public void testPackageFragmentRootMemento4() {
640 	IJavaProject project = getJavaProject("P");
641 	IFolder otherLibFolder = getFolder("/OtherProj/lib");
642 	IPackageFragmentRoot root = project.getPackageFragmentRoot(otherLibFolder);
643 	assertMemento(
644 		"=P/\\/OtherProj\\/lib",
645 		root);
646 }
647 /**
648  * Tests that a jar package fragment root in the same project
649  * can be persisted and restored using its memento.
650  */
testPackageFragmentRootMemento5()651 public void testPackageFragmentRootMemento5() {
652 	IJavaProject project = getJavaProject("P");
653 	IFile jar = getFile("/P/lib/myLib.jar");
654 	IPackageFragmentRoot root = project.getPackageFragmentRoot(jar);
655 	assertMemento(
656 		"=P/lib\\/myLib.jar",
657 		root);
658 }
659 /**
660  * Tests that a jar package fragment root in another project
661  * can be persisted and restored using its memento.
662  */
testPackageFragmentRootMemento6()663 public void testPackageFragmentRootMemento6() {
664 	IJavaProject project = getJavaProject("P");
665 	IFile jar = getFile("/OtherProj/lib/myLib.jar");
666 	IPackageFragmentRoot root = project.getPackageFragmentRoot(jar);
667 	assertMemento(
668 		"=P/\\/OtherProj\\/lib\\/myLib.jar",
669 		root);
670 }
671 /**
672  * Tests that an external jar package fragment root
673  * can be persisted and restored using its memento.
674  */
testPackageFragmentRootMemento7()675 public void testPackageFragmentRootMemento7() throws CoreException {
676 	IPackageFragmentRoot root = getPackageFragmentRoot("P", getExternalJCLPathString());
677 	assertMemento(
678 		"=P/" + getEscapedExternalJCLPath() + "",
679 		root);
680 }
681 /*
682  * Tests that a library folder package fragment root being another project
683  * can be persisted and restored using its memento.
684  * (regression test for bug 108539 Error popup at breakpoint in tomcat project)
685  */
testPackageFragmentRootMemento8()686 public void testPackageFragmentRootMemento8() {
687 	IJavaProject project = getJavaProject("P");
688 	IProject otherLibFolder = getProject("/OtherProj");
689 	IPackageFragmentRoot root = project.getPackageFragmentRoot(otherLibFolder);
690 	assertMemento(
691 		"=P/\\/OtherProj",
692 		root);
693 }
694 /**
695  * Tests that a project can be persisted and restored using its memento.
696  */
testProjectMemento()697 public void testProjectMemento() {
698 	IJavaProject project = getJavaProject("P");
699 	assertMemento(
700 		"=P",
701 		project);
702 }
703 /**
704  * Tests that a project with special chararcters in its name can be persisted and restored using its memento.
705  * (regression test for bug 47815 Refactoring doesn't work with some project names [refactoring])
706  */
testProjectMemento2()707 public void testProjectMemento2() {
708 	IJavaProject project = getJavaProject("P (abc) ~");
709 	assertMemento(
710 		"=P \\(abc) \\~",
711 		project);
712 }
713 /**
714  * Tests that a project with a ']' in its name can be persisted and restored using its memento.
715  * (regression test for bug 108615 Unable to inherit abstract methods from jarred interface)
716  */
testProjectMemento3()717 public void testProjectMemento3() {
718 	IJavaProject project = getJavaProject("P[]");
719 	assertMemento(
720 		"=P\\[\\]",
721 		project);
722 }
723 /**
724  * Tests that a bogus memento cannot be restored.
725  */
testRestoreBogusMemento()726 public void testRestoreBogusMemento() {
727 	IJavaElement restored = JavaCore.create("bogus");
728 	assertEquals("should not be able to restore a bogus memento", null, restored);
729 }
730 /**
731  * Tests that a source field can be persisted and restored using its memento.
732  */
testSourceFieldMemento()733 public void testSourceFieldMemento() {
734 	IField field = getCompilationUnit("/P/src/p/X.java").getType("X").getField("field");
735 	assertMemento(
736 		"=P/src<p{X.java[X^field",
737 		field);
738 }
739 /**
740  * Tests that a source inner type, inner field and inner method can be persisted and restored
741  * using mementos.
742  */
testSourceInnerTypeMemento()743 public void testSourceInnerTypeMemento() {
744 	IType innerType = getCompilationUnit("/P/src/p/X.java").getType("X").getType("Inner");
745 	assertMemento(
746 		"=P/src<p{X.java[X[Inner",
747 		innerType);
748 }
749 /**
750  * Tests that a source method can be persisted and restored using its memento.
751  */
testSourceMethodMemento1()752 public void testSourceMethodMemento1() {
753 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
754 	IMethod method = type.getMethod("foo", new String[] {"I", "Ljava.lang.String;"});
755 	assertMemento(
756 		"=P/src<p{X.java[X~foo~I~Ljava.lang.String;",
757 		method);
758 }
759 /**
760  * Tests that a source method can be persisted and restored using its memento.
761  */
testSourceMethodMemento2()762 public void testSourceMethodMemento2() {
763 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
764 	IMethod method = type.getMethod("bar", new String[] {});
765 	assertMemento(
766 		"=P/src<p{X.java[X~bar",
767 		method);
768 }
769 /**
770  * Tests that a source method can be persisted and restored using its memento.
771  */
testSourceMethodMemento3()772 public void testSourceMethodMemento3() {
773 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
774 	IMethod method = type.getMethod("fred", new String[] {"[Z"});
775 	assertMemento(
776 		"=P/src<p{X.java[X~fred~\\[Z",
777 		method);
778 }
779 /**
780  * Tests that a source type can be persisted and restored using its memento.
781  */
testSourceTypeMemento()782 public void testSourceTypeMemento() {
783 	IType type = getCompilationUnit("/P/src/p/X.java").getType("X");
784 	assertMemento(
785 		"=P/src<p{X.java[X",
786 		type);
787 }
788 /*
789  * Tests that a type parameter can be persisted and restored using its memento.
790  */
testTypeParameter1()791 public void testTypeParameter1() {
792 	ITypeParameter typeParameter = getCompilationUnit("/P/src/p/X.java").getType("X").getTypeParameter("T");
793 	assertMemento(
794 		"=P/src<p{X.java[X]T",
795 		typeParameter);
796 }
797 /*
798  * Tests that a type parameter can be persisted and restored using its memento.
799  */
testTypeParameter2()800 public void testTypeParameter2() {
801 	ITypeParameter typeParameter = getCompilationUnit("/P/src/p/X.java").getType("X").getMethod("foo", new String[0]).getTypeParameter("T");
802 	assertMemento(
803 		"=P/src<p{X.java[X~foo]T",
804 		typeParameter);
805 }
806 /*
807  * Test that a package fragment root name starting with '!' can be reconstructed from
808  * the handle identifier.
809  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=331821
810  */
testBug331821()811 public void testBug331821() throws JavaModelException {
812 	IPackageFragmentRoot root = getPackageFragmentRoot("P", "!");
813 	String handleIdentifier = root.getHandleIdentifier();
814 	IPackageFragmentRoot newRoot = (IPackageFragmentRoot) JavaCore.create(handleIdentifier);
815 	assertEquals(root, newRoot);
816 }
testAnnotationPath18()817 public void testAnnotationPath18() throws CoreException, IOException {
818 	// tests annotationpath in memento for a regular jar library:
819 	try {
820 		IJavaProject project = createJavaProject("Test", new String[] {"src"}, null, "bin", "1.8", false);
821 		addLibraryWithExternalAnnotations(project, "1.8", "lib.jar", "/Test/annots",
822 				new String[] {
823 					"test/Test.java",
824 					"package test;\n" +
825 					"public class Test{}\n"
826 				},
827 				null);
828 		String[] expectedIdentifiers = {
829 			"=Test/src",
830 			"=Test/lib.jar=/annotationpath=/\\/Test\\/annots=/"
831 		};
832 		IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
833 		boolean archiveSeen = false;
834 		for (int i = 0; i < roots.length; i++) {
835 			// JarPackageFragmentRoot
836 			IPackageFragmentRoot packageRoot = roots[i];
837 			String handleIdentifier = packageRoot.getHandleIdentifier();
838 			assertEquals("Root mementos", expectedIdentifiers[i], handleIdentifier);
839 			IJavaElement element = JavaCore.create(handleIdentifier, null);
840 			assertEquals("Root equivalence", packageRoot, element);
841 			if (packageRoot.isArchive()) {
842 				archiveSeen = true;
843 				// PackageFragment
844 				IPackageFragment test = packageRoot.getPackageFragment("test");
845 				handleIdentifier = test.getHandleIdentifier();
846 				String expected = expectedIdentifiers[i]+"<test";
847 				assertEquals("PackageFragment mementos", expected, handleIdentifier);
848 				element = JavaCore.create(handleIdentifier, null);
849 				assertEquals("PackageFragment equivalence", test, element);
850 				// ClassFile:
851 				IClassFile classFile = test.getClassFile("Test.class");
852 				handleIdentifier = classFile.getHandleIdentifier();
853 				assertEquals("ClassFile mementos", expected+"(Test.class", handleIdentifier);
854 				element = JavaCore.create(handleIdentifier);
855 				assertEquals("ClassFile equivalence", classFile, element);
856 			}
857 		}
858 		assertTrue("Should have seen an archive", archiveSeen);
859 	} finally {
860 		deleteProject("Test");
861 	}
862 }
testAnnotationPath9()863 public void testAnnotationPath9() throws CoreException, IOException {
864 	// tests annotationpath & add-exports in memento for a jrt system library:
865 	if (!isJRE9) return;
866 	try {
867 		IClasspathAttribute[] annPathAttr = {
868 			JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, "annots"),
869 			JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=ALL-UNNAMED")
870 		};
871 		IJavaProject project = createJava9ProjectWithJREAttributes("Test", new String[] {"src"}, annPathAttr);
872 		String attributesMemento = "=/annotationpath=/annots=/=/add-exports=/jdk.rmic\\/sun.rmi.rmic\\=ALL-UNNAMED=/";
873 
874 		// Module java.base:
875 		String expectedIdentifier = "=Test/"+getEscapedJrtJarPath()+"`java.base"+attributesMemento; // for specific PFR (see below)
876 		IModuleDescription module = project.findModule("java.base", null);
877 		String moduleIdentifier = expectedIdentifier+"<'`java.base"; // PFR - PackageFragment - ModularClassFile - Module
878 		assertEquals("Module mementos", moduleIdentifier, module.getHandleIdentifier());
879 		IJavaElement module2 = JavaCore.create(module.getHandleIdentifier(), null);
880 		assertTrue("Module existence", module2.exists());
881 		assertEquals("Module equivalence", module, module2);
882 
883 		// JrtPackageFragmentRoot - for module java.base:
884 		IPackageFragmentRoot packageRoot = (IPackageFragmentRoot) module.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
885 		String handleIdentifier = packageRoot.getHandleIdentifier();
886 		assertEquals("Root mementos", expectedIdentifier, handleIdentifier);
887 		IJavaElement element = JavaCore.create(handleIdentifier, null);
888 		assertEquals("Root equivalence", packageRoot, element);
889 
890 		// PackageFragment
891 		IPackageFragment test = packageRoot.getPackageFragment("java.lang");
892 		handleIdentifier = test.getHandleIdentifier();
893 		String expected = expectedIdentifier+"<java.lang";
894 		assertEquals("PackageFragment mementos", expected, handleIdentifier);
895 		element = JavaCore.create(handleIdentifier, null);
896 		assertEquals("PackageFragment equivalence", test, element);
897 
898 		// ClassFile:
899 		IClassFile classFile = test.getClassFile("Object.class");
900 		handleIdentifier = classFile.getHandleIdentifier();
901 		assertEquals("ClassFile mementos", expected+"(Object.class", handleIdentifier);
902 		element = JavaCore.create(handleIdentifier);
903 		assertEquals("ClassFile equivalence", classFile, element);
904 	} finally {
905 		deleteProject("Test");
906 	}
907 }
testEmptyAttribute()908 public void testEmptyAttribute() throws CoreException, IOException {
909 	try {
910 		IJavaProject project = createJavaProject("Test", new String[] {"src"}, null, "bin", "1.8", false);
911 		org.eclipse.jdt.core.tests.util.Util.createJar(
912 				new String[] {"test/Test.java", "package test; public class Test {}\n" },
913 				null, project.getProject().getLocation().toString()+"/lib.jar", null, "1.8", null);
914 
915 		project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
916 		IClasspathAttribute[] attributes = {
917 			JavaCore.newClasspathAttribute("foo", "")
918 		};
919 		addLibraryEntry(project, new Path("/Test/lib.jar"), null, null, null, null, attributes, false);
920 		String[] expectedIdentifiers = {
921 			"=Test/src",
922 			"=Test/lib.jar=/foo=/=/"
923 		};
924 		IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
925 		boolean archiveSeen = false;
926 		for (int i = 0; i < roots.length; i++) {
927 			IPackageFragmentRoot packageRoot = roots[i];
928 			String handleIdentifier = packageRoot.getHandleIdentifier();
929 			assertEquals("Root mementos", expectedIdentifiers[i], handleIdentifier);
930 			IJavaElement element = JavaCore.create(handleIdentifier, null);
931 			assertEquals("Root equivalence", packageRoot, element);
932 			if (packageRoot.isArchive()) {
933 				archiveSeen = true;
934 				// PackageFragment
935 				IPackageFragment test = packageRoot.getPackageFragment("test");
936 				handleIdentifier = test.getHandleIdentifier();
937 				String expected = expectedIdentifiers[i]+"<test";
938 				assertEquals("PackageFragment mementos", expected, handleIdentifier);
939 				element = JavaCore.create(handleIdentifier, null);
940 				assertEquals("PackageFragment equivalence", test, element);
941 				// ClassFile:
942 				IClassFile classFile = test.getClassFile("Test.class");
943 				handleIdentifier = classFile.getHandleIdentifier();
944 				assertEquals("ClassFile mementos", expected+"(Test.class", handleIdentifier);
945 				element = JavaCore.create(handleIdentifier);
946 				assertEquals("ClassFile equivalence", classFile, element);
947 			}
948 		}
949 		assertTrue("Should have seen an archive", archiveSeen);
950 	} finally {
951 		deleteProject("Test");
952 	}
953 }
954 }
955