Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 207155 Details for
Bug 356620
Make it possible to provide indexes for defined libraries
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Proposed patch
patch.txt (text/plain), 128.09 KB, created by
Satyam Kandula
on 2011-11-17 11:37:52 EST
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Satyam Kandula
Created:
2011-11-17 11:37:52 EST
Size:
128.09 KB
patch
obsolete
>diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >index 8b41712..8c25994 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >@@ -1348,6 +1348,27 @@ > } > } > } >+public static void zipFiles(File[] files, String zipPath) throws IOException { >+ File zipFile = new File(zipPath); >+ if (zipFile.exists()) { >+ if (!delete(zipFile)) >+ throw new IOException("Could not delete " + zipPath); >+ // ensure the new zip file has a different timestamp than the previous one >+ int timeToWait = 1000; // some platform (like Linux) have a 1s granularity) >+ waitAtLeast(timeToWait); >+ } else { >+ zipFile.getParentFile().mkdirs(); >+ } >+ ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile)); >+ for (int i = 0, length = files.length; i < length; i++) { >+ File file = files[i]; >+ ZipEntry entry = new ZipEntry(file.getName()); >+ zip.putNextEntry(entry); >+ zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file)); >+ zip.closeEntry(); >+ } >+ zip.close(); >+} > /** > * Returns the compilation errors / warnings for the given CompilationResult. > * >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java >new file mode 100644 >index 0000000..ca1d7af >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java >@@ -0,0 +1,775 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.model; >+ >+import java.io.File; >+import java.io.IOException; >+import java.net.URL; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.IClasspathAttribute; >+import org.eclipse.jdt.core.IClasspathEntry; >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.index.*; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.tests.util.Util; >+import org.eclipse.jdt.internal.core.JavaModelManager; >+ >+public class JavaIndexTests extends AbstractJavaSearchTests { >+ >+ static { >+ // TESTS_NAMES = new String[] {"testMultipleProjects"}; >+ } >+ public JavaIndexTests(String name) { >+ super(name); >+ } >+ >+ public static Test suite() { >+ return buildModelTestSuite(JavaIndexTests.class); >+ } >+ // Test that the index file is really generated. >+ public void testGenerateIndex() throws IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ assertTrue(new File(indexFilePath).exists()); >+ } finally { >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the index file and the jar in held after the index is created >+ public void testDeleteIndexedFile() { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ assertTrue("Could not delete the index file", new File(indexFilePath).delete()); >+ assertTrue("Could not delete the jar file", new File(jarFilePath).delete()); >+ } catch (IOException e) { >+ assertFalse("Test failed", true); >+ } >+ } >+ >+ // Test that search works fine with the index file >+ public void testUseIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ >+ waitUntilIndexesReady(); >+ >+ // Test that specified index file is really used >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Specified index file is not being used", indexFilePath,indexFile.toString()); >+ >+ // Test that search works properly >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ // Ensure that the index file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the same index file is used even after restarting >+ public void testUseIndexAfterRestart() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null, null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ // Ensure that the file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the same index file is used even after restarting >+ public void testUseIndexInternalJarAfterRestart() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = "/P/Test.jar"; >+ try { >+ IJavaProject p = createJavaProject("P"); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ IPath libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("\\P\\Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null, null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("\\P\\Test.jar pkg.Test"); >+ >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ // Ensure that the file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ } >+ } >+ >+ // Test that a jar file that gets modified after the index is created doesn't return new changes. >+ // This behavior might have to be modified but.. >+ public void testModifyJarAfterIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index >+ public void testNonExistentIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ new File(indexFilePath).delete(); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index >+ public void testNonExistentIndexRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ new File(indexFilePath).delete(); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ long modified = indexFile.lastModified(); >+ assertEquals(modified, indexFile.lastModified()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Index File should not have got modified",modified, indexFile.lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test that if the index is not existent after restart, it should build up a new index >+ public void testNonExistentIndexAfterRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ "protected Test(int i) {}\n" + "}" >+ },jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ File indexFile = new File(indexFilePath); >+ indexFile.delete(); >+ assertTrue(!indexFile.exists()); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index which becomes existent after restart >+ public void testExistentIndexAfterRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ File indexFile = new File(indexFilePath); >+ indexFile.delete(); >+ assertTrue(!indexFile.exists()); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the index file is not deletes when the project is deleted >+ public void testDeleteProject() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ IJavaProject p = createJavaProject("P"); >+ createExternalFolder("externalLib"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ deleteProject("P"); >+ File f = new File(indexFilePath); >+ assertTrue(f.exists()); >+ } finally { >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that it works if the index file is in the jar file >+ public void testIndexInJar() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexZipPath = getExternalResourcePath("TestIndex.zip"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ Util.zipFiles(new File[]{new File(indexFilePath)}, indexZipPath); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ String url = "jar:file:/"+indexZipPath+"!/Test.index"; >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, url); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString()); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString()); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ } finally { >+ deleteProject("P"); >+ new File(indexZipPath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test index file in platform >+ public void testPlatformIndexFile() throws CoreException, IOException { >+ String indexFilePath = null; >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexUrl = "platform:/resource/P/Test.index"; >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ IJavaProject p = createJavaProject("P"); >+ indexFilePath = p.getProject().getLocation().append("Test.index").toFile().getAbsolutePath(); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexUrl); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ URL url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ if (indexFilePath != null) new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test index file in platform >+ public void testPlatformJarIndexFile() throws CoreException, IOException { >+ String indexFilePath = null; >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexUrl = "platform:/resource/ForIndex/Test.index.zip!/Test.index"; >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ IProject indexProj = createProject("ForIndex"); >+ indexFilePath = indexProj.getProject().getLocation().append("Test.index").toFile().getAbsolutePath(); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ Util.zipFiles(new File[]{new File(indexFilePath)}, indexFilePath+".zip"); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexUrl); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ URL url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ } finally { >+ deleteProject("P"); >+ if (indexFilePath != null) { >+ new File(indexFilePath).delete(); >+ new File(indexFilePath+".zip").delete(); >+ } >+ new File(jarFilePath).delete(); >+ deleteProject("ForIndex"); >+ } >+ } >+ >+ public void testEditClasspath() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ File f = new File(indexFilePath); >+ long modified = f.lastModified(); >+ IJavaProject p = this.createJavaProject("P", new String[] {}, "bin"); >+ >+ String content = new String( >+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" >+ + "<classpath>\n" >+ + "<classpathentry kind=\"src\" path=\"src a\"/>\n" >+ + "<classpathentry kind=\"src\" path=\"src x\"/>\n" >+ + "<classpathentry kind=\"lib\" path=\"" >+ + getExternalJCLPath() >+ + "\"/>\n" >+ + "<classpathentry kind=\"lib\" path=\"" >+ + jarFilePath >+ + "\">" >+ + "<attributes>\n" >+ + " <attribute name=\"index_location\" value=\"file:///" >+ + indexFilePath >+ +"\"/>\n" >+ + "</attributes>\n" >+ + "</classpathentry>\n" >+ + "<classpathentry kind=\"output\" path=\"bin\"/>\n" >+ + "</classpath>\n"); >+ >+ editFile("/P/.classpath", content); >+ p.open(null); >+ waitUntilIndexesReady(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(new Path(jarFilePath), false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ f = new File(indexFilePath); >+ assertEquals(modified, f.lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test changing the classpath >+ public void testChangeClasspath() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.NewTest"); >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.NewTest"); >+ >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test changing the classpath >+ public void testChangeClasspathForInternalJar() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = "/P/Test.jar"; >+ try { >+ IJavaProject p = createJavaProject("P"); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, jarFilePath); >+ Path libPath = new Path(jarFilePath); >+ >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("\\P\\Test.jar pkg.NewTest"); >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("\\P\\Test.jar pkg.NewTest"); >+ >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ } >+ } >+ >+ public void testMultipleProjects() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ >+ IJavaProject p1 = createJavaProject("P1"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p1, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ IJavaProject p2 = createJavaProject("P2"); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p2, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p1})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ >+ } finally { >+ deleteProject("P1"); >+ deleteProject("P2"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // TODO SATYAM: Add test for containers >+} >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >index deb70fd..52af315 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -1025,7 +1025,7 @@ > > // Index the output location as it is a library for the project > IndexManager indexManager = JavaModelManager.getIndexManager(); >- indexManager.indexLibrary(new Path("/P1/bin"), project.getProject()); >+ indexManager.indexLibrary(new Path("/P1/bin"), project.getProject(), null); > waitUntilIndexesReady(); > > // Search for all types >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >index 8917c29..2d7d864 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -62,6 +62,7 @@ > allClasses.add(SearchTests.class); > allClasses.add(JavaSearchScopeTests.class); > allClasses.add(MatchingRegionsTest.class); >+ allClasses.add(JavaIndexTests.class); > > // Reset forgotten subsets of tests > TestCase.TESTS_PREFIX = null; >diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF >index bb3c0af..354c648 100644 >--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF >@@ -17,6 +17,7 @@ > org.eclipse.jdt.core.jdom, > org.eclipse.jdt.core.search, > org.eclipse.jdt.core.util, >+ org.eclipse.jdt.core.index, > org.eclipse.jdt.internal.codeassist;x-internal:=true, > org.eclipse.jdt.internal.codeassist.complete;x-internal:=true, > org.eclipse.jdt.internal.codeassist.impl;x-internal:=true, >diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java >new file mode 100644 >index 0000000..0fac7f3 >--- /dev/null >+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java >@@ -0,0 +1,63 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core; >+ >+import java.io.IOException; >+ >+import org.apache.tools.ant.BuildException; >+import org.apache.tools.ant.Task; >+import org.eclipse.jdt.core.index.JavaIndexer; >+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages; >+ >+/** >+ * <p> >+ * An Ant task to generate the index file for the given jar path. >+ * </p> >+ * <p> >+ * <code><eclipse.buildJarIndex jarPath="Test.jar" indexPath="Test.index"/></code> >+ * </p> >+ * <p> >+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ . >+ * </p> >+ * >+ * This is not intended to be subclassed by users. >+ * >+ * @since 3.8 >+ */ >+public class BuildJarIndex extends Task { >+ >+ private String jarPath; >+ private String indexPath; >+ >+ public void execute() throws BuildException { >+ if (this.jarPath == null) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.jarFile.cannot.be.null")); //$NON-NLS-1$ >+ } >+ if (this.indexPath == null) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.indexFile.cannot.be.null")); //$NON-NLS-1$ >+ } >+ >+ try { >+ JavaIndexer.generateIndexForJar(this.jarPath, this.indexPath); >+ } catch (IOException e) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.ioexception.occured", e.getLocalizedMessage())); //$NON-NLS-1$ >+ } >+ setProject(getProject()); >+ } >+ >+ public void setJarPath(String path) { >+ this.jarPath = path; >+ } >+ >+ public void setIndexPath(String path) { >+ this.indexPath = path; >+ } >+} >diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >index df61656..9cb9be2 100644 >--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2000, 2006 IBM Corporation and others. >+# Copyright (c) 2000, 2011 IBM Corporation and others. > # All rights reserved. This program and the accompanying materials > # are made available under the terms of the Eclipse Public License v1.0 > # which accompanies this distribution, and is available at >@@ -19,3 +19,7 @@ > checkDebugAttributes.property.argument.cannot.be.null=The property argument cannot be null > checkDebugAttributes.ioexception.occured=IOException occurred while reading > checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile=The file argument must be a .class or a .jar file >+ >+buildJarIndex.jarFile.cannot.be.null=The jar file argument cannot be null >+buildJarIndex.indexFile.cannot.be.null=The index file argument cannot be null >+buildJarIndex.ioexception.occured=IOException - {0} >diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties >index ff520f9..8e3f678 100644 >--- a/org.eclipse.jdt.core/build.properties >+++ b/org.eclipse.jdt.core/build.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2000, 2010 IBM Corporation and others. >+# Copyright (c) 2000, 2011 IBM Corporation and others. > # All rights reserved. This program and the accompanying materials > # are made available under the terms of the Eclipse Public License v1.0 > # which accompanies this distribution, and is available at >@@ -24,7 +24,8 @@ > org.eclipse.jdt.core.jdom.*,\ > org.eclipse.jdt.core.dom.*,\ > org.eclipse.jdt.core.dom.rewrite.*,\ >- org.eclipse.jdt.core.search.* >+ org.eclipse.jdt.core.search.*,\ >+ org.eclipse.jdt.core.index.* > source.. = batch/,\ > codeassist/,\ > compiler/,\ >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >index d90ab15..51effaf 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -58,6 +58,16 @@ > * @since 3.1 > */ > String JAVADOC_LOCATION_ATTRIBUTE_NAME = "javadoc_location"; //$NON-NLS-1$ >+ >+ /** >+ * Constant for the name of the index location attribute. >+ * >+ * <p>The value for this attribute has to be the string representation of a URL. >+ * It should point to an existing index file in a folder or a jar. The URL also supports the platform protocol.</p> >+ * >+ * @since 3.8 >+ */ >+ String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; //$NON-NLS-1$ > > /** > * Constant for the name of the optional attribute. The possible values >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java >index bc17b09..b52c5ef 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java >@@ -57,6 +57,12 @@ > * <li>{@link #F_SOURCEDETACHED} - The source attachment path or the source attachment root path > * of a classpath entry corresponding to the element was removed. This flag is only valid if the element is an > * {@link IPackageFragmentRoot}.</li> >+ * <li>{@link #F_INDEXATTACHED} - The index path or the index root path >+ * of a classpath entry corresponding to the element was added. This flag is only valid if the element is an >+ * {@link IPackageFragmentRoot}.</li> >+ * <li>{@link #F_INDEXDETACHED} - The index path or the index root path >+ * of a classpath entry corresponding to the element was removed. This flag is only valid if the element is an >+ * {@link IPackageFragmentRoot}.</li> > * <li>{@link #F_SUPER_TYPES} - One of the supertypes of an {@link IType} has changed</li>. > * </ul> > * </li> >@@ -312,6 +318,26 @@ > * @since 3.4 > */ > public int F_ANNOTATIONS = 0x400000; >+ >+ /** >+ * TODO SATYAM: We probably don't need this delta.. >+ * >+ * Change flag indicating that the index file of a classpath entry >+ * corresponding to the element was added. This flag is only valid if the element is an >+ * {@link IPackageFragmentRoot}. >+ * >+ * @since 3.8 >+ */ >+ public int F_INDEXATTACHED = 0x800000; >+ >+ /** >+ * Change flag indicating that the index file of a classpath entry >+ * corresponding to the element was removed. This flag is only valid if the element is an >+ * {@link IPackageFragmentRoot}. >+ * >+ * @since 3.8 >+ */ >+ public int F_INDEXDETACHED = 0x1000000; > > /** > * Returns deltas for the children that have been added. >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java >index c1ed588..421ae4b 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -18,6 +18,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.core; > >+import java.net.URL; > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IProgressMonitor; > >@@ -243,6 +244,18 @@ > */ > void delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor) throws JavaModelException; > /** >+ * Returns the URL to the index file attached to this package fragment root's binary archive. >+ * >+ * @return the URL to the corresponding index file, >+ * or <code>null</code> if this package fragment root's binary archive >+ * has no corresponding index file, or if this package fragment root >+ * is not a binary archive >+ * @exception JavaModelException if this operation fails >+ * >+ * @since 3.8 >+ */ >+ URL getIndexPath() throws JavaModelException; >+ /** > * Returns this package fragment root's kind encoded as an integer. > * A package fragment root can contain source files (i.e. files with one > * of the {@link JavaCore#getJavaLikeExtensions() Java-like extensions}, >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >index b96cd44..5d5e3bd 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >+import java.net.URL; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.HashSet; >@@ -335,6 +336,7 @@ > boolean found = false; > for (int j = 0; j < accumulatedRoots.size(); j++) { > IPackageFragmentRoot root = (IPackageFragmentRoot) accumulatedRoots.elementAt(j); >+ // TODO SATYAM: Shouldn't the check be opposite? > if (!root.getPath().equals(oldRoot.getPath())) { > found = true; > break; >@@ -511,7 +513,7 @@ > > for (int i = 0; i < newLength; i++) { > int index = classpathContains(this.oldResolvedClasspath, newResolvedClasspath[i]); >- if (index == -1) { >+ if (index == -1 || newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { > // remote projects are not indexed in this project > if (newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ > continue; >@@ -524,14 +526,23 @@ > boolean pathHasChanged = true; > IPath newPath = newResolvedClasspath[i].getPath(); > for (int j = 0; j < oldLength; j++) { >+ //TODO SATYAM: Isn't index == j? > IClasspathEntry oldEntry = this.oldResolvedClasspath[j]; > if (oldEntry.getPath().equals(newPath)) { >- pathHasChanged = false; >+ URL oldurl = ((ClasspathEntry)oldEntry).getLibraryIndexLocation(); >+ URL newurl = ((ClasspathEntry)newResolvedClasspath[i]).getLibraryIndexLocation(); >+ if (oldurl == null && newurl == null) { >+ pathHasChanged = false; >+ } else if (oldurl != null && newurl != null) { >+ pathHasChanged = !(newurl.equals(oldurl)); >+ } else if (oldurl != null) { >+ indexManager.removeIndex(newPath); >+ } > break; > } > } > if (pathHasChanged) { >- indexManager.indexLibrary(newPath, this.project.getProject()); >+ indexManager.indexLibrary(newPath, this.project.getProject(),((ClasspathEntry)newResolvedClasspath[i]).getLibraryIndexLocation()); > } > break; > case IClasspathEntry.CPE_SOURCE: >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >index 5656323..5faf197 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >@@ -17,6 +17,8 @@ > import java.io.InputStream; > import java.io.OutputStreamWriter; > import java.io.UnsupportedEncodingException; >+import java.net.MalformedURLException; >+import java.net.URL; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.HashSet; >@@ -1524,6 +1526,33 @@ > > return JavaCore.getResolvedClasspathEntry(this); > } >+ >+ /** >+ * This function computes the URL of the index location for this classpath entry. It returns null if the URL is >+ * invalid. >+ */ >+ public URL getLibraryIndexLocation() { >+ switch(getEntryKind()) { >+ case IClasspathEntry.CPE_LIBRARY : >+ case IClasspathEntry.CPE_VARIABLE : >+ break; >+ default : >+ return null; >+ } >+ >+ for (int i= 0; i < this.extraAttributes.length; i++) { >+ IClasspathAttribute attrib= this.extraAttributes[i]; >+ if (IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) { >+ String value = attrib.getValue(); >+ try { >+ return new URL(value); >+ } catch (MalformedURLException e) { >+ return null; >+ } >+ } >+ } >+ return null; >+ } > > /** > * Validate a given classpath and output location for a project, using the following rules: >@@ -2191,5 +2220,5 @@ > } > } > return JavaModelStatus.VERIFIED_OK; >- } >+ } > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >index 126fcc9..4ef6e0b 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >@@ -13,6 +13,7 @@ > package org.eclipse.jdt.internal.core; > > import java.io.File; >+import java.net.URL; > import java.util.*; > > import org.eclipse.core.resources.IContainer; >@@ -997,8 +998,12 @@ > // first remove the index so that it is forced to be re-indexed > this.manager.indexManager.removeIndex(entryPath); > // then index the jar >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); > } else { >+ URL indexLocation = ((ClasspathEntry)entries[j]).getLibraryIndexLocation(); >+ if (indexLocation != null) { // force reindexing, this could be faster rather than maintaining the list >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); >+ } > externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED); > } > } else { >@@ -1009,7 +1014,7 @@ > this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp)); > // index the new jar > this.manager.indexManager.removeIndex(entryPath); >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); > } > } > } else { // internal JAR >@@ -2629,13 +2634,13 @@ > switch (delta.getKind()) { > case IResourceDelta.ADDED: > // index the new jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath() ); > break; > case IResourceDelta.CHANGED: > // first remove the index so that it is forced to be re-indexed > indexManager.removeIndex(jarPath); > // then index the jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath()); > break; > case IResourceDelta.REMOVED: > // the jar was physically removed: remove the index >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java >index ee0d715..e55c951 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -569,6 +569,29 @@ > detachedDelta.changed(F_SOURCEDETACHED); > insertDeltaTree(element, detachedDelta); > } >+ >+/** >+ * Creates the nested deltas resulting from a change operation. >+ * Convenience method for creating change deltas. >+ * The constructor should be used to create the root delta >+ * and then a change operation should call this method. >+ */ >+public void indexAttached(IJavaElement element) { >+ JavaElementDelta attachedDelta = new JavaElementDelta(element); >+ attachedDelta.changed(F_INDEXATTACHED); >+ insertDeltaTree(element, attachedDelta); >+} >+/** >+ * Creates the nested deltas resulting from a change operation. >+ * Convenience method for creating change deltas. >+ * The constructor should be used to create the root delta >+ * and then a change operation should call this method. >+ */ >+public void indexDetached(IJavaElement element) { >+ JavaElementDelta detachedDelta = new JavaElementDelta(element); >+ detachedDelta.changed(F_INDEXDETACHED); >+ insertDeltaTree(element, detachedDelta); >+} > /** > * Returns a string representation of this delta's > * structure suitable for debug purposes. >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >index 9fb59c6..a640d6a 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >+import java.net.URL; > import java.util.ArrayList; > import java.util.Enumeration; > import java.util.Map; >@@ -807,4 +808,16 @@ > } > } > >+public URL getIndexPath() { >+ try { >+ if (getKind() != K_BINARY) return null; >+ >+ IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath()); >+ if (entry != null) return ((ClasspathEntry)entry).getLibraryIndexLocation(); >+ } catch (JavaModelException e) { >+ // ignore exception >+ } >+ return null; >+} >+ > } >diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml >index 3784256..5d69788 100644 >--- a/org.eclipse.jdt.core/plugin.xml >+++ b/org.eclipse.jdt.core/plugin.xml >@@ -1,7 +1,7 @@ > <?xml version="1.0" encoding="UTF-8"?> > <?eclipse version="3.0"?> > <!-- >- Copyright (c) 2004, 2010 IBM Corporation and others. >+ Copyright (c) 2004, 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 >@@ -158,6 +158,11 @@ > class="org.eclipse.jdt.core.CheckDebugAttributes" > library="jdtCompilerAdapter.jar"> > </antTask> >+ <antTask >+ name="eclipse.buildJarIndex" >+ class="org.eclipse.jdt.core.BuildJarIndex" >+ library="jdtCompilerAdapter.jar"> >+ </antTask> > </extension> > > <!-- =================================================================================== --> >@@ -196,6 +201,17 @@ > </extension> > > <!-- =================================================================================== --> >+<!-- Extension: Java Generate Indexer --> >+<!-- =================================================================================== --> >+<extension >+ id="JavaIndexer" >+ point="org.eclipse.core.runtime.applications"> >+ <application> >+ <run class="org.eclipse.jdt.core.index.JavaIndexerApplication" /> >+ </application> >+</extension> >+ >+<!-- =================================================================================== --> > <!-- Extension: Java Content Types --> > <!-- =================================================================================== --> > <extension point="org.eclipse.core.contenttype.contentTypes"> >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java >new file mode 100644 >index 0000000..3b7ef0f >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java >@@ -0,0 +1,32 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.index; >+ >+import java.io.IOException; >+import org.eclipse.jdt.internal.core.search.indexing.DefaultJavaIndexer; >+ >+/** >+ * TODO SATYAM: Write a proper javadoc >+ * @since 3.8 >+ */ >+public class JavaIndexer { >+ >+ /** >+ * TODO SATYAM: Write a javadoc >+ * @param pathToJar >+ * @param pathToIndexFile >+ * @throws IOException >+ */ >+ public static void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException { >+ new DefaultJavaIndexer().generateIndexForJar(pathToJar, pathToIndexFile); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java >new file mode 100644 >index 0000000..4b5b931 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java >@@ -0,0 +1,154 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.text.MessageFormat; >+import java.util.ArrayList; >+ >+import org.eclipse.equinox.app.IApplication; >+import org.eclipse.equinox.app.IApplicationContext; >+import org.eclipse.osgi.util.NLS; >+ >+/** >+ * Implements an Eclipse Application for org.eclipse.jdt.core.JavaIndexer. >+ * >+ * TODO SATYAM: Improve the javadoc to include the arguments. >+ * <p> >+ * On MacOS, when invoked using the Eclipse executable, the "user.dir" property is set to the folder in which the >+ * eclipse.ini file is located. This makes it harder to use relative paths to point to the files to be formatted or the >+ * configuration file to use to set the code formatter's options. >+ * </p> >+ * >+ * >+ * @since 3.8 >+ * @noinstantiate This class is not intended to be instantiated by clients. >+ * @noextend This class is not intended to be subclassed by clients. >+ */ >+public class JavaIndexerApplication implements IApplication { >+ >+ private final static class Messages extends NLS { >+ private static final String MESSAGES_NAME = "org.eclipse.jdt.core.index.messages";//$NON-NLS-1$ >+ >+ public static String CommandLineProcessing; >+ public static String CommandLineUsage; >+ public static String CommandLineOnlyOutputError; >+ public static String CommandLineOnlyOneJarError; >+ public static String CommandLineJarNotSpecified; >+ public static String CommandLineIndexFileNotSpecified; >+ public static String CaughtException; >+ public static String CommandLineJarFileNotExist; >+ >+ static { >+ NLS.initializeMessages(MESSAGES_NAME, Messages.class); >+ } >+ >+ public static String bind(String message) { >+ return bind(message, null); >+ } >+ >+ public static String bind(String message, Object binding) { >+ return bind(message, new Object[] { binding }); >+ } >+ >+ public static String bind(String message, Object binding1, Object binding2) { >+ return bind(message, new Object[] { binding1, binding2 }); >+ } >+ >+ public static String bind(String message, Object[] bindings) { >+ return MessageFormat.format(message, bindings); >+ } >+ } >+ >+ private String jarToIndex; >+ private String indexFile; >+ private boolean verbose = false; >+ private static final String PDE_LAUNCH = "-pdelaunch"; //$NON-NLS-1$ >+ private static final String ARG_HELP = "-help"; //$NON-NLS-1$ >+ private static final String ARG_VERBOSE = "-verbose"; //$NON-NLS-1$ >+ private static final String ARG_OUTPUT = "-output"; //$NON-NLS-1$ >+ >+ private void displayHelp() { >+ System.out.println(Messages.bind(Messages.CommandLineUsage)); >+ } >+ >+ private void displayError(String message) { >+ System.err.println(message); >+ System.out.println(); >+ displayHelp(); >+ } >+ >+ private boolean processCommandLine(String[] argsArray) { >+ ArrayList args = new ArrayList(); >+ for (int i = 0, max = argsArray.length; i < max; i++) { >+ args.add(argsArray[i]); >+ } >+ int index = 0; >+ final int argCount = argsArray.length; >+ >+ loop: while (index < argCount) { >+ String currentArg = argsArray[index++]; >+ if (PDE_LAUNCH.equals(currentArg)) { >+ continue loop; >+ } else if (ARG_HELP.equals(currentArg)) { >+ displayHelp(); >+ return false; >+ } else if (ARG_VERBOSE.equals(currentArg)) { >+ this.verbose = true; >+ continue loop; >+ } else if (ARG_OUTPUT.equals(currentArg)) { >+ if (this.indexFile != null || index == argCount) { >+ displayError(Messages.bind(Messages.CommandLineOnlyOutputError)); >+ return false; >+ } >+ this.indexFile = argsArray[index++]; >+ } else { >+ if (this.jarToIndex != null) { >+ displayError(Messages.bind(Messages.CommandLineOnlyOneJarError)); >+ return false; >+ } >+ this.jarToIndex = currentArg; >+ } >+ } >+ return true; >+ } >+ >+ public Object start(IApplicationContext context) throws Exception { >+ boolean execute = processCommandLine((String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS)); >+ if (execute) { >+ if (this.jarToIndex != null && this.indexFile != null) { >+ File f = new File(this.jarToIndex); >+ if (!f.exists()) { >+ System.out.println(Messages.bind(Messages.CommandLineJarFileNotExist, this.jarToIndex)); >+ } >+ if (this.verbose) { >+ System.out.println(Messages.bind(Messages.CommandLineProcessing, this.jarToIndex, this.indexFile)); >+ } >+ try { >+ JavaIndexer.generateIndexForJar(this.jarToIndex, this.indexFile); >+ } catch (IOException e) { >+ System.out.println(Messages.bind(Messages.CaughtException, "IOException", e.getLocalizedMessage())); //$NON-NLS-1$ >+ } >+ } else if (this.jarToIndex == null) { >+ System.out.println(Messages.bind(Messages.CommandLineJarNotSpecified)); >+ } else if (this.indexFile == null) { >+ System.out.println(Messages.bind(Messages.CommandLineIndexFileNotSpecified)); >+ } >+ } >+ return IApplication.EXIT_OK; >+ } >+ >+ public void stop() { >+ // do nothing >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties >new file mode 100644 >index 0000000..704b29f >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties >@@ -0,0 +1,28 @@ >+############################################################################### >+# Copyright (c) 2000, 2006 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 >+############################################################################### >+CommandLineUsage=Usage: eclipse -application org.eclipse.jdt.core.JavaCodeGenerateIndex [ OPTIONS ] -output <indexFile> <jarfile>\n\ >+\n\ >+\ -output <indexFile> The index file to be generated.\n\ >+\ >+\ <jarfile> Jar file for which index needs to be generated.\n\ >+\ >+\n\ >+\ OPTIONS:\n\ >+\n\ >+\ -help Display this message.\n\ >+\ -verbose Be verbose about the job. >+CommandLineProcessing=Generating index {1} for the jar {0}. >+CommandLineOnlyOutputError=Only one output need to be specified. >+CommandLineOnlyOneJarError=Only one jar file need to be specified. >+CommandLineJarNotSpecified=No jar file is specified. >+CommandLineIndexFileNotSpecified=No index file is specified. >+CaughtException=Exception {0} - {1}. >+CommandLineJarFileNotExist={0} does not exist. >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >index 4e3f6c4..761633e 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >@@ -14,6 +14,8 @@ > import org.eclipse.core.runtime.*; > import org.eclipse.jdt.internal.core.JavaModel; > import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.index.FlatFileIndex; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.IndexManager; > > /** >@@ -192,9 +194,9 @@ > * </p> > * > * @param document the document to index >- * @param indexLocation the location on the file system of the index >+ * @param indexPath the location on the file system of the index > */ >- public final void scheduleDocumentIndexing(SearchDocument document, IPath indexLocation) { >+ public final void scheduleDocumentIndexing(SearchDocument document, IPath indexPath) { > IPath documentPath = new Path(document.getPath()); > Object file = JavaModel.getTarget(documentPath, true); > IPath containerPath = documentPath; >@@ -205,11 +207,13 @@ > } > IndexManager manager = JavaModelManager.getIndexManager(); > // TODO (frederic) should not have to create index manually, should expose API that recreates index instead >+ IndexLocation indexLocation; >+ indexLocation = new FlatFileIndex(indexPath.toFile()); > manager.ensureIndexExists(indexLocation, containerPath); > manager.scheduleDocumentIndexing(document, containerPath, indexLocation, this); >- if (!indexLocation.equals(this.lastIndexLocation)) { >- manager.updateParticipant(indexLocation, containerPath); >- this.lastIndexLocation = indexLocation; >+ if (!indexPath.equals(this.lastIndexLocation)) { >+ manager.updateParticipant(indexPath, containerPath); >+ this.lastIndexLocation = indexPath; > } > } > >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >index 7644036..e393c17 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >@@ -23,7 +23,7 @@ > > public class DiskIndex { > >-File indexFile; >+IndexLocation indexFile; > > private int headerInfoOffset; > private int numberOfChunks; >@@ -82,12 +82,7 @@ > } > > >-DiskIndex(String fileName) { >- if (fileName == null) >- throw new java.lang.IllegalArgumentException(); >- this.indexFile = new File(fileName); >- >- // clear cached items >+DiskIndex() { > this.headerInfoOffset = -1; > this.numberOfChunks = -1; > this.sizeOfLastChunk = -1; >@@ -99,6 +94,13 @@ > this.cachedCategoryName = null; > this.categoryOffsets = null; > this.categoryEnds = null; >+} >+DiskIndex(IndexLocation location) throws IOException { >+ this(); >+ if (location == null) { >+ throw new IllegalArgumentException(); >+ } >+ this.indexFile = location; > } > SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException { > // must skip over documents which have been added/changed/deleted in the memory index >@@ -230,7 +232,7 @@ > private void cacheDocumentNames() throws IOException { > // will need all document names so get them now > this.cachedChunks = new String[this.numberOfChunks][]; >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexFile.getInputStream(); > try { > if (this.numberOfChunks > 5) BUFFER_READ_SIZE <<= 1; > int offset = this.chunkOffsets[0]; >@@ -372,7 +374,7 @@ > void initialize(boolean reuseExistingFile) throws IOException { > if (this.indexFile.exists()) { > if (reuseExistingFile) { >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexFile.getInputStream(); > this.streamBuffer = new byte[BUFFER_READ_SIZE]; > this.bufferIndex = 0; > this.bufferEnd = stream.read(this.streamBuffer, 0, 128); >@@ -400,7 +402,7 @@ > } > } > if (this.indexFile.createNewFile()) { >- FileOutputStream stream = new FileOutputStream(this.indexFile, false); >+ FileOutputStream stream = new FileOutputStream(this.indexFile.getIndexFile(), false); > try { > this.streamBuffer = new byte[BUFFER_READ_SIZE]; > this.bufferIndex = 0; >@@ -500,6 +502,9 @@ > DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException { > // assume write lock is held > // compute & write out new docNames >+ if (this.indexFile == null) { >+ throw new IOException("Pre-built index file not writeable"); //$NON-NLS-1$ >+ } > String[] docNames = readAllDocumentNames(); > int previousLength = docNames.length; > int[] positions = new int[previousLength]; // keeps track of the position of each document in the new sorted docNames >@@ -509,15 +514,16 @@ > if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved > > // index is now empty since all the saved documents were removed >- DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath()); >+ DiskIndex newDiskIndex = new DiskIndex(this.indexFile); > newDiskIndex.initialize(false); > return newDiskIndex; > } >- >- DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath() + ".tmp"); //$NON-NLS-1$ >+ File oldIndexFile = this.indexFile.getIndexFile(); >+ DiskIndex newDiskIndex = new DiskIndex(new FlatFileIndex(new File(oldIndexFile.getPath() + ".tmp"))); //$NON-NLS-1$ >+ File newIndexFile = newDiskIndex.indexFile.getIndexFile(); > try { >- newDiskIndex.initializeFrom(this, newDiskIndex.indexFile); >- FileOutputStream stream = new FileOutputStream(newDiskIndex.indexFile, false); >+ newDiskIndex.initializeFrom(this, newIndexFile); >+ FileOutputStream stream = new FileOutputStream(newIndexFile, false); > int offsetToHeader = -1; > try { > newDiskIndex.writeAllDocumentNames(docNames, stream); >@@ -549,18 +555,18 @@ > newDiskIndex.writeOffsetToHeader(offsetToHeader); > > // rename file by deleting previous index file & renaming temp one >- if (this.indexFile.exists() && !this.indexFile.delete()) { >+ if (oldIndexFile.exists() && !oldIndexFile.delete()) { > if (DEBUG) > System.out.println("mergeWith - Failed to delete " + this.indexFile); //$NON-NLS-1$ > throw new IOException("Failed to delete index file " + this.indexFile); //$NON-NLS-1$ > } >- if (!newDiskIndex.indexFile.renameTo(this.indexFile)) { >+ if (!newIndexFile.renameTo(oldIndexFile)) { > if (DEBUG) > System.out.println("mergeWith - Failed to rename " + this.indexFile); //$NON-NLS-1$ > throw new IOException("Failed to rename index file " + this.indexFile); //$NON-NLS-1$ > } > } catch (IOException e) { >- if (newDiskIndex.indexFile.exists() && !newDiskIndex.indexFile.delete()) >+ if (newIndexFile.exists() && !newIndexFile.delete()) > if (DEBUG) > System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexFile); //$NON-NLS-1$ > throw e; >@@ -573,7 +579,7 @@ > if (this.numberOfChunks <= 0) > return CharOperation.NO_STRINGS; > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexFile.getInputStream(); > try { > int offset = this.chunkOffsets[0]; > stream.skip(offset); >@@ -612,7 +618,7 @@ > } > } > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexFile.getInputStream(); > HashtableOfObject categoryTable = null; > char[][] matchingWords = null; > int count = 0; >@@ -678,7 +684,7 @@ > } > > if (matchingWords != null && count > 0) { >- stream = new FileInputStream(this.indexFile); >+ stream = this.indexFile.getInputStream(); > try { > stream.skip(firstOffset); > this.bufferIndex = 0; >@@ -696,7 +702,7 @@ > this.streamBuffer = null; > return categoryTable; > } >-private void readChunk(String[] docNames, FileInputStream stream, int index, int size) throws IOException { >+private void readChunk(String[] docNames, InputStream stream, int index, int size) throws IOException { > String current = new String(readStreamChars(stream)); > docNames[index++] = current; > for (int i = 1; i < size; i++) { >@@ -734,7 +740,7 @@ > throw new IllegalArgumentException(); > this.streamBuffer = new byte[numberOfBytes]; > this.bufferIndex = 0; >- FileInputStream file = new FileInputStream(this.indexFile); >+ InputStream file = this.indexFile.getInputStream(); > try { > file.skip(start); > if (file.read(this.streamBuffer, 0, numberOfBytes) != numberOfBytes) >@@ -763,7 +769,7 @@ > if (arrayOffset instanceof int[]) > return (int[]) arrayOffset; > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexFile.getInputStream(); > try { > int offset = ((Integer) arrayOffset).intValue(); > stream.skip(offset); >@@ -776,15 +782,15 @@ > this.streamBuffer = null; > } > } >-private void readHeaderInfo(FileInputStream stream) throws IOException { >+private void readHeaderInfo(InputStream stream) throws IOException { > > // must be same order as writeHeaderInfo() > this.numberOfChunks = readStreamInt(stream); > this.sizeOfLastChunk = this.streamBuffer[this.bufferIndex++] & 0xFF; > this.documentReferenceSize = this.streamBuffer[this.bufferIndex++] & 0xFF; > this.separator = (char) (this.streamBuffer[this.bufferIndex++] & 0xFF); >- long fileLength = this.indexFile.length(); >- if (this.numberOfChunks > fileLength ) { >+ long length = this.indexFile.length(); >+ if (length != -1 && this.numberOfChunks > length) { > // not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612 > if (DEBUG) > System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >@@ -799,7 +805,7 @@ > int size = readStreamInt(stream); > this.categoryOffsets = new HashtableOfIntValues(size); > this.categoryEnds = new HashtableOfIntValues(size); >- if (size > fileLength) { >+ if (length != -1 && this.numberOfChunks > length) { > // not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612 > if (DEBUG) > System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >@@ -840,7 +846,7 @@ > } > } > } >-private void readStreamBuffer(FileInputStream stream) throws IOException { >+private void readStreamBuffer(InputStream stream) throws IOException { > // if we're about to read a known amount at the end of the existing buffer, but it does not completely fit > // so we need to shift the remaining bytes to be read, and fill the buffer from the stream > if (this.bufferEnd < this.streamBuffer.length) >@@ -872,7 +878,7 @@ > * @exception UTFDataFormatException if the bytes do not represent a > * valid UTF-8 encoding of a Unicode string. > */ >-private char[] readStreamChars(FileInputStream stream) throws IOException { >+private char[] readStreamChars(InputStream stream) throws IOException { > // read chars array length > if (stream != null && this.bufferIndex + 2 >= this.bufferEnd) > readStreamBuffer(stream); >@@ -931,7 +937,7 @@ > } > return word; > } >-private int[] readStreamDocumentArray(FileInputStream stream, int arraySize) throws IOException { >+private int[] readStreamDocumentArray(InputStream stream, int arraySize) throws IOException { > int[] indexes = new int[arraySize]; > if (arraySize == 0) return indexes; > >@@ -972,7 +978,7 @@ > } > return indexes; > } >-private int readStreamInt(FileInputStream stream) throws IOException { >+private int readStreamInt(InputStream stream) throws IOException { > if (this.bufferIndex + 4 >= this.bufferEnd) { > readStreamBuffer(stream); > } >@@ -1182,7 +1188,7 @@ > } > private void writeOffsetToHeader(int offsetToHeader) throws IOException { > if (offsetToHeader > 0) { >- RandomAccessFile file = new RandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$ >+ RandomAccessFile file = new RandomAccessFile(this.indexFile.getIndexFile(), "rw"); //$NON-NLS-1$ > try { > file.seek(this.headerInfoOffset); // offset to position in header > file.writeInt(offsetToHeader); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FlatFileIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FlatFileIndex.java >new file mode 100644 >index 0000000..87231b4 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FlatFileIndex.java >@@ -0,0 +1,82 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.FileInputStream; >+import java.io.IOException; >+import java.io.InputStream; >+import java.net.URL; >+ >+public class FlatFileIndex extends IndexLocation { >+ File indexFile; >+ >+ public FlatFileIndex(File file) { >+ super(file); >+ this.indexFile = file; >+ } >+ >+ public FlatFileIndex(URL url, File file) { >+ super(url); >+ this.indexFile = file; >+ } >+ >+ public boolean createNewFile() throws IOException { >+ return this.indexFile.createNewFile(); >+ } >+ >+ public boolean delete() { >+ return this.indexFile.delete(); >+ } >+ >+ public boolean equals(Object other) { >+ if (!(other instanceof FlatFileIndex)) return false; >+ return this.indexFile.equals(((FlatFileIndex) other).indexFile); >+ } >+ >+ public boolean exists() { >+ return this.indexFile.exists(); >+ } >+ >+ public String fileName() { >+ return this.indexFile.getName(); >+ } >+ >+ public File getIndexFile() { >+ return this.indexFile; >+ } >+ >+ InputStream getInputStream() throws IOException { >+ return new FileInputStream(this.indexFile); >+ } >+ >+ public String getFilePath() { >+ try { >+ return this.indexFile.getCanonicalPath(); >+ } catch (IOException e) { >+ // ignore >+ } >+ return null; >+ } >+ >+ public int hashCode() { >+ return this.indexFile.hashCode(); >+ } >+ >+ public long lastModified() { >+ return this.indexFile.lastModified(); >+ } >+ >+ public long length() { >+ return this.indexFile.length(); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >index 3d32607..fe171d9 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -88,12 +88,12 @@ > } > > >-public Index(String fileName, String containerPath, boolean reuseExistingFile) throws IOException { >+public Index(IndexLocation location, String containerPath, boolean reuseExistingFile) throws IOException { > this.containerPath = containerPath; > this.monitor = new ReadWriteMonitor(); > > this.memoryIndex = new MemoryIndex(); >- this.diskIndex = new DiskIndex(fileName); >+ this.diskIndex = new DiskIndex(location); > this.diskIndex.initialize(reuseExistingFile); > if (reuseExistingFile) this.separator = this.diskIndex.separator; > } >@@ -109,8 +109,14 @@ > } > return documentPath.substring(index + 1); > } >-public File getIndexFile() { >+public IndexLocation getIndexLocation() { > return this.diskIndex == null ? null : this.diskIndex.indexFile; >+} >+public File getIndexFile() { >+ return this.diskIndex == null ? null : this.diskIndex.indexFile.getIndexFile(); >+} >+public long getIndexLastModified() { >+ return this.diskIndex == null? -1 : this.diskIndex.indexFile.lastModified(); > } > public boolean hasChanged() { > return this.memoryIndex.hasChanged(); >@@ -180,7 +186,7 @@ > */ > public void reset() throws IOException { > this.memoryIndex = new MemoryIndex(); >- this.diskIndex = new DiskIndex(this.diskIndex.indexFile.getCanonicalPath()); >+ this.diskIndex = new DiskIndex(this.diskIndex.indexFile); > this.diskIndex.initialize(false/*do not reuse the index file*/); > } > public void save() throws IOException { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java >new file mode 100644 >index 0000000..3c822de >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java >@@ -0,0 +1,99 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.InputStream; >+ >+import java.net.MalformedURLException; >+import java.net.URL; >+ >+import org.eclipse.core.runtime.FileLocator; >+ >+/** >+ * TODO SATYAM: Write a comment about this file >+ * >+ */ >+public abstract class IndexLocation { >+ private final URL url; >+ private boolean participantIndex; >+ >+ public IndexLocation(File file) { >+ URL tempUrl = null; >+ try { >+ tempUrl = file.toURI().toURL(); >+ } catch (MalformedURLException e) { >+ // should not happen >+ } >+ this.url = tempUrl; >+ } >+ >+ public static IndexLocation createIndexLocation(URL url) { >+ URL localUrl; >+ try { >+ localUrl = FileLocator.resolve(url); >+ } catch (IOException e) { >+ return null; >+ } >+ if (localUrl.getProtocol().equals("file")) { //$NON-NLS-1$ >+ return new FlatFileIndex(url, new File(localUrl.getPath())); >+ } >+ return new JarEntryIndex(url, localUrl); >+ } >+ >+ public IndexLocation(URL url) { >+ this.url = url; >+ } >+ >+ public abstract boolean createNewFile() throws IOException; >+ >+ public void close() { >+ // default nothing to do >+ } >+ >+ public abstract boolean delete(); >+ >+ public abstract boolean exists(); >+ >+ public abstract String fileName(); >+ >+ public abstract File getIndexFile(); >+ >+ abstract InputStream getInputStream() throws IOException; >+ >+ public abstract String getFilePath(); >+ >+ public URL getUrl() { >+ return this.url; >+ } >+ >+ public int hashCode() { >+ return this.url.hashCode(); >+ } >+ >+ public boolean isParticipantIndex() { >+ return this.participantIndex; >+ } >+ >+ public void setParticipantIndex() { >+ this.participantIndex = true; >+ } >+ >+ public abstract long lastModified(); >+ >+ public abstract long length(); >+ >+ public String toString() { >+ return this.url.toString(); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarEntryIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarEntryIndex.java >new file mode 100644 >index 0000000..17ff8ea >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarEntryIndex.java >@@ -0,0 +1,101 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.InputStream; >+import java.net.JarURLConnection; >+import java.net.URL; >+import java.util.jar.JarEntry; >+import java.util.jar.JarFile; >+ >+public class JarEntryIndex extends IndexLocation { >+ private JarFile jarFile = null; >+ private JarEntry jarEntry = null; >+ private URL localUrl; >+ >+ public JarEntryIndex(URL url, URL localUrl2) { >+ super(url); >+ this.localUrl = localUrl2; >+ } >+ >+ public boolean createNewFile() throws IOException { >+ return false; >+ } >+ >+ public void close() { >+ if (this.jarFile != null) { >+ try { >+ this.jarFile.close(); >+ } catch (IOException e) { >+ // ignore >+ } >+ this.jarFile = null; >+ } >+ } >+ >+ public boolean delete() { >+ return false; >+ } >+ >+ public boolean equals(Object other) { >+ if (!(other instanceof JarEntryIndex)) return false; >+ return this.localUrl.equals(((JarEntryIndex) other).localUrl); >+ } >+ >+ public boolean exists() { >+ try { >+ if (this.jarFile == null) { >+ JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection(); >+ JarFile file = connection.getJarFile(); >+ if (file == null) >+ return false; >+ file.close(); >+ } >+ } catch (IOException e) { >+ return false; >+ } >+ return true; >+ } >+ >+ public String fileName() { >+ return null; >+ } >+ >+ public File getIndexFile() { >+ return null; >+ } >+ >+ InputStream getInputStream() throws IOException { >+ if (this.jarFile == null) { >+ JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection(); >+ this.jarFile = connection.getJarFile(); >+ this.jarEntry = connection.getJarEntry(); >+ } >+ if (this.jarFile == null || this.jarEntry == null) >+ return null; >+ return this.jarFile.getInputStream(this.jarEntry); >+ } >+ >+ public String getFilePath() { >+ return null; >+ } >+ >+ public long lastModified() { >+ return -1; >+ } >+ >+ public long length() { >+ return -1; >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >index 4e584f2..20990c9 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >@@ -27,6 +27,7 @@ > import org.eclipse.jdt.internal.core.JavaProject; > import org.eclipse.jdt.internal.core.builder.ReferenceCollection; > import org.eclipse.jdt.internal.core.builder.State; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.IndexManager; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; > import org.eclipse.jdt.internal.core.search.matching.MethodPattern; >@@ -38,7 +39,7 @@ > public class IndexSelector { > IJavaSearchScope searchScope; > SearchPattern pattern; >- IPath[] indexLocations; // cache of the keys for looking index up >+ IndexLocation[] indexLocations; // cache of the keys for looking index up > > public IndexSelector( > IJavaSearchScope searchScope, >@@ -267,10 +268,10 @@ > } > > locations.remove(null); // Ensure no nulls >- this.indexLocations = (IPath[]) locations.toArray(new IPath[locations.size()]); >+ this.indexLocations = (IndexLocation[]) locations.toArray(new IndexLocation[locations.size()]); > } > >-public IPath[] getIndexLocations() { >+public IndexLocation[] getIndexLocations() { > if (this.indexLocations == null) { > initializeIndexLocations(); > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >index 13d6820..ae8568b 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >@@ -10,8 +10,10 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core.search; > >+ > import org.eclipse.core.runtime.*; > import org.eclipse.jdt.core.search.*; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer; > import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; >@@ -98,7 +100,20 @@ > * @see org.eclipse.jdt.core.search.SearchParticipant#selectIndexes(org.eclipse.jdt.core.search.SearchQuery, org.eclipse.jdt.core.search.SearchContext) > */ > public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) { >+ IndexSelector selector = (IndexSelector) this.indexSelector.get(); >+ if (selector == null) { >+ selector = new IndexSelector(scope, pattern); >+ this.indexSelector.set(selector); >+ } >+ IndexLocation[] urls = selector.getIndexLocations(); >+ IPath[] paths = new IPath[urls.length]; >+ for (int i = 0; i < urls.length; i++) { >+ paths[i] = new Path(urls[i].getIndexFile().getPath()); >+ } >+ return paths; >+ } > >+ public IndexLocation[] selectIndexURLs(SearchPattern pattern, IJavaSearchScope scope) { > IndexSelector selector = (IndexSelector) this.indexSelector.get(); > if (selector == null) { > selector = new IndexSelector(scope, pattern); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >index 459730c..ee66f53 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >@@ -17,7 +17,9 @@ > import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.jdt.core.search.*; > import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.index.FlatFileIndex; > import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; > import org.eclipse.jdt.internal.core.search.processing.IJob; >@@ -76,8 +78,20 @@ > } > public Index[] getIndexes(IProgressMonitor progressMonitor) { > // acquire the in-memory indexes on the fly >- IPath[] indexLocations = this.participant.selectIndexes(this.pattern, this.scope); >- int length = indexLocations.length; >+ IndexLocation[] indexLocations; >+ int length; >+ if (this.participant instanceof JavaSearchParticipant) { >+ indexLocations = ((JavaSearchParticipant)this.participant).selectIndexURLs(this.pattern, this.scope); >+ length = indexLocations.length; >+ } else { >+ IPath[] paths = this.participant.selectIndexes(this.pattern, this.scope); >+ length =paths.length; >+ indexLocations = new IndexLocation[paths.length]; >+ for (int i = 0; i < paths.length; i++) { >+ indexLocations[i] = new FlatFileIndex(paths[i].toFile()); >+ indexLocations[i].setParticipantIndex(); >+ } >+ } > Index[] indexes = JavaModelManager.getIndexManager().getIndexes(indexLocations, progressMonitor); > this.areIndexesReady = indexes.length == length; > return indexes; >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >index 168904f..c4f8552 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -34,6 +34,7 @@ > import org.eclipse.jdt.internal.compiler.util.Util; > import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.JavaSearchDocument; > import org.eclipse.jdt.internal.core.search.processing.JobManager; > >@@ -42,14 +43,17 @@ > private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); > IFile resource; > Scanner scanner; >+ private IndexLocation indexFileURL; > >- public AddJarFileToIndex(IFile resource, IndexManager manager) { >+ public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) { > super(resource.getFullPath(), manager); > this.resource = resource; >+ this.indexFileURL = indexFile; > } >- public AddJarFileToIndex(IPath jarPath, IndexManager manager) { >+ public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) { > // external JAR scenario - no resource > super(jarPath, manager); >+ this.indexFileURL = indexFile; > } > public boolean equals(Object o) { > if (o instanceof AddJarFileToIndex) { >@@ -70,6 +74,12 @@ > public boolean execute(IProgressMonitor progressMonitor) { > > if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >+ >+ if (this.indexFileURL != null) { >+ boolean added = this.manager.addIndex(this.containerPath, this.indexFileURL); >+ if (added) return true; >+ this.indexFileURL = null; >+ } > > try { > // if index is already cached, then do not perform any check >@@ -192,7 +202,11 @@ > return false; > } > index.separator = JAR_SEPARATOR; >- >+ IPath indexPath = null; >+ IndexLocation indexLocation; >+ if ((indexLocation = index.getIndexLocation()) != null) { >+ indexPath = new Path(indexLocation.getFilePath()); >+ } > for (Enumeration e = zip.entries(); e.hasMoreElements();) { > if (this.isCancelled) { > if (JobManager.VERBOSE) >@@ -208,7 +222,7 @@ > // index only classes coming from valid packages - https://bugs.eclipse.org/bugs/show_bug.cgi?id=293861 > final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); > JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); >- this.manager.indexDocument(entryDocument, participant, index, this.containerPath); >+ this.manager.indexDocument(entryDocument, participant, index, indexPath); > } > } > this.manager.saveIndex(index); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java >new file mode 100644 >index 0000000..8db1795 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java >@@ -0,0 +1,51 @@ >+package org.eclipse.jdt.internal.core.search.indexing; >+ >+import java.io.File; >+import java.io.FileNotFoundException; >+import java.io.IOException; >+import java.util.Enumeration; >+import java.util.zip.ZipEntry; >+import java.util.zip.ZipFile; >+ >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.search.IJavaSearchScope; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.search.SearchParticipant; >+import org.eclipse.jdt.internal.compiler.util.Util; >+import org.eclipse.jdt.internal.core.index.FlatFileIndex; >+import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; >+import org.eclipse.jdt.internal.core.search.JavaSearchDocument; >+ >+public class DefaultJavaIndexer { >+ private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); >+ >+ public void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException { >+ File f = new File(pathToJar); >+ if (!f.exists()) { >+ throw new FileNotFoundException(pathToJar + "not found"); //$NON-NLS-1$ >+ } >+ IndexLocation indexLocation = new FlatFileIndex(new File(pathToIndexFile)); >+ Index index = new Index(indexLocation, pathToJar, false /*reuse index file*/); >+ SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); >+ index.separator = JAR_SEPARATOR; >+ ZipFile zip = new ZipFile(pathToJar); >+ for (Enumeration e = zip.entries(); e.hasMoreElements();) { >+ // iterate each entry to index it >+ ZipEntry ze = (ZipEntry) e.nextElement(); >+ String zipEntryName = ze.getName(); >+ if (Util.isClassFileName(zipEntryName)) { >+ final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); >+ JavaSearchDocument entryDocument = new JavaSearchDocument(ze, new Path(pathToJar), classFileBytes, participant); >+ entryDocument.setIndex(index); >+ if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(entryDocument.getPath())) { >+ new BinaryIndexer(entryDocument).indexDocument(); >+ } >+ } >+ } >+ zip.close(); >+ index.save(); >+ return; >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >index 4313621..96aa904 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -77,7 +77,7 @@ > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectPath)) { > // the project is also a library folder (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89815) > // ensure a job exists to index it as a binary folder >- this.manager.indexLibrary(projectPath, this.project); >+ this.manager.indexLibrary(projectPath, this.project, ((ClasspathEntry)entry).getLibraryIndexLocation()); > return true; > } > } >@@ -107,7 +107,7 @@ > for (int i = 0; i < max; i++) > indexedFileNames.put(paths[i], DELETED); > } >- final long indexLastModified = max == 0 ? 0L : index.getIndexFile().lastModified(); >+ final long indexLastModified = max == 0 ? 0L : index.getIndexLastModified(); > > IWorkspaceRoot root = this.project.getWorkspace().getRoot(); > for (int i = 0; i < sourceEntriesNumber; i++) { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >index 7bb90f9..b06e0df 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >@@ -80,7 +80,7 @@ > for (int i = 0; i < max; i++) { > indexedFileNames.put(paths[i], DELETED); > } >- final long indexLastModified = index.getIndexFile().lastModified(); >+ final long indexLastModified = index.getIndexLastModified(); > this.folder.accept( > new IResourceProxyVisitor() { > public boolean visit(IResourceProxy proxy) throws CoreException { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >index f08c249..68b47b0 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -11,6 +11,7 @@ > package org.eclipse.jdt.internal.core.search.indexing; > > import java.io.*; >+import java.net.URL; > import java.util.*; > import java.util.zip.CRC32; > >@@ -59,6 +60,7 @@ > public static final Integer UPDATING_STATE = new Integer(1); > public static final Integer UNKNOWN_STATE = new Integer(2); > public static final Integer REBUILDING_STATE = new Integer(3); >+ public static final Integer REUSE_STATE = new Integer(4); > > // search participants who register indexes with the index manager > private SimpleLookupTable participantsContainers = null; >@@ -70,10 +72,10 @@ > public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) { > // newIndexState is either UPDATING_STATE or REBUILDING_STATE > // must tag the index as inconsistent, in case we exit before the update job is started >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Object state = getIndexStates().get(indexLocation); > Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; >- if (currentIndexState.equals(REBUILDING_STATE)) return; // already rebuilding the index >+ if (currentIndexState.compareTo(REBUILDING_STATE) >= 0) return; // already rebuilding the index > > int compare = newIndexState.compareTo(currentIndexState); > if (compare > 0) { >@@ -92,7 +94,7 @@ > if (JavaCore.getPlugin() == null) return; > SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); > SearchDocument document = participant.getDocument(resource.getFullPath().toString()); >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > scheduleDocumentIndexing(document, containerPath, indexLocation, participant); > } > /** >@@ -104,7 +106,7 @@ > SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); > SearchDocument document = participant.getDocument(resource.getFullPath().toString()); > document.setParser(parser); >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > scheduleDocumentIndexing(document, containerPath, indexLocation, participant); > } > /* >@@ -116,17 +118,17 @@ > PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null); > Index[] selectedIndexes = job.getIndexes(null); > for (int i = 0, l = selectedIndexes.length; i < l; i++) { >- String path = selectedIndexes[i].getIndexFile().getAbsolutePath(); >- knownPaths.add(path); >+ IndexLocation IndexLocation = selectedIndexes[i].getIndexLocation(); >+ knownPaths.add(IndexLocation); > } > > if (this.indexStates != null) { > Object[] keys = this.indexStates.keyTable; >- IPath[] locations = new IPath[this.indexStates.elementSize]; >+ IndexLocation[] locations = new IndexLocation[this.indexStates.elementSize]; > int count = 0; > for (int i = 0, l = keys.length; i < l; i++) { >- IPath key = (IPath) keys[i]; >- if (key != null && !knownPaths.includes(key.toOSString())) >+ IndexLocation key = (IndexLocation) keys[i]; >+ if (key != null && !knownPaths.includes(key)) > locations[count++] = key; > } > if (count > 0) >@@ -134,8 +136,8 @@ > } > deleteIndexFiles(knownPaths); > } >-public synchronized IPath computeIndexLocation(IPath containerPath) { >- IPath indexLocation = (IPath) this.indexLocations.get(containerPath); >+public synchronized IndexLocation computeIndexLocation(IPath containerPath) { >+ IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath); > if (indexLocation == null) { > String pathString = containerPath.toOSString(); > CRC32 checksumCalculator = new CRC32(); >@@ -144,7 +146,7 @@ > if (VERBOSE) > Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$ > // to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table >- indexLocation = (IPath) getIndexStates().getKey(getJavaPluginWorkingLocation().append(fileName)); >+ indexLocation = (IndexLocation) getIndexStates().getKey(new FlatFileIndex(new File(getSavedIndexesDirectory(), fileName))); > this.indexLocations.put(containerPath, indexLocation); > } > return indexLocation; >@@ -161,7 +163,7 @@ > > for (int i = 0, l = indexesFiles.length; i < l; i++) { > String fileName = indexesFiles[i].getAbsolutePath(); >- if (pathsToKeep != null && pathsToKeep.includes(fileName)) continue; >+ if (pathsToKeep != null && pathsToKeep.includes(new FlatFileIndex(indexesFiles[i]))) continue; > String suffix = ".index"; //$NON-NLS-1$ > if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) { > if (VERBOSE || DEBUG) >@@ -173,7 +175,7 @@ > /* > * Creates an empty index at the given location, for the given container path, if none exist. > */ >-public synchronized void ensureIndexExists(IPath indexLocation, IPath containerPath) { >+public synchronized void ensureIndexExists(IndexLocation indexLocation, IPath containerPath) { > SimpleLookupTable states = getIndexStates(); > Object state = states.get(indexLocation); > if (state == null) { >@@ -207,7 +209,7 @@ > * @param indexLocation The path of the index file > * @return The corresponding index or <code>null</code> if not found > */ >-public synchronized Index getIndex(IPath indexLocation) { >+public synchronized Index getIndex(IndexLocation indexLocation) { > return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed > } > /** >@@ -219,7 +221,7 @@ > * Warning: Does not check whether index is consistent (not being used) > */ > public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); > } > /** >@@ -230,7 +232,7 @@ > * > * Warning: Does not check whether index is consistent (not being used) > */ >-public synchronized Index getIndex(IPath containerPath, IPath indexLocation, boolean reuseExistingFile, boolean createIfMissing) { >+public synchronized Index getIndex(IPath containerPath, IndexLocation indexLocation, boolean reuseExistingFile, boolean createIfMissing) { > // Path is already canonical per construction > Index index = getIndex(indexLocation); > if (index == null) { >@@ -245,19 +247,17 @@ > > // index isn't cached, consider reusing an existing index file > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); >- String indexLocationString = indexLocation.toOSString(); > if (reuseExistingFile) { >- File indexFile = new File(indexLocationString); >- if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing >+ if (indexLocation.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing > try { >- index = new Index(indexLocationString, containerPathString, true /*reuse index file*/); >+ index = new Index(indexLocation, containerPathString, true /*reuse index file*/); > this.indexes.put(indexLocation, index); > return index; > } catch (IOException e) { > // failed to read the existing file or its no longer compatible >- if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt >+ if (currentIndexState != REBUILDING_STATE || currentIndexState != REUSE_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt > if (VERBOSE) >- Util.verbose("-> cannot reuse existing index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ > rebuildIndex(indexLocation, containerPath); > return null; > } >@@ -268,18 +268,27 @@ > rebuildIndex(indexLocation, containerPath); > return null; > } >+ if (currentIndexState == REUSE_STATE) { >+ // supposed to be in reuse state but error in the index file, so reindex. >+ if (VERBOSE) >+ Util.verbose("-> cannot reuse given index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ this.indexLocations.put(containerPath, null); >+ indexLocation = computeIndexLocation(containerPath); >+ rebuildIndex(indexLocation, containerPath); >+ return null; >+ } > } > // index wasn't found on disk, consider creating an empty new one > if (createIfMissing) { > try { > if (VERBOSE) >- Util.verbose("-> create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >- index = new Index(indexLocationString, containerPathString, false /*do not reuse index file*/); >+ Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); > this.indexes.put(indexLocation, index); > return index; > } catch (IOException e) { > if (VERBOSE) >- Util.verbose("-> unable to create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ > // The file could not be created. Possible reason: the project has been deleted. > return null; > } >@@ -295,7 +304,7 @@ > * @param locations The list of of the index files path > * @return The corresponding indexes list. > */ >-public Index[] getIndexes(IPath[] locations, IProgressMonitor progressMonitor) { >+public Index[] getIndexes(IndexLocation[] locations, IProgressMonitor progressMonitor) { > // acquire the in-memory indexes on the fly > int length = locations.length; > Index[] locatedIndexes = new Index[length]; >@@ -308,7 +317,7 @@ > throw new OperationCanceledException(); > } > // may trigger some index recreation work >- IPath indexLocation = locations[i]; >+ IndexLocation indexLocation = locations[i]; > Index index = getIndex(indexLocation); > if (index == null) { > // only need containerPath if the index must be built >@@ -330,18 +339,16 @@ > index = null; > } > } else { >- if (!getJavaPluginWorkingLocation().isPrefixOf(indexLocation)) { // the index belongs to non-jdt search participant >- if (indexLocation.toFile().exists()) { >- try { >- IPath container = getParticipantsContainer(indexLocation); >- if (container != null) { >- index = new Index(indexLocation.toOSString(), container.toOSString(), true /*reuse index file*/); >- this.indexes.put(indexLocation, index); >- } >- } catch (IOException e) { >- // ignore >+ if (indexLocation.isParticipantIndex() && indexLocation.exists()) { // the index belongs to non-jdt search participant >+ try { >+ IPath container = getParticipantsContainer(indexLocation); >+ if (container != null) { >+ index = new Index(indexLocation, container.toOSString(), true /*reuse index file*/); >+ this.indexes.put(indexLocation, index); > } >- } >+ } catch (IOException e) { >+ // ignore >+ } > } > } > } >@@ -358,7 +365,7 @@ > return locatedIndexes; > } > public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > if (getIndexStates().get(indexLocation) == REBUILDING_STATE) > return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); > >@@ -368,13 +375,13 @@ > if (this.indexStates != null) return this.indexStates; > > this.indexStates = new SimpleLookupTable(); >- IPath indexesDirectoryPath = getJavaPluginWorkingLocation(); >- char[][] savedNames = readIndexState(indexesDirectoryPath.toOSString()); >+ File indexesDirectoryPath = getSavedIndexesDirectory(); >+ char[][] savedNames = readIndexState(getJavaPluginWorkingLocation().toOSString()); > if (savedNames != null) { > for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState() > char[] savedName = savedNames[i]; > if (savedName.length > 0) { >- IPath indexLocation = indexesDirectoryPath.append(new String(savedName)); // shares indexesDirectoryPath's segments >+ IndexLocation indexLocation = new FlatFileIndex(new File(indexesDirectoryPath, String.valueOf(savedName))); // shares indexesDirectoryPath's segments > if (VERBOSE) > Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$ > this.indexStates.put(indexLocation, SAVED_STATE); >@@ -389,7 +396,7 @@ > } > return this.indexStates; > } >-private IPath getParticipantsContainer(IPath indexLocation) { >+private IPath getParticipantsContainer(IndexLocation indexLocation) { > if (this.participantsContainers == null) { > readParticipantsIndexNamesFile(); > } >@@ -474,7 +481,7 @@ > for (int i = 0; i < entries.length; i++) { > IClasspathEntry entry= entries[i]; > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) >- indexLibrary(entry.getPath(), project); >+ indexLibrary(entry.getPath(), project, ((ClasspathEntry)entry).getLibraryIndexLocation()); > } > } catch(JavaModelException e){ // cannot retrieve classpath info > } >@@ -488,16 +495,16 @@ > * Trigger addition of a library to an index > * Note: the actual operation is performed in background > */ >-public void indexLibrary(IPath path, IProject requestingProject) { >+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) { > // requestingProject is no longer used to cancel jobs but leave it here just in case >+ IndexLocation indexFile = indexURL != null ? IndexLocation.createIndexLocation(indexURL): null; > if (JavaCore.getPlugin() == null) return; >- >- Object target = JavaModel.getTarget(path, true); > IndexRequest request = null; >+ Object target = JavaModel.getTarget(path, true); > if (target instanceof IFile) { >- request = new AddJarFileToIndex((IFile) target, this); >+ request = new AddJarFileToIndex((IFile) target, indexFile, this); > } else if (target instanceof File) { >- request = new AddJarFileToIndex(path, this); >+ request = new AddJarFileToIndex(path, indexFile, this); > } else if (target instanceof IContainer) { > request = new IndexBinaryFolder((IContainer) target, this); > } else { >@@ -508,6 +515,19 @@ > if (!isJobWaiting(request)) > request(request); > } >+ >+synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) { >+ this.indexStates.put(indexFile, REUSE_STATE); >+ this.indexLocations.put(containerPath, indexFile); >+ Index index = getIndex(containerPath, indexFile, true, false); >+ if (index == null) { >+ indexFile.close(); >+ this.indexLocations.put(containerPath, null); >+ return false; >+ } >+ return true; >+} >+ > /** > * Index the content of the given source folder. > */ >@@ -522,7 +542,7 @@ > request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this)); > } > public synchronized void jobWasCancelled(IPath containerPath) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > if (index != null) { > index.monitor = null; >@@ -568,7 +588,7 @@ > } > return null; > } >-private void rebuildIndex(IPath indexLocation, IPath containerPath) { >+private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) { > Object target = JavaModel.getTarget(containerPath, true); > if (target == null) return; > >@@ -584,9 +604,9 @@ > } else if (target instanceof IFolder) { > request = new IndexBinaryFolder((IFolder) target, this); > } else if (target instanceof IFile) { >- request = new AddJarFileToIndex((IFile) target, this); >+ request = new AddJarFileToIndex((IFile) target, null, this); > } else if (target instanceof File) { >- request = new AddJarFileToIndex(containerPath, this); >+ request = new AddJarFileToIndex(containerPath, null, this); > } > if (request != null) > request(request); >@@ -601,13 +621,13 @@ > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); > try { > // Path is already canonical >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > ReadWriteMonitor monitor = index == null ? null : index.monitor; > > if (VERBOSE) > Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >- index = new Index(indexLocation.toOSString(), containerPathString, false /*do not reuse index file*/); >+ index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); > this.indexes.put(indexLocation, index); > index.monitor = monitor; > return index; >@@ -634,7 +654,7 @@ > public synchronized void removeIndex(IPath containerPath) { > if (VERBOSE || DEBUG) > Util.verbose("removing index " + containerPath); //$NON-NLS-1$ >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > File indexFile = null; > if (index != null) { >@@ -642,8 +662,11 @@ > indexFile = index.getIndexFile(); > } > if (indexFile == null) >- indexFile = new File(indexLocation.toOSString()); // index is not cached yet, but still want to delete the file >- if (indexFile.exists()) { >+ indexFile = indexLocation.getIndexFile(); // index is not cached yet, but still want to delete the file >+ if (this.indexStates.get(indexLocation) == REUSE_STATE) { >+ indexLocation.close(); >+ this.indexLocations.put(containerPath, null); >+ } else if (indexFile != null && indexFile.exists()) { > if (DEBUG) > Util.verbose("removing index file " + indexFile); //$NON-NLS-1$ > indexFile.delete(); >@@ -659,24 +682,25 @@ > Util.verbose("removing index path " + path); //$NON-NLS-1$ > Object[] keyTable = this.indexes.keyTable; > Object[] valueTable = this.indexes.valueTable; >- IPath[] locations = null; >+ IndexLocation[] locations = null; > int max = this.indexes.elementSize; > int count = 0; > for (int i = 0, l = keyTable.length; i < l; i++) { >- IPath indexLocation = (IPath) keyTable[i]; >+ IndexLocation indexLocation = (IndexLocation) keyTable[i]; > if (indexLocation == null) > continue; >- if (path.isPrefixOf(indexLocation)) { >+ if (path.isPrefixOf(new Path(indexLocation.getFilePath()))) { > Index index = (Index) valueTable[i]; > index.monitor = null; > if (locations == null) >- locations = new IPath[max]; >+ locations = new IndexLocation[max]; > locations[count++] = indexLocation; >- File indexFile = index.getIndexFile(); >- if (indexFile.exists()) { >+ if (this.indexStates.get(indexLocation) == REUSE_STATE) { >+ indexLocation.close(); >+ } else { > if (DEBUG) >- Util.verbose("removing index file " + indexFile); //$NON-NLS-1$ >- indexFile.delete(); >+ Util.verbose("removing index file " + indexLocation); //$NON-NLS-1$ >+ indexLocation.delete(); > } > } else { > max--; >@@ -686,9 +710,15 @@ > for (int i = 0; i < count; i++) > this.indexes.removeKey(locations[i]); > removeIndexesState(locations); >- if (this.participantsContainers != null && this.participantsContainers.get(path.toOSString()) != null) { >- this.participantsContainers.removeKey(path.toOSString()); >- writeParticipantsIndexNamesFile(); >+ if (this.participantsContainers != null) { >+ boolean update = false; >+ for (int i = 0; i < count; i++) { >+ if (this.participantsContainers.get(locations[i]) != null) { >+ update = true; >+ this.participantsContainers.removeKey(locations[i]); >+ } >+ } >+ if (update) writeParticipantsIndexNamesFile(); > } > } > } >@@ -746,7 +776,7 @@ > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); > try { > // Path is already canonical >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > if (VERBOSE) { > Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >@@ -770,7 +800,7 @@ > // must have permission to write from the write monitor > if (index.hasChanged()) { > if (VERBOSE) >- Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$ >+ Util.verbose("-> saving index " + index.getIndexLocation()); //$NON-NLS-1$ > index.save(); > } > synchronized (this) { >@@ -782,7 +812,7 @@ > if (((IndexRequest) job).containerPath.equals(containerPath)) return; > } > } >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > updateIndexState(indexLocation, SAVED_STATE); > } > } >@@ -837,20 +867,21 @@ > } > this.needToSave = !allSaved; > } >-public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IPath indexLocation, final SearchParticipant searchParticipant) { >+public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IndexLocation indexLocation, final SearchParticipant searchParticipant) { > request(new IndexRequest(container, this) { > public boolean execute(IProgressMonitor progressMonitor) { > if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; > > /* ensure no concurrent write access to index */ >- Index index = getIndex(this.containerPath, indexLocation, true, /*reuse index file*/ true /*create if none*/); >+ Index index; >+ index = getIndex(this.containerPath, indexLocation, true, /*reuse index file*/ true /*create if none*/); > if (index == null) return true; > ReadWriteMonitor monitor = index.monitor; > if (monitor == null) return true; // index got deleted since acquired > > try { > monitor.enterWrite(); // ask permission to write >- indexDocument(searchDocument, searchParticipant, index, indexLocation); >+ indexDocument(searchDocument, searchParticipant, index, new Path(indexLocation.getFilePath())); > } finally { > monitor.exitWrite(); // free write lock > } >@@ -904,7 +935,9 @@ > // First line is DiskIndex signature (see writeParticipantsIndexNamesFile()) > if (DiskIndex.SIGNATURE.equals(new String(names[0]))) { > for (int i = 1, l = names.length-1 ; i < l ; i+=2) { >- containers.put(new Path(new String(names[i])), new Path(new String(names[i+1]))); >+ IndexLocation indexLocation = new FlatFileIndex(new File(new String(names[i]))); >+ indexLocation.setParticipantIndex(); >+ containers.put(indexLocation, new Path(new String(names[i+1]))); > } > } > } >@@ -916,7 +949,7 @@ > this.participantsContainers = containers; > return; > } >-private synchronized void removeIndexesState(IPath[] locations) { >+private synchronized void removeIndexesState(IndexLocation[] locations) { > getIndexStates(); // ensure the states are initialized > int length = locations.length; > boolean changed = false; >@@ -933,8 +966,8 @@ > > writeSavedIndexNamesFile(); > } >-private synchronized void updateIndexState(IPath indexLocation, Integer indexState) { >- if (indexLocation.isEmpty()) >+private synchronized void updateIndexState(IndexLocation indexLocation, Integer indexState) { >+ if (indexLocation == null) > throw new IllegalArgumentException(); > > getIndexStates(); // ensure the states are initialized >@@ -962,12 +995,14 @@ > } > > } >-public void updateParticipant(IPath indexLocation, IPath containerPath) { >+public void updateParticipant(IPath indexPath, IPath containerPath) { > if (this.participantsContainers == null) { > readParticipantsIndexNamesFile(); >- } >+ } >+ IndexLocation indexLocation = new FlatFileIndex(indexPath.toFile()); > if (this.participantsContainers.get(indexLocation) == null) { > this.participantsContainers.put(indexLocation, containerPath); >+ indexLocation.setParticipantIndex(); > this.participantUpdated = true; > } > } >@@ -1014,9 +1049,9 @@ > Object[] indexFiles = this.participantsContainers.keyTable; > Object[] containers = this.participantsContainers.valueTable; > for (int i = 0, l = indexFiles.length; i < l; i++) { >- IPath indexFile = (IPath)indexFiles[i]; >+ IndexLocation indexFile = (IndexLocation)indexFiles[i]; > if (indexFile != null) { >- writer.write(indexFile.toOSString()); >+ writer.write(indexFile.getIndexFile().getPath()); > writer.write('\n'); > writer.write(((IPath)containers[i]).toOSString()); > writer.write('\n'); >@@ -1046,9 +1081,9 @@ > Object[] keys = this.indexStates.keyTable; > Object[] states = this.indexStates.valueTable; > for (int i = 0, l = states.length; i < l; i++) { >- IPath key = (IPath) keys[i]; >- if (key != null && !key.isEmpty() && states[i] == SAVED_STATE) { >- writer.write(key.lastSegment()); >+ IndexLocation key = (IndexLocation) keys[i]; >+ if (key != null && states[i] == SAVED_STATE) { >+ writer.write(key.fileName()); > writer.write('\n'); > } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 356620
:
205241
|
207155
|
207847
|
208084