/*******************************************************************************
* Copyright (c) 2000, 2008 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.wst.jsdt.internal.core.search.indexing;
import java.io.File;
import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.jsdt.core.search.SearchEngine;
import org.eclipse.wst.jsdt.core.search.SearchParticipant;
import org.eclipse.wst.jsdt.internal.compiler.util.Util;
import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
import org.eclipse.wst.jsdt.internal.core.index.Index;
import org.eclipse.wst.jsdt.internal.core.search.JavaSearchDocument;
import org.eclipse.wst.jsdt.internal.core.search.processing.JobManager;
class AddLibraryFileToIndex extends IndexRequest {
IPath absolutePath;
public AddLibraryFileToIndex(IFile resource, IndexManager manager) {
super(resource.getFullPath(), manager);
this.absolutePath=resource.getLocation();
}
public AddLibraryFileToIndex(IPath jarPath, IndexManager manager) {
// external JAR scenario - no resource
super(jarPath, manager);
}
public boolean equals(Object o) {
if (o instanceof AddLibraryFileToIndex) {
if (this.containerPath != null)
return this.containerPath.equals(((AddLibraryFileToIndex) o).containerPath);
}
return false;
}
public int hashCode() {
if (this.containerPath != null)
return this.containerPath.hashCode();
return -1;
}
public boolean execute(IProgressMonitor progressMonitor) {
if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
try {
// if index is already cached, then do not perform any check
// MUST reset the IndexManager if a jar file is changed
Index index = this.manager.getIndexForUpdate(this.containerPath, false, /*do not reuse index file*/ false /*do not create if none*/);
if (index != null) {
if (JobManager.VERBOSE)
org.eclipse.wst.jsdt.internal.core.util.Util.verbose("-> no indexing required (index already exists) for " + this.containerPath); //$NON-NLS-1$
return true;
}
index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
if (index == null) {
if (JobManager.VERBOSE)
org.eclipse.wst.jsdt.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.wst.jsdt.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
}
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 libraryFilePath = null;
monitor.enterWrite(); // ask permission to write
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()
libraryFilePath = (Path) this.containerPath;
// path is already canonical since coming from a library classpath entry
if (this.isCancelled) {
if (JobManager.VERBOSE)
org.eclipse.wst.jsdt.internal.core.util.Util.verbose("-> indexing of " + libraryFilePath.toString() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
if (JobManager.VERBOSE)
org.eclipse.wst.jsdt.internal.core.util.Util.verbose("-> indexing " + libraryFilePath.toString()); //$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);
//
// if (Util.isClassFileName(libraryFilePath.toPortableString()))
// indexedFileNames.put(libraryFilePath.toPortableString(), 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.wst.jsdt.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();
index = manager.recreateIndex(this.containerPath);
if (index == null) {
// failed to recreate index, see 73330
manager.removeIndex(this.containerPath);
return false;
}
// for (Enumeration e = zip.entries(); e.hasMoreElements();) {
// if (this.isCancelled) {
// if (JobManager.VERBOSE)
// org.eclipse.wst.jsdt.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();
// if (Util.isClassFileName(ze.getName())) {
// final byte[] classFileBytes = org.eclipse.wst.jsdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
// JavaSearchDocument entryDocument = new JavaSearchDocument(ze, libraryFilePath, classFileBytes, participant);
// this.manager.indexDocument(entryDocument, participant, index, this.containerPath);
// }
// }
IPath filePath=(this.absolutePath!=null)?this.absolutePath : this.containerPath;
File file = new File(filePath.toOSString());
if (file.isFile())
indexFile(file, participant, index, libraryFilePath);
else
{
indexDirectory(file, participant, index, libraryFilePath);
}
this.manager.saveIndex(index);
if (JobManager.VERBOSE)
org.eclipse.wst.jsdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$
+ libraryFilePath.toString() + " (" //$NON-NLS-1$
+ (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$
} finally {
monitor.exitWrite(); // free write lock
}
} catch (IOException e) {
if (JobManager.VERBOSE) {
org.eclipse.wst.jsdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
e.printStackTrace();
}
manager.removeIndex(this.containerPath);
return false;
}
return true;
}
protected Integer updatedIndexState() {
return IndexManager.REBUILDING_STATE;
}
public String toString() {
return "indexing " + this.containerPath.toString(); //$NON-NLS-1$
}
private void indexFile(File file,SearchParticipant participant, Index index, IPath libraryFilePath)
{
try {
final char[] classFileChars = org.eclipse.wst.jsdt.internal.compiler.util.Util.getFileCharContent(file,null);
String packageName="";
JavaSearchDocument entryDocument = new JavaSearchDocument( new Path(file.getAbsolutePath()), classFileChars, participant,packageName);
this.manager.indexDocument(entryDocument, participant, index, this.containerPath);
} catch (Exception ex)
{}
}
private void indexDirectory(File file,SearchParticipant participant, Index index, IPath libraryFilePath)
{
File[] files = file.listFiles();
if (files!=null)
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory())
indexDirectory(files[i], participant, index, libraryFilePath);
else if (Util.isClassFileName(files[i].getName()))
indexFile(files[i], participant, index, libraryFilePath);
}
}
}