package org.codemap.search; import static java.util.Arrays.asList; import static org.codemap.util.ArrayUtil.isEmpty; import java.util.Collection; import java.util.HashSet; import org.codemap.CodemapCore; import org.codemap.MapPerProject; import org.codemap.MapSelection; import org.codemap.commands.SearchResultCommand; import org.codemap.layers.SearchResultsOverlay; import org.codemap.util.Resources; import org.eclipse.search.ui.ISearchQuery; import org.eclipse.search.ui.ISearchResult; import org.eclipse.search.ui.NewSearchUI; import org.eclipse.search.ui.text.AbstractTextSearchResult; public class SearchResultController { private SearchResultListener searchListener; private MapSelection mapSelection; private QueryListener theQueryListener; private SearchResultCommand currentCommand; public SearchResultController() { searchListener = new SearchResultListener(this); mapSelection = new MapSelection(); theQueryListener = new QueryListener(this); registerQueryListener(); } private void registerQueryListener() { NewSearchUI.addQueryListener(theQueryListener); } private void unregisterQueryListener() { NewSearchUI.removeQueryListener(theQueryListener); } public void onLayerActivated() { ISearchQuery[] queries = NewSearchUI.getQueries(); if (isEmpty(queries)) return; // TODO check if this is necessary. addListener(queries); // new queries are at the first position loadNewestQueryResult(queries); } private boolean isActive() { if (currentCommand == null) return false; return currentCommand.isEnabled(); } public void onLayerDeactivated() { clearSelection(); } public void onQueryAdded(ISearchQuery query) { query.getSearchResult().addListener(searchListener); } public void onAllQueriesRemoved() { clearSelection(); } private void clearSelection() { getSearchSelection().clear(); } public void onElementsAdded(Collection<Object> elements) { if (!isActive()) return; getSearchSelection().addAll(extractMatches(elements)); } public void onElementsRemoved(Collection<Object> elements) { getSearchSelection().removeAll(extractMatches(elements)); } private void loadNewestQueryResult(ISearchQuery[] queries) { // new queries are added at first position ISearchQuery query = queries[0]; ISearchResult searchResult = query.getSearchResult(); if (searchResult instanceof AbstractTextSearchResult) { AbstractTextSearchResult res = (AbstractTextSearchResult) searchResult; onElementsAdded(asList(res.getElements())); } } private void addListener(ISearchQuery[] queries) { for(ISearchQuery each: queries) { onQueryAdded(each); } } public MapSelection getSearchSelection() { MapPerProject activeMap = CodemapCore.getPlugin().getActiveMap(); if (! activeMap.containsLayer(SearchResultsOverlay.class)) { SearchResultsOverlay searchOverlay = new SearchResultsOverlay(this); activeMap.addSelectionLayer(searchOverlay, mapSelection); } return mapSelection; } private Collection<String> extractMatches(Collection<Object> elements) { Collection<String> idents = new HashSet<String>(); for (Object each: elements) { String path = Resources.asPath(each); if (path != null) idents.add(path); } return idents; } public void dispose() { unregisterQueryListener(); } public void onQueryRemoved(ISearchQuery query) { ISearchResult searchResult = query.getSearchResult(); if (searchResult instanceof AbstractTextSearchResult) { AbstractTextSearchResult res = (AbstractTextSearchResult) searchResult; onElementsRemoved(asList(res.getElements())); } } public void setCurrentCommand(SearchResultCommand searchResultCommand) { currentCommand = searchResultCommand; } }