GH-1425: groundwork to allow nested beans in internal index structure

This commit is contained in:
Martin Lippert
2025-01-24 16:41:48 +01:00
parent 313f03d544
commit bdc7086586
15 changed files with 328 additions and 149 deletions

View File

@@ -54,8 +54,8 @@ public class SpringMetamodelIndexTest {
@Test
void testEmptyIndex() {
SpringMetamodelIndex index = new SpringMetamodelIndex();
assertNull(index.getBeansOfProject("someProject"));
assertNull(index.getBeansWithName("someProject", "someBeanName"));
assertEquals(0, index.getBeansOfProject("someProject").length);
assertEquals(0, index.getBeansWithName("someProject", "someBeanName").length);
}
@Test
@@ -126,7 +126,7 @@ public class SpringMetamodelIndexTest {
assertTrue(beansList.contains(bean2));
assertFalse(beansList.contains(bean3));
assertNull(index.getBeansWithName("nonExistingProject", "beanName1"));
assertEquals(0, index.getBeansWithName("nonExistingProject", "beanName1").length);
}
@Test
@@ -203,7 +203,7 @@ public class SpringMetamodelIndexTest {
assertFalse(beansList.contains(bean2));
assertTrue(beansList.contains(bean3));
assertNull(index.getBeansOfProject("someProject1"));
assertEquals(0, index.getBeansOfProject("someProject1").length);
}
@Test
@@ -364,7 +364,7 @@ public class SpringMetamodelIndexTest {
assertEquals(0, matchingBeans.length);
matchingBeans = index.getMatchingBeans("otherProject", "supertype1");
assertNull(matchingBeans);
assertEquals(0, matchingBeans.length);
}
@Test
@@ -400,41 +400,46 @@ public class SpringMetamodelIndexTest {
@Test
void testBasicSpringIndexStructure() {
SubType1 child1 = new SubType1(AbstractSpringIndexElement.NO_CHILDREN);
SpringIndexElement[] children = new SpringIndexElement[] {child1};
Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, Set.of("supertype1", "supertype2"), emptyAnnotations, false, children);
Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, Set.of("supertype1", "supertype2"), emptyAnnotations, false);
SubType1 child1 = new SubType1();
bean1.addChild(child1);
SpringIndexElement[] children2 = bean1.getChildren();
assertEquals(1, children2.length);
assertSame(child1, children2[0]);
List<SpringIndexElement> children2 = bean1.getChildren();
assertEquals(1, children2.size());
assertSame(child1, children2.get(0));
}
@Test
void testSpringIndexStructurePolymorphicSerialization() {
Gson gson = IndexCacheOnDiscDeltaBased.createGson();
SubType2 subNode = new SubType2(null);
SubType2 subNode = new SubType2();
SubType1 node1 = new SubType1(new SpringIndexElement[] {subNode});
SubType2 node2 = new SubType2(null);
SubType1 node1 = new SubType1();
node1.addChild(subNode);
Root root = new Root(new SpringIndexElement[] {node1, node2});
SubType2 node2 = new SubType2();
Root root = new Root();
root.addChild(node1);
root.addChild(node2);
String json = gson.toJson(root);
Root deserializedRoot = gson.fromJson(json, Root.class);
SpringIndexElement[] children = deserializedRoot.getChildren();
assertEquals(2, children.length);
List<SpringIndexElement> children = deserializedRoot.getChildren();
assertEquals(2, children.size());
SubType1 deserializedNode1 = (SubType1) java.util.Arrays.stream(children).filter(node -> node instanceof SubType1).findAny().get();
SubType2 deserializedNode2 = (SubType2) java.util.Arrays.stream(children).filter(node -> node instanceof SubType2).findAny().get();
SubType1 deserializedNode1 = (SubType1) children.stream().filter(node -> node instanceof SubType1).findAny().get();
SubType2 deserializedNode2 = (SubType2) children.stream().filter(node -> node instanceof SubType2).findAny().get();
assertNotNull(deserializedNode1);
assertNotNull(deserializedNode2);
SpringIndexElement[] deserializedChild2 = deserializedNode1.getChildren();
assertEquals(1, deserializedChild2.length);
assertTrue(deserializedChild2[0] instanceof SubType2);
List<SpringIndexElement> deserializedChild2 = deserializedNode1.getChildren();
assertEquals(1, deserializedChild2.size());
assertTrue(deserializedChild2.get(0) instanceof SubType2);
}
@Test
@@ -442,45 +447,59 @@ public class SpringMetamodelIndexTest {
Gson gson = IndexCacheOnDiscDeltaBased.createGson();
SubType2 childOfChild = new SubType2(null);
SubType1 child1 = new SubType1(new SpringIndexElement[] {childOfChild});
SubType2 child2 = new SubType2(null);
Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, true, new SpringIndexElement[] {child1, child2});
SubType2 childOfChild = new SubType2();
SubType1 child1 = new SubType1();
child1.addChild(childOfChild);
SubType2 child2 = new SubType2();
Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, true);
bean1.addChild(child1);
bean1.addChild(child2);
String serialized = gson.toJson(bean1);
Bean deserializedBean = gson.fromJson(serialized, Bean.class);
SpringIndexElement[] children = deserializedBean.getChildren();
assertEquals(2, children.length);
List<SpringIndexElement> children = deserializedBean.getChildren();
assertEquals(2, children.size());
SpringIndexElement deserializedChild1 = java.util.Arrays.stream(children).filter(element -> element instanceof SubType1).findAny().get();
SpringIndexElement deserializedChild1 = children.stream().filter(element -> element instanceof SubType1).findAny().get();
assertNotNull(deserializedChild1);
SpringIndexElement[] childrenOfChild = deserializedChild1.getChildren();
assertEquals(1, childrenOfChild.length);
assertTrue(childrenOfChild[0] instanceof SubType2);
List<SpringIndexElement> childrenOfChild = deserializedChild1.getChildren();
assertEquals(1, childrenOfChild.size());
assertTrue(childrenOfChild.get(0) instanceof SubType2);
SpringIndexElement deserializedChild2 = java.util.Arrays.stream(children).filter(element -> element instanceof SubType2).findAny().get();
SpringIndexElement deserializedChild2 = children.stream().filter(element -> element instanceof SubType2).findAny().get();
assertNotNull(deserializedChild2);
assertEquals(0, deserializedChild2.getChildren().length);
assertEquals(0, deserializedChild2.getChildren().size());
}
@Test
void testAddChildAfterDeserialize() {
Gson gson = IndexCacheOnDiscDeltaBased.createGson();
SubType1 child1 = new SubType1();
Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, true);
bean1.addChild(child1);
String serialized = gson.toJson(bean1);
Bean deserializedBean = gson.fromJson(serialized, Bean.class);
SubType2 newChild = new SubType2();
deserializedBean.addChild(newChild);
List<SpringIndexElement> childrenAfterNewChildAdded = deserializedBean.getChildren();
assertEquals(2, childrenAfterNewChildAdded.size());
}
static class SubType1 extends AbstractSpringIndexElement {
public SubType1(SpringIndexElement[] children) {
super(children);
}
}
static class SubType2 extends AbstractSpringIndexElement {
public SubType2(SpringIndexElement[] children) {
super(children);
}
}
static class Root extends AbstractSpringIndexElement {
public Root(SpringIndexElement[] children) {
super(children);
}
}
}

