From 56d518c8ea31ac8157ca26841c2de264cb3be16a Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 24 Jan 2013 11:37:11 -0500 Subject: Bug 253272 - Remote C/C++ Search on the workspace only searches one connection --- .../ui/search/GroupRemoteSearchQueryAdapter.java | 162 +++++++++++++++++++ .../internal/rdt/ui/search/RemoteSearchPage.java | 178 ++++++++++++--------- .../ptp/rdt/ui/messages/messages.properties | 4 +- 3 files changed, 264 insertions(+), 80 deletions(-) create mode 100644 rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/GroupRemoteSearchQueryAdapter.java diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/GroupRemoteSearchQueryAdapter.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/GroupRemoteSearchQueryAdapter.java new file mode 100644 index 000000000..601810132 --- /dev/null +++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/GroupRemoteSearchQueryAdapter.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ + +/* -- ST-Origin -- + * Source folder: org.eclipse.cdt.ui/src + * Class: org.eclipse.cdt.internal.ui.search.PDOMSearchQuery + * Version: 1.34 + */ + +package org.eclipse.ptp.internal.rdt.ui.search; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ptp.rdt.ui.UIPlugin; +import org.eclipse.ptp.rdt.ui.messages.Messages; +import org.eclipse.search.ui.ISearchQuery; +import org.eclipse.search.ui.ISearchResult; +import org.eclipse.search.ui.text.AbstractTextSearchResult; +import org.eclipse.search.ui.text.Match; + +/** + * Manages queries for multiple servers and adapts RemoteSearchQuery instances so that they may be used with Eclipse's + * search framework. + * + */ +public class GroupRemoteSearchQueryAdapter implements ISearchQuery { + + private List jobs; + private ISearchResult result; + + public GroupRemoteSearchQueryAdapter(List _jobs) { + jobs = _jobs; + // NPE check is in RemoteSearchPage and there is always one job in the list + // when this object is called. + result = jobs.get(0).getSearchResult(); + } + + public boolean canRerun() { + return true; + } + + public boolean canRunInBackground() { + return true; + } + + public ISearchResult getSearchResult() { + return result; + } + + private Match[] computeContainedMatches(AbstractTextSearchResult result, URI locationURI) throws CoreException { + List list = new ArrayList(); + Object[] elements = result.getElements(); + for (int i = 0; i < elements.length; ++i) { + //if (locationURI.normalize().equals(((RemoteSearchElement)elements[i]).getLocation().getURI().normalize())) { + Match[] matches = result.getMatches(elements[i]); + for (int j = 0; j < matches.length; ++j) { + if (matches[j] instanceof RemoteSearchMatchAdapter) { + list.add(matches[j]); + } + } + //} + } + return list.toArray(new Match[list.size()]); + } + + public IStatus run(IProgressMonitor monitor) { + final int numOfJobs = jobs.size(); + monitor.beginTask(Messages.getString("GroupRemoteSearchQueryAdapter_0"), 2); //$NON-NLS-1$ + final String JOBFAMILYNAME = Messages.getString("GroupRemoteSearchQueryAdapter_1"); //$NON-NLS-1$ + + // one job group associated with one progress monitor group. + IJobManager jobMan = Job.getJobManager(); + IProgressMonitor myGroup = jobMan.createProgressGroup(); + myGroup.beginTask(JOBFAMILYNAME, numOfJobs * 300); + + try { + for (final ISearchQuery query: jobs) { + if (monitor.isCanceled()) { + jobMan.cancel(JOBFAMILYNAME); + return new Status(IStatus.CANCEL, "org.eclipse.ptp.rdt.ui", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + Job job = new Job(JOBFAMILYNAME) { + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(JOBFAMILYNAME, 300); + + if (monitor.isCanceled()) { + return new Status(IStatus.CANCEL, "org.eclipse.ptp.rdt.ui", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + query.run(monitor); + // progress to 300/300 + monitor.worked(300); + monitor.done(); + return Status.OK_STATUS; + } + + public boolean belongsTo(Object family) { + return getName().equals(family); + } + }; + job.setProgressGroup(myGroup, numOfJobs * 300); + job.setPriority(Job.LONG); + job.schedule(); + } + + try { + jobMan.join(JOBFAMILYNAME, null); + // progress to 1/2 + monitor.worked(1); + } catch (InterruptedException e) { + UIPlugin.log(e); + } + + combineResults(); + // progress to 2/2 + monitor.worked(1); + } finally { + monitor.done(); + } + + return new Status(IStatus.OK, "org.eclipse.ptp.rdt.ui", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void combineResults() { + RemoteSearchResult result = (RemoteSearchResult) jobs.get(0).getSearchResult(); + for (int i = 1; i < jobs.size(); i ++) { + RemoteSearchResult result2 = (RemoteSearchResult) jobs.get(i).getSearchResult(); + + Match[] matches = null; + try { + matches = computeContainedMatches(result2, null); + } catch (CoreException e) { + UIPlugin.log(e); + } + + result.addMatches(matches); + } + this.result = result; + } + + public String getLabel() { + return result.getLabel(); + } + +} diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/RemoteSearchPage.java b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/RemoteSearchPage.java index f1d0487e4..27d730c7a 100644 --- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/RemoteSearchPage.java +++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/internal/rdt/ui/search/RemoteSearchPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 QNX Software Systems and others. + * Copyright (c) 2006, 2013 QNX Software Systems 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 @@ -20,7 +20,6 @@ package org.eclipse.ptp.internal.rdt.ui.search; import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.regex.PatternSyntaxException; @@ -33,8 +32,8 @@ import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.ui.search.CSearchMessages; -import org.eclipse.cdt.internal.ui.search.CSearchUtil; import org.eclipse.cdt.internal.ui.search.CSearchPatternQuery; +import org.eclipse.cdt.internal.ui.search.CSearchUtil; import org.eclipse.cdt.internal.ui.util.Messages; import org.eclipse.cdt.internal.ui.util.RowLayouter; import org.eclipse.cdt.ui.CUIPlugin; @@ -214,7 +213,93 @@ public class RemoteSearchPage extends DialogPage implements ISearchPage { String patternStr = patternCombo.getText(); // Get search flags - int searchFlags = 0; + int searchFlags = getSearchFlags(); + + // get the list of elements for the scope + Set elements = new HashSet(); + String scopeDescription = getScopeDescriptionFromElements(elements); + + // get scope + ICElement[] scope = elements.isEmpty() ? null : elements.toArray(new ICElement[elements.size()]); + + try { + List jobs = new ArrayList(); + Set visitedHost = new HashSet(); + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + + for (IProject project : projects) { + try { + if (project.isOpen() && project.hasNature(RemoteNature.REMOTE_NATURE_ID)) { + String hostName = new Scope(project).getHost(); + if (visitedHost.contains(hostName)) { + continue; + } + + visitedHost.add(hostName); + + // get remote index service for a qualified project + IServiceModelManager smm = ServiceModelManager.getInstance(); + IServiceConfiguration serviceConfig = smm.getActiveConfiguration(project); + IService indexingService = smm.getService(IRDTServiceConstants.SERVICE_C_INDEX); + IServiceProvider serviceProvider = serviceConfig.getServiceProvider(indexingService); + if (!(serviceProvider instanceof IIndexServiceProvider2)) { + return false; + } + ISearchService service = ((IIndexServiceProvider2) serviceProvider).getSearchService(); + + // create a query job and add it into job queue + ISearchQuery job = service.createSearchPatternQuery(Scope.WORKSPACE_ROOT_SCOPE, scope, scopeDescription, patternStr, isCaseSensitive, searchFlags); + jobs.add(job); + } + } catch (CoreException e) { + UIPlugin.log(e); + } + } + + if (jobs.size() == 0) { + return false; + } + + // create a query adapter including multiple queries and pass that adapter to Eclipse Search framework. + ISearchQuery bigJob = new GroupRemoteSearchQueryAdapter(jobs); + NewSearchUI.activateSearchResultView(); + NewSearchUI.runQueryInBackground(bigJob); + } catch (PatternSyntaxException e) { + fLineManager.setErrorMessage(CSearchMessages.PDOMSearch_query_pattern_error); + return false; + } + + // Save our settings + IDialogSettings settings = getDialogSettings(); + settings.put(STORE_CASE_SENSITIVE, isCaseSensitive); + + if (previousPatterns == null) + previousPatterns = new String[] { patternStr }; + else { + // Add only if we don't have it already + boolean addit = true; + for (int i = 0; i < previousPatterns.length; ++i) { + if (patternStr.equals(previousPatterns[i])) { + addit = false; + break; + } + } + if (addit) { + // Insert it into the beginning of the list + String[] newPatterns = new String[previousPatterns.length + 1]; + System.arraycopy(previousPatterns, 0, newPatterns, 1, previousPatterns.length); + newPatterns[0] = patternStr; + previousPatterns = newPatterns; + } + } + + settings.put(STORE_PREVIOUS_PATTERNS, previousPatterns); + settings.put(STORE_SEARCH_FLAGS, searchFlags); + return true; + } + + private int getSearchFlags() { + int searchFlags = 0; if (searchForButtons[searchAllButtonIndex].getSelection()) searchFlags |= CSearchPatternQuery.FIND_ALL_TYPES; else { @@ -227,9 +312,15 @@ public class RemoteSearchPage extends DialogPage implements ISearchPage { if (limitToButtons[i].getSelection()) searchFlags |= ((Integer)limitToButtons[i].getData()).intValue(); } - - // get the list of elements for the scope - Set elements = new HashSet(); + return searchFlags; + } + + /** + * + * @param elements + * @return + */ + private String getScopeDescriptionFromElements(Set elements) { String scopeDescription = ""; //$NON-NLS-1$ switch (getContainer().getSelectedScope()) { case ISearchPageContainer.SELECTED_PROJECTS_SCOPE: @@ -303,78 +394,7 @@ public class RemoteSearchPage extends DialogPage implements ISearchPage { } break; } - - ICElement[] scope = elements.isEmpty() ? - null : elements.toArray(new ICElement[elements.size()]); - - - try { - // TODO: Where are we going to find an IProject when doing a global search? - IProject project = null; - IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); - for (IProject p : projects) { - try { - if (p.isOpen() && p.hasNature(RemoteNature.REMOTE_NATURE_ID)) { - project = p; - } - } catch (CoreException e) { - CUIPlugin.log(e); - } - } - if (project == null) { - return false; - } - - IServiceModelManager smm = ServiceModelManager.getInstance(); - IServiceConfiguration serviceConfig = smm.getActiveConfiguration(project); - - IService indexingService = smm.getService(IRDTServiceConstants.SERVICE_C_INDEX); - - IServiceProvider serviceProvider = serviceConfig.getServiceProvider(indexingService); - - if (!(serviceProvider instanceof IIndexServiceProvider2)) { - return false; - } - ISearchService service = ((IIndexServiceProvider2) serviceProvider).getSearchService(); - ISearchQuery job = service.createSearchPatternQuery(Scope.WORKSPACE_ROOT_SCOPE, scope, scopeDescription, patternStr, isCaseSensitive, searchFlags); - - NewSearchUI.activateSearchResultView(); - - NewSearchUI.runQueryInBackground(job); - } catch (PatternSyntaxException e) { - fLineManager.setErrorMessage(CSearchMessages.PDOMSearch_query_pattern_error); - return false; - } - - // Save our settings - IDialogSettings settings = getDialogSettings(); - settings.put(STORE_CASE_SENSITIVE, isCaseSensitive); - - if (previousPatterns == null) - previousPatterns = new String[] { patternStr }; - else { - // Add only if we don't have it already - boolean addit = true; - for (int i = 0; i < previousPatterns.length; ++i) { - if (patternStr.equals(previousPatterns[i])) { - addit = false; - break; - } - } - if (addit) { - // Insert it into the beginning of the list - String[] newPatterns = new String[previousPatterns.length + 1]; - System.arraycopy(previousPatterns, 0, newPatterns, 1, previousPatterns.length); - newPatterns[0] = patternStr; - previousPatterns = newPatterns; - } - } - - settings.put(STORE_PREVIOUS_PATTERNS, previousPatterns); - - settings.put(STORE_SEARCH_FLAGS, searchFlags); - - return true; + return scopeDescription; } public void createControl(Composite parent) { diff --git a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/messages/messages.properties b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/messages/messages.properties index 69d1e5490..82a01623b 100755 --- a/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/messages/messages.properties +++ b/rdt/org.eclipse.ptp.rdt.ui/src/org/eclipse/ptp/rdt/ui/messages/messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2008, 2011 IBM Corporation and others. +# Copyright (c) 2008, 2013 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 @@ -10,6 +10,8 @@ ############################################################################### ConfigureRemoteServices.0=Default ConvertToRemoteWizardPage.0=Convert project +GroupRemoteSearchQueryAdapter_0=Remote Group Search +GroupRemoteSearchQueryAdapter_1=Remote Group Search... HostSelectionDialog_0=Host: HostSelectionDialog.0=New Connection... HostSelectionDialog.1=Choose Host for Remote C/C++ Indexing Service -- cgit v1.2.3