|
29 | 29 |
|
30 | 30 | package org.scijava.search.module; |
31 | 31 |
|
| 32 | +import java.util.Arrays; |
32 | 33 | import java.util.Collections; |
33 | 34 | import java.util.LinkedHashSet; |
34 | 35 | import java.util.List; |
@@ -80,22 +81,33 @@ public List<SearchResult> search(final String text, final boolean fuzzy) { |
80 | 81 | .collect(Collectors.toList()); |
81 | 82 |
|
82 | 83 | final String textLower = text.toLowerCase(); |
| 84 | + final List<String> textLowerParts = Arrays.asList(textLower.split("\\s+")); |
83 | 85 |
|
84 | | - // First, add modules where title starts with the text. |
| 86 | + // Add modules where title starts with the text. |
85 | 87 | modules.stream() // |
86 | 88 | .filter(info -> startsWith(info, textLower) ) // |
87 | 89 | .forEach(matches::add); |
88 | 90 |
|
89 | | - // Next, add modules where title has text inside somewhere. |
| 91 | + // Add modules where title has text inside somewhere. |
90 | 92 | modules.stream() // |
91 | 93 | .filter(info -> hasSubstringInTitle(info, textLower)) // |
92 | 94 | .forEach(matches::add); |
93 | 95 |
|
94 | | - // Finally, add modules where menu path has text inside somewhere. |
| 96 | + // Add modules where menu path has text inside somewhere. |
95 | 97 | modules.stream() // |
96 | 98 | .filter(info -> hasSubstringInMenu(info, textLower)) // |
97 | 99 | .forEach(matches::add); |
98 | 100 |
|
| 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 | + |
99 | 111 | // Wrap each matching ModuleInfo in a ModuleSearchResult. |
100 | 112 | return matches.stream() // |
101 | 113 | .map(info -> new ModuleSearchResult(info, baseDir)) // |
@@ -168,11 +180,27 @@ private boolean hasSubstringInTitle(final ModuleInfo info, |
168 | 180 | title.toLowerCase().matches(".*" + desiredLower + ".*"); |
169 | 181 | } |
170 | 182 |
|
| 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 | + |
171 | 191 | private boolean hasSubstringInMenu(final ModuleInfo info, |
172 | 192 | final String desiredLower) |
173 | 193 | { |
174 | 194 | MenuPath menuPath = info.getMenuPath(); |
175 | 195 | if(menuPath == null) return false; |
176 | 196 | return menuPath.stream().anyMatch(entry -> entry.getName().toLowerCase().contains(desiredLower)); |
177 | 197 | } |
| 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 | + } |
178 | 206 | } |
0 commit comments