View File

@@ -83,7 +83,7 @@ public class SpringMetamodelIndexingTest {
deleteProject.get(5, TimeUnit.SECONDS);
Bean[] noBeansAnymore = springIndex.getBeansOfProject("test-spring-indexing");
assertNull(noBeansAnymore);
assertEquals(0, noBeansAnymore.length);
assertEquals(2, harness.getIndexUpdatedCount()); // 1x project created, 1x project deleted
}

View File

@@ -39,7 +39,6 @@ import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerMet
import org.springframework.ide.vscode.commons.java.IJavaProject;
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.InjectionPoint;
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
@@ -102,8 +101,8 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals(1, routeBeans.length);
assertEquals("route", routeBeans[0].getName());
SpringIndexElement[] children = routeBeans[0].getChildren();
assertEquals(8, children.length);
List<SpringIndexElement> children = routeBeans[0].getChildren();
assertEquals(8, children.size());
WebfluxHandlerMethodIndexElement handlerElement1 = getWebfluxIndexElements(children, "/hello", "GET").get(0);
assertEquals("/hello", handlerElement1.getPath());
@@ -151,8 +150,8 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals(1, routeBeans.length);
assertEquals("routingFunction1", routeBeans[0].getName());
SpringIndexElement[] children = routeBeans[0].getChildren();
assertEquals(6, children.length);
List<SpringIndexElement> children = routeBeans[0].getChildren();
assertEquals(6, children.size());
WebfluxHandlerMethodIndexElement handlerElement1 = getWebfluxIndexElements(children, "/person/{id}", "GET").get(0);
assertEquals("/person/{id}", handlerElement1.getPath());
@@ -192,8 +191,8 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals(1, routeBeans.length);
assertEquals("routingFunction2", routeBeans[0].getName());
SpringIndexElement[] children = routeBeans[0].getChildren();
assertEquals(6, children.length);
List<SpringIndexElement> children = routeBeans[0].getChildren();
assertEquals(6, children.size());
WebfluxHandlerMethodIndexElement handlerelement1 = getWebfluxIndexElements(children, "/person/{id}", "GET").get(0);
assertEquals("/person/{id}", handlerelement1.getPath());
@@ -237,8 +236,8 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals(1, routeBeans.length);
assertEquals("routingFunction", routeBeans[0].getName());
SpringIndexElement[] children = routeBeans[0].getChildren();
assertEquals(12, children.length);
List<SpringIndexElement> children = routeBeans[0].getChildren();
assertEquals(12, children.size());
WebfluxHandlerMethodIndexElement handlerElement1 = getWebfluxIndexElements(children, "/person/sub1/sub2/{id}", "GET").get(0);
assertEquals("/person/sub1/sub2/{id}", handlerElement1.getPath());
@@ -302,8 +301,8 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals(1, routeBeans.length);
assertEquals("route", routeBeans[0].getName());
SpringIndexElement[] children = routeBeans[0].getChildren();
assertEquals(8, children.length);
List<SpringIndexElement> children = routeBeans[0].getChildren();
assertEquals(8, children.size());
WebfluxHandlerMethodIndexElement handlerElement1 = getWebfluxIndexElements(children, "/hello-updated", "GET").get(0);
assertEquals("/hello-updated", handlerElement1.getPath());
@@ -334,8 +333,8 @@ public class WebFluxMappingSymbolProviderTest {
return false;
}
private List<WebfluxHandlerMethodIndexElement> getWebfluxIndexElements(SpringIndexElement[] indexElements, String path, String httpMethod) {
return Arrays.stream(indexElements)
private List<WebfluxHandlerMethodIndexElement> getWebfluxIndexElements(List<SpringIndexElement> children, String path, String httpMethod) {
return children.stream()
.filter((obj) -> obj instanceof WebfluxHandlerMethodIndexElement)
.map((obj -> (WebfluxHandlerMethodIndexElement) obj))
.filter((addon) -> addon.getPath().equals(path) && Arrays.asList(addon.getHttpMethods()).contains(httpMethod))