diff options
author | Holger Voormann | 2014-02-05 08:40:58 +0000 |
---|---|---|
committer | Holger Voormann | 2014-02-05 08:40:58 +0000 |
commit | db9fe060d2d90831010e426a1f3f7eaf4a58f02b (patch) | |
tree | 84ce2cbf57b22cce51a0103c03b325cb5a6d83ef | |
parent | acce130be709cb2373506a9e7aa97ec8293cc409 (diff) | |
download | eclipse.platform.ua-db9fe060d2d90831010e426a1f3f7eaf4a58f02b.tar.gz eclipse.platform.ua-db9fe060d2d90831010e426a1f3f7eaf4a58f02b.tar.xz eclipse.platform.ua-db9fe060d2d90831010e426a1f3f7eaf4a58f02b.zip |
Bug 365549 - [Help][Search] Changing the search results order via
org.eclipse.help.searchProcessor can cause duplicated search categories
Problem:
If "Show results categories" is enabled the search results which are
first sorted by scoring are then resorted primarily by the categories
and secondarily by the scoring (line 439: via SearchResultComparator).
Based on this order the categories are shown: a category heading line is
inserted above every result, which belongs to a different category than
the category of the previous result. The order of search results can be
changed via the "org.eclipse.help.base.searchProcessor" extension point.
These search processors are applied after (re)sorting the search results
(line 183: "ISearchResult tmp[] =
processors[p].postSearch(searchWord,results)"). A search processor is
not aware of whether "Show results categories" is enabled or disabled,
and after applying the search processors the search results may not be
primarily sorted by categories: the heading of the same categories may
be inserted more than once.
Fix:
To avoid showing the same categories multiple times a sorting by
categories only (keeping the order of results within each category)
should be done if "Show results categories" is enabled after, rather
than before applying the search processors. Because "Arrays.sort()"
guarantees to be stable (equal elements will not be reordered as a
result of the sort) the resorting by category can be simplified (without
secondarily sorting by scoring).
Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=365549
Signed-off-by: Holger Voormann <eclipse@voormann.de>
-rw-r--r-- | org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java | 78 |
1 files changed, 31 insertions, 47 deletions
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java index 37534a731..23c96507e 100644 --- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java +++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Sebastian Davids <sdavids@gmx.de> - fix for Bug 182466 + * Holger Voormann - fix for bug 365549 (http://eclip.se/365549) *******************************************************************************/ package org.eclipse.help.internal.webapp.data; @@ -189,6 +190,8 @@ public class SearchData extends ActivitiesData { } if (reset) hits = SearchManager.convertResultsToHits(results); + if (isShowCategories()) + primallySortByCategory(hits); } } } @@ -434,11 +437,6 @@ public class SearchData extends ActivitiesData { HelpWebappPlugin .logWarning("No search results returned. Help index is in use."); //$NON-NLS-1$ } - else { - if (isShowCategories()) { - Arrays.sort(hits, new SearchResultComparator()); - } - } return; } // progress @@ -671,48 +669,34 @@ public class SearchData extends ActivitiesData { } } - private static class SearchResultComparator implements Comparator { - public int category(Object element) { - if (element instanceof ISearchEngineResult) { - ISearchEngineResult r = (ISearchEngineResult)element; - IHelpResource c = r.getCategory(); - if (c!=null) { - String label = c.getLabel(); - if (label.length()==0) - return 10; - return 5; - } - } - return 0; - } - - public int compare(Object e1, Object e2) { - int cat1 = category(e1); - int cat2 = category(e2); - if (cat1 != cat2) { - return cat1 - cat2; - } - ISearchEngineResult r1 = (ISearchEngineResult)e1; - ISearchEngineResult r2 = (ISearchEngineResult)e2; - IHelpResource c1 = r1.getCategory(); - IHelpResource c2 = r2.getCategory(); - if (c1 != null && c2 != null) { - int cat = c1.getLabel().compareToIgnoreCase(c2.getLabel()); - if (cat != 0) { - return cat; - } - } - float rank1 = ((ISearchEngineResult)e1).getScore(); - float rank2 = ((ISearchEngineResult)e2).getScore(); - if (rank1 - rank2 > 0) { - return -1; - } - else if (rank1 == rank2) { - return 0; - } - else { - return 1; + /** + * Sorts the given {@link ISearchEngineResult} array alphabetically (case + * insensitive) by category label but keeps the order within each category. + * Results without a category or of a category without a label or with an + * empty label are sorted to the end ({@code "Category Label" < "" < null}). + * + * @param toSort the {@link ISearchEngineResult} array to sort; must not + * contain {@code null} elements + */ + private static void primallySortByCategory(ISearchEngineResult[] toSort) { + Arrays.sort(toSort, new Comparator() { + public int compare(Object e1, Object e2) { + IHelpResource c1 = ((ISearchEngineResult)e1).getCategory(); + IHelpResource c2 = ((ISearchEngineResult)e2).getCategory(); + if (c1 == null && c2 == null) return 0; + if (c1 == null) return 1; + if (c2 == null) return -1; + String l1 = c1.getLabel(); + String l2 = c2.getLabel(); + if (l1 == null && l2 == null) return 0; + if (l1 == null) return 1; + if (l2 == null) return -1; + if (l1.length() == 0 && l2.length() == 0) return 0; + if (l1.length() == 0) return 1; + if (l2.length() == 0) return -1; + return l1.compareToIgnoreCase(l2); } - } + }); } + } |