GH-1049: spring index protocol now has new request for find matching beans
This commit is contained in:
@@ -99,6 +99,7 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.Reconcile
|
||||
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.MatchingBeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndex;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
@@ -927,13 +928,14 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, SpringInd
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Bean>> beans(BeansParams params) {
|
||||
Map<String, SpringIndex> allSpringIndex = appContext.getBeansOfType(SpringIndex.class, false, false);
|
||||
Assert.isLegal(allSpringIndex.size() <= 1, "One at most SpringModel bean is expected");
|
||||
if (!allSpringIndex.isEmpty()) {
|
||||
SpringIndex springIndex = allSpringIndex.values().iterator().next();
|
||||
return springIndex.beans(params);
|
||||
}
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
SpringIndex springIndex = appContext.getBean(SpringIndex.class);
|
||||
return springIndex.beans(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Bean>> matchingBeans(MatchingBeansParams params) {
|
||||
SpringIndex springIndex = appContext.getBean(SpringIndex.class);
|
||||
return springIndex.matchingBeans(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.protocol.spring;
|
||||
|
||||
public class MatchingBeansParams extends BeansParams {
|
||||
|
||||
private String beanType;
|
||||
|
||||
public String getBeanTypeToMatch() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
public void setBeanTypeToMatch(String beanType) {
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,5 +16,6 @@ import java.util.concurrent.CompletableFuture;
|
||||
public interface SpringIndex {
|
||||
|
||||
CompletableFuture<List<Bean>> beans(BeansParams params);
|
||||
CompletableFuture<List<Bean>> matchingBeans(MatchingBeansParams params);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,5 +22,10 @@ public interface SpringIndexLanguageServer extends LanguageServer {
|
||||
default CompletableFuture<List<Bean>> beans(BeansParams params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@JsonRequest("spring/index/beans/matches")
|
||||
default CompletableFuture<List<Bean>> matchingBeans(MatchingBeansParams params) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocu
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.MatchingBeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndex;
|
||||
import org.springframework.ide.vscode.commons.util.Futures;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
@@ -720,7 +721,21 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Bean>> matchingBeans(MatchingBeansParams params) {
|
||||
String projectName = params.getProjectName();
|
||||
String matchType = params.getBeanTypeToMatch();
|
||||
|
||||
CompletableFuture<Void> latestTask = this.latestScheduledTaskByProject.get(projectName);
|
||||
|
||||
if (latestTask != null) {
|
||||
return latestTask.thenApply((e) -> Arrays.asList(springIndex.getMatchingBeans(projectName, matchType)));
|
||||
}
|
||||
else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -989,4 +1004,5 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
public void onUpdate(Consumer<Void> listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -97,4 +97,15 @@ public class SpringMetamodelIndex {
|
||||
}
|
||||
}
|
||||
|
||||
public Bean[] getMatchingBeans(String projectName, String matchType) {
|
||||
Bean[] allBeans = this.beansPerProject.get(projectName);
|
||||
|
||||
if (allBeans != null) {
|
||||
return Arrays.stream(allBeans).filter(bean -> bean.isTypeCompatibleWith(matchType)).collect(Collectors.toList()).toArray(new Bean[0]);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.MatchingBeansParams;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -86,4 +87,35 @@ public class SpringIndexViaLSPMethodTest {
|
||||
assertEquals(11, beans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMatchingBeansForObject() throws Exception {
|
||||
MatchingBeansParams params = new MatchingBeansParams();
|
||||
params.setProjectName("test-spring-indexing");
|
||||
params.setBeanTypeToMatch("java.lang.Object");
|
||||
|
||||
CompletableFuture<List<Bean>> result = indexer.matchingBeans(params);
|
||||
|
||||
List<Bean> beans = result.get(5, TimeUnit.SECONDS);
|
||||
|
||||
assertNotNull(beans);
|
||||
assertEquals(10, beans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMatchingBeansForSpecificSupertype() throws Exception {
|
||||
MatchingBeansParams params = new MatchingBeansParams();
|
||||
params.setProjectName("test-spring-indexing");
|
||||
params.setBeanTypeToMatch("org.test.springdata.CustomerRepository");
|
||||
|
||||
CompletableFuture<List<Bean>> result = indexer.matchingBeans(params);
|
||||
|
||||
List<Bean> beans = result.get(5, TimeUnit.SECONDS);
|
||||
|
||||
assertNotNull(beans);
|
||||
assertEquals(1, beans.size());
|
||||
|
||||
assertEquals("customerRepository", beans.get(0).getName());
|
||||
assertEquals("org.test.springdata.CustomerRepository", beans.get(0).getType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -266,5 +266,78 @@ public class SpringMetamodelIndexTest {
|
||||
Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes);
|
||||
assertSame(DefaultValues.EMPTY_INJECTION_POINTS, bean1.getInjectionPoints());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindNoMatchingBeansWithEmptySupertypes() {
|
||||
SpringMetamodelIndex index = new SpringMetamodelIndex();
|
||||
Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes);
|
||||
Bean bean2 = new Bean("beanName2", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes);
|
||||
|
||||
index.updateBeans("someProject", new Bean[] {bean1, bean2});
|
||||
|
||||
Bean[] matchingBeans = index.getMatchingBeans("someProject", "");
|
||||
assertEquals(0, matchingBeans.length);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("someProject", "sometype");
|
||||
assertEquals(0, matchingBeans.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindMatchingBeansWithOneProject() {
|
||||
SpringMetamodelIndex index = new SpringMetamodelIndex();
|
||||
Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"});
|
||||
Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4", "supertype5"});
|
||||
|
||||
index.updateBeans("someProject", new Bean[] {bean1, bean2});
|
||||
|
||||
Bean[] matchingBeans = index.getMatchingBeans("someProject", "supertype2");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean1, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("someProject", "beanType1");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean1, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("someProject", "supertype5");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean2, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("someProject", "sometype");
|
||||
assertEquals(0, matchingBeans.length);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("otherProject", "supertype1");
|
||||
assertNull(matchingBeans);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindMatchingBeansWithMultipleProjects() {
|
||||
SpringMetamodelIndex index = new SpringMetamodelIndex();
|
||||
Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"});
|
||||
Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4, supertype5"});
|
||||
|
||||
Bean bean3 = new Bean("beanName3", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"});
|
||||
Bean bean4 = new Bean("beanName4", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4, supertype5"});
|
||||
|
||||
index.updateBeans("projectA", new Bean[] {bean1, bean2});
|
||||
index.updateBeans("projectB", new Bean[] {bean3, bean4});
|
||||
|
||||
Bean[] matchingBeans = index.getMatchingBeans("projectA", "supertype2");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean1, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("projectA", "beanType2");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean2, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("projectB", "supertype2");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean3, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("projectB", "beanType2");
|
||||
assertEquals(1, matchingBeans.length);
|
||||
assertSame(bean4, matchingBeans[0]);
|
||||
|
||||
matchingBeans = index.getMatchingBeans("otherProject", "supertype1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user