blob: 0747b8bc271598f1faa573f6357fd48a88783270 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 xored software, Inc.
*
* 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:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.core.search.indexing.core;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.core.internal.environment.EFSFileHandle;
import org.eclipse.dltk.core.search.index.Index;
import org.eclipse.dltk.core.search.indexing.AbstractJob;
import org.eclipse.dltk.core.search.indexing.IProjectIndexer;
import org.eclipse.dltk.core.search.indexing.ReadWriteMonitor;
import org.eclipse.dltk.core.search.indexing.IProjectIndexer.Internal;
abstract class IndexRequest extends AbstractJob {
private IProjectIndexer indexer;
public IndexRequest(IProjectIndexer indexer) {
this.indexer = indexer;
}
public IProjectIndexer.Internal getIndexer() {
return (Internal) indexer;
}
/**
* Returns the document names that starts with the given substring, if
* <code>null</code> then returns all of them. Read lock is acquired
* automatically.
*
* @param index
* @return
* @throws IOException
*/
protected String[] queryDocumentNames(final Index index) throws IOException {
final ReadWriteMonitor monitor = index.monitor;
monitor.enterRead();
try {
return index.queryDocumentNames(null);
} finally {
monitor.exitRead();
}
}
protected Map collectSourceModulePaths(Collection modules,
IPath containerPath) {
final Map paths = new HashMap();
for (Iterator i = modules.iterator(); i.hasNext();) {
final ISourceModule module = (ISourceModule) i.next();
paths.put(SourceIndexUtil.containerRelativePath(containerPath,
module), module);
}
return paths;
}
/**
* Check changes of the specified modules compared to the index. Returns the
* {@link List} of changes. List items could be {@link String} if that
* document should be removed from the index or ISourceModule if that module
* should be indexed. If there are no changes the empty {@link List} is
* returned. If <code>environment</code> is specified then it is used to
* retrieve the modification time of the files to compare with the
* modification time of the index.
*
* @param index
* @param modules
* @param containerPath
* @param environment
* could be <code>null</code>
* @return
* @throws ModelException
* @throws IOException
*/
protected List checkChanges(Index index, Collection modules,
IPath containerPath, IEnvironment environment)
throws ModelException, IOException {
final String[] documents = queryDocumentNames(index);
if (documents != null && documents.length != 0) {
final long indexLastModified = index.getIndexFile().lastModified();
final List changes = new ArrayList();
final Map m = collectSourceModulePaths(modules, containerPath);
if (DEBUG) {
log("documents.length=" + documents.length); //$NON-NLS-1$
log("modules.size=" + modules.size()); //$NON-NLS-1$
log("map.size=" + m.size()); //$NON-NLS-1$
}
for (int i = 0; i < documents.length; ++i) {
final String document = documents[i];
final ISourceModule module = (ISourceModule) m.remove(document);
if (module == null) {
changes.add(document);
} else if (environment != null) {
// final IFileHandle handle = environment
// .getFile(EnvironmentPathUtils.getLocalPath(module
// .getPath()));
IFileHandle handle = EnvironmentPathUtils.getFile(module);
long lmodif = 0;
if (handle instanceof EFSFileHandle) {
lmodif = ((EFSFileHandle) handle)
.lastModifiedFromCache();
} else {
lmodif = handle.lastModified();
}
if (handle != null && lmodif > indexLastModified) {
changes.add(module);
}
}
}
if (!m.isEmpty()) {
changes.addAll(m.values());
}
return changes;
} else {
return new ArrayList(modules);
}
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((indexer == null) ? 0 : indexer.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IndexRequest other = (IndexRequest) obj;
if (indexer == null) {
if (other.indexer != null)
return false;
} else if (!indexer.equals(other.indexer))
return false;
return true;
}
}