GH-1425: groundwork to allow nested beans in internal index structure
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,10 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.protocol.spring;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SpringIndexElement {
|
||||
|
||||
SpringIndexElement[] getChildren();
|
||||
List<SpringIndexElement> getChildren();
|
||||
|
||||
}
|
||||
|
||||
@@ -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()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user