diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaWorkspaceSymbolHandler.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaWorkspaceSymbolHandler.java index f1293f80b..5e779b889 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaWorkspaceSymbolHandler.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaWorkspaceSymbolHandler.java @@ -30,7 +30,7 @@ public class BootJavaWorkspaceSymbolHandler implements WorkspaceSymbolHandler { @Override public List handle(WorkspaceSymbolParams params) { - return indexer.getAllSymbols(); + return indexer.getAllSymbols(params.getQuery()); } } diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java index fc4b18eed..e80f0a861 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java @@ -103,9 +103,33 @@ public class SpringIndexer { // TODO: update information because of doc change } - public List getAllSymbols() { + public List getAllSymbols(String query) { initialize(); - return this.symbols; + if (query != null && query.length() > 0) { + return searchMatchingSymbols(this.symbols, query); + } + else { + return this.symbols; + } + } + + private List searchMatchingSymbols(List allsymbols, String query) { + return allsymbols.stream() + .filter(symbol -> containsCharacters(symbol.getName().toCharArray(), query.toCharArray())).collect(Collectors.toList()); + } + + private boolean containsCharacters(char[] symbolChars, char[] queryChars) { + int symbolindex = 0; + int queryindex = 0; + + while (queryindex < queryChars.length && symbolindex < symbolChars.length) { + if (symbolChars[symbolindex] == queryChars[queryindex]) { + queryindex++; + } + symbolindex++; + } + + return queryindex == queryChars.length; } public List getSymbols(String docURI) { diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java index d0c5c4b8e..fddc8c7a9 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java @@ -77,7 +77,7 @@ public class SpringIndexerTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); indexer.scanFiles(directory); - List allSymbols = indexer.getAllSymbols(); + List allSymbols = indexer.getAllSymbols(""); assertEquals(8, allSymbols.size()); @@ -128,7 +128,7 @@ public class SpringIndexerTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/").toURI()); indexer.scanFiles(directory); - List allSymbols = indexer.getAllSymbols(); + List allSymbols = indexer.getAllSymbols(""); assertEquals(8, allSymbols.size()); @@ -144,6 +144,63 @@ public class SpringIndexerTest { assertTrue(containsSymbol(allSymbols, "@/classlevel/mapping-subpackage -- (no method defined)", uriPrefix + "/src/main/java/org/test/sub/MappingClassSubpackage.java", 7, 1, 7, 38)); } + @Test + public void testFilterSymbolsUsingQueryString() throws Exception { + harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); + + SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectFinder, symbolProviders); + File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); + indexer.scanFiles(directory); + + List allSymbols = indexer.getAllSymbols("mapp"); + + assertEquals(6, allSymbols.size()); + + String uriPrefix = "file://" + directory.getAbsolutePath(); + + assertTrue(containsSymbol(allSymbols, "@/embedded-foo-mapping -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 17, 1, 17, 41)); + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 24, 0, 24, 36)); + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping/embedded-foo-mapping-with-root -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 27, 1, 27, 51)); + assertTrue(containsSymbol(allSymbols, "@/mapping1 -- (no method defined)", uriPrefix + "/src/main/java/org/test/SimpleMappingClass.java", 6, 1, 6, 28)); + assertTrue(containsSymbol(allSymbols, "@/mapping2 -- (no method defined)", uriPrefix + "/src/main/java/org/test/SimpleMappingClass.java", 11, 1, 11, 28)); + assertTrue(containsSymbol(allSymbols, "@/classlevel/mapping-subpackage -- (no method defined)", uriPrefix + "/src/main/java/org/test/sub/MappingClassSubpackage.java", 7, 1, 7, 38)); + } + + @Test + public void testFilterSymbolsUsingQueryStringSplittedResult() throws Exception { + harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); + + SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectFinder, symbolProviders); + File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); + indexer.scanFiles(directory); + + List allSymbols = indexer.getAllSymbols("@/foo-root-mapping -- (no method defined)"); + + assertEquals(2, allSymbols.size()); + + String uriPrefix = "file://" + directory.getAbsolutePath(); + + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 24, 0, 24, 36)); + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping/embedded-foo-mapping-with-root -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 27, 1, 27, 51)); + } + + @Test + public void testFilterSymbolsUsingQueryStringFullSymbolString() throws Exception { + harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); + + SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectFinder, symbolProviders); + File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); + indexer.scanFiles(directory); + + List allSymbols = indexer.getAllSymbols("@/foo-root-mapping/embedded-foo-mapping-with-root -- (no method defined)"); + + assertEquals(1, allSymbols.size()); + + String uriPrefix = "file://" + directory.getAbsolutePath(); + + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping/embedded-foo-mapping-with-root -- (no method defined)", uriPrefix + "/src/main/java/org/test/MainClass.java", 27, 1, 27, 51)); + } + private boolean containsSymbol(List symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) { for (Iterator iterator = symbols.iterator(); iterator.hasNext();) { SymbolInformation symbol = iterator.next();