| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.model; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaCore; |
| /** |
| * These test ensure that modifications in external jar are correctly reported as |
| * IJavaEllementDeltas after a JavaModel#refreshExternalArchives(). |
| */ |
| public class ExternalJarDeltaTests extends ModifyingResourceTests { |
| |
| public ExternalJarDeltaTests(String name) { |
| super(name); |
| } |
| public static Test suite() { |
| return buildModelTestSuite(ExternalJarDeltaTests.class); |
| } |
| // Use this static initializer to specify subset for tests |
| // All specified tests which do not belong to the class are skipped... |
| static { |
| // TESTS_PREFIX = "testBug79990"; |
| // TESTS_NAMES = new String[] { "testExternalJarInternalExternalJar"}; |
| // TESTS_NUMBERS = new int[] { 79860, 80918, 91078 }; |
| // TESTS_RANGE = new int[] { 83304, -1 }; |
| } |
| |
| /* |
| * Ensures that passing an empty scope to refreshExternalArchives(..) doesn't throw a NPE |
| * (regression test for bug 202076 NPE in DeltaProcessor) |
| */ |
| public void testEmptyScope() throws Exception { |
| try { |
| startDeltas(); |
| getJavaModel().refreshExternalArchives(new IJavaElement[0], null); |
| assertDeltas("Unexpected delta", ""); |
| } finally { |
| stopDeltas(); |
| } |
| } |
| |
| /** |
| * Test if a modification is detected without doing a refresh. |
| * Currently no modification are detected. |
| */ |
| public void testExternalJar0() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| |
| startDeltas(); |
| touch(f); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| |
| /** |
| * Refresh the JavaModel after a modification of an external jar. |
| */ |
| public void testExternalJarChanged1() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| touch(f); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh a JavaProject after a modification of an external jar. |
| */ |
| public void testExternalJarChanged2() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| touch(f); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{project},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh an external jar after a modification of this jar. |
| */ |
| public void testExternalJarChanged3() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| touch(f); |
| IPackageFragmentRoot root = project.getPackageFragmentRoot(pPath); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{root},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh the JavaModel after a modification of an external jar after shutdown. |
| * (regression test for bug 39856 External jar's timestamps should be persisted accross sessions) |
| */ |
| public void testExternalJarChanged4() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| |
| // exit, change the jar, and restart |
| simulateExit(); |
| try { |
| touch(f); |
| } finally { |
| simulateRestart(); |
| } |
| |
| startDeltas(); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Ensure that the external jars are refreshed by a call to JavaCore#initializeAfterLoad() |
| * (regression test for bug 93668 Search indexes not rebuild) |
| */ |
| public void testExternalJarChanged5() throws CoreException, IOException { |
| System.out.println("testExternalJarChanged5"); |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| |
| // exit, change the jar, and restart |
| simulateExit(); |
| try { |
| touch(f); |
| } finally { |
| simulateRestart(); |
| } |
| |
| startDeltas(); |
| JavaCore.initializeAfterLoad(null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /* |
| * Ensures that the correct delta is reported after a setRawClasspath and after a modification of an external jar. |
| * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769 ) |
| */ |
| public void testExternalJarChanged6() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| touch(f); |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null), JavaCore.newSourceEntry(new Path("/P"))}); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" + |
| " <project root>[*]: {ADDED TO CLASSPATH}\n" + |
| " "+f.getCanonicalPath()+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}\n" + |
| " ResourceDelta(/P/.classpath)[*]" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh the JavaModel after an addition of an external jar. |
| */ |
| public void testExternalJarAdded1() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "pAdded1.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[+]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh a JavaProject after an addition of an external jar. |
| */ |
| public void testExternalJarAdded2() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "pAdded2.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{project},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[+]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh an external jar after an addition of this jar. |
| */ |
| public void testExternalJarAdded3() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "pAdded3.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| IPackageFragmentRoot root = project.getPackageFragmentRoot(pPath); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{root},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[+]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh the JavaModel after a removal of an external jar. |
| */ |
| public void testExternalJarRemoved1() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| deleteResource(f); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[-]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh a JavaProject after a removal of an external jar. |
| */ |
| public void testExternalJarRemoved2() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| deleteResource(f); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{project},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[-]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * Refresh an external jar after a removal of this jar. |
| */ |
| public void testExternalJarRemoved3() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String pPath = getExternalPath() + "p.jar"; |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(pPath), null, null)}); |
| |
| f = new File(pPath); |
| f.createNewFile(); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| deleteResource(f); |
| IPackageFragmentRoot root = project.getPackageFragmentRoot(pPath); |
| getJavaModel().refreshExternalArchives(new IJavaElement[]{root},null); |
| |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN}\n"+ |
| " "+f.getCanonicalPath()+"[-]: {}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| /** |
| * - add an internal jar to claspath |
| * - remove internal jar and the same jar as external jar |
| * - touch the extenal jar |
| * - refresh the JavaModel |
| */ |
| public void testExternalJarInternalExternalJar() throws CoreException, IOException { |
| File f = null; |
| try { |
| IJavaProject project = this.createJavaProject("P", new String[] {""}, ""); |
| |
| String internalFooPath = "/P/foo.jar"; |
| IFile fooIFile = this.createFile(internalFooPath, new byte[0]); |
| |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(new Path(internalFooPath), null, null)}); |
| getJavaModel().refreshExternalArchives(null,null); |
| waitUntilIndexesReady(); |
| startDeltas(); |
| |
| // canonicalize the external path as this is not done on case sensitive platforms when creating a new lib entry |
| IPath externalFooPath = new Path(fooIFile.getLocation().toFile().getCanonicalPath()); |
| setClasspath(project, new IClasspathEntry[]{JavaCore.newLibraryEntry(externalFooPath, null, null)}); |
| |
| project.open(null); // ensure that project is opened, as external jar delta is optimized for this case (if the project is not opened, there is no need for broadcasting an external jar delta) |
| f = new File(externalFooPath.toOSString()); |
| touch(f); |
| getJavaModel().refreshExternalArchives(null,null); |
| |
| String externalFooPathString = f.getCanonicalPath(); |
| assertDeltas( |
| "Unexpected delta", |
| "P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n"+ |
| " foo.jar[*]: {REMOVED FROM CLASSPATH}\n"+ |
| " "+externalFooPathString+"[+]: {}\n"+ |
| " ResourceDelta(/P/.classpath)[*]\n"+ |
| "\n"+ |
| "P[*]: {CHILDREN}\n"+ |
| " "+externalFooPathString+"[*]: {CONTENT | ARCHIVE CONTENT CHANGED}" |
| ); |
| } finally { |
| if(f != null) { |
| deleteResource(f); |
| } |
| this.deleteProject("P"); |
| stopDeltas(); |
| } |
| } |
| } |
| |