Skip to content

Commit fd6afdc

Browse files
committed
ModuleSearcher: Fix search for incoherent words
* searches for all parts of a the search term divided by space individually
1 parent 2cd5824 commit fd6afdc

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/main/java/org/scijava/search/module/ModuleSearcher.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
package org.scijava.search.module;
3131

32+
import java.util.Arrays;
3233
import java.util.Collections;
3334
import java.util.LinkedHashSet;
3435
import java.util.List;
@@ -80,22 +81,33 @@ public List<SearchResult> search(final String text, final boolean fuzzy) {
8081
.collect(Collectors.toList());
8182

8283
final String textLower = text.toLowerCase();
84+
final List<String> textLowerParts = Arrays.asList(textLower.split("\\s+"));
8385

84-
// First, add modules where title starts with the text.
86+
// Add modules where title starts with the text.
8587
modules.stream() //
8688
.filter(info -> startsWith(info, textLower) ) //
8789
.forEach(matches::add);
8890

89-
// Next, add modules where title has text inside somewhere.
91+
// Add modules where title has text inside somewhere.
9092
modules.stream() //
9193
.filter(info -> hasSubstringInTitle(info, textLower)) //
9294
.forEach(matches::add);
9395

94-
// Finally, add modules where menu path has text inside somewhere.
96+
// Add modules where menu path has text inside somewhere.
9597
modules.stream() //
9698
.filter(info -> hasSubstringInMenu(info, textLower)) //
9799
.forEach(matches::add);
98100

101+
// Add modules where title has all parts of the text inside somewhere.
102+
modules.stream() //
103+
.filter(info -> hasSubstringsInTitle(info, textLowerParts)) //
104+
.forEach(matches::add);
105+
106+
// Add modules where menu path has all parts of the text inside somewhere.
107+
modules.stream() //
108+
.filter(info -> hasSubstringsInMenu(info, textLowerParts)) //
109+
.forEach(matches::add);
110+
99111
// Wrap each matching ModuleInfo in a ModuleSearchResult.
100112
return matches.stream() //
101113
.map(info -> new ModuleSearchResult(info, baseDir)) //
@@ -168,11 +180,27 @@ private boolean hasSubstringInTitle(final ModuleInfo info,
168180
title.toLowerCase().matches(".*" + desiredLower + ".*");
169181
}
170182

183+
private boolean hasSubstringsInTitle(final ModuleInfo info,
184+
final List<String> desiredLower)
185+
{
186+
final String title = title(info);
187+
if(title == null) return false;
188+
return desiredLower.stream().allMatch(part -> title.toLowerCase().contains(part));
189+
}
190+
171191
private boolean hasSubstringInMenu(final ModuleInfo info,
172192
final String desiredLower)
173193
{
174194
MenuPath menuPath = info.getMenuPath();
175195
if(menuPath == null) return false;
176196
return menuPath.stream().anyMatch(entry -> entry.getName().toLowerCase().contains(desiredLower));
177197
}
198+
199+
private boolean hasSubstringsInMenu(final ModuleInfo info,
200+
final List<String> desiredLower)
201+
{
202+
MenuPath menuPath = info.getMenuPath();
203+
if(menuPath == null) return false;
204+
return desiredLower.stream().allMatch(part -> menuPath.stream().anyMatch(entry -> entry.getName().toLowerCase().contains(part)));
205+
}
178206
}

src/test/java/org/scijava/search/module/ModuleSearcherTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.List;
1717

18+
import static org.junit.Assert.assertFalse;
1819
import static org.junit.Assert.assertNotNull;
1920
import static org.junit.Assert.assertTrue;
2021

@@ -77,6 +78,23 @@ public void testMenu() {
7778
assertTrue(containsModule(results, "nolabel"));
7879
}
7980

81+
@Test
82+
public void testMatchingPartsInMenu() {
83+
createTestModule("nolabel", "Do>something>silly");
84+
List<SearchResult> results = moduleSearcher.search("Do silly", true);
85+
assertNotNull(results);
86+
assertTrue(results.size()>=1);
87+
assertTrue(containsModule(results, "nolabel"));
88+
}
89+
90+
@Test
91+
public void testNonMatchingPartsInMenu() {
92+
createTestModule("nolabel", "Do>something>silly");
93+
List<SearchResult> results = moduleSearcher.search("Do nothing", true);
94+
assertNotNull(results);
95+
assertFalse(containsModule(results, "nolabel"));
96+
}
97+
8098
private boolean containsModule(List<SearchResult> results, String moduleName) {
8199
boolean foundModule = false;
82100
for(SearchResult result : results) {

0 commit comments

Comments
 (0)