View | Details | Raw Unified | Return to bug 356620 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java (+28 lines)
Lines 1348-1353 Link Here
1348
        }
1348
        }
1349
    }
1349
    }
1350
}
1350
}
1351
1352
/**
1353
 * Zips the given files into the given jar. All the files are kept at the root of the zip. 
1354
 */
1355
public static void zipFiles(File[] files, String zipPath) throws IOException {
1356
	File zipFile = new File(zipPath);
1357
	if (zipFile.exists()) {
1358
		if (!delete(zipFile))
1359
			throw new IOException("Could not delete " + zipPath);
1360
		// ensure the new zip file has a different timestamp than the previous one
1361
		int timeToWait = 1000; // some platform (like Linux) have a 1s granularity)
1362
		waitAtLeast(timeToWait);
1363
	} else {
1364
		zipFile.getParentFile().mkdirs();
1365
	}
1366
	ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile));
1367
	try {
1368
		for (int i = 0, length = files.length; i < length; i++) {
1369
			File file = files[i];
1370
			ZipEntry entry = new ZipEntry(file.getName());
1371
			zip.putNextEntry(entry);
1372
			zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file));
1373
			zip.closeEntry();
1374
		}
1375
	} finally {
1376
		zip.close();
1377
	}
1378
}
1351
/**
1379
/**
1352
 * Returns the compilation errors / warnings for the given CompilationResult.
1380
 * Returns the compilation errors / warnings for the given CompilationResult.
1353
 *
1381
 *
(-)a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java (-2 / +100 lines)
Lines 12-20 Link Here
12
12
13
import java.io.File;
13
import java.io.File;
14
import java.io.IOException;
14
import java.io.IOException;
15
import java.net.URL;
15
16
16
import junit.framework.Test;
17
import junit.framework.Test;
17
18
19
import org.eclipse.core.resources.IProject;
18
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
22
import org.eclipse.core.runtime.Path;
Lines 28-33 Link Here
28
import org.eclipse.jdt.core.JavaCore;
30
import org.eclipse.jdt.core.JavaCore;
29
import org.eclipse.jdt.core.index.*;
31
import org.eclipse.jdt.core.index.*;
30
import org.eclipse.jdt.core.search.SearchEngine;
32
import org.eclipse.jdt.core.search.SearchEngine;
33
import org.eclipse.jdt.core.tests.util.Util;
31
import org.eclipse.jdt.internal.core.JavaModelManager;
34
import org.eclipse.jdt.internal.core.JavaModelManager;
32
import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer;
35
import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer;
33
import org.osgi.service.prefs.BackingStoreException;
36
import org.osgi.service.prefs.BackingStoreException;
Lines 709-716 Link Here
709
		System.arraycopy(entries, 0, entries = new IClasspathEntry[length+1], 0, length);
712
		System.arraycopy(entries, 0, entries = new IClasspathEntry[length+1], 0, length);
710
		entries[length] = JavaCore.newContainerEntry(containerSuggestion.getPath());
713
		entries[length] = JavaCore.newContainerEntry(containerSuggestion.getPath());
711
		p.setRawClasspath(entries, null);
714
		p.setRawClasspath(entries, null);
712
713
	}
715
	}
716
	
714
	public void testUserLibraryIndex() throws IOException, CoreException, BackingStoreException {
717
	public void testUserLibraryIndex() throws IOException, CoreException, BackingStoreException {
715
		String indexFilePath = getExternalResourcePath("Test.index");
718
		String indexFilePath = getExternalResourcePath("Test.index");
716
		String jarFilePath = getExternalResourcePath("Test.jar");
719
		String jarFilePath = getExternalResourcePath("Test.jar");
Lines 759-765 Link Here
759
			deleteProject("P");
762
			deleteProject("P");
760
			new File(indexFilePath).delete();
763
			new File(indexFilePath).delete();
761
			new File(jarFilePath).delete();
764
			new File(jarFilePath).delete();
765
		}		
766
	}
767
	
768
	// Test that it works if the index file is in the jar file
769
	public void testIndexInJar() throws IOException, CoreException {
770
		String indexFilePath = getExternalResourcePath("Test.index");
771
		String jarFilePath = getExternalResourcePath("Test.jar");
772
		String indexZipPath =  getExternalResourcePath("TestIndex.zip");
773
		try {
774
			createJar(new String[] {
775
					"pkg/Test.java",
776
					"package pkg;\n" +
777
					"public class Test {\n" +
778
					"  protected Test(int i) {}\n" +
779
					"}"}, jarFilePath);
780
			
781
			JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath);
782
			Util.zipFiles(new File[]{new File(indexFilePath)}, indexZipPath);
783
			
784
			IJavaProject p = createJavaProject("P");
785
			Path libPath = new Path(jarFilePath);
786
			String url = "jar:file:/"+indexZipPath+"!/Test.index";
787
			IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, url);
788
			IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false);
789
			setClasspath(p, new IClasspathEntry[] {entry});
790
			waitUntilIndexesReady();
791
			
792
			assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString());
793
			
794
			search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
795
			assertSearchResults(getExternalPath() + "Test.jar pkg.Test");
796
			
797
			simulateExitRestart();
798
			getJavaModel().refreshExternalArchives(null,null);
799
			waitUntilIndexesReady();
800
			
801
			this.resultCollector = new JavaSearchResultCollector();
802
			assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString());
803
			search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
804
			assertSearchResults(getExternalPath() + "Test.jar pkg.Test");
805
		} finally {
806
			deleteProject("P");
807
			new File(indexZipPath).delete();
808
			new File(jarFilePath).delete();
762
		}
809
		}
763
		
810
	}
811
812
	// Test index file in platform
813
	public void testPlatformJarIndexFile() throws CoreException, IOException {
814
		String indexFilePath = null;
815
		String jarFilePath = getExternalResourcePath("Test.jar");
816
		String indexUrl = "platform:/resource/ForIndex/Test.index.zip!/Test.index";
817
		try {
818
			createJar(new String[] {
819
					"pkg/Test.java",
820
					"package pkg;\n" +
821
					"public class Test {\n" +
822
					"  protected Test(int i) {}\n" +
823
					"}"}, jarFilePath);
824
			
825
			IProject indexProj = createProject("ForIndex");
826
			indexFilePath = indexProj.getProject().getLocation().append("Test.index").toFile().getAbsolutePath();
827
			JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath);
828
			Util.zipFiles(new File[]{new File(indexFilePath)}, indexFilePath+".zip");
829
			
830
			IJavaProject p = createJavaProject("P");
831
			Path libPath = new Path(jarFilePath);
832
			IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexUrl);
833
			IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false);
834
			setClasspath(p, new IClasspathEntry[] {entry});
835
			waitUntilIndexesReady();
836
			
837
			search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
838
			assertSearchResults(getExternalPath() + "Test.jar pkg.Test");
839
			
840
			URL url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl();
841
			assertEquals(indexUrl, url.toString());
842
			
843
			simulateExitRestart();
844
			getJavaModel().refreshExternalArchives(null,null);
845
			waitUntilIndexesReady();
846
			
847
			this.resultCollector = new JavaSearchResultCollector();
848
			search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
849
			assertSearchResults(getExternalPath() + "Test.jar pkg.Test");
850
			
851
			url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl();
852
			assertEquals(indexUrl, url.toString());
853
		} finally {
854
			deleteProject("P");
855
			if (indexFilePath != null) {
856
				new File(indexFilePath).delete();
857
				new File(indexFilePath+".zip").delete();
858
			}
859
			new File(jarFilePath).delete();
860
			deleteProject("ForIndex");
861
		}
764
	}
862
	}
765
}
863
}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java (-5 / +9 lines)
Lines 14-19 Link Here
14
import org.eclipse.core.runtime.*;
14
import org.eclipse.core.runtime.*;
15
import org.eclipse.jdt.internal.core.JavaModel;
15
import org.eclipse.jdt.internal.core.JavaModel;
16
import org.eclipse.jdt.internal.core.JavaModelManager;
16
import org.eclipse.jdt.internal.core.JavaModelManager;
17
import org.eclipse.jdt.internal.core.index.FileIndexLocation;
18
import org.eclipse.jdt.internal.core.index.IndexLocation;
17
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
19
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
18
20
19
/**
21
/**
Lines 192-200 Link Here
192
	 * </p>
194
	 * </p>
193
	 *
195
	 *
194
	 * @param document the document to index
196
	 * @param document the document to index
195
	 * @param indexLocation the location on the file system of the index
197
	 * @param indexPath the location on the file system of the index
196
	 */
198
	 */
197
	public final void scheduleDocumentIndexing(SearchDocument document, IPath indexLocation) {
199
	public final void scheduleDocumentIndexing(SearchDocument document, IPath indexPath) {
198
		IPath documentPath = new Path(document.getPath());
200
		IPath documentPath = new Path(document.getPath());
199
		Object file = JavaModel.getTarget(documentPath, true);
201
		Object file = JavaModel.getTarget(documentPath, true);
200
		IPath containerPath = documentPath;
202
		IPath containerPath = documentPath;
Lines 205-215 Link Here
205
		}
207
		}
206
		IndexManager manager = JavaModelManager.getIndexManager();
208
		IndexManager manager = JavaModelManager.getIndexManager();
207
		// TODO (frederic) should not have to create index manually, should expose API that recreates index instead
209
		// TODO (frederic) should not have to create index manually, should expose API that recreates index instead
210
		IndexLocation indexLocation;
211
		indexLocation = new FileIndexLocation(indexPath.toFile(), true);
208
		manager.ensureIndexExists(indexLocation, containerPath);
212
		manager.ensureIndexExists(indexLocation, containerPath);
209
		manager.scheduleDocumentIndexing(document, containerPath, indexLocation, this);
213
		manager.scheduleDocumentIndexing(document, containerPath, indexLocation, this);
210
		if (!indexLocation.equals(this.lastIndexLocation)) {
214
		if (!indexPath.equals(this.lastIndexLocation)) {
211
			manager.updateParticipant(indexLocation, containerPath);
215
			manager.updateParticipant(indexPath, containerPath);
212
			this.lastIndexLocation = indexLocation;
216
			this.lastIndexLocation = indexPath;
213
		}
217
		}
214
	}
218
	}
