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

@@ -10,19 +10,39 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSpringIndexElement implements SpringIndexElement {
public static final SpringIndexElement[] NO_CHILDREN = new SpringIndexElement[0];
private final SpringIndexElement[] children;
public static final List<SpringIndexElement> NO_CHILDREN = List.of();
private List<SpringIndexElement> children;
public AbstractSpringIndexElement(SpringIndexElement[] children) {
this.children = children != null ? children : NO_CHILDREN;
public AbstractSpringIndexElement() {
this.children = NO_CHILDREN;
}
@Override
public SpringIndexElement[] getChildren() {
public List<SpringIndexElement> getChildren() {
return children;
}
public void addChild(SpringIndexElement child) {
if (children == NO_CHILDREN) {
children = new ArrayList<>();
}
this.children.add(child);
}
public void removeChild(SpringIndexElement doc) {
boolean removed = this.children.remove(doc);
if (removed && this.children.size() == 0) {
this.children = NO_CHILDREN;
}
}
}

View File

@@ -33,11 +33,8 @@ public class Bean extends AbstractSpringIndexElement {
InjectionPoint[] injectionPoints,
Set<String> supertypes,
AnnotationMetadata[] annotations,
boolean isConfiguration,
SpringIndexElement[] children) {
boolean isConfiguration) {
super(children);
this.name = name;
this.type = type;
this.location = location;
@@ -68,18 +65,6 @@ public class Bean extends AbstractSpringIndexElement {
}
}
public Bean(
String name,
String type,
Location location,
InjectionPoint[] injectionPoints,
Set<String> supertypes,
AnnotationMetadata[] annotations,
boolean isConfiguration) {
this(name, type, location, injectionPoints, supertypes, annotations, isConfiguration, AbstractSpringIndexElement.NO_CHILDREN);
}
public String getName() {
return name;
}

View File

@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom
* 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:
* Broadcom - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
public class DocumentElement extends AbstractSpringIndexElement {
private final String docURI;
public DocumentElement(String docURI) {
this.docURI = docURI;
}
public String getDocURI() {
return docURI;
}
}

View File

@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2025 Broadcom
* 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:
* Broadcom - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
import java.util.Iterator;
import java.util.List;
public class ProjectElement extends AbstractSpringIndexElement {
private String projectName;
public ProjectElement(String projectName) {
this.projectName = projectName;
}
public String getProjectName() {
return projectName;
}
public void removeDocument(String docURI) {
List<SpringIndexElement> children = this.getChildren();
for (Iterator<SpringIndexElement> iterator = children.iterator(); iterator.hasNext();) {
SpringIndexElement springIndexElement = (SpringIndexElement) iterator.next();
if (springIndexElement instanceof DocumentElement doc && doc.getDocURI().equals(docURI)) {
iterator.remove();
}
}
}
}

View File

@@ -10,8 +10,10 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
import java.util.List;
public interface SpringIndexElement {
SpringIndexElement[] getChildren();
List<SpringIndexElement> getChildren();
}

View File

@@ -10,125 +10,207 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.index;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
import org.springframework.ide.vscode.commons.protocol.spring.DocumentElement;
import org.springframework.ide.vscode.commons.protocol.spring.ProjectElement;
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
public class SpringMetamodelIndex {
private final ConcurrentMap<String, Bean[]> beansPerProject;
private final ConcurrentMap<String, ProjectElement> projectRootElements;
public SpringMetamodelIndex() {
beansPerProject = new ConcurrentHashMap<>();
projectRootElements = new ConcurrentHashMap<>();
}
public void updateBeans(String projectName, Bean[] beanDefinitions) {
beansPerProject.put(projectName, beanDefinitions);
ProjectElement projectRoot = new ProjectElement(projectName);
Map<String, DocumentElement> documents = new HashMap<>();
for (Bean bean : beanDefinitions) {
String docURI = bean.getLocation() != null ? bean.getLocation().getUri() : null;
if (docURI != null) {
DocumentElement document = documents.computeIfAbsent(docURI, uri -> {
DocumentElement newDocument = new DocumentElement(uri);
projectRoot.addChild(newDocument);
return newDocument;
});
document.addChild(bean);
}
else {
projectRoot.addChild(bean);
}
}
projectRootElements.put(projectName, projectRoot);
}
public void updateBeans(String projectName, String docURI, Bean[] beanDefinitions) {
Bean[] existingBeans = beansPerProject.putIfAbsent(projectName, beanDefinitions);
if (existingBeans != null) {
List<Bean> beans = new ArrayList<>();
// add old, unrelated beans
for (Bean bean : existingBeans) {
if (!bean.getLocation().getUri().equals(docURI)) {
beans.add(bean);
}
}
// add new beans for doc URI
beans.addAll(Arrays.asList(beanDefinitions));
// set new beans set
beansPerProject.put(projectName, (Bean[]) beans.toArray(new Bean[beans.size()]));
ProjectElement project = this.projectRootElements.computeIfAbsent(projectName, name -> new ProjectElement(name));
project.removeDocument(docURI);
DocumentElement document = new DocumentElement(docURI);
for (Bean bean : beanDefinitions) {
document.addChild(bean);
}
project.addChild(document);
}
public void removeBeans(String projectName) {
beansPerProject.remove(projectName);
projectRootElements.remove(projectName);
}
public void removeBeans(String projectName, String docURI) {
Bean[] oldBeans = beansPerProject.get(projectName);
if (oldBeans != null) {
List<Bean> newBeans = Arrays.stream(oldBeans)
.filter(bean -> !bean.getLocation().getUri().equals(docURI))
.collect(Collectors.toList());
beansPerProject.put(projectName, (Bean[]) newBeans.toArray(new Bean[newBeans.size()]));
ProjectElement project = projectRootElements.get(projectName);
if (project != null) {
project.removeDocument(docURI);
}
}
public Bean[] getBeans() {
List<Bean> result = new ArrayList<>();
for (Bean[] beans : beansPerProject.values()) {
for (Bean bean : beans) {
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.addAll(this.projectRootElements.values());
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean) {
result.add(bean);
}
elementsToVisit.addAll(element.getChildren());
}
return (Bean[]) result.toArray(new Bean[result.size()]);
}
public Bean[] getBeansOfProject(String projectName) {
return beansPerProject.get(projectName);
}
public Bean[] getBeansOfDocument(String docURI) {
List<Bean> result = new ArrayList<>();
for (Bean[] beans : beansPerProject.values()) {
for (Bean bean : beans) {
if (bean.getLocation().getUri().equals(docURI)) {
ProjectElement project = this.projectRootElements.get(projectName);
if (project != null) {
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.push(project);
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean) {
result.add(bean);
}
elementsToVisit.addAll(element.getChildren());
}
}
return (Bean[]) result.toArray(new Bean[result.size()]);
}
public Bean[] getBeansWithName(String project, String name) {
Bean[] allBeans = this.beansPerProject.get(project);
public Bean[] getBeansOfDocument(String docURI) {
List<Bean> result = new ArrayList<>();
if (allBeans != null) {
return Arrays.stream(allBeans).filter(bean -> bean.getName().equals(name)).toArray(Bean[]::new);
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.addAll(this.projectRootElements.values());
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean) {
result.add(bean);
}
if (element instanceof DocumentElement doc) {
if (doc.getDocURI().equals(docURI)) {
elementsToVisit.addAll(doc.getChildren());
}
// else do not look into other document structures
}
else {
elementsToVisit.addAll(element.getChildren());
}
}
else {
return null;
return (Bean[]) result.toArray(new Bean[result.size()]);
}
public Bean[] getBeansWithName(String projectName, String name) {
List<Bean> result = new ArrayList<>();
ProjectElement project = this.projectRootElements.get(projectName);
if (project != null) {
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.push(project);
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean && bean.getName().equals(name)) {
result.add(bean);
}
elementsToVisit.addAll(element.getChildren());
}
}
return (Bean[]) result.toArray(new Bean[result.size()]);
}
public Bean[] getBeansWithType(String project, String type) {
Bean[] allBeans = this.beansPerProject.get(project);
if (allBeans != null) {
return Arrays.stream(allBeans).filter(bean -> bean.getType().equals(type)).toArray(Bean[]::new);
}
else {
return null;
public Bean[] getBeansWithType(String projectName, String type) {
List<Bean> result = new ArrayList<>();
ProjectElement project = this.projectRootElements.get(projectName);
if (project != null) {
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.push(project);
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean && bean.getType().equals(type)) {
result.add(bean);
}
elementsToVisit.addAll(element.getChildren());
}
}
return (Bean[]) result.toArray(new Bean[result.size()]);
}
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;
List<Bean> result = new ArrayList<>();
ProjectElement project = this.projectRootElements.get(projectName);
if (project != null) {
ArrayDeque<SpringIndexElement> elementsToVisit = new ArrayDeque<>();
elementsToVisit.push(project);
while (!elementsToVisit.isEmpty()) {
SpringIndexElement element = elementsToVisit.pop();
if (element instanceof Bean bean && bean.isTypeCompatibleWith(matchType)) {
result.add(bean);
}
elementsToVisit.addAll(element.getChildren());
}
}
return (Bean[]) result.toArray(new Bean[result.size()]);
}
}

View File

@@ -660,9 +660,15 @@ public class IndexCacheOnDiscDeltaBased implements IndexCache {
boolean isConfiguration = context.deserialize(isConfigurationObject, boolean.class);
JsonElement childrenObject = parsedObject.get("children");
SpringIndexElement[] children = context.deserialize(childrenObject, SpringIndexElement[].class);
Type childrenListType = TypeToken.getParameterized(List.class, SpringIndexElement.class).getType();
List<SpringIndexElement> children = context.deserialize(childrenObject, childrenListType);
return new Bean(beanName, beanType, location, injectionPoints, supertypes, annotations, isConfiguration, children);
Bean bean = new Bean(beanName, beanType, location, injectionPoints, supertypes, annotations, isConfiguration);
for (SpringIndexElement springIndexElement : children) {
bean.addChild(springIndexElement);
}
return bean;
}
}

View File

@@ -115,7 +115,12 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
Collection<Annotation> annotationsOnMethod = ASTUtils.getAnnotations(method);
AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnMethod, doc);
Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations, false, childElements.toArray(SpringIndexElement[]::new));
Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations, false);
if (childElements.size() > 0) {
for (SpringIndexElement springIndexElement : childElements) {
beanDefinition.addChild(springIndexElement);
}
}
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));

