diff options
Diffstat (limited to 'plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java')
-rw-r--r-- | plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java | 91 |
1 files changed, 85 insertions, 6 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java b/plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java index 64e6b3a4e28..a89feebb29f 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java +++ b/plugins/uml/org.eclipse.papyrus.uml.search.ui/src/org/eclipse/papyrus/uml/search/ui/query/CompositePapyrusQuery.java @@ -11,6 +11,8 @@ *****************************************************************************/ package org.eclipse.papyrus.uml.search.ui.query; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; @@ -22,10 +24,17 @@ import org.eclipse.core.runtime.SubMonitor; import org.eclipse.papyrus.uml.search.ui.Activator; import org.eclipse.papyrus.uml.search.ui.results.PapyrusSearchResult; import org.eclipse.search.ui.ISearchResult; +import org.eclipse.search.ui.ISearchResultListener; +import org.eclipse.search.ui.SearchResultEvent; import org.eclipse.search.ui.text.AbstractTextSearchResult; +import org.eclipse.search.ui.text.Match; +import org.eclipse.search.ui.text.MatchEvent; +import org.eclipse.search.ui.text.RemoveAllEvent; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; /** * A composite query delegates execution to multiple nested queries and synthesizes their results. @@ -34,6 +43,8 @@ public class CompositePapyrusQuery extends AbstractPapyrusQuery { private final List<? extends AbstractPapyrusQuery> queries; + private final CompositeSearchResult searchResult = new CompositeSearchResult(); + protected CompositePapyrusQuery(List<? extends AbstractPapyrusQuery> queries) { this.queries = queries; } @@ -95,29 +106,97 @@ public class CompositePapyrusQuery extends AbstractPapyrusQuery { public IStatus run(IProgressMonitor monitor) throws OperationCanceledException { List<IStatus> result = new java.util.ArrayList<IStatus>(queries.size()); + searchResult.clear(); + SubMonitor sub = SubMonitor.convert(monitor, result.size()); for(AbstractPapyrusQuery next : queries) { IStatus status = next.run(sub.newChild(1)); if(!status.isOK()) { result.add(status); } + + searchResult.addSearchResult((AbstractTextSearchResult)next.getSearchResult()); } return result.isEmpty() ? Status.OK_STATUS : (result.size() == 1) ? result.get(0) : new MultiStatus(Activator.PLUGIN_ID, 0, result.toArray(new IStatus[result.size()]), "Problems occurred in search.", null); } public ISearchResult getSearchResult() { - PapyrusSearchResult result = new PapyrusSearchResult(this); + return searchResult; + } - for(AbstractPapyrusQuery next : queries) { - AbstractTextSearchResult nextResult = (AbstractTextSearchResult)next.getSearchResult(); + // + // Nested types + // + + private final class CompositeSearchResult extends PapyrusSearchResult implements ISearchResultListener { + + private final Multimap<AbstractTextSearchResult, Match> searchResults = ArrayListMultimap.create(); - Object[] elements = nextResult.getElements(); + CompositeSearchResult() { + super(CompositePapyrusQuery.this); + } + + void clear() { + for(AbstractTextSearchResult next : searchResults.keySet()) { + next.removeListener(this); + } + searchResults.clear(); + } + + void addSearchResult(AbstractTextSearchResult searchResult) { + Object[] elements = searchResult.getElements(); for(int i = 0; i < elements.length; i++) { - result.addMatches(nextResult.getMatches(elements[i])); + Match[] matches = searchResult.getMatches(elements[i]); + searchResults.putAll(searchResult, Arrays.asList(matches)); + addMatches(matches); // I need them, too + } + + if(!searchResults.containsKey(searchResult)) { + // we have to make sure that we remember this empty result! + searchResults.putAll(searchResult, Collections.<Match> emptyList()); } + + searchResult.addListener(this); } - return result; + public void searchResultChanged(SearchResultEvent e) { + AbstractTextSearchResult source = (AbstractTextSearchResult)e.getSearchResult(); + + if(e instanceof RemoveAllEvent) { + removeAll(source); + } else if(e instanceof MatchEvent) { + MatchEvent event = (MatchEvent)e; + switch(event.getKind()) { + case MatchEvent.ADDED: + add(source, event.getMatches()); + break; + case MatchEvent.REMOVED: + remove(source, event.getMatches()); + break; + default: + Activator.log.warn("Unrecognized MatcheEvent kind: " + event.getKind()); //$NON-NLS-1$ + break; + } + } + } + + private void removeAll(AbstractTextSearchResult searchResult) { + Match[] removed = Iterables.toArray(searchResults.get(searchResult), Match.class); + + // we still need the search result in the keys! + searchResults.get(searchResult).clear(); + + removeMatches(removed); + } + + private void remove(AbstractTextSearchResult searchResult, Match[] matches) { + searchResults.get(searchResult).removeAll(Arrays.asList(matches)); + removeMatches(matches); + } + + private void add(AbstractTextSearchResult searchResult, Match[] matches) { + searchResults.putAll(searchResult, Arrays.asList(matches)); + } } } |