215
219
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java (-58 / +66 lines)
Lines 23-29 Link Here
23
23
24
public class DiskIndex {
24
public class DiskIndex {
25
25
26
File indexFile;
26
IndexLocation indexLocation;
27
27
28
private int headerInfoOffset;
28
private int headerInfoOffset;
29
private int numberOfChunks;
29
private int numberOfChunks;
Lines 82-93 Link Here
82
}
82
}
83
83
84
84
85
DiskIndex(String fileName) {
85
DiskIndex() {
86
	if (fileName == null)
87
		throw new java.lang.IllegalArgumentException();
88
	this.indexFile = new File(fileName);
89
90
	// clear cached items
91
	this.headerInfoOffset = -1;
86
	this.headerInfoOffset = -1;
92
	this.numberOfChunks = -1;
87
	this.numberOfChunks = -1;
93
	this.sizeOfLastChunk = -1;
88
	this.sizeOfLastChunk = -1;
Lines 99-104 Link Here
99
	this.cachedCategoryName = null;
94
	this.cachedCategoryName = null;
100
	this.categoryOffsets = null;
95
	this.categoryOffsets = null;
101
	this.categoryEnds = null;
96
	this.categoryEnds = null;
97
}
98
DiskIndex(IndexLocation location) throws IOException {
99
	this();
100
	if (location == null) {
101
		throw new IllegalArgumentException();
102
	}
103
	this.indexLocation = location;
102
}
104
}
103
SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException {
105
SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException {
104
	// must skip over documents which have been added/changed/deleted in the memory index
106
	// must skip over documents which have been added/changed/deleted in the memory index
Lines 230-236 Link Here
230
private void cacheDocumentNames() throws IOException {
232
private void cacheDocumentNames() throws IOException {
231
	// will need all document names so get them now
233
	// will need all document names so get them now
232
	this.cachedChunks = new String[this.numberOfChunks][];
234
	this.cachedChunks = new String[this.numberOfChunks][];
233
	FileInputStream stream = new FileInputStream(this.indexFile);
235
	InputStream stream = this.indexLocation.getInputStream();
234
	try {
236
	try {
235
		if (this.numberOfChunks > 5) BUFFER_READ_SIZE <<= 1;
237
		if (this.numberOfChunks > 5) BUFFER_READ_SIZE <<= 1;
236
		int offset = this.chunkOffsets[0];
238
		int offset = this.chunkOffsets[0];
Lines 370-378 Link Here
370
	}
372
	}
371
}
373
}
372
void initialize(boolean reuseExistingFile) throws IOException {
374
void initialize(boolean reuseExistingFile) throws IOException {
373
	if (this.indexFile.exists()) {
375
	if (this.indexLocation.exists()) {
374
		if (reuseExistingFile) {
376
		if (reuseExistingFile) {
375
			FileInputStream stream = new FileInputStream(this.indexFile);
377
			InputStream stream = this.indexLocation.getInputStream();
376
			this.streamBuffer = new byte[BUFFER_READ_SIZE];
378
			this.streamBuffer = new byte[BUFFER_READ_SIZE];
377
			this.bufferIndex = 0;
379
			this.bufferIndex = 0;
378
			this.bufferEnd = stream.read(this.streamBuffer, 0, 128);
380
			this.bufferEnd = stream.read(this.streamBuffer, 0, 128);
Lines 393-406 Link Here
393
			}
395
			}
394
			return;
396
			return;
395
		}
397
		}
396
		if (!this.indexFile.delete()) {
398
		if (!this.indexLocation.delete()) {
397
			if (DEBUG)
399
			if (DEBUG)
398
				System.out.println("initialize - Failed to delete index " + this.indexFile); //$NON-NLS-1$
400
				System.out.println("initialize - Failed to delete index " + this.indexLocation); //$NON-NLS-1$
399
			throw new IOException("Failed to delete index " + this.indexFile); //$NON-NLS-1$
401
			throw new IOException("Failed to delete index " + this.indexLocation); //$NON-NLS-1$
400
		}
402
		}
401
	}
403
	}
402
	if (this.indexFile.createNewFile()) {
404
	if (this.indexLocation.createNewFile()) {
403
		FileOutputStream stream = new FileOutputStream(this.indexFile, false);
405
		FileOutputStream stream = new FileOutputStream(this.indexLocation.getIndexFile(), false);
404
		try {
406
		try {
405
			this.streamBuffer = new byte[BUFFER_READ_SIZE];
407
			this.streamBuffer = new byte[BUFFER_READ_SIZE];
406
			this.bufferIndex = 0;
408
			this.bufferIndex = 0;
Lines 416-433 Link Here
416
		}
418
		}
417
	} else {
419
	} else {
418
		if (DEBUG)
420
		if (DEBUG)
419
			System.out.println("initialize - Failed to create new index " + this.indexFile); //$NON-NLS-1$
421
			System.out.println("initialize - Failed to create new index " + this.indexLocation); //$NON-NLS-1$
420
		throw new IOException("Failed to create new index " + this.indexFile); //$NON-NLS-1$
422
		throw new IOException("Failed to create new index " + this.indexLocation); //$NON-NLS-1$
421
	}
423
	}
422
}
424
}
423
private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException {
425
private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException {
424
	if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file
426
	if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file
425
		if (DEBUG)
427
		if (DEBUG)
426
			System.out.println("initializeFrom - Failed to delete temp index " + this.indexFile); //$NON-NLS-1$
428
			System.out.println("initializeFrom - Failed to delete temp index " + this.indexLocation); //$NON-NLS-1$
427
	} else if (!newIndexFile.createNewFile()) {
429
	} else if (!newIndexFile.createNewFile()) {
428
		if (DEBUG)
430
		if (DEBUG)
429
			System.out.println("initializeFrom - Failed to create temp index " + this.indexFile); //$NON-NLS-1$
431
			System.out.println("initializeFrom - Failed to create temp index " + this.indexLocation); //$NON-NLS-1$
430
		throw new IOException("Failed to create temp index " + this.indexFile); //$NON-NLS-1$
432
		throw new IOException("Failed to create temp index " + this.indexLocation); //$NON-NLS-1$
431
	}
433
	}
432
434
433
	int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize;
435
	int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize;
Lines 500-505 Link Here
500
DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
502
DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
501
 	// assume write lock is held
503
 	// assume write lock is held
502
	// compute & write out new docNames
504
	// compute & write out new docNames
505
	if (this.indexLocation == null) {
506
		throw new IOException("Pre-built index file not writeable");  //$NON-NLS-1$
507
	}
503
	String[] docNames = readAllDocumentNames();
508
	String[] docNames = readAllDocumentNames();
504
	int previousLength = docNames.length;
509
	int previousLength = docNames.length;
505
	int[] positions = new int[previousLength]; // keeps track of the position of each document in the new sorted docNames
510
	int[] positions = new int[previousLength]; // keeps track of the position of each document in the new sorted docNames
Lines 509-523 Link Here
509
		if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved
514
		if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved
510
515
511
		// index is now empty since all the saved documents were removed
516
		// index is now empty since all the saved documents were removed
512
		DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath());
517
		DiskIndex newDiskIndex = new DiskIndex(this.indexLocation);
513
		newDiskIndex.initialize(false);
518
		newDiskIndex.initialize(false);
514
		return newDiskIndex;
519
		return newDiskIndex;
515
	}
520
	}
516
521
	File oldIndexFile = this.indexLocation.getIndexFile();
517
	DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath() + ".tmp"); //$NON-NLS-1$
522
	DiskIndex newDiskIndex = new DiskIndex(new FileIndexLocation(new File(oldIndexFile.getPath() + ".tmp"))); //$NON-NLS-1$
523
	File newIndexFile = newDiskIndex.indexLocation.getIndexFile();
518
	try {
524
	try {
519
		newDiskIndex.initializeFrom(this, newDiskIndex.indexFile);
525
		newDiskIndex.initializeFrom(this, newIndexFile);
520
		FileOutputStream stream = new FileOutputStream(newDiskIndex.indexFile, false);
526
		FileOutputStream stream = new FileOutputStream(newIndexFile, false);
521
		int offsetToHeader = -1;
527
		int offsetToHeader = -1;
522
		try {
528
		try {
523
			newDiskIndex.writeAllDocumentNames(docNames, stream);
529
			newDiskIndex.writeAllDocumentNames(docNames, stream);
Lines 549-579 Link Here
549
		newDiskIndex.writeOffsetToHeader(offsetToHeader);
555
		newDiskIndex.writeOffsetToHeader(offsetToHeader);
550
556
551
		// rename file by deleting previous index file & renaming temp one
557
		// rename file by deleting previous index file & renaming temp one
552
		if (this.indexFile.exists() && !this.indexFile.delete()) {
558
		if (oldIndexFile.exists() && !oldIndexFile.delete()) {
553
			if (DEBUG)
559
			if (DEBUG)
554
				System.out.println("mergeWith - Failed to delete " + this.indexFile); //$NON-NLS-1$
560
				System.out.println("mergeWith - Failed to delete " + this.indexLocation); //$NON-NLS-1$
555
			throw new IOException("Failed to delete index file " + this.indexFile); //$NON-NLS-1$
561
			throw new IOException("Failed to delete index file " + this.indexLocation); //$NON-NLS-1$
556
		}
562
		}
557
		if (!newDiskIndex.indexFile.renameTo(this.indexFile)) {
563
		if (!newIndexFile.renameTo(oldIndexFile)) {
558
			if (DEBUG)
564
			if (DEBUG)
559
				System.out.println("mergeWith - Failed to rename " + this.indexFile); //$NON-NLS-1$
565
				System.out.println("mergeWith - Failed to rename " + this.indexLocation); //$NON-NLS-1$
560
			throw new IOException("Failed to rename index file " + this.indexFile); //$NON-NLS-1$
566
			throw new IOException("Failed to rename index file " + this.indexLocation); //$NON-NLS-1$
561
		}
567
		}
562
	} catch (IOException e) {
568
	} catch (IOException e) {
563
		if (newDiskIndex.indexFile.exists() && !newDiskIndex.indexFile.delete())
569
		if (newIndexFile.exists() && !newIndexFile.delete())
564
			if (DEBUG)
570
			if (DEBUG)
565
				System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexFile); //$NON-NLS-1$
571
				System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexLocation); //$NON-NLS-1$
566
		throw e;
572
		throw e;
567
	}
573
	}
568
574
569
	newDiskIndex.indexFile = this.indexFile;
575
	newDiskIndex.indexLocation = this.indexLocation;
570
	return newDiskIndex;
576
	return newDiskIndex;
571
}
577
}
572
private synchronized String[] readAllDocumentNames() throws IOException {
578
private synchronized String[] readAllDocumentNames() throws IOException {
573
	if (this.numberOfChunks <= 0)
579
	if (this.numberOfChunks <= 0)
574
		return CharOperation.NO_STRINGS;
580
		return CharOperation.NO_STRINGS;
575
581
576
	FileInputStream stream = new FileInputStream(this.indexFile);
582
	InputStream stream = this.indexLocation.getInputStream();
577
	try {
583
	try {
578
		int offset = this.chunkOffsets[0];
584
		int offset = this.chunkOffsets[0];
579
		stream.skip(offset);
585
		stream.skip(offset);
Lines 612-618 Link Here
612
		}
618
		}
613
	}
619
	}
