diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java
index 1893d3f..f8e8a9f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 2013 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
@@ -864,3 +864,70 @@
}
}
+ public void testManagingPreBuildIndexFile() throws CoreException, IOException {
+
+ // locate the JDT core preference
+ String prefNodeName = "org.eclipse.jdt.core";
+ IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(prefNodeName);
+ if(prefs == null) {
+ fail("The preferences for '" + prefNodeName + "' could not be located.");
+ }
+ // create the pre-built index
+ File indexFile = null;
+ String jarFilePath = getExternalResourcePath("Test.jar");
+ File jarFile = new File(jarFilePath);
+ IJavaProject p = null;
+ try {
+ createJar(new String[] {
+ "pkg/Test.java",
+ "package pkg;\n" +
+ "public class Test {\n" +
+ " protected Test(int i) {}\n" +
+ " protected void helloWorld() {}\n" +
+ "}"}, jarFilePath);
+ indexFile = new File(getExternalResourcePath("Test.index"));
+ JavaIndexer.generateIndexForJar(jarFilePath, indexFile.getAbsolutePath());
+ // create project P and add the Test.jar to the classpath (associate the index to it)
+ p = createJavaProject("P");
+ Path libPath = new Path(jarFilePath);
+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexFile.toURI().toURL().toString());
+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false);
+ this.setClasspath(p, new IClasspathEntry[] {entry});
+ AbstractJavaModelTests.waitUntilIndexesReady();
+ // verify the current index is correct
+ this.resultCollector = new JavaSearchResultCollector();
+ this.search("helloWorld", METHOD, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
+ this.assertSearchResults(getExternalPath() + "Test.jar void pkg.Test.helloWorld()");
+ // restart the product so the index manager enables management of pre-build indexes
+ prefs.put(JavaCore.MANAGE_PREBUILT_INDEXES, JavaCore.ENABLED);
+ this.simulateExit();
+ // update the class file (when the product is not running) by changing
+ // the method signature (simulate the contents of a JAR file changing)
+ createJar(new String[] {
+ "pkg/Test.java",
+ "package pkg;\n" +
+ "public class Test {\n" +
+ " protected Test(int i) {}\n" +
+ " protected void helloWorld(int i) {}\n" +
+ "}"}, jarFilePath);
+ this.simulateRestart();
+ JavaCore.initializeAfterLoad(null);
+ AbstractJavaModelTests.waitUntilIndexesReady();
+ // verify that the index is updated
+ this.resultCollector = new JavaSearchResultCollector();
+ this.search("helloWorld", METHOD, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p}));
+ this.assertSearchResults(getExternalPath() + "Test.jar void pkg.Test.helloWorld(int)");
+ }
+ finally {
+ // restart the product so the index manager disables management of pre-build indexes
+ prefs.put(JavaCore.MANAGE_PREBUILT_INDEXES, JavaCore.DISABLED);
+ // clean-up artifacts that were created
+ if(p != null) {
+ deleteProject("P");
+ }
+ if (indexFile != null) {
+ indexFile.delete();
+ }
+ jarFile.delete();
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 1af5510..4ac884e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -2172,4 +2172,16 @@
*/
public static final String TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC = PLUGIN_ID + ".timeoutForParameterNameFromAttachedJavadoc"; //$NON-NLS-1$
+ /**
+ * Core option ID: The indexer will manage (update or delete) pre-built indexes
+ *
When enabled, the indexer will manage any pre-built index files
+ *
+ * - Option id:
"org.eclipse.jdt.core.index.manageProductIndexes"
+ * - Possible values:
{ "enabled", "disabled" }
+ * - Default:
"disabled"
+ *
+ * @since 3.9
+ * @category CoreOptionID
+ */
+ public static final String MANAGE_PREBUILT_INDEXES = PLUGIN_ID + ".index.manageProductIndexes"; //$NON-NLS-1$
/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index c36e288..8accbb6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -999,5 +999,5 @@
this.manager.indexManager.removeIndex(entryPath);
// then index the jar
- this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation());
+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation(), true);
} else {
URL indexLocation = ((ClasspathEntry)entries[j]).getLibraryIndexLocation();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index 91c6dde..3756005 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -94,4 +94,6 @@
// Time out for parameter names
defaultOptionsMap.put(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, "50"); //$NON-NLS-1$
+ // update product index (default: disabled)
+ defaultOptionsMap.put(JavaCore.MANAGE_PREBUILT_INDEXES, JavaCore.DISABLED);
// Store default values to default preferences
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index cfa351a..a7e1319 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -2256,4 +2256,6 @@
// Time out for parameter names
defaultOptionsMap.put(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, "50"); //$NON-NLS-1$
+ // update product index (default: disabled)
+ defaultOptionsMap.put(JavaCore.MANAGE_PREBUILT_INDEXES, JavaCore.DISABLED);
return new Hashtable(defaultOptionsMap);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
index 46dfe21..c88ed49 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -45,14 +45,23 @@
Scanner scanner;
private IndexLocation indexFileURL;
+ private final boolean forceIndexUpdate;
public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) {
+ this(resource, indexFile, manager, false);
+ }
+ public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
super(resource.getFullPath(), manager);
this.resource = resource;
this.indexFileURL = indexFile;
+ this.forceIndexUpdate = updateIndex;
}
public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) {
+ this(jarPath, indexFile, manager, false);
+ }
+ public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
// external JAR scenario - no resource
super(jarPath, manager);
this.indexFileURL = indexFile;
+ this.forceIndexUpdate = updateIndex;
}
public boolean equals(Object o) {
@@ -76,5 +85,5 @@
if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
- if (this.indexFileURL != null) {
+ if (this.hasPreBuiltIndex()) {
boolean added = this.manager.addIndex(this.containerPath, this.indexFileURL);
if (added) return true;
@@ -292,8 +301,20 @@
}
protected Integer updatedIndexState() {
- return IndexManager.REBUILDING_STATE;
+
+ Integer updateState = null;
+ if(this.hasPreBuiltIndex()) {
+ updateState = IndexManager.REUSE_STATE;
+ }
+ else {
+ updateState = IndexManager.REBUILDING_STATE;
+ }
+ return updateState;
}
public String toString() {
return "indexing " + this.containerPath.toString(); //$NON-NLS-1$
}
-}
+
+ protected boolean hasPreBuiltIndex() {
+ return !this.forceIndexUpdate && ((this.indexFileURL != null) && this.indexFileURL.exists());
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index d130e0f..8c4e265 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -1,4 +1,4 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -68,8 +68,23 @@
private boolean participantUpdated = false;
+ // should JDT manage (update, delete as needed) pre-built indexes?
+ private Boolean manageUserIndexes = null;
+
// Debug
public static boolean DEBUG = false;
- public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) {
+private boolean isManagingPreBuiltIndexes() {
+ if (this.manageUserIndexes == null) {
+ String manageIndexPropertyValue = JavaCore.getOption(JavaCore.MANAGE_PREBUILT_INDEXES);
+ if (manageIndexPropertyValue != null) {
+ this.manageUserIndexes = Boolean.valueOf(JavaCore.ENABLED.equals(manageIndexPropertyValue));
+ } else {
+ this.manageUserIndexes = Boolean.FALSE;
+ }
+ }
+ return this.manageUserIndexes.booleanValue();
+ }
+
+public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) {
// newIndexState is either UPDATING_STATE or REBUILDING_STATE
// must tag the index as inconsistent, in case we exit before the update job is started
@@ -137,4 +152,35 @@
}
deleteIndexFiles(knownPaths);
+}
+/**
+ * Compute the pre-built index location for a specified URL
+ */
+public synchronized IndexLocation computeIndexLocation(IPath containerPath, final URL newIndexURL) {
+ IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath);
+ if (indexLocation == null) {
+ if(newIndexURL != null) {
+ indexLocation = IndexLocation.createIndexLocation(newIndexURL);
+ // update caches
+ indexLocation = (IndexLocation) getIndexStates().getKey(indexLocation);
+ this.indexLocations.put(containerPath, indexLocation);
+ }
+ }
+ else {
+ // an existing index location exists - make sure it has not changed (i.e. the URL has not changed)
+ URL existingURL = indexLocation.getUrl();
+ if (newIndexURL != null) {
+ // if either URL is different then the index location has been updated so rebuild.
+ if(!newIndexURL.equals(existingURL)) {
+ // URL has changed so remove the old index and create a new one
+ this.removeIndex(containerPath);
+ // create a new one
+ indexLocation = IndexLocation.createIndexLocation(newIndexURL);
+ // update caches
+ indexLocation = (IndexLocation) getIndexStates().getKey(indexLocation);
+ this.indexLocations.put(containerPath, indexLocation);
+ }
+ }
+ }
+ return indexLocation;
}
public synchronized IndexLocation computeIndexLocation(IPath containerPath) {
@@ -494,18 +540,26 @@
request(request);
}
+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) {
+ this.indexLibrary(path, requestingProject, indexURL, false);
+}
+
/**
* Trigger addition of a library to an index
* Note: the actual operation is performed in background
*/
-public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) {
+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL, final boolean updateIndex) {
// requestingProject is no longer used to cancel jobs but leave it here just in case
- IndexLocation indexFile = indexURL != null ? IndexLocation.createIndexLocation(indexURL): null;
+ IndexLocation indexFile = null;
+ if (indexURL != null) {
+ indexFile = computeIndexLocation(path, indexURL);
+ }
if (JavaCore.getPlugin() == null) return;
IndexRequest request = null;
+ boolean forceIndexUpdate = this.isManagingPreBuiltIndexes() && updateIndex;
Object target = JavaModel.getTarget(path, true);
if (target instanceof IFile) {
- request = new AddJarFileToIndex((IFile) target, indexFile, this);
+ request = new AddJarFileToIndex((IFile) target, indexFile, this, forceIndexUpdate);
} else if (target instanceof File) {
- request = new AddJarFileToIndex(path, indexFile, this);
+ request = new AddJarFileToIndex(path, indexFile, this, forceIndexUpdate);
} else if (target instanceof IContainer) {
request = new IndexBinaryFolder((IContainer) target, this);
@@ -676,4 +730,7 @@
}
this.indexes.removeKey(indexLocation);
+ if (isManagingPreBuiltIndexes()) {
+ this.indexLocations.removeKey(containerPath);
+ }
updateIndexState(indexLocation, null);
}
@@ -770,4 +827,5 @@
this.indexLocations = new SimpleLookupTable();
this.javaPluginLocation = null;
+ this.manageUserIndexes = null;
}
/**
@@ -1014,4 +1072,5 @@
else if (indexState == UNKNOWN_STATE) state = "UNKNOWN"; //$NON-NLS-1$
else if (indexState == REBUILDING_STATE) state = "REBUILDING"; //$NON-NLS-1$
+ else if (indexState == REUSE_STATE) state = "REUSE"; //$NON-NLS-1$
Util.verbose("-> index state updated to: " + state + " for: "+indexLocation); //$NON-NLS-1$ //$NON-NLS-2$
}