001: /*******************************************************************************
002: * Copyright (c) 2003, 2004 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.core.indexsearch;
011:
012: import java.io.IOException;
013: import java.util.*;
014: import java.util.Iterator;
015:
016: import org.eclipse.core.resources.*;
017: import org.eclipse.core.resources.IFile;
018: import org.eclipse.core.resources.ResourcesPlugin;
019: import org.eclipse.core.runtime.*;
020: import org.eclipse.core.runtime.IPath;
021: import org.eclipse.core.runtime.IProgressMonitor;
022: import org.eclipse.core.runtime.SubProgressMonitor;
023:
024: /**
025: * A <code>SearchEngine</code> searches for java elements following a search pattern.
026: * <p>
027: * This class may be instantiated; it is not intended to be subclassed.
028: */
029: public class SearchEngine {
030:
031: static class MyIndex implements IIndex {
032:
033: private HashMap fMap = new HashMap();
034:
035: public void addRef(String word, String path) {
036: System.err.println("Index.add: " + path + " " + word); //$NON-NLS-1$ //$NON-NLS-2$
037: HashMap words = (HashMap) fMap.get(path);
038: if (words == null) {
039: words = new HashMap();
040: fMap.put(path, words);
041: }
042: words.put(word, word);
043: }
044:
045: public void remove(String path) {
046: System.err.println("Index.remove: " + path); //$NON-NLS-1$
047: fMap.remove(path);
048: }
049:
050: public void queryPrefix(HashSet results, String w) {
051: Iterator iter = fMap.keySet().iterator();
052: while (iter.hasNext()) {
053: String path = (String) iter.next();
054: HashMap words = (HashMap) fMap.get(path);
055: if (words.containsKey(w))
056: results.add(path);
057: }
058: }
059: }
060:
061: /* Waiting policies */
062: /**
063: * The search operation throws an <code>org.eclipse.core.runtime.OperationCanceledException</code>
064: * if the underlying indexer has not finished indexing the workspace.
065: */
066: public static int CANCEL_IF_NOT_READY_TO_SEARCH = 0;
067: /**
068: * The search operation waits for the underlying indexer to finish indexing
069: * the workspace before starting the search.
070: */
071: public static int WAIT_UNTIL_READY_TO_SEARCH = 1;
072:
073: private static SearchEngine fgSearchEngine;
074:
075: private HashMap fIndexes = new HashMap();
076:
077: private SearchEngine() {
078: }
079:
080: /**
081: *
082: * @return
083: */
084: public static SearchEngine getSearchEngine() {
085: if (fgSearchEngine == null)
086: fgSearchEngine = new SearchEngine();
087: return fgSearchEngine;
088: }
089:
090: /**
091: * Trigger removal of a resource to an index
092: * Note: the actual operation is performed in background
093: */
094: public void remove(String resourceName, IPath indexedContainer) {
095: IIndex index = getIndex(indexedContainer, false);
096: if (index != null)
097: index.remove(resourceName);
098: }
099:
100: public void add(IPath indexedContainer, IIndexer indexer) {
101: IIndex index = getIndex(indexedContainer, true);
102: try {
103: indexer.index(index);
104: } catch (IOException e) {
105: }
106: }
107:
108: /**
109: * Returns the files that correspond to the paths that have been collected.
110: * TODO_SEARCH
111: */
112: private IFile[] getFiles(HashSet pc, IWorkspace workspace) {
113: IFile[] result = new IFile[pc.size()];
114: int i = 0;
115: for (Iterator iter = pc.iterator(); iter.hasNext();) {
116: String resourcePath = (String) iter.next();
117: IPath path = new Path(resourcePath);
118: result[i++] = workspace.getRoot().getFile(path);
119: }
120: return result;
121: }
122:
123: /**
124: * Perform the given query against the index and return results via the resultCollector.
125: */
126: public void search(IIndexQuery search,
127: ISearchResultCollector resultCollector,
128: IProgressMonitor progressMonitor, int waitingPolicy) {
129:
130: HashSet pathCollector = new HashSet();
131: IProgressMonitor pm = progressMonitor == null ? null
132: : new SubProgressMonitor(progressMonitor, 5);
133: execute(search, pathCollector, pm);
134:
135: /* TODO_SEARCH */
136: IFile[] files = getFiles(pathCollector, ResourcesPlugin
137: .getWorkspace());
138: for (int i = 0; i < files.length; i++) {
139: IFile file = files[i];
140: search.locateMatches(file, resultCollector);
141: }
142: }
143:
144: public IIndex getIndex(IPath indexPath, boolean create) {
145: IIndex ix = (IIndex) fIndexes.get(indexPath);
146: if (create && ix == null) {
147: ix = new MyIndex();
148: fIndexes.put(indexPath, ix);
149: }
150: return ix;
151: }
152:
153: private boolean execute(IIndexQuery search, HashSet pathCollector,
154: IProgressMonitor progressMonitor) {
155:
156: if (progressMonitor != null && progressMonitor.isCanceled())
157: throw new OperationCanceledException();
158: boolean isComplete = true;
159: IIndex[] searchIndexes = getIndexes(search);
160: try {
161: int max = searchIndexes.length;
162: if (progressMonitor != null) {
163: progressMonitor.beginTask("", max); //$NON-NLS-1$
164: }
165: for (int i = 0; i < max; i++) {
166: isComplete &= search(search, searchIndexes[i],
167: pathCollector, progressMonitor);
168: if (progressMonitor != null) {
169: if (progressMonitor.isCanceled()) {
170: throw new OperationCanceledException();
171: } else {
172: progressMonitor.worked(1);
173: }
174: }
175: }
176: return isComplete;
177: } finally {
178: if (progressMonitor != null) {
179: progressMonitor.done();
180: }
181: }
182: }
183:
184: private IIndex[] getIndexes(IIndexQuery search) {
185: IPath[] fIndexKeys = null; // cache of the keys for looking index up
186: if (fIndexKeys == null) {
187: ArrayList requiredIndexKeys = new ArrayList();
188: search.computePathsKeyingIndexFiles(requiredIndexKeys);
189: fIndexKeys = new IPath[requiredIndexKeys.size()];
190: requiredIndexKeys.toArray(fIndexKeys);
191: }
192: // acquire the in-memory indexes on the fly
193: int length = fIndexKeys.length;
194: IIndex[] indexes = new IIndex[length];
195: int count = 0;
196: for (int i = 0; i < length; i++) {
197: // may trigger some index recreation work
198: IIndex index = getIndex(fIndexKeys[i], false);
199: if (index != null)
200: indexes[count++] = index; // only consider indexes which are ready yet
201: }
202: if (count != length) {
203: System.arraycopy(indexes, 0, indexes = new IIndex[count],
204: 0, count);
205: }
206: return indexes;
207: }
208:
209: private boolean search(IIndexQuery search, IIndex index,
210: HashSet pathCollector, IProgressMonitor progressMonitor) {
211:
212: if (progressMonitor != null && progressMonitor.isCanceled())
213: throw new OperationCanceledException();
214:
215: if (index == null)
216: return true;
217: try {
218: search.findIndexMatches(index, pathCollector,
219: progressMonitor);
220: return true;
221: } catch (IOException e) {
222: return false;
223: }
224: }
225: }
|