614
620
615
	FileInputStream stream = new FileInputStream(this.indexFile);
621
	InputStream stream = this.indexLocation.getInputStream();
616
	HashtableOfObject categoryTable = null;
622
	HashtableOfObject categoryTable = null;
617
	char[][] matchingWords = null;
623
	char[][] matchingWords = null;
618
	int count = 0;
624
	int count = 0;
Lines 626-632 Link Here
626
		try {
632
		try {
627
			if (size < 0) { // DEBUG
633
			if (size < 0) { // DEBUG
628
				System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
634
				System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
629
				System.err.println("file = "+this.indexFile); //$NON-NLS-1$
635
				System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
630
				System.err.println("offset = "+offset); //$NON-NLS-1$
636
				System.err.println("offset = "+offset); //$NON-NLS-1$
631
				System.err.println("size = "+size); //$NON-NLS-1$
637
				System.err.println("size = "+size); //$NON-NLS-1$
632
				System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
638
				System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
Lines 636-642 Link Here
636
			// DEBUG
642
			// DEBUG
637
			oom.printStackTrace();
643
			oom.printStackTrace();
638
			System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
644
			System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
639
			System.err.println("file = "+this.indexFile); //$NON-NLS-1$
645
			System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
640
			System.err.println("offset = "+offset); //$NON-NLS-1$
646
			System.err.println("offset = "+offset); //$NON-NLS-1$
641
			System.err.println("size = "+size); //$NON-NLS-1$
647
			System.err.println("size = "+size); //$NON-NLS-1$
642
			System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
648
			System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
Lines 678-684 Link Here
678
	}
684
	}
679
685
680
	if (matchingWords != null && count > 0) {
686
	if (matchingWords != null && count > 0) {
681
		stream = new FileInputStream(this.indexFile);
687
		stream = this.indexLocation.getInputStream();
682
		try {
688
		try {
683
			stream.skip(firstOffset);
689
			stream.skip(firstOffset);
684
			this.bufferIndex = 0;
690
			this.bufferIndex = 0;
Lines 696-702 Link Here
696
	this.streamBuffer = null;
702
	this.streamBuffer = null;
697
	return categoryTable;
703
	return categoryTable;
698
}
704
}
699
private void readChunk(String[] docNames, FileInputStream stream, int index, int size) throws IOException {
705
private void readChunk(String[] docNames, InputStream stream, int index, int size) throws IOException {
700
	String current = new String(readStreamChars(stream));
706
	String current = new String(readStreamChars(stream));
701
	docNames[index++] = current;
707
	docNames[index++] = current;
702
	for (int i = 1; i < size; i++) {
708
	for (int i = 1; i < size; i++) {
Lines 734-740 Link Here
734
			throw new IllegalArgumentException();
740
			throw new IllegalArgumentException();
735
		this.streamBuffer = new byte[numberOfBytes];
741
		this.streamBuffer = new byte[numberOfBytes];
736
		this.bufferIndex = 0;
742
		this.bufferIndex = 0;
737
		FileInputStream file = new FileInputStream(this.indexFile);
743
		InputStream file = this.indexLocation.getInputStream();
738
		try {
744
		try {
739
			file.skip(start);
745
			file.skip(start);
740
			if (file.read(this.streamBuffer, 0, numberOfBytes) != numberOfBytes)
746
			if (file.read(this.streamBuffer, 0, numberOfBytes) != numberOfBytes)
Lines 763-769 Link Here
763
	if (arrayOffset instanceof int[])
769
	if (arrayOffset instanceof int[])
764
		return (int[]) arrayOffset;
770
		return (int[]) arrayOffset;
765
771
766
	FileInputStream stream = new FileInputStream(this.indexFile);
772
	InputStream stream = this.indexLocation.getInputStream();
767
	try {
773
	try {
768
		int offset = ((Integer) arrayOffset).intValue();
774
		int offset = ((Integer) arrayOffset).intValue();
769
		stream.skip(offset);
775
		stream.skip(offset);
Lines 776-794 Link Here
776
		this.streamBuffer = null;
782
		this.streamBuffer = null;
777
	}
783
	}
778
}
784
}
779
private void readHeaderInfo(FileInputStream stream) throws IOException {
785
private void readHeaderInfo(InputStream stream) throws IOException {
780
786
781
	// must be same order as writeHeaderInfo()
787
	// must be same order as writeHeaderInfo()
782
	this.numberOfChunks = readStreamInt(stream);
788
	this.numberOfChunks = readStreamInt(stream);
783
	this.sizeOfLastChunk = this.streamBuffer[this.bufferIndex++] & 0xFF;
789
	this.sizeOfLastChunk = this.streamBuffer[this.bufferIndex++] & 0xFF;
784
	this.documentReferenceSize = this.streamBuffer[this.bufferIndex++] & 0xFF;
790
	this.documentReferenceSize = this.streamBuffer[this.bufferIndex++] & 0xFF;
785
	this.separator = (char) (this.streamBuffer[this.bufferIndex++] & 0xFF);
791
	this.separator = (char) (this.streamBuffer[this.bufferIndex++] & 0xFF);
786
	long fileLength = this.indexFile.length();
792
	long length = this.indexLocation.length();
787
	if (this.numberOfChunks > fileLength ) {
793
	if (length != -1 && this.numberOfChunks > length) {
788
		// not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
794
		// not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
789
		if (DEBUG)
795
		if (DEBUG)
790
			System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$
796
			System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
791
		throw new IOException("Index file is corrupted " + this.indexFile); //$NON-NLS-1$
797
		throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
792
	}
798
	}
793
	this.chunkOffsets = new int[this.numberOfChunks];
799
	this.chunkOffsets = new int[this.numberOfChunks];
794
	for (int i = 0; i < this.numberOfChunks; i++)
800
	for (int i = 0; i < this.numberOfChunks; i++)
Lines 799-809 Link Here
799
	int size = readStreamInt(stream);
805
	int size = readStreamInt(stream);
800
	this.categoryOffsets = new HashtableOfIntValues(size);
806
	this.categoryOffsets = new HashtableOfIntValues(size);
801
	this.categoryEnds = new HashtableOfIntValues(size);
807
	this.categoryEnds = new HashtableOfIntValues(size);
802
	if (size > fileLength) {
808
	if (length != -1 && size > length) {
803
		//  not an accurate check, but good enough  https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
809
		//  not an accurate check, but good enough  https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
804
		if (DEBUG)
810
		if (DEBUG)
805
			System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$
811
			System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
806
		throw new IOException("Index file is corrupted " + this.indexFile); //$NON-NLS-1$
812
		throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
807
	}
813
	}
808
	char[] previousCategory = null;
814
	char[] previousCategory = null;
809
	int offset = -1;
815
	int offset = -1;
Lines 840-850 Link Here
840
		}
846
		}
841
	}
847
	}
842
}
848
}
843
private void readStreamBuffer(FileInputStream stream) throws IOException {
849
private void readStreamBuffer(InputStream stream) throws IOException {
844
	// if we're about to read a known amount at the end of the existing buffer, but it does not completely fit
850
	// if we're about to read a known amount at the end of the existing buffer, but it does not completely fit
845
	// so we need to shift the remaining bytes to be read, and fill the buffer from the stream
851
	// so we need to shift the remaining bytes to be read, and fill the buffer from the stream
846
	if (this.bufferEnd < this.streamBuffer.length)
852
	if (this.bufferEnd < this.streamBuffer.length) {
847
		return; // we're at the end of the stream - nothing left to read
853
		if (stream.available() == 0)
854
			return; // we're at the end of the stream - nothing left to read
855
	}
848
856
849
	int bytesInBuffer = this.bufferEnd - this.bufferIndex;
857
	int bytesInBuffer = this.bufferEnd - this.bufferIndex;
850
	if (bytesInBuffer > 0)
858
	if (bytesInBuffer > 0)
Lines 872-878 Link Here
872
 * @exception  UTFDataFormatException  if the bytes do not represent a
880
 * @exception  UTFDataFormatException  if the bytes do not represent a
873
 *               valid UTF-8 encoding of a Unicode string.
881
 *               valid UTF-8 encoding of a Unicode string.
874
 */
882
 */
875
private char[] readStreamChars(FileInputStream stream) throws IOException {
883
private char[] readStreamChars(InputStream stream) throws IOException {
876
	// read chars array length
884
	// read chars array length
877
	if (stream != null && this.bufferIndex + 2 >= this.bufferEnd)
885
	if (stream != null && this.bufferIndex + 2 >= this.bufferEnd)
878
		readStreamBuffer(stream);
886
		readStreamBuffer(stream);
Lines 886-892 Link Here
886
		// how many characters can be decoded without refilling the buffer?
894
		// how many characters can be decoded without refilling the buffer?
887
		int charsInBuffer = i + ((this.bufferEnd - this.bufferIndex) / 3);
895
		int charsInBuffer = i + ((this.bufferEnd - this.bufferIndex) / 3);
888
		// all the characters must already be in the buffer if we're at the end of the stream
896
		// all the characters must already be in the buffer if we're at the end of the stream
889
		if (charsInBuffer > length || this.bufferEnd != this.streamBuffer.length || stream == null)
897
		if (charsInBuffer > length || stream == null  || (this.bufferEnd != this.streamBuffer.length && stream.available() == 0))
890
			charsInBuffer = length;
898
			charsInBuffer = length;
891
		while (i < charsInBuffer) {
899
		while (i < charsInBuffer) {
892
			byte b = this.streamBuffer[this.bufferIndex++];
900
			byte b = this.streamBuffer[this.bufferIndex++];
Lines 931-937 Link Here
931
	}
939
	}
932
	return word;
940
	return word;
933
}
941
}
934
private int[] readStreamDocumentArray(FileInputStream stream, int arraySize) throws IOException {
942
private int[] readStreamDocumentArray(InputStream stream, int arraySize) throws IOException {
935
	int[] indexes = new int[arraySize];
943
	int[] indexes = new int[arraySize];
936
	if (arraySize == 0) return indexes;
944
	if (arraySize == 0) return indexes;
937
945
Lines 972-978 Link Here
972
	}
980
	}
973
	return indexes;
981
	return indexes;
974
}
982
}
975
private int readStreamInt(FileInputStream stream) throws IOException {
983
private int readStreamInt(InputStream stream) throws IOException {
976
	if (this.bufferIndex + 4 >= this.bufferEnd) {
984
	if (this.bufferIndex + 4 >= this.bufferEnd) {
977
		readStreamBuffer(stream);
985
		readStreamBuffer(stream);
978
	}
986
	}
Lines 1182-1188 Link Here
1182
}
1190
}
1183
private void writeOffsetToHeader(int offsetToHeader) throws IOException {
1191
private void writeOffsetToHeader(int offsetToHeader) throws IOException {
1184
	if (offsetToHeader > 0) {
1192
	if (offsetToHeader > 0) {
1185
		RandomAccessFile file = new RandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$
1193
		RandomAccessFile file = new RandomAccessFile(this.indexLocation.getIndexFile(), "rw"); //$NON-NLS-1$
1186
		try {
1194
		try {
1187
			file.seek(this.headerInfoOffset); // offset to position in header
1195
			file.seek(this.headerInfoOffset); // offset to position in header
1188
			file.writeInt(offsetToHeader);
1196
			file.writeInt(offsetToHeader);
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java (+98 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.core.index;
12
13
import java.io.File;
14
import java.io.FileInputStream;
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.net.URL;
18
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
21
22
public class FileIndexLocation extends IndexLocation {
23
	File indexFile;
24
25
	public FileIndexLocation(File file) {
26
		super(file);
27
		this.indexFile = file;
28
	}
29
30
	public FileIndexLocation(URL url, File file) {
31
		super(url);
32
		this.indexFile = file;
33
	}
34
35
	public FileIndexLocation(File file, boolean participantIndex) {
36
		this(file);
37
		this.participantIndex = true;
38
	}
39
40
	public boolean createNewFile() throws IOException {
41
		return this.indexFile.createNewFile();
42
	}
43
44
	public boolean delete() {
45
		return this.indexFile.delete();
46
	}
47
48
	public boolean equals(Object other) {
49
		if (!(other instanceof FileIndexLocation)) return false;
50
		return this.indexFile.equals(((FileIndexLocation) other).indexFile);
51
	}
52
53
	public boolean exists() {
54
		return this.indexFile.exists();
55
	}
56
57
	public String fileName() {
58
		return this.indexFile.getName();
59
	}
60
	
61
	public File getIndexFile() {
62
		return this.indexFile;
63
	}
64
65
	InputStream getInputStream() throws IOException {
66
		return new FileInputStream(this.indexFile);
67
	}
68
69
	public String getCanonicalFilePath() {
70
		try {
71
			return this.indexFile.getCanonicalPath();
72
		} catch (IOException e) {
73
			// ignore
74
		}
75
		return null;
76
	}
77
78
	public int hashCode() {
79
		return this.indexFile.hashCode();
80
	}
81
82
	public long lastModified() {
83
		return this.indexFile.lastModified();
84
	}
85
86
	public long length() {
87
		return this.indexFile.length();
88
	}
89
90
	public boolean startsWith(IPath path) {
91
		try {
92
			return path.isPrefixOf(new Path(this.indexFile.getCanonicalPath()));
93
		} catch (IOException e) {
94
			return false;
95
		}
96
	}
97
98
}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java (-5 / +11 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 88-99 Link Here
88
}
88
}
89
89
90
90
91
public Index(String fileName, String containerPath, boolean reuseExistingFile) throws IOException {
91
public Index(IndexLocation location, String containerPath, boolean reuseExistingFile) throws IOException {
92
	this.containerPath = containerPath;
92
	this.containerPath = containerPath;
93
	this.monitor = new ReadWriteMonitor();
93
	this.monitor = new ReadWriteMonitor();
94
94
95
	this.memoryIndex = new MemoryIndex();
95
	this.memoryIndex = new MemoryIndex();
96
	this.diskIndex = new DiskIndex(fileName);
96
	this.diskIndex = new DiskIndex(location);
97
	this.diskIndex.initialize(reuseExistingFile);
97
	this.diskIndex.initialize(reuseExistingFile);
98
	if (reuseExistingFile) this.separator = this.diskIndex.separator;
98
	if (reuseExistingFile) this.separator = this.diskIndex.separator;
99
}
99
}
Lines 110-116 Link Here
110
	return documentPath.substring(index + 1);
110
	return documentPath.substring(index + 1);
111
}
111
}
112
public File getIndexFile() {
112
public File getIndexFile() {
113
	return this.diskIndex == null ? null : this.diskIndex.indexFile;
113
	return this.diskIndex == null ? null : this.diskIndex.indexLocation.getIndexFile();
114
}
115
public IndexLocation getIndexLocation() {
116
	return this.diskIndex == null ? null : this.diskIndex.indexLocation;
117
}
118
public long getIndexLastModified() {
119
	return this.diskIndex == null? -1 : this.diskIndex.indexLocation.lastModified();
114
}
120
}
115
public boolean hasChanged() {
121
public boolean hasChanged() {
116
	return this.memoryIndex.hasChanged();
122
	return this.memoryIndex.hasChanged();
Lines 180-186 Link Here
180
 */
186
 */
181
public void reset() throws IOException {
187
public void reset() throws IOException {
182
	this.memoryIndex = new MemoryIndex();
188
	this.memoryIndex = new MemoryIndex();
183
	this.diskIndex = new DiskIndex(this.diskIndex.indexFile.getCanonicalPath());
189
	this.diskIndex = new DiskIndex(this.diskIndex.indexLocation);
184
	this.diskIndex.initialize(false/*do not reuse the index file*/);
190
	this.diskIndex.initialize(false/*do not reuse the index file*/);
185
}
191
}
186
public void save() throws IOException {
192
public void save() throws IOException {
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java (+124 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.core.index;
12
13
import java.io.File;
14
import java.io.IOException;
15
import java.io.InputStream;
16
17
import java.net.MalformedURLException;
18
import java.net.URL;
19
20
import org.eclipse.core.runtime.FileLocator;
21
import org.eclipse.core.runtime.IPath;
22
23
/**
24
 * The location of the index files are represented as {@link IndexLocation}
25
 * 
26
 * This is an abstract class to allow different implementation for a jar entry and a file
27
 * on the disk. Some of these functions could mean different for a jar entry or a file
28
 * 
29
 */
30
public abstract class IndexLocation {
31
	
32
	public static IndexLocation createIndexLocation(URL url) {
33
		URL localUrl;
34
		try {
35
			localUrl = FileLocator.resolve(url);
36
		} catch (IOException e) {
37
			return null;
38
		}
39
		if (localUrl.getProtocol().equals("file")) { //$NON-NLS-1$
40
			return new FileIndexLocation(url, new File(localUrl.getPath()));
41
		}
42
		return new JarIndexLocation(url, localUrl);
43
	}
44
	
45
	private final URL url; // url of the given index location
46
47
	/**
48
	 * Set to true if this index location is of an index file specified
49
	 * by a participant through 
50
	 * {@link org.eclipse.jdt.core.search.SearchParticipant#scheduleDocumentIndexing}
51
	 */
52
	protected boolean participantIndex;
53
	
54
	protected IndexLocation(File file) {
55
		URL tempUrl = null;
56
		try {
57
			tempUrl = file.toURI().toURL();
58
		} catch (MalformedURLException e) {
59
			// should not happen
60
		}
61
		this.url = tempUrl;
62
	}
63
	
64
	public IndexLocation(URL url) {
65
		this.url = url;
66
	}
67
68
	/**
69
	 * Closes any open streams.
70
	 */
71
	public void close() {
72
		// default nothing to do
73
	}
74
75
	/**
76
	 * Creates a new file for the given index location
77
	 * @return true if the file is created
78
	 * @throws IOException
79
	 */
80
	public abstract boolean createNewFile() throws IOException;
81
82
	public abstract boolean delete();
83
84
	public abstract boolean exists();
85
	
86
	public abstract String fileName();
87
88
	/**
89
	 * @return the canonical file path if the location is a file or null otherwise
90
	 */
91
	public abstract String getCanonicalFilePath();
92
93
	public abstract File getIndexFile();
94
95
	abstract InputStream getInputStream() throws IOException;
96
97
	public URL getUrl() {
98
		return this.url;
99
	}
100
101
	public int hashCode() {
102
		return this.url.hashCode();
103
	}
104
105
	public boolean isParticipantIndex() {
106
		return this.participantIndex;
107
	}
108
109
	/**
110
	 * @return the last modified time if the location is a file or -1 otherwise
111
	 */
112
	public abstract long lastModified();
113
114
	/**
115
	 * @return the length of the file if the location is a file or -1 otherwise
116
	 */
117
	public abstract long length();
118
119
	public abstract boolean startsWith(IPath path);
120
121
	public String toString() {
122
		return this.url.toString();
123
	}
124
}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java (+108 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.core.index;
12
13
import java.io.File;
14
import java.io.IOException;
15
import java.io.InputStream;
16
import java.net.JarURLConnection;
17
import java.net.URL;
18
import java.util.jar.JarEntry;
19
import java.util.jar.JarFile;
20
21
import org.eclipse.core.runtime.IPath;
22
import org.eclipse.core.runtime.Path;
23
24
public class JarIndexLocation extends IndexLocation {
25
	private JarFile jarFile = null;
26
	private JarEntry jarEntry = null;
27
	private URL localUrl;
28
29
	public JarIndexLocation(URL url, URL localUrl2) {
30
		super(url);
31
		this.localUrl = localUrl2;
32
	}
33
34
	public boolean createNewFile() throws IOException {
35
		return false;
36
	}
37
38
	public void close() {
39
		if (this.jarFile != null) {
40
			try {
41
				this.jarFile.close();
42
			} catch (IOException e) {
43
				// ignore
44
			}
45
			this.jarFile = null;
46
		}
47
	}
48
49
	public boolean delete() {
50
		return false;
51
	}
52
53
	public boolean equals(Object other) {
54
		if (!(other instanceof JarIndexLocation)) return false;
55
		return this.localUrl.equals(((JarIndexLocation) other).localUrl);
56
	}
57
58
	public boolean exists() {
59
		try {
60
			if (this.jarFile == null) {
61
				JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
62
				JarFile file = connection.getJarFile();
63
				if (file == null)
64
					return false;
65
				file.close();
66
			}
67
		} catch (IOException e) {
68
			return false;
69
		}
70
		return true;
71
	}
72
73
	public String fileName() {
74
		return null;
75
	}
76
77
	public File getIndexFile() {
78
		return null;
79
	}
80
81
	InputStream getInputStream() throws IOException {
82
		if (this.jarFile == null) {
83
			JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
84
			this.jarFile = connection.getJarFile();
85
			this.jarEntry = connection.getJarEntry();
86
		}
87
		if (this.jarFile == null || this.jarEntry == null)
88
			return null;
89
		return this.jarFile.getInputStream(this.jarEntry);
90
	}
91
92
	public String getCanonicalFilePath() {
93
		return null;
94
	}
95
96
	public long lastModified() {
97
		return -1;
98
	}
99
100
	public long length() {
101
		return -1;
102
	}
103
104
	public boolean startsWith(IPath path) {
105
		return (path.isPrefixOf(new Path(this.localUrl.getPath())));
106
	}
107
108
}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java (-3 / +4 lines)
Lines 27-32 Link Here
27
import org.eclipse.jdt.internal.core.JavaProject;
27
import org.eclipse.jdt.internal.core.JavaProject;
28
import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
28
import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
29
import org.eclipse.jdt.internal.core.builder.State;
29
import org.eclipse.jdt.internal.core.builder.State;
30
import org.eclipse.jdt.internal.core.index.IndexLocation;
30
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
31
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
31
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
32
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
32
import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
33
import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
Lines 38-44 Link Here
38
public class IndexSelector {
39
public class IndexSelector {
39
	IJavaSearchScope searchScope;
40
	IJavaSearchScope searchScope;
40
	SearchPattern pattern;
41
	SearchPattern pattern;
41
	IPath[] indexLocations; // cache of the keys for looking index up
42
	IndexLocation[] indexLocations; // cache of the keys for looking index up
42
43
43
public IndexSelector(
44
public IndexSelector(
44
		IJavaSearchScope searchScope,
45
		IJavaSearchScope searchScope,
Lines 267-276 Link Here
267
	}
268
	}
268
269
269
	locations.remove(null); // Ensure no nulls
270
	locations.remove(null); // Ensure no nulls
270
	this.indexLocations = (IPath[]) locations.toArray(new IPath[locations.size()]);
271
	this.indexLocations = (IndexLocation[]) locations.toArray(new IndexLocation[locations.size()]);
271
}
272
}
272
273
273
public IPath[] getIndexLocations() {
274
public IndexLocation[] getIndexLocations() {
274
	if (this.indexLocations == null) {
275
	if (this.indexLocations == null) {
275
		initializeIndexLocations();
276
		initializeIndexLocations();
276
	}
277
	}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java (-1 / +15 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 12-17 Link Here
12
12
13
import org.eclipse.core.runtime.*;
13
import org.eclipse.core.runtime.*;
14
import org.eclipse.jdt.core.search.*;
14
import org.eclipse.jdt.core.search.*;
15
import org.eclipse.jdt.internal.core.index.IndexLocation;
15
import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
16
import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
16
import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer;
17
import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer;
17
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
18
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
Lines 98-104 Link Here
98
	 * @see org.eclipse.jdt.core.search.SearchParticipant#selectIndexes(org.eclipse.jdt.core.search.SearchQuery, org.eclipse.jdt.core.search.SearchContext)
99
	 * @see org.eclipse.jdt.core.search.SearchParticipant#selectIndexes(org.eclipse.jdt.core.search.SearchQuery, org.eclipse.jdt.core.search.SearchContext)
99
	 */
100
	 */
100
	public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) {
101
	public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) {
102
		IndexSelector selector = (IndexSelector) this.indexSelector.get();
103
		if (selector == null) {
104
			selector = new IndexSelector(scope, pattern);
105
			this.indexSelector.set(selector);
106
		}
107
		IndexLocation[] urls = selector.getIndexLocations();
108
		IPath[] paths = new IPath[urls.length];
109
		for (int i = 0; i < urls.length; i++) {
110
			paths[i] = new Path(urls[i].getIndexFile().getPath());
111
		}
112
		return paths;
113
	}
101
114
115
	public IndexLocation[] selectIndexURLs(SearchPattern pattern, IJavaSearchScope scope) {
102
		IndexSelector selector = (IndexSelector) this.indexSelector.get();
116
		IndexSelector selector = (IndexSelector) this.indexSelector.get();
103
		if (selector == null) {
117
		if (selector == null) {
104
			selector = new IndexSelector(scope, pattern);
118
			selector = new IndexSelector(scope, pattern);
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java (-2 / +15 lines)
Lines 17-23 Link Here
17
import org.eclipse.core.runtime.OperationCanceledException;
17
import org.eclipse.core.runtime.OperationCanceledException;
18
import org.eclipse.jdt.core.search.*;
18
import org.eclipse.jdt.core.search.*;
19
import org.eclipse.jdt.internal.core.JavaModelManager;
19
import org.eclipse.jdt.internal.core.JavaModelManager;
20
import org.eclipse.jdt.internal.core.index.FileIndexLocation;
20
import org.eclipse.jdt.internal.core.index.Index;
21
import org.eclipse.jdt.internal.core.index.Index;
22
import org.eclipse.jdt.internal.core.index.IndexLocation;
21
import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
23
import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
22
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
24
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
23
import org.eclipse.jdt.internal.core.search.processing.IJob;
25
import org.eclipse.jdt.internal.core.search.processing.IJob;
Lines 76-83 Link Here
76
}
78
}
77
public Index[] getIndexes(IProgressMonitor progressMonitor) {
79
public Index[] getIndexes(IProgressMonitor progressMonitor) {
78
	// acquire the in-memory indexes on the fly
80
	// acquire the in-memory indexes on the fly
79
	IPath[] indexLocations = this.participant.selectIndexes(this.pattern, this.scope);
81
	IndexLocation[] indexLocations;
80
	int length = indexLocations.length;
82
	int length;
83
	if (this.participant instanceof JavaSearchParticipant) {
84
		indexLocations = ((JavaSearchParticipant)this.participant).selectIndexURLs(this.pattern, this.scope);
85
		length = indexLocations.length;
86
	} else {
87
		IPath[] paths = this.participant.selectIndexes(this.pattern, this.scope);
88
		length = paths.length;
89
		indexLocations = new IndexLocation[paths.length];
90
		for (int i = 0, len = paths.length; i < len; i++) {
91
			indexLocations[i] = new FileIndexLocation(paths[i].toFile(), true);
92
		}
93
	}
81
	Index[] indexes = JavaModelManager.getIndexManager().getIndexes(indexLocations, progressMonitor);
94
	Index[] indexes = JavaModelManager.getIndexManager().getIndexes(indexLocations, progressMonitor);
82
	this.areIndexesReady = indexes.length == length;
95
	this.areIndexesReady = indexes.length == length;
83
	return indexes;
96
	return indexes;
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java (-4 / +9 lines)
Lines 34-39 Link Here
34
import org.eclipse.jdt.internal.compiler.util.Util;
34
import org.eclipse.jdt.internal.compiler.util.Util;
35
import org.eclipse.jdt.internal.core.JavaModelManager;
35
import org.eclipse.jdt.internal.core.JavaModelManager;
36
import org.eclipse.jdt.internal.core.index.Index;
36
import org.eclipse.jdt.internal.core.index.Index;
37
import org.eclipse.jdt.internal.core.index.IndexLocation;
37
import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
38
import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
38
import org.eclipse.jdt.internal.core.search.processing.JobManager;
39
import org.eclipse.jdt.internal.core.search.processing.JobManager;
39
40
Lines 42-55 Link Here
42
	private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0);
43
	private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0);
43
	IFile resource;
44
	IFile resource;
44
	Scanner scanner;
45
	Scanner scanner;
45
	private IPath indexFileURL;
46
	private IndexLocation indexFileURL;
46
47
47
	public AddJarFileToIndex(IFile resource, IPath indexFile, IndexManager manager) {
48
	public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) {
48
		super(resource.getFullPath(), manager);
49
		super(resource.getFullPath(), manager);
49
		this.resource = resource;
50
		this.resource = resource;
50
		this.indexFileURL = indexFile;
51
		this.indexFileURL = indexFile;
51
	}
52
	}
52
	public AddJarFileToIndex(IPath jarPath, IPath indexFile, IndexManager manager) {
53
	public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) {
53
		// external JAR scenario - no resource
54
		// external JAR scenario - no resource
54
		super(jarPath, manager);
55
		super(jarPath, manager);
55
		this.indexFileURL = indexFile;
56
		this.indexFileURL = indexFile;
Lines 201-207 Link Here
201
					return false;
202
					return false;
202
				}
203
				}
203
				index.separator = JAR_SEPARATOR;
204
				index.separator = JAR_SEPARATOR;
204
				IPath indexPath = this.manager.computeIndexLocation(this.containerPath);
205
				IPath indexPath = null;
206
				IndexLocation indexLocation;
207
				if ((indexLocation = index.getIndexLocation()) != null) {
208
					indexPath = new Path(indexLocation.getCanonicalFilePath());
209
				}
205
				for (Enumeration e = zip.entries(); e.hasMoreElements();) {
210
				for (Enumeration e = zip.entries(); e.hasMoreElements();) {
206
					if (this.isCancelled) {
211
					if (this.isCancelled) {
207
						if (JobManager.VERBOSE)
212
						if (JobManager.VERBOSE)
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java (-1 / +4 lines)
Lines 22-28 Link Here
22
import org.eclipse.jdt.core.search.SearchEngine;
22
import org.eclipse.jdt.core.search.SearchEngine;
23
import org.eclipse.jdt.core.search.SearchParticipant;
23
import org.eclipse.jdt.core.search.SearchParticipant;
24
import org.eclipse.jdt.internal.compiler.util.Util;
24
import org.eclipse.jdt.internal.compiler.util.Util;
25
import org.eclipse.jdt.internal.core.index.FileIndexLocation;
25
import org.eclipse.jdt.internal.core.index.Index;
26
import org.eclipse.jdt.internal.core.index.Index;
27
import org.eclipse.jdt.internal.core.index.IndexLocation;
26
import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
28
import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
27
29
28
public class DefaultJavaIndexer {
30
public class DefaultJavaIndexer {
Lines 33-39 Link Here
33
		if (!f.exists()) {
35
		if (!f.exists()) {
34
			throw new FileNotFoundException(pathToJar + " not found"); //$NON-NLS-1$
36
			throw new FileNotFoundException(pathToJar + " not found"); //$NON-NLS-1$
35
		}
37
		}
36
		Index index = new Index(pathToIndexFile, pathToJar, false /*reuse index file*/);
38
		IndexLocation indexLocation = new FileIndexLocation(new File(pathToIndexFile));
39
		Index index = new Index(indexLocation, pathToJar, false /*reuse index file*/);
37
		SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
40
		SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
38
		index.separator = JAR_SEPARATOR;
41
		index.separator = JAR_SEPARATOR;
39
		ZipFile zip = new ZipFile(pathToJar);
42
		ZipFile zip = new ZipFile(pathToJar);
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java (-1 / +1 lines)
Lines 107-113 Link Here
107
				for (int i = 0; i < max; i++)
107
				for (int i = 0; i < max; i++)
108
					indexedFileNames.put(paths[i], DELETED);
108
					indexedFileNames.put(paths[i], DELETED);
109
			}
109
			}
110
			final long indexLastModified = max == 0 ? 0L : index.getIndexFile().lastModified();
110
			final long indexLastModified = max == 0 ? 0L : index.getIndexLastModified();
111
111
112
			IWorkspaceRoot root = this.project.getWorkspace().getRoot();
112
			IWorkspaceRoot root = this.project.getWorkspace().getRoot();
113
			for (int i = 0; i < sourceEntriesNumber; i++) {
113
			for (int i = 0; i < sourceEntriesNumber; i++) {
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java (-1 / +1 lines)
Lines 80-86 Link Here
80
				for (int i = 0; i < max; i++) {
80
				for (int i = 0; i < max; i++) {
81
					indexedFileNames.put(paths[i], DELETED);
81
					indexedFileNames.put(paths[i], DELETED);
82
				}
82
				}
83
				final long indexLastModified = index.getIndexFile().lastModified();
83
				final long indexLastModified = index.getIndexLastModified();
84
				this.folder.accept(
84
				this.folder.accept(
85
					new IResourceProxyVisitor() {
85
					new IResourceProxyVisitor() {
86
						public boolean visit(IResourceProxy proxy) throws CoreException {
86
						public boolean visit(IResourceProxy proxy) throws CoreException {
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java (-84 / +76 lines)
Lines 16-22 Link Here
16
import java.util.zip.CRC32;
16
import java.util.zip.CRC32;
17
17
18
import org.eclipse.core.resources.*;
18
import org.eclipse.core.resources.*;
19
import org.eclipse.core.runtime.FileLocator;
20
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IProgressMonitor;
22
import org.eclipse.core.runtime.OperationCanceledException;
21
import org.eclipse.core.runtime.OperationCanceledException;
Lines 73-79 Link Here
73
	public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) {
72
	public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) {
74
	// newIndexState is either UPDATING_STATE or REBUILDING_STATE
73
	// newIndexState is either UPDATING_STATE or REBUILDING_STATE
75
	// must tag the index as inconsistent, in case we exit before the update job is started
74
	// must tag the index as inconsistent, in case we exit before the update job is started
76
	IPath indexLocation = computeIndexLocation(containerPath);
75
	IndexLocation indexLocation = computeIndexLocation(containerPath);
77
	Object state = getIndexStates().get(indexLocation);
76
	Object state = getIndexStates().get(indexLocation);
78
	Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
77
	Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
79
	if (currentIndexState.compareTo(REBUILDING_STATE) >= 0) return; // already rebuilding the index
78
	if (currentIndexState.compareTo(REBUILDING_STATE) >= 0) return; // already rebuilding the index
Lines 95-101 Link Here
95
	if (JavaCore.getPlugin() == null) return;
94
	if (JavaCore.getPlugin() == null) return;
96
	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
95
	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
97
	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
96
	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
98
	IPath indexLocation = computeIndexLocation(containerPath);
97
	IndexLocation indexLocation = computeIndexLocation(containerPath);
99
	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
98
	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
100
}
99
}
101
/**
100
/**
Lines 107-113 Link Here
107
	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
106
	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
108
	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
107
	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
109
	document.setParser(parser);
108
	document.setParser(parser);
110
	IPath indexLocation = computeIndexLocation(containerPath);
109
	IndexLocation indexLocation = computeIndexLocation(containerPath);
111
	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
110
	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
112
}
111
}
113
/*
112
/*
Lines 119-135 Link Here
119
	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
118
	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
120
	Index[] selectedIndexes = job.getIndexes(null);
119
	Index[] selectedIndexes = job.getIndexes(null);
121
	for (int i = 0, l = selectedIndexes.length; i < l; i++) {
120
	for (int i = 0, l = selectedIndexes.length; i < l; i++) {
122
		String path = selectedIndexes[i].getIndexFile().getAbsolutePath();
121
		IndexLocation IndexLocation = selectedIndexes[i].getIndexLocation();
123
		knownPaths.add(path);
122
		knownPaths.add(IndexLocation);
124
	}
123
	}
125
124
126
	if (this.indexStates != null) {
125
	if (this.indexStates != null) {
127
		Object[] keys = this.indexStates.keyTable;
126
		Object[] keys = this.indexStates.keyTable;
128
		IPath[] locations = new IPath[this.indexStates.elementSize];
127
		IndexLocation[] locations = new IndexLocation[this.indexStates.elementSize];
129
		int count = 0;
128
		int count = 0;
130
		for (int i = 0, l = keys.length; i < l; i++) {
129
		for (int i = 0, l = keys.length; i < l; i++) {
131
			IPath key = (IPath) keys[i];
130
			IndexLocation key = (IndexLocation) keys[i];
132
			if (key != null && !knownPaths.includes(key.toOSString()))
131
			if (key != null && !knownPaths.includes(key))
133
				locations[count++] = key;
132
				locations[count++] = key;
134
		}
133
		}
135
		if (count > 0)
134
		if (count > 0)
Lines 137-144 Link Here
137
	}
136
	}
138
	deleteIndexFiles(knownPaths);
137
	deleteIndexFiles(knownPaths);
139
}
138
}
140
public synchronized IPath computeIndexLocation(IPath containerPath) {
139
public synchronized IndexLocation computeIndexLocation(IPath containerPath) {
141
	IPath indexLocation = (IPath) this.indexLocations.get(containerPath);
140
	IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath);
142
	if (indexLocation == null) {
141
	if (indexLocation == null) {
143
		String pathString = containerPath.toOSString();
142
		String pathString = containerPath.toOSString();
144
		CRC32 checksumCalculator = new CRC32();
143
		CRC32 checksumCalculator = new CRC32();
Lines 147-153 Link Here
147
		if (VERBOSE)
146
		if (VERBOSE)
148
			Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
147
			Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
149
		// to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table
148
		// to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table
150
		indexLocation = (IPath) getIndexStates().getKey(getJavaPluginWorkingLocation().append(fileName));
149
		indexLocation = (IndexLocation) getIndexStates().getKey(new FileIndexLocation(new File(getSavedIndexesDirectory(), fileName)));
151
		this.indexLocations.put(containerPath, indexLocation);
150
		this.indexLocations.put(containerPath, indexLocation);
152
	}
151
	}
153
	return indexLocation;
152
	return indexLocation;
Lines 164-170 Link Here
164
163
165
	for (int i = 0, l = indexesFiles.length; i < l; i++) {
164
	for (int i = 0, l = indexesFiles.length; i < l; i++) {
166
		String fileName = indexesFiles[i].getAbsolutePath();
165
		String fileName = indexesFiles[i].getAbsolutePath();
167
		if (pathsToKeep != null && pathsToKeep.includes(fileName)) continue;
166
		if (pathsToKeep != null && pathsToKeep.includes(new FileIndexLocation(indexesFiles[i]))) continue;
168
		String suffix = ".index"; //$NON-NLS-1$
167
		String suffix = ".index"; //$NON-NLS-1$
169
		if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) {
168
		if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) {
170
			if (VERBOSE || DEBUG)
169
			if (VERBOSE || DEBUG)
Lines 176-182 Link Here
176
/*
175
/*
177
 * Creates an empty index at the given location, for the given container path, if none exist.
176
 * Creates an empty index at the given location, for the given container path, if none exist.
178
 */
177
 */
179
public synchronized void ensureIndexExists(IPath indexLocation, IPath containerPath) {
178
public synchronized void ensureIndexExists(IndexLocation indexLocation, IPath containerPath) {
180
	SimpleLookupTable states = getIndexStates();
179
	SimpleLookupTable states = getIndexStates();
181
	Object state = states.get(indexLocation);
180
	Object state = states.get(indexLocation);
182
	if (state == null) {
181
	if (state == null) {
Lines 210-216 Link Here
210
 * @param indexLocation The path of the index file
209
 * @param indexLocation The path of the index file
211
 * @return The corresponding index or <code>null</code> if not found
210
 * @return The corresponding index or <code>null</code> if not found
212
 */
211
 */
213
public synchronized Index getIndex(IPath indexLocation) {
212
public synchronized Index getIndex(IndexLocation indexLocation) {
214
	return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
213
	return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
215
}
214
}
216
/**
215
/**
Lines 222-228 Link Here
222
 * Warning: Does not check whether index is consistent (not being used)
221
 * Warning: Does not check whether index is consistent (not being used)
223
 */
222
 */
224
public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
223
public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
225
	IPath indexLocation = computeIndexLocation(containerPath);
224
	IndexLocation indexLocation = computeIndexLocation(containerPath);
226
	return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
225
	return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
227
}
226
}
228
/**
227
/**
Lines 233-239 Link Here
233
 *
232
 *
234
 * Warning: Does not check whether index is consistent (not being used)
233
 * Warning: Does not check whether index is consistent (not being used)
235
 */
234
 */
236
public synchronized Index getIndex(IPath containerPath, IPath indexLocation, boolean reuseExistingFile, boolean createIfMissing) {
235
public synchronized Index getIndex(IPath containerPath, IndexLocation indexLocation, boolean reuseExistingFile, boolean createIfMissing) {
237
	// Path is already canonical per construction
236
	// Path is already canonical per construction
238
	Index index = getIndex(indexLocation);
237
	Index index = getIndex(indexLocation);
239
	if (index == null) {
238
	if (index == null) {
Lines 248-266 Link Here
248
247
249
		// index isn't cached, consider reusing an existing index file
248
		// index isn't cached, consider reusing an existing index file
250
		String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
249
		String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
251
		String indexLocationString = indexLocation.toOSString();
252
		if (reuseExistingFile) {
250
		if (reuseExistingFile) {
253
			File indexFile = new File(indexLocationString);
251
			if (indexLocation.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
254
			if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
255
				try {
252
				try {
256
					index = new Index(indexLocationString, containerPathString, true /*reuse index file*/);
253
					index = new Index(indexLocation, containerPathString, true /*reuse index file*/);
257
					this.indexes.put(indexLocation, index);
254
					this.indexes.put(indexLocation, index);
258
					return index;
255
					return index;
259
				} catch (IOException e) {
256
				} catch (IOException e) {
260
					// failed to read the existing file or its no longer compatible
257
					// failed to read the existing file or its no longer compatible
261
					if (currentIndexState != REBUILDING_STATE && currentIndexState != REUSE_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt
258
					if (currentIndexState != REBUILDING_STATE && currentIndexState != REUSE_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt
262
						if (VERBOSE)
259
						if (VERBOSE)
263
							Util.verbose("-> cannot reuse existing index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
260
							Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
264
						rebuildIndex(indexLocation, containerPath);
261
						rebuildIndex(indexLocation, containerPath);
265
						return null;
262
						return null;
266
					}
263
					}
Lines 285-297 Link Here
285
		if (createIfMissing) {
282
		if (createIfMissing) {
286
			try {
283
			try {
287
				if (VERBOSE)
284
				if (VERBOSE)
288
					Util.verbose("-> create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
285
					Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
289
				index = new Index(indexLocationString, containerPathString, false /*do not reuse index file*/);
286
				index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/);
290
				this.indexes.put(indexLocation, index);
287
				this.indexes.put(indexLocation, index);
291
				return index;
288
				return index;
292
			} catch (IOException e) {
289
			} catch (IOException e) {
293
				if (VERBOSE)
290
				if (VERBOSE)
294
					Util.verbose("-> unable to create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
291
					Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
295
				// The file could not be created. Possible reason: the project has been deleted.
292
				// The file could not be created. Possible reason: the project has been deleted.
296
				return null;
293
				return null;
297
			}
294
			}
Lines 307-313 Link Here
307
 * @param locations The list of of the index files path
304
 * @param locations The list of of the index files path
308
 * @return The corresponding indexes list.
305
 * @return The corresponding indexes list.
309
 */
306
 */
310
public Index[] getIndexes(IPath[] locations, IProgressMonitor progressMonitor) {
307
public Index[] getIndexes(IndexLocation[] locations, IProgressMonitor progressMonitor) {
311
	// acquire the in-memory indexes on the fly
308
	// acquire the in-memory indexes on the fly
312
	int length = locations.length;
309
	int length = locations.length;
313
	Index[] locatedIndexes = new Index[length];
310
	Index[] locatedIndexes = new Index[length];
Lines 320-326 Link Here
320
			throw new OperationCanceledException();
317
			throw new OperationCanceledException();
321
		}
318
		}
322
		// may trigger some index recreation work
319
		// may trigger some index recreation work
323
		IPath indexLocation = locations[i];
320
		IndexLocation indexLocation = locations[i];
324
		Index index = getIndex(indexLocation);
321
		Index index = getIndex(indexLocation);
325
		if (index == null) {
322
		if (index == null) {
326
			// only need containerPath if the index must be built
323
			// only need containerPath if the index must be built
Lines 342-359 Link Here
342
					index = null;
339
					index = null;
343
				}
340
				}
344
			} else {
341
			} else {
345
				if (!getJavaPluginWorkingLocation().isPrefixOf(indexLocation)) { // the index belongs to non-jdt search participant
342
				if (indexLocation.isParticipantIndex() && indexLocation.exists()) { // the index belongs to non-jdt search participant
346
					if (indexLocation.toFile().exists()) { 
343
					try {
347
						try {
344
						IPath container = getParticipantsContainer(indexLocation);
348
							IPath container = getParticipantsContainer(indexLocation);
345
						if (container != null) {
349
							if (container != null) {
346
							index = new Index(indexLocation, container.toOSString(), true /*reuse index file*/);
350
								index = new Index(indexLocation.toOSString(), container.toOSString(), true /*reuse index file*/);
347
							this.indexes.put(indexLocation, index);
351
								this.indexes.put(indexLocation, index);
352
							}
353
						} catch (IOException e) {
354
							// ignore
355
						}
348
						}
356
					} 
349
					} catch (IOException e) {
350
						// ignore
351
					}
357
				}
352
				}
358
			}
353
			}
359
		}
354
		}
Lines 370-376 Link Here
370
	return locatedIndexes;
365
	return locatedIndexes;
371
}
366
}
372
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
367
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
373
	IPath indexLocation = computeIndexLocation(containerPath);
368
	IndexLocation indexLocation = computeIndexLocation(containerPath);
374
	if (getIndexStates().get(indexLocation) == REBUILDING_STATE)
369
	if (getIndexStates().get(indexLocation) == REBUILDING_STATE)
375
		return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
370
		return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
376
371
Lines 380-392 Link Here
380
	if (this.indexStates != null) return this.indexStates;
375
	if (this.indexStates != null) return this.indexStates;
381
376
382
	this.indexStates = new SimpleLookupTable();
377
	this.indexStates = new SimpleLookupTable();
383
	IPath indexesDirectoryPath = getJavaPluginWorkingLocation();
378
	File indexesDirectoryPath = getSavedIndexesDirectory();
384
	char[][] savedNames = readIndexState(indexesDirectoryPath.toOSString());
379
	char[][] savedNames = readIndexState(getJavaPluginWorkingLocation().toOSString());
385
	if (savedNames != null) {
380
	if (savedNames != null) {
386
		for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState()
381
		for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState()
387
			char[] savedName = savedNames[i];
382
			char[] savedName = savedNames[i];
388
			if (savedName.length > 0) {
383
			if (savedName.length > 0) {
389
				IPath indexLocation = indexesDirectoryPath.append(new String(savedName)); // shares indexesDirectoryPath's segments
384
				IndexLocation indexLocation = new FileIndexLocation(new File(indexesDirectoryPath, String.valueOf(savedName))); // shares indexesDirectoryPath's segments
390
				if (VERBOSE)
385
				if (VERBOSE)
391
					Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$
386
					Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$
392
				this.indexStates.put(indexLocation, SAVED_STATE);
387
				this.indexStates.put(indexLocation, SAVED_STATE);
Lines 401-407 Link Here
401
	}
396
	}
402
	return this.indexStates;
397
	return this.indexStates;
403
}
398
}
404
private IPath getParticipantsContainer(IPath indexLocation) {
399
private IPath getParticipantsContainer(IndexLocation indexLocation) {
405
	if (this.participantsContainers == null) {
400
	if (this.participantsContainers == null) {
406
		readParticipantsIndexNamesFile();
401
		readParticipantsIndexNamesFile();
407
	}
402
	}
Lines 502-516 Link Here
502
 */
497
 */
503
public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) {
498
public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) {
504
	// requestingProject is no longer used to cancel jobs but leave it here just in case
499
	// requestingProject is no longer used to cancel jobs but leave it here just in case
505
	IPath indexFile = null; 
500
	IndexLocation indexFile = indexURL != null ? IndexLocation.createIndexLocation(indexURL): null;
506
	if (indexURL != null)  {
507
		try {
508
			indexFile = new Path(FileLocator.resolve(indexURL).getPath());
509
		} catch (IOException e) {
510
			if (VERBOSE)
511
				Util.verbose("-> cannot resolve the url : "+ indexURL + " specified for " + path); //$NON-NLS-1$ //$NON-NLS-2$
512
		}
513
	}
514
	if (JavaCore.getPlugin() == null) return;
501
	if (JavaCore.getPlugin() == null) return;
515
	IndexRequest request = null;
502
	IndexRequest request = null;
516
	Object target = JavaModel.getTarget(path, true);
503
	Object target = JavaModel.getTarget(path, true);
Lines 529-539 Link Here
529
		request(request);
516
		request(request);
530
}
517
}
531
518
532
synchronized boolean addIndex(IPath containerPath, IPath indexFile) {
519
synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) {
533
	this.indexStates.put(indexFile, REUSE_STATE);
520
	this.indexStates.put(indexFile, REUSE_STATE);
534
	this.indexLocations.put(containerPath, indexFile);
521
	this.indexLocations.put(containerPath, indexFile);
535
	Index index = getIndex(containerPath, indexFile, true, false);
522
	Index index = getIndex(containerPath, indexFile, true, false);
536
	if (index == null) {
523
	if (index == null) {
524
		indexFile.close();
537
		this.indexLocations.put(containerPath, null);
525
		this.indexLocations.put(containerPath, null);
538
		return false;
526
		return false;
539
	}
527
	}
Lines 554-560 Link Here
554
	request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this));
542
	request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this));
555
}
543
}
556
public synchronized void jobWasCancelled(IPath containerPath) {
544
public synchronized void jobWasCancelled(IPath containerPath) {
557
	IPath indexLocation = computeIndexLocation(containerPath);
545
	IndexLocation indexLocation = computeIndexLocation(containerPath);
558
	Index index = getIndex(indexLocation);
546
	Index index = getIndex(indexLocation);
559
	if (index != null) {
547
	if (index != null) {
560
		index.monitor = null;
548
		index.monitor = null;
Lines 600-606 Link Here
600
	}
588
	}
601
	return null;
589
	return null;
602
}
590
}
603
private void rebuildIndex(IPath indexLocation, IPath containerPath) {
591
private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) {
604
	Object target = JavaModel.getTarget(containerPath, true);
592
	Object target = JavaModel.getTarget(containerPath, true);
605
	if (target == null) return;
593
	if (target == null) return;
606
594
Lines 633-645 Link Here
633
	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
621
	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
634
	try {
622
	try {
635
		// Path is already canonical
623
		// Path is already canonical
636
		IPath indexLocation = computeIndexLocation(containerPath);
624
		IndexLocation indexLocation = computeIndexLocation(containerPath);
637
		Index index = getIndex(indexLocation);
625
		Index index = getIndex(indexLocation);
638
		ReadWriteMonitor monitor = index == null ? null : index.monitor;
626
		ReadWriteMonitor monitor = index == null ? null : index.monitor;
639
627
640
		if (VERBOSE)
628
		if (VERBOSE)
641
			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
629
			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
642
		index = new Index(indexLocation.toOSString(), containerPathString, false /*do not reuse index file*/);
630
		index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/);
643
		this.indexes.put(indexLocation, index);
631
		this.indexes.put(indexLocation, index);
644
		index.monitor = monitor;
632
		index.monitor = monitor;
645
		return index;
633
		return index;
Lines 666-672 Link Here
666
public synchronized void removeIndex(IPath containerPath) {
654
public synchronized void removeIndex(IPath containerPath) {
667
	if (VERBOSE || DEBUG)
655
	if (VERBOSE || DEBUG)
668
		Util.verbose("removing index " + containerPath); //$NON-NLS-1$
656
		Util.verbose("removing index " + containerPath); //$NON-NLS-1$
669
	IPath indexLocation = computeIndexLocation(containerPath);
657
	IndexLocation indexLocation = computeIndexLocation(containerPath);
670
	Index index = getIndex(indexLocation);
658
	Index index = getIndex(indexLocation);
671
	File indexFile = null;
659
	File indexFile = null;
672
	if (index != null) {
660
	if (index != null) {
Lines 674-683 Link Here
674
		indexFile = index.getIndexFile();
662
		indexFile = index.getIndexFile();
675
	}
663
	}
676
	if (indexFile == null)
664
	if (indexFile == null)
677
		indexFile = new File(indexLocation.toOSString()); // index is not cached yet, but still want to delete the file
665
		indexFile = indexLocation.getIndexFile(); // index is not cached yet, but still want to delete the file
678
	if (this.indexStates.get(indexLocation) == REUSE_STATE) {
666
	if (this.indexStates.get(indexLocation) == REUSE_STATE) {
667
		indexLocation.close();
679
		this.indexLocations.put(containerPath, null);
668
		this.indexLocations.put(containerPath, null);
680
	} else if (indexFile.exists()) {
669
	} else if (indexFile != null && indexFile.exists()) {
681
		if (DEBUG)
670
		if (DEBUG)
682
			Util.verbose("removing index file " + indexFile); //$NON-NLS-1$
671
			Util.verbose("removing index file " + indexFile); //$NON-NLS-1$
683
		indexFile.delete();
672
		indexFile.delete();
Lines 693-716 Link Here
693
		Util.verbose("removing index path " + path); //$NON-NLS-1$
682
		Util.verbose("removing index path " + path); //$NON-NLS-1$
694
	Object[] keyTable = this.indexes.keyTable;
683
	Object[] keyTable = this.indexes.keyTable;
695
	Object[] valueTable = this.indexes.valueTable;
684
	Object[] valueTable = this.indexes.valueTable;
696
	IPath[] locations = null;
685
	IndexLocation[] locations = null;
697
	int max = this.indexes.elementSize;
686
	int max = this.indexes.elementSize;
698
	int count = 0;
687
	int count = 0;
699
	for (int i = 0, l = keyTable.length; i < l; i++) {
688
	for (int i = 0, l = keyTable.length; i < l; i++) {
700
		IPath indexLocation = (IPath) keyTable[i];
689
		IndexLocation indexLocation = (IndexLocation) keyTable[i];
701
		if (indexLocation == null)
690
		if (indexLocation == null)
702
			continue;
691
			continue;
703
		if (path.isPrefixOf(indexLocation)) {
692
		if (indexLocation.startsWith(path)) {
704
			Index index = (Index) valueTable[i];
693
			Index index = (Index) valueTable[i];
705
			index.monitor = null;
694
			index.monitor = null;
706
			if (locations == null)
695
			if (locations == null)
707
				locations = new IPath[max];
696
				locations = new IndexLocation[max];
708
			locations[count++] = indexLocation;
697
			locations[count++] = indexLocation;
709
			File indexFile = index.getIndexFile();
698
			if (this.indexStates.get(indexLocation) == REUSE_STATE) {
710
			if (indexFile.exists()) {
699
				indexLocation.close();
700
			} else {
711
				if (DEBUG)
701
				if (DEBUG)
712
					Util.verbose("removing index file " + indexFile); //$NON-NLS-1$
702
					Util.verbose("removing index file " + indexLocation); //$NON-NLS-1$
713
				indexFile.delete();
703
				indexLocation.delete();
714
			}
704
			}
715
		} else {
705
		} else {
716
			max--;
706
			max--;
Lines 786-792 Link Here
786
	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
776
	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
787
	try {
777
	try {
788
		// Path is already canonical
778
		// Path is already canonical
789
		IPath indexLocation = computeIndexLocation(containerPath);
779
		IndexLocation indexLocation = computeIndexLocation(containerPath);
790
		Index index = getIndex(indexLocation);
780
		Index index = getIndex(indexLocation);
791
		if (VERBOSE) {
781
		if (VERBOSE) {
792
			Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
782
			Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
Lines 810-816 Link Here
810
	// must have permission to write from the write monitor
800
	// must have permission to write from the write monitor
811
	if (index.hasChanged()) {
801
	if (index.hasChanged()) {
812
		if (VERBOSE)
802
		if (VERBOSE)
813
			Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$
803
			Util.verbose("-> saving index " + index.getIndexLocation()); //$NON-NLS-1$
814
		index.save();
804
		index.save();
815
	}
805
	}
816
	synchronized (this) {
806
	synchronized (this) {
Lines 822-828 Link Here
822
					if (((IndexRequest) job).containerPath.equals(containerPath)) return;
812
					if (((IndexRequest) job).containerPath.equals(containerPath)) return;
823
			}
813
			}
824
		}
814
		}
825
		IPath indexLocation = computeIndexLocation(containerPath);
815
		IndexLocation indexLocation = computeIndexLocation(containerPath);
826
		updateIndexState(indexLocation, SAVED_STATE);
816
		updateIndexState(indexLocation, SAVED_STATE);
827
	}
817
	}
828
}
818
}
Lines 877-883 Link Here
877
	}
867
	}
878
	this.needToSave = !allSaved;
868
	this.needToSave = !allSaved;
879
}
869
}
880
public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IPath indexLocation, final SearchParticipant searchParticipant) {
870
public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IndexLocation indexLocation, final SearchParticipant searchParticipant) {
881
	request(new IndexRequest(container, this) {
871
	request(new IndexRequest(container, this) {
882
		public boolean execute(IProgressMonitor progressMonitor) {
872
		public boolean execute(IProgressMonitor progressMonitor) {
883
			if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
873
			if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
Lines 890-896 Link Here
890
880
891
			try {
881
			try {
892
				monitor.enterWrite(); // ask permission to write
882
				monitor.enterWrite(); // ask permission to write
893
				indexDocument(searchDocument, searchParticipant, index, indexLocation);
883
				indexDocument(searchDocument, searchParticipant, index, new Path(indexLocation.getCanonicalFilePath()));
894
			} finally {
884
			} finally {
895
				monitor.exitWrite(); // free write lock
885
				monitor.exitWrite(); // free write lock
896
			}
886
			}
Lines 944-950 Link Here
944
				// First line is DiskIndex signature  (see writeParticipantsIndexNamesFile())
934
				// First line is DiskIndex signature  (see writeParticipantsIndexNamesFile())
945
				if (DiskIndex.SIGNATURE.equals(new String(names[0]))) {					
935
				if (DiskIndex.SIGNATURE.equals(new String(names[0]))) {					
946
					for (int i = 1, l = names.length-1 ; i < l ; i+=2) {
936
					for (int i = 1, l = names.length-1 ; i < l ; i+=2) {
947
						containers.put(new Path(new String(names[i])), new Path(new String(names[i+1])));
937
						IndexLocation indexLocation = new FileIndexLocation(new File(new String(names[i])), true);
938
						containers.put(indexLocation, new Path(new String(names[i+1])));
948
					}
939
					}
949
				}				
940
				}				
950
			}
941
			}
Lines 956-962 Link Here
956
	this.participantsContainers = containers;
947
	this.participantsContainers = containers;
957
	return;
948
	return;
958
}
949
}
959
private synchronized void removeIndexesState(IPath[] locations) {
950
private synchronized void removeIndexesState(IndexLocation[] locations) {
960
	getIndexStates(); // ensure the states are initialized
951
	getIndexStates(); // ensure the states are initialized
961
	int length = locations.length;
952
	int length = locations.length;
962
	boolean changed = false;
953
	boolean changed = false;
Lines 973-980 Link Here
973
964
974
	writeSavedIndexNamesFile();
965
	writeSavedIndexNamesFile();
975
}
966
}
976
private synchronized void updateIndexState(IPath indexLocation, Integer indexState) {
967
private synchronized void updateIndexState(IndexLocation indexLocation, Integer indexState) {
977
	if (indexLocation.isEmpty())
968
	if (indexLocation == null)
978
		throw new IllegalArgumentException();
969
		throw new IllegalArgumentException();
979
970
980
	getIndexStates(); // ensure the states are initialized
971
	getIndexStates(); // ensure the states are initialized
Lines 1002-1011 Link Here
1002
	}
993
	}
1003
994
1004
}
995
}
1005
public void updateParticipant(IPath indexLocation, IPath containerPath) {
996
public void updateParticipant(IPath indexPath, IPath containerPath) {
1006
	if (this.participantsContainers == null) {
997
	if (this.participantsContainers == null) {
1007
		readParticipantsIndexNamesFile();
998
		readParticipantsIndexNamesFile();
1008
	} 
999
	}
1000
	IndexLocation indexLocation = new FileIndexLocation(indexPath.toFile(), true);
1009
	if (this.participantsContainers.get(indexLocation) == null) {
1001
	if (this.participantsContainers.get(indexLocation) == null) {
1010
		this.participantsContainers.put(indexLocation, containerPath);
1002
		this.participantsContainers.put(indexLocation, containerPath);
1011
		this.participantUpdated  = true;
1003
		this.participantUpdated  = true;
Lines 1054-1062 Link Here
1054
		Object[] indexFiles = this.participantsContainers.keyTable;
1046
		Object[] indexFiles = this.participantsContainers.keyTable;
1055
		Object[] containers = this.participantsContainers.valueTable;
1047
		Object[] containers = this.participantsContainers.valueTable;
1056
		for (int i = 0, l = indexFiles.length; i < l; i++) {
1048
		for (int i = 0, l = indexFiles.length; i < l; i++) {
1057
			IPath indexFile = (IPath)indexFiles[i];
1049
			IndexLocation indexFile = (IndexLocation)indexFiles[i];
1058
			if (indexFile != null) {
1050
			if (indexFile != null) {
1059
				writer.write(indexFile.toOSString());
1051
				writer.write(indexFile.getIndexFile().getPath());
1060
				writer.write('\n');
1052
				writer.write('\n');
1061
				writer.write(((IPath)containers[i]).toOSString());
1053
				writer.write(((IPath)containers[i]).toOSString());
1062
				writer.write('\n');
1054
				writer.write('\n');
Lines 1086-1094 Link Here
1086
		Object[] keys = this.indexStates.keyTable;
1078
		Object[] keys = this.indexStates.keyTable;
1087
		Object[] states = this.indexStates.valueTable;
1079
		Object[] states = this.indexStates.valueTable;
1088
		for (int i = 0, l = states.length; i < l; i++) {
1080
		for (int i = 0, l = states.length; i < l; i++) {
1089
			IPath key = (IPath) keys[i];
1081
			IndexLocation key = (IndexLocation) keys[i];
1090
			if (key != null && !key.isEmpty() && states[i] == SAVED_STATE) {
1082
			if (key != null && states[i] == SAVED_STATE) {
1091
				writer.write(key.lastSegment());
1083
				writer.write(key.fileName());
1092
				writer.write('\n');
1084
				writer.write('\n');
1093
			}
1085
			}
1094
		}
1086
		}

Return to bug 356620