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 c88a835..56d83cb 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 @@ -2204,7 +2204,19 @@ * @category CoreOptionID */ public static final String TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC = PLUGIN_ID + ".timeoutForParameterNameFromAttachedJavadoc"; //$NON-NLS-1$ - + /** + * Core option ID: JDT will update indexes provided by the product. + *

When enabled, JDT will update any index files provided by a product

+ *
+ *
Option id:
"org.eclipse.jdt.core.index.updateProductIndexes"
+ *
Possible values:
{ "enabled", "disabled" }
+ *
Default:
"disabled"
+ *
+ * @since 3.9 + * @category CoreOptionID + */ + public static final String UPDATE_PRODUCT_INDEXES = PLUGIN_ID + ".index.updateProductIndexes"; //$NON-NLS-1$ + /** * @since 2.0 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION}, 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..172a809 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 @@ -998,7 +998,7 @@ // first remove the index so that it is forced to be re-indexed this.manager.indexManager.removeIndex(entryPath); // then index the jar - this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); + this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation(), true); } else { URL indexLocation = ((ClasspathEntry)entries[j]).getLibraryIndexLocation(); if (indexLocation != null) { // force reindexing, this could be faster rather than maintaining the list 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 fb926c3..c0ce272 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 @@ -94,7 +94,9 @@ // 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.UPDATE_PRODUCT_INDEXES, JavaCore.DISABLED); + // Store default values to default preferences IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(JavaCore.PLUGIN_ID); for (Iterator iter = defaultOptionsMap.entrySet().iterator(); iter.hasNext();) { 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 57aa94c..3a9230c 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 @@ -2255,7 +2255,9 @@ // 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.UPDATE_PRODUCT_INDEXES, JavaCore.DISABLED); + return new Hashtable(defaultOptionsMap); } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java index d410f72..aec7034 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java @@ -13,8 +13,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; - import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import org.eclipse.core.runtime.FileLocator; @@ -37,7 +38,15 @@ return null; } if (localUrl.getProtocol().equals("file")) { //$NON-NLS-1$ - return new FileIndexLocation(url, new File(localUrl.getPath())); + File localFile = null; + try { + URI localFileURI = new URI(localUrl.toExternalForm()); + localFile = new File(localFileURI); + } + catch(URISyntaxException uriSyntaxEx) { + localFile = new File(localUrl.getPath()); + } + return new FileIndexLocation(url, localFile); } return new JarIndexLocation(url, localUrl); } 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..864dc7d 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 @@ -44,16 +44,31 @@ IFile resource; Scanner scanner; private IndexLocation indexFileURL; - + private final boolean updateIndexIfNecessary; + public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) { + + this(resource, indexFile, manager, false); + } + + public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) { + + this(jarPath, 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.updateIndexIfNecessary = updateIndex; } - public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) { + public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) { + // external JAR scenario - no resource super(jarPath, manager); this.indexFileURL = indexFile; + this.updateIndexIfNecessary = updateIndex; } public boolean equals(Object o) { if (o instanceof AddJarFileToIndex) { @@ -76,11 +91,21 @@ if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; if (this.indexFileURL != null) { - boolean added = this.manager.addIndex(this.containerPath, this.indexFileURL); - if (added) return true; - this.indexFileURL = null; + try { + boolean added = this.createOrUpdatePreBuiltIndex(progressMonitor); + if(added) return true; + this.indexFileURL = null; + } + catch (IOException e) { + if (JobManager.VERBOSE) { + org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + this.manager.removeIndex(this.containerPath); + } } - + + boolean result = false; try { // if index is already cached, then do not perform any check // MUST reset the IndexManager if a jar file is changed @@ -97,162 +122,202 @@ org.eclipse.jdt.internal.core.util.Util.verbose("-> index could not be created for " + this.containerPath); //$NON-NLS-1$ return true; } - ReadWriteMonitor monitor = index.monitor; - if (monitor == null) { - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> index for " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$ - return true; // index got deleted since acquired - } - index.separator = JAR_SEPARATOR; - ZipFile zip = null; - try { - // this path will be a relative path to the workspace in case the zipfile in the workspace otherwise it will be a path in the - // local file system - Path zipFilePath = null; - - monitor.enterWrite(); // ask permission to write - if (this.resource != null) { - URI location = this.resource.getLocationURI(); - if (location == null) return false; - if (JavaModelManager.ZIP_ACCESS_VERBOSE) - System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$ //$NON-NLS-2$ - File file = null; - try { - file = org.eclipse.jdt.internal.core.util.Util.toLocalFile(location, progressMonitor); - } catch (CoreException e) { - if (JobManager.VERBOSE) { - org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ - e.printStackTrace(); - } - } - if (file == null) { - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because the file could not be fetched"); //$NON-NLS-1$ //$NON-NLS-2$ - return false; - } - zip = new ZipFile(file); - zipFilePath = (Path) this.resource.getFullPath().makeRelative(); - // absolute path relative to the workspace - } else { - if (JavaModelManager.ZIP_ACCESS_VERBOSE) - System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$ - // external file -> it is ok to use toFile() - zip = new ZipFile(this.containerPath.toFile()); - zipFilePath = (Path) this.containerPath; - // path is already canonical since coming from a library classpath entry - } - - if (this.isCancelled) { - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ - return false; - } - - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing " + zip.getName()); //$NON-NLS-1$ - long initialTime = System.currentTimeMillis(); - - String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$ - if (paths != null) { - int max = paths.length; - /* check integrity of the existing index file - * if the length is equal to 0, we want to index the whole jar again - * If not, then we want to check that there is no missing entry, if - * one entry is missing then we recreate the index - */ - String EXISTS = "OK"; //$NON-NLS-1$ - String DELETED = "DELETED"; //$NON-NLS-1$ - SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11); - for (int i = 0; i < max; i++) - indexedFileNames.put(paths[i], DELETED); - for (Enumeration e = zip.entries(); e.hasMoreElements();) { - // iterate each entry to index it - ZipEntry ze = (ZipEntry) e.nextElement(); - String zipEntryName = ze.getName(); - if (Util.isClassFileName(zipEntryName) && isValidPackageNameForClass(zipEntryName)) - // the class file may not be there if the package name is not valid - indexedFileNames.put(zipEntryName, EXISTS); - } - boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added - if (!needToReindex) { - Object[] valueTable = indexedFileNames.valueTable; - for (int i = 0, l = valueTable.length; i < l; i++) { - if (valueTable[i] == DELETED) { - needToReindex = true; // a file was deleted so re-index - break; - } - } - if (!needToReindex) { - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$ - + zip.getName() + " (" //$NON-NLS-1$ - + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ - this.manager.saveIndex(index); // to ensure its placed into the saved state - return true; - } - } - } - - // Index the jar for the first time or reindex the jar in case the previous index file has been corrupted - // index already existed: recreate it so that we forget about previous entries - SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); - if (!this.manager.resetIndex(this.containerPath)) { - // failed to recreate index, see 73330 - this.manager.removeIndex(this.containerPath); - return false; - } - index.separator = JAR_SEPARATOR; - IPath indexPath = null; - IndexLocation indexLocation; - if ((indexLocation = index.getIndexLocation()) != null) { - indexPath = new Path(indexLocation.getCanonicalFilePath()); - } - for (Enumeration e = zip.entries(); e.hasMoreElements();) { - if (this.isCancelled) { - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ - return false; - } - - // iterate each entry to index it - ZipEntry ze = (ZipEntry) e.nextElement(); - String zipEntryName = ze.getName(); - if (Util.isClassFileName(zipEntryName) && - isValidPackageNameForClass(zipEntryName)) { - // index only classes coming from valid packages - https://bugs.eclipse.org/bugs/show_bug.cgi?id=293861 - final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); - JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); - this.manager.indexDocument(entryDocument, participant, index, indexPath); - } - } - this.manager.saveIndex(index); - if (JobManager.VERBOSE) - org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$ - + zip.getName() + " (" //$NON-NLS-1$ - + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ - } finally { - if (zip != null) { - if (JavaModelManager.ZIP_ACCESS_VERBOSE) - System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Closing ZipFile " + zip); //$NON-NLS-1$ //$NON-NLS-2$ - zip.close(); - } - monitor.exitWrite(); // free write lock - } + result = this.populateIndex(index, progressMonitor); } catch (IOException e) { if (JobManager.VERBOSE) { org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ e.printStackTrace(); } this.manager.removeIndex(this.containerPath); - return false; } - return true; + return result; } + public String getJobFamily() { if (this.resource != null) return super.getJobFamily(); return this.containerPath.toOSString(); // external jar } + + private boolean createOrUpdatePreBuiltIndex(final IProgressMonitor progressMonitor) throws IOException { + + boolean success = false; + if(this.updateIndexIfNecessary || !this.indexFileURL.getIndexFile().exists()) { + // construct a new index and populate the contents + String containerPathString = this.containerPath.getDevice() == null ? this.containerPath.toString() + : this.containerPath.toOSString(); + Index newIndex = null; + try { + newIndex = new Index(this.indexFileURL, containerPathString, false); + this.populateIndex(newIndex, progressMonitor); + } catch (IOException e) { + if (JobManager.VERBOSE) { + org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to create index for " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + this.manager.removeIndex(this.containerPath); + } + // add this index to the indexmanager + if(newIndex != null) { + success = this.manager.addIndex(this.containerPath, newIndex); + } + } + else { + // add the index as-is to the manager + success = this.manager.addIndex(this.containerPath, this.indexFileURL); + } + if(!success && JobManager.VERBOSE) { + org.eclipse.jdt.internal.core.util.Util.verbose("-> pre-build index could not be updated for " + this.containerPath); //$NON-NLS-1$ + } + return success; + } + + private boolean populateIndex(final Index index, final IProgressMonitor progressMonitor) throws IOException { + + ReadWriteMonitor monitor = index.monitor; + if (monitor == null) { + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> index for " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$ + return true; // index got deleted since acquired + } + index.separator = JAR_SEPARATOR; + ZipFile zip = null; + try { + // this path will be a relative path to the workspace in case the zipfile in the workspace otherwise it will be a path in the + // local file system + Path zipFilePath = null; + + monitor.enterWrite(); // ask permission to write + if (this.resource != null) { + URI location = this.resource.getLocationURI(); + if (location == null) return false; + if (JavaModelManager.ZIP_ACCESS_VERBOSE) + System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$ //$NON-NLS-2$ + File file = null; + try { + file = org.eclipse.jdt.internal.core.util.Util.toLocalFile(location, progressMonitor); + } catch (CoreException e) { + if (JobManager.VERBOSE) { + org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + } + if (file == null) { + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because the file could not be fetched"); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + zip = new ZipFile(file); + zipFilePath = (Path) this.resource.getFullPath().makeRelative(); + // absolute path relative to the workspace + } else { + if (JavaModelManager.ZIP_ACCESS_VERBOSE) + System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$ + // external file -> it is ok to use toFile() + zip = new ZipFile(this.containerPath.toFile()); + zipFilePath = (Path) this.containerPath; + // path is already canonical since coming from a library classpath entry + } + + if (this.isCancelled) { + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing " + zip.getName()); //$NON-NLS-1$ + long initialTime = System.currentTimeMillis(); + + String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$ + if (paths != null) { + int max = paths.length; + /* check integrity of the existing index file + * if the length is equal to 0, we want to index the whole jar again + * If not, then we want to check that there is no missing entry, if + * one entry is missing then we recreate the index + */ + String EXISTS = "OK"; //$NON-NLS-1$ + String DELETED = "DELETED"; //$NON-NLS-1$ + SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11); + for (int i = 0; i < max; i++) + indexedFileNames.put(paths[i], DELETED); + for (Enumeration e = zip.entries(); e.hasMoreElements();) { + // iterate each entry to index it + ZipEntry ze = (ZipEntry) e.nextElement(); + String zipEntryName = ze.getName(); + if (Util.isClassFileName(zipEntryName) && isValidPackageNameForClass(zipEntryName)) + // the class file may not be there if the package name is not valid + indexedFileNames.put(zipEntryName, EXISTS); + } + boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added + if (!needToReindex) { + Object[] valueTable = indexedFileNames.valueTable; + for (int i = 0, l = valueTable.length; i < l; i++) { + if (valueTable[i] == DELETED) { + needToReindex = true; // a file was deleted so re-index + break; + } + } + if (!needToReindex) { + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$ + + zip.getName() + " (" //$NON-NLS-1$ + + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ + this.manager.saveIndex(index); // to ensure its placed into the saved state + return true; + } + } + } + + // Index the jar for the first time or reindex the jar in case the previous index file has been corrupted + // index already existed: recreate it so that we forget about previous entries + SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); + if (!this.manager.resetIndex(this.containerPath)) { + // failed to recreate index, see 73330 + this.manager.removeIndex(this.containerPath); + return false; + } + index.separator = JAR_SEPARATOR; + IPath indexPath = null; + IndexLocation indexLocation; + if ((indexLocation = index.getIndexLocation()) != null) { + indexPath = new Path(indexLocation.getCanonicalFilePath()); + } + for (Enumeration e = zip.entries(); e.hasMoreElements();) { + if (this.isCancelled) { + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$ + return false; + } + + // iterate each entry to index it + ZipEntry ze = (ZipEntry) e.nextElement(); + String zipEntryName = ze.getName(); + if (Util.isClassFileName(zipEntryName) && + isValidPackageNameForClass(zipEntryName)) { + // index only classes coming from valid packages - https://bugs.eclipse.org/bugs/show_bug.cgi?id=293861 + final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); + JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); + this.manager.indexDocument(entryDocument, participant, index, indexPath); + } + } + this.manager.saveIndex(index); + if (JobManager.VERBOSE) + org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$ + + zip.getName() + " (" //$NON-NLS-1$ + + (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$ + } finally { + if (zip != null) { + if (JavaModelManager.ZIP_ACCESS_VERBOSE) + System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Closing ZipFile " + zip); //$NON-NLS-1$ //$NON-NLS-2$ + zip.close(); + } + monitor.exitWrite(); // free write lock + } + return true; + } + private boolean isIdentifier() throws InvalidInputException { switch(this.scanner.scanIdentifier()) { // assert and enum will not be recognized as java identifiers 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..18961ac 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 @@ -70,6 +70,21 @@ // Debug public static boolean DEBUG = false; + private Boolean manageUserIndexes = null; + + public synchronized boolean isManageUserIndexes() { + + if (this.manageUserIndexes == null) { + String manageIndexPropertyValue = JavaCore.getOption(JavaCore.UPDATE_PRODUCT_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 @@ -493,20 +508,32 @@ if (!isJobWaiting(request)) request(request); } + /** * 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) { + + 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, final boolean forceUpdate) { // requestingProject is no longer used to cancel jobs but leave it here just in case IndexLocation indexFile = indexURL != null ? IndexLocation.createIndexLocation(indexURL): null; if (JavaCore.getPlugin() == null) return; IndexRequest request = null; Object target = JavaModel.getTarget(path, true); + // bug395897: work-around to enable any pre-built indexes to be regenerated + boolean updateIndex = this.isManageUserIndexes() && forceUpdate; if (target instanceof IFile) { - request = new AddJarFileToIndex((IFile) target, indexFile, this); + request = new AddJarFileToIndex((IFile) target, indexFile, this, updateIndex); } else if (target instanceof File) { - request = new AddJarFileToIndex(path, indexFile, this); + request = new AddJarFileToIndex(path, indexFile, this, updateIndex); } else if (target instanceof IContainer) { request = new IndexBinaryFolder((IContainer) target, this); } else { @@ -518,6 +545,18 @@ request(request); } +synchronized boolean addIndex(final IPath containerPath, final Index index) { + + boolean result = false; + if((index != null) && (containerPath != null)) { + getIndexStates().put(index.getIndexLocation(), REUSE_STATE); + this.indexLocations.put(containerPath, index.getIndexLocation()); // TODO + result = true; + } + writeIndexMapFile(); + return result; +} + synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) { getIndexStates().put(indexFile, REUSE_STATE); this.indexLocations.put(containerPath, indexFile);