001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.internal.ui.search;
011:
012: import org.eclipse.core.runtime.CoreException;
013: import org.eclipse.core.runtime.IProgressMonitor;
014: import org.eclipse.core.runtime.ISafeRunnable;
015: import org.eclipse.core.runtime.IStatus;
016: import org.eclipse.core.runtime.PerformanceStats;
017: import org.eclipse.core.runtime.SafeRunner;
018: import org.eclipse.core.runtime.Status;
019: import org.eclipse.core.runtime.SubProgressMonitor;
020:
021: import org.eclipse.core.resources.IProject;
022: import org.eclipse.core.resources.IResource;
023:
024: import org.eclipse.jface.resource.ImageDescriptor;
025:
026: import org.eclipse.search.ui.ISearchQuery;
027: import org.eclipse.search.ui.ISearchResult;
028: import org.eclipse.search.ui.NewSearchUI;
029: import org.eclipse.search.ui.text.Match;
030:
031: import org.eclipse.jdt.core.IJavaElement;
032: import org.eclipse.jdt.core.search.IJavaSearchConstants;
033: import org.eclipse.jdt.core.search.SearchEngine;
034: import org.eclipse.jdt.core.search.SearchParticipant;
035: import org.eclipse.jdt.core.search.SearchPattern;
036:
037: import org.eclipse.jdt.internal.corext.util.Messages;
038: import org.eclipse.jdt.internal.corext.util.SearchUtils;
039:
040: import org.eclipse.jdt.ui.JavaElementLabels;
041: import org.eclipse.jdt.ui.search.ElementQuerySpecification;
042: import org.eclipse.jdt.ui.search.IMatchPresentation;
043: import org.eclipse.jdt.ui.search.IQueryParticipant;
044: import org.eclipse.jdt.ui.search.ISearchRequestor;
045: import org.eclipse.jdt.ui.search.PatternQuerySpecification;
046: import org.eclipse.jdt.ui.search.QuerySpecification;
047:
048: import org.eclipse.jdt.internal.ui.JavaPlugin;
049: import org.eclipse.jdt.internal.ui.JavaPluginImages;
050:
051: public class JavaSearchQuery implements ISearchQuery {
052:
053: private static final String PERF_SEARCH_PARTICIPANT = "org.eclipse.jdt.ui/perf/search/participants"; //$NON-NLS-1$
054:
055: private ISearchResult fResult;
056: private final QuerySpecification fPatternData;
057:
058: public JavaSearchQuery(QuerySpecification data) {
059: if (data == null) {
060: throw new IllegalArgumentException("data must not be null"); //$NON-NLS-1$
061: }
062: fPatternData = data;
063: }
064:
065: private static class SearchRequestor implements ISearchRequestor {
066: private IQueryParticipant fParticipant;
067: private JavaSearchResult fSearchResult;
068:
069: public void reportMatch(Match match) {
070: IMatchPresentation participant = fParticipant
071: .getUIParticipant();
072: if (participant == null
073: || match.getElement() instanceof IJavaElement
074: || match.getElement() instanceof IResource) {
075: fSearchResult.addMatch(match);
076: } else {
077: fSearchResult.addMatch(match, participant);
078: }
079: }
080:
081: protected SearchRequestor(IQueryParticipant participant,
082: JavaSearchResult result) {
083: super ();
084: fParticipant = participant;
085: fSearchResult = result;
086: }
087: }
088:
089: public IStatus run(IProgressMonitor monitor) {
090: final JavaSearchResult textResult = (JavaSearchResult) getSearchResult();
091: textResult.removeAll();
092: // Don't need to pass in working copies in 3.0 here
093: SearchEngine engine = new SearchEngine();
094: try {
095:
096: int totalTicks = 1000;
097: IProject[] projects = JavaSearchScopeFactory.getInstance()
098: .getProjects(fPatternData.getScope());
099: final SearchParticipantRecord[] participantDescriptors = SearchParticipantsExtensionPoint
100: .getInstance().getSearchParticipants(projects);
101: final int[] ticks = new int[participantDescriptors.length];
102: for (int i = 0; i < participantDescriptors.length; i++) {
103: final int iPrime = i;
104: ISafeRunnable runnable = new ISafeRunnable() {
105: public void handleException(Throwable exception) {
106: ticks[iPrime] = 0;
107: String message = SearchMessages.JavaSearchQuery_error_participant_estimate;
108: JavaPlugin.log(new Status(IStatus.ERROR,
109: JavaPlugin.getPluginId(), 0, message,
110: exception));
111: }
112:
113: public void run() throws Exception {
114: ticks[iPrime] = participantDescriptors[iPrime]
115: .getParticipant().estimateTicks(
116: fPatternData);
117: }
118: };
119:
120: SafeRunner.run(runnable);
121: totalTicks += ticks[i];
122: }
123:
124: SearchPattern pattern;
125: String stringPattern;
126:
127: if (fPatternData instanceof ElementQuerySpecification) {
128: IJavaElement element = ((ElementQuerySpecification) fPatternData)
129: .getElement();
130: stringPattern = JavaElementLabels.getElementLabel(
131: element, JavaElementLabels.ALL_DEFAULT);
132: if (!element.exists()) {
133: return new Status(
134: IStatus.ERROR,
135: JavaPlugin.getPluginId(),
136: 0,
137: Messages
138: .format(
139: SearchMessages.JavaSearchQuery_error_element_does_not_exist,
140: stringPattern), null);
141: }
142: pattern = SearchPattern.createPattern(element,
143: fPatternData.getLimitTo(),
144: SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
145: } else {
146: PatternQuerySpecification patternSpec = (PatternQuerySpecification) fPatternData;
147: stringPattern = patternSpec.getPattern();
148: int matchMode = getMatchMode(stringPattern)
149: | SearchPattern.R_ERASURE_MATCH;
150: if (patternSpec.isCaseSensitive())
151: matchMode |= SearchPattern.R_CASE_SENSITIVE;
152: pattern = SearchPattern.createPattern(patternSpec
153: .getPattern(), patternSpec.getSearchFor(),
154: patternSpec.getLimitTo(), matchMode);
155: }
156:
157: if (pattern == null) {
158: return new Status(
159: IStatus.ERROR,
160: JavaPlugin.getPluginId(),
161: 0,
162: Messages
163: .format(
164: SearchMessages.JavaSearchQuery_error_unsupported_pattern,
165: stringPattern), null);
166: }
167: monitor.beginTask(Messages.format(
168: SearchMessages.JavaSearchQuery_task_label,
169: stringPattern), totalTicks);
170: IProgressMonitor mainSearchPM = new SubProgressMonitor(
171: monitor, 1000);
172:
173: boolean ignorePotentials = NewSearchUI
174: .arePotentialMatchesIgnored();
175: NewSearchResultCollector collector = new NewSearchResultCollector(
176: textResult, ignorePotentials);
177:
178: engine.search(pattern,
179: new SearchParticipant[] { SearchEngine
180: .getDefaultSearchParticipant() },
181: fPatternData.getScope(), collector, mainSearchPM);
182: for (int i = 0; i < participantDescriptors.length; i++) {
183: final ISearchRequestor requestor = new SearchRequestor(
184: participantDescriptors[i].getParticipant(),
185: textResult);
186: final IProgressMonitor participantPM = new SubProgressMonitor(
187: monitor, ticks[i]);
188:
189: final int iPrime = i;
190: ISafeRunnable runnable = new ISafeRunnable() {
191: public void handleException(Throwable exception) {
192: participantDescriptors[iPrime].getDescriptor()
193: .disable();
194: String message = SearchMessages.JavaSearchQuery_error_participant_search;
195: JavaPlugin.log(new Status(IStatus.ERROR,
196: JavaPlugin.getPluginId(), 0, message,
197: exception));
198: }
199:
200: public void run() throws Exception {
201:
202: final IQueryParticipant participant = participantDescriptors[iPrime]
203: .getParticipant();
204:
205: final PerformanceStats stats = PerformanceStats
206: .getStats(PERF_SEARCH_PARTICIPANT,
207: participant);
208: stats.startRun();
209:
210: participant.search(requestor, fPatternData,
211: participantPM);
212:
213: stats.endRun();
214: }
215: };
216:
217: SafeRunner.run(runnable);
218: }
219:
220: } catch (CoreException e) {
221: return e.getStatus();
222: }
223: String message = Messages.format(
224: SearchMessages.JavaSearchQuery_status_ok_message,
225: String.valueOf(textResult.getMatchCount()));
226: return new Status(IStatus.OK, JavaPlugin.getPluginId(), 0,
227: message, null);
228: }
229:
230: private int getMatchMode(String pattern) {
231: if (pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1) {
232: return SearchPattern.R_PATTERN_MATCH;
233: } else if (SearchUtils.isCamelCasePattern(pattern)) {
234: return SearchPattern.R_CAMEL_CASE_MATCH
235: | SearchPattern.R_PREFIX_MATCH;
236: }
237: return SearchPattern.R_EXACT_MATCH;
238: }
239:
240: public String getLabel() {
241: return SearchMessages.JavaSearchQuery_label;
242: }
243:
244: public String getResultLabel(int nMatches) {
245: if (nMatches == 1) {
246: String[] args = { getSearchPatternDescription(),
247: fPatternData.getScopeDescription() };
248: switch (fPatternData.getLimitTo()) {
249: case IJavaSearchConstants.IMPLEMENTORS:
250: return Messages
251: .format(
252: SearchMessages.JavaSearchOperation_singularImplementorsPostfix,
253: args);
254: case IJavaSearchConstants.DECLARATIONS:
255: return Messages
256: .format(
257: SearchMessages.JavaSearchOperation_singularDeclarationsPostfix,
258: args);
259: case IJavaSearchConstants.REFERENCES:
260: return Messages
261: .format(
262: SearchMessages.JavaSearchOperation_singularReferencesPostfix,
263: args);
264: case IJavaSearchConstants.ALL_OCCURRENCES:
265: return Messages
266: .format(
267: SearchMessages.JavaSearchOperation_singularOccurrencesPostfix,
268: args);
269: case IJavaSearchConstants.READ_ACCESSES:
270: return Messages
271: .format(
272: SearchMessages.JavaSearchOperation_singularReadReferencesPostfix,
273: args);
274: case IJavaSearchConstants.WRITE_ACCESSES:
275: return Messages
276: .format(
277: SearchMessages.JavaSearchOperation_singularWriteReferencesPostfix,
278: args);
279: default:
280: return Messages
281: .format(
282: SearchMessages.JavaSearchOperation_singularOccurrencesPostfix,
283: args);
284: }
285: } else {
286: Object[] args = { getSearchPatternDescription(),
287: new Integer(nMatches),
288: fPatternData.getScopeDescription() };
289: switch (fPatternData.getLimitTo()) {
290: case IJavaSearchConstants.IMPLEMENTORS:
291: return Messages
292: .format(
293: SearchMessages.JavaSearchOperation_pluralImplementorsPostfix,
294: args);
295: case IJavaSearchConstants.DECLARATIONS:
296: return Messages
297: .format(
298: SearchMessages.JavaSearchOperation_pluralDeclarationsPostfix,
299: args);
300: case IJavaSearchConstants.REFERENCES:
301: return Messages
302: .format(
303: SearchMessages.JavaSearchOperation_pluralReferencesPostfix,
304: args);
305: case IJavaSearchConstants.ALL_OCCURRENCES:
306: return Messages
307: .format(
308: SearchMessages.JavaSearchOperation_pluralOccurrencesPostfix,
309: args);
310: case IJavaSearchConstants.READ_ACCESSES:
311: return Messages
312: .format(
313: SearchMessages.JavaSearchOperation_pluralReadReferencesPostfix,
314: args);
315: case IJavaSearchConstants.WRITE_ACCESSES:
316: return Messages
317: .format(
318: SearchMessages.JavaSearchOperation_pluralWriteReferencesPostfix,
319: args);
320: default:
321: return Messages
322: .format(
323: SearchMessages.JavaSearchOperation_pluralOccurrencesPostfix,
324: args);
325: }
326: }
327: }
328:
329: private String getSearchPatternDescription() {
330: if (fPatternData instanceof ElementQuerySpecification) {
331: IJavaElement element = ((ElementQuerySpecification) fPatternData)
332: .getElement();
333: return JavaElementLabels.getElementLabel(element,
334: JavaElementLabels.ALL_DEFAULT
335: | JavaElementLabels.ALL_FULLY_QUALIFIED
336: | JavaElementLabels.USE_RESOLVED);
337: }
338: return ((PatternQuerySpecification) fPatternData).getPattern();
339: }
340:
341: ImageDescriptor getImageDescriptor() {
342: if (fPatternData.getLimitTo() == IJavaSearchConstants.IMPLEMENTORS
343: || fPatternData.getLimitTo() == IJavaSearchConstants.DECLARATIONS)
344: return JavaPluginImages.DESC_OBJS_SEARCH_DECL;
345: else
346: return JavaPluginImages.DESC_OBJS_SEARCH_REF;
347: }
348:
349: public boolean canRerun() {
350: return true;
351: }
352:
353: public boolean canRunInBackground() {
354: return true;
355: }
356:
357: public ISearchResult getSearchResult() {
358: if (fResult == null) {
359: JavaSearchResult result = new JavaSearchResult(this );
360: new SearchResultUpdater(result);
361: fResult = result;
362: }
363: return fResult;
364: }
365:
366: QuerySpecification getSpecification() {
367: return fPatternData;
368: }
369: }
|