/******************************************************************************* * Copyright (c) 2000, 2017 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 * *******************************************************************************/ package org.eclipse.dltk.internal.ui.search; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PerformanceStats; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.dltk.core.IDLTKLanguageToolkit; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.search.IDLTKSearchConstants; import org.eclipse.dltk.core.search.SearchEngine; import org.eclipse.dltk.core.search.SearchParticipant; import org.eclipse.dltk.core.search.SearchPattern; import org.eclipse.dltk.internal.corext.util.Messages; import org.eclipse.dltk.internal.corext.util.SearchUtils; import org.eclipse.dltk.ui.DLTKPluginImages; import org.eclipse.dltk.ui.DLTKUIPlugin; import org.eclipse.dltk.ui.ScriptElementLabels; import org.eclipse.dltk.ui.search.ElementQuerySpecification; import org.eclipse.dltk.ui.search.IMatchPresentation; import org.eclipse.dltk.ui.search.IQueryParticipant; import org.eclipse.dltk.ui.search.ISearchRequestor; import org.eclipse.dltk.ui.search.PatternQuerySpecification; import org.eclipse.dltk.ui.search.QuerySpecification; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.search.ui.ISearchQuery; import org.eclipse.search.ui.ISearchResult; import org.eclipse.search.ui.NewSearchUI; import org.eclipse.search.ui.text.Match; public class DLTKSearchQuery implements ISearchQuery { private static final String PERF_SEARCH_PARTICIPANT= "org.eclipse.dltk.ui/perf/search/participants"; //$NON-NLS-1$ private ISearchResult fResult; private final QuerySpecification fPatternData; public DLTKSearchQuery(QuerySpecification data) { if (data == null) { throw new IllegalArgumentException("data must not be null"); //$NON-NLS-1$ } fPatternData= data; } private static class SearchRequestor implements ISearchRequestor { private IQueryParticipant fParticipant; private DLTKSearchResult fSearchResult; @Override public void reportMatch(Match match) { IMatchPresentation participant= fParticipant.getUIParticipant(); if (participant == null || match.getElement() instanceof IModelElement || match.getElement() instanceof IResource) { fSearchResult.addMatch(match); } else { fSearchResult.addMatch(match, participant); } } protected SearchRequestor(IQueryParticipant participant, DLTKSearchResult result) { super(); fParticipant= participant; fSearchResult= result; } } @Override public IStatus run(IProgressMonitor monitor) { final DLTKSearchResult textResult= (DLTKSearchResult) getSearchResult(); textResult.removeAll(); // Don't need to pass in working copies in 3.0 here SearchEngine engine= new SearchEngine(); try { int totalTicks= 1000; IProject[] projects= DLTKSearchScopeFactory.getInstance().getProjects(fPatternData.getScope()); final SearchParticipantRecord[] participantDescriptors = SearchParticipantsExtensionPoint .getInstance().getSearchParticipants(this.fPatternData.getScope().getLanguageToolkit(), projects); final int[] ticks= new int[participantDescriptors.length]; for (int i= 0; i < participantDescriptors.length; i++) { final int iPrime= i; ISafeRunnable runnable= new ISafeRunnable() { @Override public void handleException(Throwable exception) { ticks[iPrime]= 0; String message= SearchMessages.DLTKSearchQuery_error_participant_estimate; DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, exception)); } @Override public void run() throws Exception { ticks[iPrime]= participantDescriptors[iPrime].getParticipant().estimateTicks(fPatternData); } }; SafeRunner.run(runnable); totalTicks+= ticks[i]; } SearchPattern pattern; String stringPattern; IDLTKLanguageToolkit toolkit = this.fPatternData.getScope().getLanguageToolkit(); if (fPatternData instanceof ElementQuerySpecification) { IModelElement element= ((ElementQuerySpecification) fPatternData).getElement(); stringPattern= ScriptElementLabels.getDefault().getElementLabel(element, ScriptElementLabels.ALL_DEFAULT); if (!element.exists()) { return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, Messages.format(SearchMessages.DLTKSearchQuery_error_element_does_not_exist, stringPattern), null); } pattern= SearchPattern.createPattern(element, fPatternData.getLimitTo(), SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE, toolkit); } else { PatternQuerySpecification patternSpec = (PatternQuerySpecification) fPatternData; stringPattern= patternSpec.getPattern(); int matchMode= getMatchMode(stringPattern) | SearchPattern.R_ERASURE_MATCH; if (patternSpec.isCaseSensitive()) matchMode |= SearchPattern.R_CASE_SENSITIVE; pattern= SearchPattern.createPattern(patternSpec.getPattern(), patternSpec.getSearchFor(), patternSpec.getLimitTo(), matchMode, toolkit); } if (pattern == null) { return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, Messages.format(SearchMessages.DLTKSearchQuery_error_unsupported_pattern, stringPattern), null); } monitor.beginTask(Messages.format(SearchMessages.DLTKSearchQuery_task_label, stringPattern), totalTicks); IProgressMonitor mainSearchPM= new SubProgressMonitor(monitor, 1000); boolean ignorePotentials= NewSearchUI.arePotentialMatchesIgnored(); NewSearchResultCollector collector= new NewSearchResultCollector(textResult, ignorePotentials); engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, fPatternData.getScope(), collector, mainSearchPM); for (int i= 0; i < participantDescriptors.length; i++) { final ISearchRequestor requestor= new SearchRequestor(participantDescriptors[i].getParticipant(), textResult); final IProgressMonitor participantPM= new SubProgressMonitor(monitor, ticks[i]); final int iPrime= i; ISafeRunnable runnable= new ISafeRunnable() { @Override public void handleException(Throwable exception) { participantDescriptors[iPrime].getDescriptor().disable(); String message= SearchMessages.DLTKSearchQuery_error_participant_search; DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, exception)); } @Override public void run() throws Exception { final IQueryParticipant participant= participantDescriptors[iPrime].getParticipant(); final PerformanceStats stats= PerformanceStats.getStats(PERF_SEARCH_PARTICIPANT, participant); stats.startRun(); participant.search(requestor, fPatternData, participantPM); stats.endRun(); } }; SafeRunner.run(runnable); } } catch (CoreException e) { return e.getStatus(); } String message= Messages.format(SearchMessages.DLTKSearchQuery_status_ok_message, String.valueOf(textResult.getMatchCount())); return new Status(IStatus.OK, DLTKUIPlugin.getPluginId(), 0, message, null); } private int getMatchMode(String pattern) { if (pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1) { return SearchPattern.R_PATTERN_MATCH; } else if (SearchUtils.isCamelCasePattern(pattern)) { return SearchPattern.R_CAMELCASE_MATCH; } return SearchPattern.R_EXACT_MATCH; } @Override public String getLabel() { return SearchMessages.DLTKSearchQuery_label; } public String getResultLabel(int nMatches) { if (nMatches == 1) { String[] args= { getSearchPatternDescription(), fPatternData.getScopeDescription() }; switch (fPatternData.getLimitTo()) { // case IDLTKSearchConstants.IMPLEMENTORS: // return Messages.format(SearchMessages.DLTKSearchOperation_singularImplementorsPostfix, args); case IDLTKSearchConstants.DECLARATIONS: return Messages.format(SearchMessages.DLTKSearchOperation_singularDeclarationsPostfix, args); case IDLTKSearchConstants.REFERENCES: return Messages.format(SearchMessages.DLTKSearchOperation_singularReferencesPostfix, args); case IDLTKSearchConstants.ALL_OCCURRENCES: return Messages.format(SearchMessages.DLTKSearchOperation_singularOccurrencesPostfix, args); // case IDLTKSearchConstants.READ_ACCESSES: // return Messages.format(SearchMessages.DLTKSearchOperation_singularReadReferencesPostfix, args); // case IDLTKSearchConstants.WRITE_ACCESSES: // return Messages.format(SearchMessages.DLTKSearchOperation_singularWriteReferencesPostfix, args); default: return Messages.format(SearchMessages.DLTKSearchOperation_singularOccurrencesPostfix, args); } } else { Object[] args= { getSearchPatternDescription(), Integer.valueOf(nMatches), fPatternData.getScopeDescription() }; switch (fPatternData.getLimitTo()) { // case IDLTKSearchConstants.IMPLEMENTORS: // return Messages.format(SearchMessages.DLTKSearchOperation_pluralImplementorsPostfix, args); case IDLTKSearchConstants.DECLARATIONS: return Messages.format(SearchMessages.DLTKSearchOperation_pluralDeclarationsPostfix, args); case IDLTKSearchConstants.REFERENCES: return Messages.format(SearchMessages.DLTKSearchOperation_pluralReferencesPostfix, args); case IDLTKSearchConstants.ALL_OCCURRENCES: return Messages.format(SearchMessages.DLTKSearchOperation_pluralOccurrencesPostfix, args); // case IDLTKSearchConstants.READ_ACCESSES: // return Messages.format(SearchMessages.DLTKSearchOperation_pluralReadReferencesPostfix, args); // case IDLTKSearchConstants.WRITE_ACCESSES: // return Messages.format(SearchMessages.DLTKSearchOperation_pluralWriteReferencesPostfix, args); default: return Messages.format(SearchMessages.DLTKSearchOperation_pluralOccurrencesPostfix, args); } } } private String getSearchPatternDescription() { if (fPatternData instanceof ElementQuerySpecification) { IModelElement element= ((ElementQuerySpecification) fPatternData).getElement(); return ScriptElementLabels.getDefault().getElementLabel(element, ScriptElementLabels.ALL_DEFAULT | ScriptElementLabels.ALL_FULLY_QUALIFIED | ScriptElementLabels.USE_RESOLVED); } return ((PatternQuerySpecification) fPatternData).getPattern(); } ImageDescriptor getImageDescriptor() { if (/*fPatternData.getLimitTo() == IDLTKSearchConstants.IMPLEMENTORS ||*/ fPatternData.getLimitTo() == IDLTKSearchConstants.DECLARATIONS) return DLTKPluginImages.DESC_OBJS_SEARCH_DECL; else return DLTKPluginImages.DESC_OBJS_SEARCH_REF; } @Override public boolean canRerun() { return true; } @Override public boolean canRunInBackground() { return true; } @Override public ISearchResult getSearchResult() { if (fResult == null) { fResult= new DLTKSearchResult(this); new SearchResultUpdater((DLTKSearchResult) fResult); } return fResult; } QuerySpecification getSpecification() { return fPatternData; } }