| /******************************************************************************* |
| * Copyright (c) 2003, 2004 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.core.indexsearch; |
| |
| import java.io.IOException; |
| import java.util.*; |
| import java.util.Iterator; |
| |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| |
| /** |
| * A <code>SearchEngine</code> searches for java elements following a search pattern. |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| */ |
| public class SearchEngine { |
| |
| static class MyIndex implements IIndex { |
| |
| private HashMap fMap= new HashMap(); |
| |
| public void addRef(String word, String path) { |
| System.err.println("Index.add: " + path + " " + word); //$NON-NLS-1$ //$NON-NLS-2$ |
| HashMap words= (HashMap) fMap.get(path); |
| if (words == null) { |
| words= new HashMap(); |
| fMap.put(path, words); |
| } |
| words.put(word, word); |
| } |
| |
| public void remove(String path) { |
| System.err.println("Index.remove: " + path); //$NON-NLS-1$ |
| fMap.remove(path); |
| } |
| |
| public void queryPrefix(HashSet results, String w) { |
| Iterator iter= fMap.keySet().iterator(); |
| while (iter.hasNext()) { |
| String path= (String) iter.next(); |
| HashMap words= (HashMap) fMap.get(path); |
| if (words.containsKey(w)) |
| results.add(path); |
| } |
| } |
| } |
| |
| /* Waiting policies */ |
| /** |
| * The search operation throws an <code>org.eclipse.core.runtime.OperationCanceledException</code> |
| * if the underlying indexer has not finished indexing the workspace. |
| */ |
| public static int CANCEL_IF_NOT_READY_TO_SEARCH = 0; |
| /** |
| * The search operation waits for the underlying indexer to finish indexing |
| * the workspace before starting the search. |
| */ |
| public static int WAIT_UNTIL_READY_TO_SEARCH = 1; |
| |
| |
| private static SearchEngine fgSearchEngine; |
| |
| private HashMap fIndexes= new HashMap(); |
| |
| private SearchEngine() { |
| } |
| |
| /** |
| * |
| * @return |
| */ |
| public static SearchEngine getSearchEngine() { |
| if (fgSearchEngine == null) |
| fgSearchEngine= new SearchEngine(); |
| return fgSearchEngine; |
| } |
| |
| /** |
| * Trigger removal of a resource to an index |
| * Note: the actual operation is performed in background |
| */ |
| public void remove(String resourceName, IPath indexedContainer) { |
| IIndex index= getIndex(indexedContainer, false); |
| if (index != null) |
| index.remove(resourceName); |
| } |
| |
| public void add(IPath indexedContainer, IIndexer indexer) { |
| IIndex index= getIndex(indexedContainer, true); |
| try { |
| indexer.index(index); |
| } catch (IOException e) { |
| } |
| } |
| |
| /** |
| * Returns the files that correspond to the paths that have been collected. |
| * TODO_SEARCH |
| */ |
| private IFile[] getFiles(HashSet pc, IWorkspace workspace) { |
| IFile[] result= new IFile[pc.size()]; |
| int i = 0; |
| for (Iterator iter= pc.iterator(); iter.hasNext();) { |
| String resourcePath= (String)iter.next(); |
| IPath path= new Path(resourcePath); |
| result[i++]= workspace.getRoot().getFile(path); |
| } |
| return result; |
| } |
| |
| /** |
| * Perform the given query against the index and return results via the resultCollector. |
| */ |
| public void search(IIndexQuery search, ISearchResultCollector resultCollector, |
| IProgressMonitor progressMonitor, int waitingPolicy) { |
| |
| HashSet pathCollector= new HashSet(); |
| IProgressMonitor pm= progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 5); |
| execute(search, pathCollector, pm); |
| |
| /* TODO_SEARCH */ |
| IFile[] files= getFiles(pathCollector, ResourcesPlugin.getWorkspace()); |
| for (int i= 0; i < files.length; i++) { |
| IFile file= files[i]; |
| search.locateMatches(file, resultCollector); |
| } |
| } |
| |
| public IIndex getIndex(IPath indexPath, boolean create) { |
| IIndex ix= (IIndex) fIndexes.get(indexPath); |
| if (create && ix == null) { |
| ix= new MyIndex(); |
| fIndexes.put(indexPath, ix); |
| } |
| return ix; |
| } |
| |
| private boolean execute(IIndexQuery search, HashSet pathCollector, IProgressMonitor progressMonitor) { |
| |
| if (progressMonitor != null && progressMonitor.isCanceled()) |
| throw new OperationCanceledException(); |
| boolean isComplete= true; |
| IIndex[] searchIndexes= getIndexes(search); |
| try { |
| int max= searchIndexes.length; |
| if (progressMonitor != null) { |
| progressMonitor.beginTask("", max); //$NON-NLS-1$ |
| } |
| for (int i = 0; i < max; i++) { |
| isComplete &= search(search, searchIndexes[i], pathCollector, progressMonitor); |
| if (progressMonitor != null) { |
| if (progressMonitor.isCanceled()) { |
| throw new OperationCanceledException(); |
| } else { |
| progressMonitor.worked(1); |
| } |
| } |
| } |
| return isComplete; |
| } finally { |
| if (progressMonitor != null) { |
| progressMonitor.done(); |
| } |
| } |
| } |
| |
| private IIndex[] getIndexes(IIndexQuery search) { |
| IPath[] fIndexKeys= null; // cache of the keys for looking index up |
| if (fIndexKeys == null) { |
| ArrayList requiredIndexKeys= new ArrayList(); |
| search.computePathsKeyingIndexFiles(requiredIndexKeys); |
| fIndexKeys= new IPath[requiredIndexKeys.size()]; |
| requiredIndexKeys.toArray(fIndexKeys); |
| } |
| // acquire the in-memory indexes on the fly |
| int length = fIndexKeys.length; |
| IIndex[] indexes = new IIndex[length]; |
| int count = 0; |
| for (int i = 0; i < length; i++){ |
| // may trigger some index recreation work |
| IIndex index = getIndex(fIndexKeys[i], false); |
| if (index != null) indexes[count++] = index; // only consider indexes which are ready yet |
| } |
| if (count != length) { |
| System.arraycopy(indexes, 0, indexes= new IIndex[count], 0, count); |
| } |
| return indexes; |
| } |
| |
| private boolean search(IIndexQuery search, IIndex index, HashSet pathCollector, IProgressMonitor progressMonitor) { |
| |
| if (progressMonitor != null && progressMonitor.isCanceled()) |
| throw new OperationCanceledException(); |
| |
| if (index == null) |
| return true; |
| try { |
| search.findIndexMatches(index, pathCollector, progressMonitor); |
| return true; |
| } catch (IOException e) { |
| return false; |
| } |
| } |
| } |