View File

@@ -95,7 +95,7 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
Bean[] beans = springIndex.getBeans();
return Arrays.stream(beans)
.flatMap(bean -> Arrays.stream(bean.getChildren()))
.flatMap(bean -> bean.getChildren().stream())
.filter(element -> element instanceof WebfluxHandlerMethodIndexElement)
.map(element -> (WebfluxHandlerMethodIndexElement) element)
.filter(webfluxElement -> webfluxElement.getHandlerClass() != null && webfluxElement.getHandlerClass().equals(handlerClass)

View File

@@ -23,8 +23,6 @@ public class WebfluxHandlerMethodIndexElement extends AbstractSpringIndexElement
private final String[] acceptTypes;
public WebfluxHandlerMethodIndexElement(String handlerClass, String handlerMethod, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
super(AbstractSpringIndexElement.NO_CHILDREN);
this.handlerClass = handlerClass;
this.handlerMethod = handlerMethod;

View File

@@ -21,7 +21,6 @@ public class WebfluxRouteElementRangesIndexElement extends AbstractSpringIndexEl
private Range[] ranges;
public WebfluxRouteElementRangesIndexElement(Range... ranges) {
super(AbstractSpringIndexElement.NO_CHILDREN);
this.ranges = ranges != null ? ranges : NO_RANGES;
}

View File

@@ -44,7 +44,7 @@ public class WebfluxRouteHighlightProdivder implements HighlightProvider {
Bean[] beans = springIndex.getBeans();
Arrays.stream(beans)
.flatMap(bean -> Arrays.stream(bean.getChildren()))
.flatMap(bean -> bean.getChildren().stream())
.filter(element -> element instanceof WebfluxRouteElementRangesIndexElement)
.map(element -> (WebfluxRouteElementRangesIndexElement) element)
.filter(rangesElement -> rangesElement.contains(position))

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))