001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.jdt.core.search;
011:
012: import org.eclipse.core.resources.IResource;
013: import org.eclipse.core.resources.IWorkspaceRoot;
014: import org.eclipse.core.resources.ResourcesPlugin;
015: import org.eclipse.core.runtime.*;
016: import org.eclipse.jdt.internal.core.JavaModel;
017: import org.eclipse.jdt.internal.core.JavaModelManager;
018: import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
019:
020: /**
021: * A search participant describes a particular extension to a generic search
022: * mechanism, permitting combined search actions which will involve all required
023: * participants.
024: * <p>
025: * A search participant is involved in the indexing phase and in the search phase.
026: * The indexing phase consists in taking one or more search documents, parse them, and
027: * add index entries in an index chosen by the participant. An index is identified by a
028: * path on disk.
029: * The search phase consists in selecting the indexes corresponding to a search pattern
030: * and a search scope, from these indexes the search infrastructure extracts the document paths
031: * that match the search pattern asking the search participant for the corresponding document,
032: * finally the search participant is asked to locate the matches precisely in these search documents.
033: * </p>
034: * <p>
035: * This class is intended to be subclassed by clients. During the indexing phase,
036: * a subclass will be called with the following requests in order:
037: * <ul>
038: * <li>{@link #scheduleDocumentIndexing(SearchDocument, IPath)}</li>
039: * <li>{@link #indexDocument(SearchDocument, IPath)}</li>
040: * </ul>
041: * During the search phase, a subclass will be called with the following requests in order:
042: * <ul>
043: * <li>{@link #selectIndexes(SearchPattern, IJavaSearchScope)}</li>
044: * <li>one or more {@link #getDocument(String)}</li>
045: * <li>{@link #locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor)}</li>
046: * </ul>
047: * </p>
048: *
049: * @since 3.0
050: */
051: public abstract class SearchParticipant {
052:
053: /**
054: * Creates a new search participant.
055: */
056: protected SearchParticipant() {
057: // do nothing
058: }
059:
060: /**
061: * Notification that this participant's help is needed in a search.
062: * <p>
063: * This method should be re-implemented in subclasses that need to do something
064: * when the participant is needed in a search.
065: * </p>
066: */
067: public void beginSearching() {
068: // do nothing
069: }
070:
071: /**
072: * Notification that this participant's help is no longer needed.
073: * <p>
074: * This method should be re-implemented in subclasses that need to do something
075: * when the participant is no longer needed in a search.
076: * </p>
077: */
078: public void doneSearching() {
079: // do nothing
080: }
081:
082: /**
083: * Returns a displayable name of this search participant.
084: * <p>
085: * This method should be re-implemented in subclasses that need to
086: * display a meaningfull name.
087: * </p>
088: *
089: * @return the displayable name of this search participant
090: */
091: public String getDescription() {
092: return "Search participant"; //$NON-NLS-1$
093: }
094:
095: /**
096: * Returns a search document for the given path.
097: * The given document path is a string that uniquely identifies the document.
098: * Most of the time it is a workspace-relative path, but it can also be a file system path, or a path inside a zip file.
099: * <p>
100: * Implementors of this method can either create an instance of their own subclass of
101: * {@link SearchDocument} or return an existing instance of such a subclass.
102: * </p>
103: *
104: * @param documentPath the path of the document.
105: * @return a search document
106: */
107: public abstract SearchDocument getDocument(String documentPath);
108:
109: /**
110: * Indexes the given document in the given index. A search participant
111: * asked to index a document should parse it and call
112: * {@link SearchDocument#addIndexEntry(char[], char[])} as many times as
113: * needed to add index entries to the index. If delegating to another
114: * participant, it should use the original index location (and not the
115: * delegatee's one). In the particular case of delegating to the default
116: * search participant (see {@link SearchEngine#getDefaultSearchParticipant()}),
117: * the provided document's path must be a path ending with one of the
118: * {@link org.eclipse.jdt.core.JavaCore#getJavaLikeExtensions() Java-like extensions}
119: * or with '.class'.
120: * <p>
121: * The given index location must represent a path in the file system to a file that
122: * either already exists or is going to be created. If it exists, it must be an index file,
123: * otherwise its data might be overwritten.
124: * </p><p>
125: * Clients are not expected to call this method.
126: * </p>
127: *
128: * @param document the document to index
129: * @param indexLocation the location in the file system to the index
130: */
131: public abstract void indexDocument(SearchDocument document,
132: IPath indexLocation);
133:
134: /**
135: * Locates the matches in the given documents using the given search pattern
136: * and search scope, and reports them to the givenn search requestor. This
137: * method is called by the search engine once it has search documents
138: * matching the given pattern in the given search scope.
139: * <p>
140: * Note that a participant (e.g. a JSP participant) can pre-process the contents of the given documents,
141: * create its own documents whose contents are Java compilation units and delegate the match location
142: * to the default participant (see {@link SearchEngine#getDefaultSearchParticipant()}). Passing its own
143: * {@link SearchRequestor} this particpant can then map the match positions back to the original
144: * contents, create its own matches and report them to the original requestor.
145: * </p><p>
146: * Implementors of this method should check the progress monitor
147: * for cancelation when it is safe and appropriate to do so. The cancelation
148: * request should be propagated to the caller by throwing
149: * <code>OperationCanceledException</code>.
150: * </p>
151: *
152: * @param documents the documents to locate matches in
153: * @param pattern the search pattern to use when locating matches
154: * @param scope the scope to limit the search to
155: * @param requestor the requestor to report matches to
156: * @param monitor the progress monitor to report progress to,
157: * or <code>null</code> if no progress should be reported
158: * @throws CoreException if the requestor had problem accepting one of the matches
159: */
160: public abstract void locateMatches(SearchDocument[] documents,
161: SearchPattern pattern, IJavaSearchScope scope,
162: SearchRequestor requestor, IProgressMonitor monitor)
163: throws CoreException;
164:
165: /**
166: * Removes the index for a given path.
167: * <p>
168: * The given index location must represent a path in the file system to a file that
169: * already exists and must be an index file, otherwise nothing will be done.
170: * </p><p>
171: * It is strongly recommended to use this method instead of deleting file directly
172: * otherwise cached index will not be removed.
173: * </p>
174: *
175: * @param indexLocation the location in the file system to the index
176: * @since 3.2
177: */
178: public void removeIndex(IPath indexLocation) {
179: IndexManager manager = JavaModelManager.getIndexManager();
180: manager.removeIndexPath(indexLocation);
181: }
182:
183: /**
184: * Schedules the indexing of the given document.
185: * Once the document is ready to be indexed,
186: * {@link #indexDocument(SearchDocument, IPath) indexDocument(document, indexPath)}
187: * will be called in a different thread than the caller's thread.
188: * <p>
189: * The given index location must represent a path in the file system to a file that
190: * either already exists or is going to be created. If it exists, it must be an index file,
191: * otherwise its data might be overwritten.
192: * </p><p>
193: * When the index is no longer needed, clients should use {@link #removeIndex(IPath) }
194: * to discard it.
195: * </p>
196: *
197: * @param document the document to index
198: * @param indexLocation the location on the file system of the index
199: */
200: public final void scheduleDocumentIndexing(SearchDocument document,
201: IPath indexLocation) {
202: IPath documentPath = new Path(document.getPath());
203: IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
204: Object file = JavaModel.getTarget(root, documentPath, true);
205: IPath containerPath = documentPath;
206: if (file instanceof IResource) {
207: containerPath = ((IResource) file).getProject()
208: .getFullPath();
209: } else if (file == null) {
210: containerPath = documentPath
211: .removeLastSegments(documentPath.segmentCount() - 1);
212: }
213: IndexManager manager = JavaModelManager.getIndexManager();
214: // TODO (frederic) should not have to create index manually, should expose API that recreates index instead
215: manager.ensureIndexExists(indexLocation, containerPath);
216: manager.scheduleDocumentIndexing(document, containerPath,
217: indexLocation, this );
218: }
219:
220: /**
221: * Returns the collection of index locations to consider when performing the
222: * given search query in the given scope. The search engine calls this
223: * method before locating matches.
224: * <p>
225: * An index location represents a path in the file system to a file that holds index information.
226: * </p><p>
227: * Clients are not expected to call this method.
228: * </p>
229: *
230: * @param query the search pattern to consider
231: * @param scope the given search scope
232: * @return the collection of index paths to consider
233: */
234: public abstract IPath[] selectIndexes(SearchPattern query,
235: IJavaSearchScope scope);
236: }
|