| /******************************************************************************* |
| * Copyright (c) 2000, 2010 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.model; |
| |
| import junit.framework.Test; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.search.*; |
| import org.eclipse.jdt.core.tests.model.AbstractJavaSearchTests.JavaSearchResultCollector; |
| import org.eclipse.jdt.core.tests.util.Util; |
| import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer; |
| import org.eclipse.jdt.internal.core.search.processing.JobManager; |
| |
| /** |
| * Tests the search participant supprt. |
| */ |
| public class SearchParticipantTests extends ModifyingResourceTests implements IJavaSearchConstants { |
| |
| IJavaProject project; |
| boolean deleteProject = true; |
| |
| public class TestSearchParticipant extends SearchParticipant { |
| |
| class WrapperDocument extends SearchDocument { |
| |
| private SearchDocument document; |
| |
| WrapperDocument(SearchDocument document, SearchParticipant participant) { |
| super(document.getPath().replaceAll(".test", ".java"), participant); |
| this.document = document; |
| } |
| |
| public byte[] getByteContents() { |
| return this.document.getByteContents(); |
| } |
| |
| public char[] getCharContents() { |
| return this.document.getCharContents(); |
| } |
| |
| public String getEncoding() { |
| return this.document.getEncoding(); |
| } |
| } |
| |
| private SearchParticipant defaultSearchParticipant = SearchEngine.getDefaultSearchParticipant(); |
| |
| public SearchDocument getDocument(String documentPath) { |
| return new TestSearchDocument(documentPath, this); |
| } |
| |
| public void indexDocument(SearchDocument document, IPath indexLocation) { |
| ((TestSearchDocument) document).indexingRequested = true; |
| document.removeAllIndexEntries(); |
| String documentPath = document.getPath(); |
| if (documentPath.endsWith(".test")) { |
| new SourceIndexer(document).indexDocument(); |
| } |
| } |
| |
| public void locateMatches(SearchDocument[] documents, SearchPattern pattern, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { |
| int length = documents.length; |
| SearchDocument[] wrapperDocuments = new SearchDocument[length]; |
| for (int i = 0; i < length; i++) { |
| wrapperDocuments[i] = new WrapperDocument(documents[i], this); |
| } |
| this.defaultSearchParticipant.locateMatches(wrapperDocuments, pattern, scope, requestor, monitor); |
| } |
| |
| public IPath[] selectIndexes(SearchPattern query, IJavaSearchScope scope) { |
| return new IPath[] {getIndexLocation()}; |
| } |
| } |
| |
| public class TestSearchDocument extends SearchDocument { |
| |
| public boolean indexingRequested; |
| private String fileSystemPath; |
| |
| protected TestSearchDocument(String documentPath, SearchParticipant participant) { |
| super(documentPath, participant); |
| this.fileSystemPath = getWorkspaceRoot().getFile(new Path(documentPath)).getLocation().toOSString(); |
| } |
| |
| public byte[] getByteContents() { |
| String fileContent = Util.fileContent(this.fileSystemPath); |
| if (fileContent == null) return null; |
| return fileContent.getBytes(); |
| } |
| |
| public char[] getCharContents() { |
| String fileContent = Util.fileContent(this.fileSystemPath); |
| if (fileContent == null) return null; |
| return fileContent.toCharArray(); |
| } |
| |
| public String getEncoding() { |
| return null; |
| } |
| } |
| |
| public class TestResultCollector extends JavaSearchResultCollector { |
| protected char[] getSource(IResource resource, IJavaElement element, ICompilationUnit unit) throws JavaModelException { |
| IPath path = resource.getLocation().removeFileExtension().addFileExtension("test"); |
| String fileContent = Util.fileContent(path.toFile().getPath()); |
| if (fileContent == null) return null; |
| return fileContent.toCharArray(); |
| } |
| protected String getPathString(IResource resource, IJavaElement element) { |
| return super.getPathString(resource, element).replaceAll(".java", ".test"); |
| } |
| } |
| |
| // Use this static initializer to specify subset for tests |
| // All specified tests which do not belong to the class are skipped... |
| static { |
| // TESTS_NAMES = new String[] { "testSearch"}; |
| // TESTS_NUMBERS = new int[] { 23, 28, 38 }; |
| // TESTS_RANGE = new int[] { 21, 38 }; |
| } |
| |
| public static Test suite() { |
| return buildModelTestSuite(SearchParticipantTests.class); |
| } |
| |
| public void setUpSuite() throws Exception { |
| super.setUpSuite(); |
| deleteResource(getIndexLocation().toFile()); |
| } |
| |
| public void tearDownSuite() throws Exception { |
| super.tearDownSuite(); |
| if (this.project != null) { |
| deleteProject("P"); |
| } |
| } |
| |
| protected void setUp() throws Exception { |
| super.setUp(); |
| if (this.project == null) { |
| this.project = createJavaProject("P"); |
| } |
| this.deleteProject = true; |
| if (JobManager.VERBOSE) { |
| System.out.println("--------------------------------------------------------------------------------"); |
| System.out.println("Run test "+getName()+"..."); |
| } |
| } |
| |
| protected void tearDown() throws Exception { |
| // Do not delete specific index file between tests as corresponding still lives in IndexManager cache |
| // TODO (frederic) Uncomment when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=116650 will be fixed |
| //deleteFile(getIndexLocation().toFile()); |
| if (this.deleteProject) { |
| deleteProject("P"); |
| this.project = null; |
| } |
| super.tearDown(); |
| } |
| |
| public SearchParticipantTests(String name) { |
| super(name); |
| } |
| |
| IPath getIndexLocation() { |
| return new Path(getExternalPath() + "test.index"); |
| } |
| |
| /* |
| * Ensures that scheduleDocumentIndexing(...) triggers a call to indexDocument(...) |
| * (case of document existing on disk) |
| */ |
| public void testScheduleDocumentIndexing1() throws CoreException { |
| createFile("/P/X.test", ""); |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| assertTrue("Should have requested to index document", document.indexingRequested); |
| } |
| |
| /* |
| * Ensures that scheduleDocumentIndexing(...) triggers a call to indexDocument(...) |
| * (case of document that doesn't exist on disk) |
| */ |
| public void testScheduleDocumentIndexing2() throws CoreException { |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| assertTrue("Should have requested to index document", document.indexingRequested); |
| } |
| |
| /* |
| * Ensures that adding index entries through indexDocument() updates the index file. |
| */ |
| public synchronized void testIndexDocument01() throws CoreException, InterruptedException { |
| createFile( |
| "/P/X.test", |
| "public class X {\n" + |
| "}" |
| ); |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| wait(1100); // wait more than 1000ms so as to allow for the index to be saved on disk |
| document = new TestSearchDocument("/P/no", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| assertTrue("Index file should have been written", getIndexLocation().toFile().length() > 0); |
| |
| // remove index file |
| participant.removeIndex(getIndexLocation()); |
| assertFalse("Index file should have been removed", getIndexLocation().toFile().exists()); |
| } |
| |
| /* |
| * Ensures that adding index entries through indexDocument() updates the index file |
| * and that exit session keeps it. |
| */ |
| public synchronized void testIndexDocument02() throws CoreException, InterruptedException { |
| TestSearchParticipant participant = new TestSearchParticipant(){ |
| public void indexDocument(SearchDocument document, IPath indexLocation) { |
| if (!document.getPath().equals("/P/no")) { |
| for (int i = 0; i < 1000; i++) { |
| document.addIndexEntry(("category" + i).toCharArray(), ("key" + i).toCharArray()); |
| } |
| } |
| } |
| }; |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| wait(1100); // wait more than 1000ms so as to allow for the index to be saved on disk |
| document = new TestSearchDocument("/P/no", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| wait(1100); // wait more than 1000ms so as to allow for the index to be saved on disk |
| assertTrue("Index file should have been written", getIndexLocation().toFile().length() > 0); |
| |
| // shutdown |
| simulateExit(); |
| assertTrue("Index file should stay after shutdown", getIndexLocation().toFile().length() > 0); |
| this.deleteProject = false; |
| |
| // remove index file |
| participant.removeIndex(getIndexLocation()); |
| assertFalse("Index file should have been removed", getIndexLocation().toFile().exists()); |
| |
| // restart |
| simulateRestart(); |
| } |
| |
| /* |
| * Ensures that adding index entries through indexDocument() updates the index file. |
| */ |
| public synchronized void testIndexDocument03() throws CoreException, InterruptedException { |
| createFile( |
| "/P/X.test", |
| "public class X {\n" + |
| "}" |
| ); |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| wait(1100); // wait more than 1000ms so as to allow for the index to be saved on disk |
| document = new TestSearchDocument("/P/no", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| assertTrue("Index file should have been written", getIndexLocation().toFile().length() > 0); |
| |
| // remove index file |
| participant.removeIndex(getIndexLocation()); |
| assertFalse("Index file should have been removed", getIndexLocation().toFile().exists()); |
| } |
| |
| /* |
| * Ensures that a simple search that forwards queries to the default participant works as expected |
| */ |
| public void testSearch() throws CoreException { |
| createFile( |
| "/P/X.test", |
| "public class X {\n" + |
| "}" |
| ); |
| |
| // index file |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| |
| // search for declaration of X |
| SearchPattern pattern = SearchPattern.createPattern("X", IJavaSearchConstants.DECLARATIONS, IJavaSearchConstants.TYPE, SearchPattern.R_EXACT_MATCH); |
| IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); |
| SearchRequestor requestor = new TestResultCollector(); |
| new SearchEngine().search(pattern, new SearchParticipant[] {participant}, scope, requestor, null); |
| assertSearchResults( |
| "X.test X [X]", |
| requestor); |
| } |
| |
| /* |
| * Ensures that a simple search that forwards queries to the default participant works as expected even after restart |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=308402 |
| */ |
| public void testSearchAfterRestart() throws CoreException { |
| createFile( |
| "/P/X.test", |
| "public class X {\n" + |
| "}" |
| ); |
| |
| // index file |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| try { |
| Thread.sleep(5000); // wait for the indexes to go into the disk |
| } catch (InterruptedException e) { |
| // ignore |
| } |
| simulateExit(); |
| simulateRestart(); |
| waitUntilIndexesReady(); |
| |
| // search for declaration of X |
| SearchPattern pattern = SearchPattern.createPattern("X", IJavaSearchConstants.DECLARATIONS, IJavaSearchConstants.TYPE, SearchPattern.R_EXACT_MATCH); |
| IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); |
| SearchRequestor requestor = new TestResultCollector(); |
| new SearchEngine().search(pattern, new SearchParticipant[] {participant}, scope, requestor, null); |
| assertSearchResults( |
| "X.test X [X]", |
| requestor); |
| |
| } |
| |
| /* |
| * Ensures that a simple search that forwards queries to the default participant works as expected even after removing |
| * the index and then doing a restart |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=308402 |
| */ |
| public void testSearchAfterRemoveAndRestart() throws CoreException { |
| createFile( |
| "/P/X.test", |
| "public class X {\n" + |
| "}" |
| ); |
| |
| // index file |
| TestSearchParticipant participant = new TestSearchParticipant(); |
| TestSearchDocument document = new TestSearchDocument("/P/X.test", participant); |
| participant.scheduleDocumentIndexing(document, getIndexLocation()); |
| waitUntilIndexesReady(); |
| |
| // search for declaration of X |
| SearchPattern pattern = SearchPattern.createPattern("X", IJavaSearchConstants.DECLARATIONS, IJavaSearchConstants.TYPE, SearchPattern.R_EXACT_MATCH); |
| IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); |
| SearchRequestor requestor = new TestResultCollector(); |
| new SearchEngine().search(pattern, new SearchParticipant[] {participant}, scope, requestor, null); |
| |
| // remove the index |
| participant.removeIndex(getIndexLocation()); |
| assertSearchResults( |
| "X.test X [X]", |
| requestor); |
| try { |
| Thread.sleep(5000); // wait for the indexes to go into the disk |
| } catch (InterruptedException e) { |
| // ignore |
| } |
| requestor = new TestResultCollector(); |
| new SearchEngine().search(pattern, new SearchParticipant[] {participant}, scope, requestor, null); |
| assertSearchResults("", requestor); |
| |
| simulateExit(); |
| simulateRestart(); |
| waitUntilIndexesReady(); |
| requestor = new TestResultCollector(); |
| new SearchEngine().search(pattern, new SearchParticipant[] {participant}, scope, requestor, null); |
| assertSearchResults("", requestor); |
| } |
| } |