GH-1425: refactored indexer mechanics to mostly work on indexer model elements instead of concrete bean objects
This commit is contained in:
@@ -15,5 +15,8 @@ import java.util.List;
|
||||
public interface SpringIndexElement {
|
||||
|
||||
List<SpringIndexElement> getChildren();
|
||||
|
||||
void addChild(SpringIndexElement child);
|
||||
void removeChild(SpringIndexElement doc);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -83,6 +84,7 @@ 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.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.util.Futures;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
@@ -166,7 +168,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
|
||||
SymbolHandler handler = new SymbolHandler() {
|
||||
@Override
|
||||
public void addSymbols(IJavaProject project, String docURI, EnhancedSymbolInformation[] enhancedSymbols, Bean[] beanDefinitions,
|
||||
public void addSymbols(IJavaProject project, String docURI, EnhancedSymbolInformation[] enhancedSymbols, List<SpringIndexElement> beanDefinitions,
|
||||
List<Diagnostic> diagnostics) {
|
||||
|
||||
if (enhancedSymbols != null) {
|
||||
@@ -174,7 +176,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
}
|
||||
|
||||
if (beanDefinitions != null) {
|
||||
springIndex.updateBeans(project.getElementName(), docURI, beanDefinitions);
|
||||
springIndex.updateElements(project.getElementName(), docURI, beanDefinitions.toArray(SpringIndexElement[]::new));
|
||||
}
|
||||
|
||||
if (diagnostics != null) {
|
||||
@@ -185,7 +187,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
|
||||
@Override
|
||||
public void addSymbols(IJavaProject project, EnhancedSymbolInformation[] enhancedSymbols,
|
||||
Bean[] beanDefinitions, Map<String, List<Diagnostic>> diagnosticsPerDoc) {
|
||||
Map<String, List<SpringIndexElement>> beanDefinitionsByDoc, Map<String, List<Diagnostic>> diagnosticsPerDoc) {
|
||||
|
||||
if (enhancedSymbols != null) {
|
||||
|
||||
@@ -207,21 +209,14 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
}
|
||||
}
|
||||
|
||||
if (beanDefinitions != null) {
|
||||
if (beanDefinitionsByDoc != null) {
|
||||
|
||||
// organize beans per doc URI
|
||||
Map<String, List<Bean>> beansPerDoc = new HashMap<>();
|
||||
for (Bean bean : beanDefinitions) {
|
||||
String docURI = bean.getLocation().getUri();
|
||||
beansPerDoc.computeIfAbsent(docURI, k -> new ArrayList<>()).add(bean);
|
||||
}
|
||||
|
||||
// add beans per doc URI
|
||||
for (Map.Entry<String, List<Bean>> entry : beansPerDoc.entrySet()) {
|
||||
for (Entry<String, List<SpringIndexElement>> entry : beanDefinitionsByDoc.entrySet()) {
|
||||
String docURI = entry.getKey();
|
||||
List<Bean> beans = entry.getValue();
|
||||
List<SpringIndexElement> elements = entry.getValue();
|
||||
|
||||
springIndex.updateBeans(project.getElementName(), docURI, (Bean[]) beans.toArray(new Bean[beans.size()]));
|
||||
springIndex.updateElements(project.getElementName(), docURI, elements.toArray(SpringIndexElement[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +231,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
@Override
|
||||
public void removeSymbols(IJavaProject project, String docURI) {
|
||||
SpringSymbolIndex.this.removeSymbolsByDoc(project, docURI);
|
||||
springIndex.removeBeans(project.getElementName(), docURI);
|
||||
springIndex.removeElements(project.getElementName(), docURI);
|
||||
|
||||
// TODO remove diagnostics ?!? maybe, maybe not
|
||||
|
||||
@@ -382,11 +377,14 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
private CompletableFuture<Void> _initializeProject(IJavaProject project, boolean clean) {
|
||||
try {
|
||||
if (SpringProjectUtil.isBootProject(project) || SpringProjectUtil.isSpringProject(project)) {
|
||||
|
||||
if (project.getElementName() == null) {
|
||||
// Projects indexed by name. No name - no index for it
|
||||
log.debug("Project with NULL name is being initialized");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
|
||||
} else {
|
||||
|
||||
synchronized(this) { // synchronized since the `indexers` array can change via a settings change
|
||||
@SuppressWarnings("unchecked")
|
||||
CompletableFuture<Void>[] futures = new CompletableFuture[this.indexers.length + 1];
|
||||
@@ -394,7 +392,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
// clean future
|
||||
futures[0] = CompletableFuture.runAsync(() -> {
|
||||
removeSymbolsByProject(project);
|
||||
springIndex.removeBeans(project.getElementName());
|
||||
springIndex.removeProject(project.getElementName());
|
||||
}, this.updateQueue);
|
||||
|
||||
// index futures
|
||||
@@ -923,7 +921,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
try {
|
||||
for (String doc : this.docURIs) {
|
||||
removeSymbolsByDoc(project, doc);
|
||||
springIndex.removeBeans(project.getElementName(), doc);
|
||||
springIndex.removeElements(project.getElementName(), doc);
|
||||
}
|
||||
|
||||
for (SpringIndexer index : this.indexer) {
|
||||
@@ -955,7 +953,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
for (SpringIndexer index : this.indexer) {
|
||||
index.removeProject(project);
|
||||
}
|
||||
springIndex.removeBeans(project.getElementName());
|
||||
springIndex.removeProject(project.getElementName());
|
||||
server.getClient().indexUpdated();
|
||||
|
||||
log.debug("{} completed", this);
|
||||
|
||||
@@ -56,23 +56,23 @@ public class SpringMetamodelIndex {
|
||||
projectRootElements.put(projectName, projectRoot);
|
||||
}
|
||||
|
||||
public void updateBeans(String projectName, String docURI, Bean[] beanDefinitions) {
|
||||
public void updateElements(String projectName, String docURI, SpringIndexElement[] beanDefinitions) {
|
||||
ProjectElement project = this.projectRootElements.computeIfAbsent(projectName, name -> new ProjectElement(name));
|
||||
project.removeDocument(docURI);
|
||||
|
||||
DocumentElement document = new DocumentElement(docURI);
|
||||
for (Bean bean : beanDefinitions) {
|
||||
for (SpringIndexElement bean : beanDefinitions) {
|
||||
document.addChild(bean);
|
||||
}
|
||||
|
||||
project.addChild(document);
|
||||
}
|
||||
|
||||
public void removeBeans(String projectName) {
|
||||
public void removeProject(String projectName) {
|
||||
projectRootElements.remove(projectName);
|
||||
}
|
||||
|
||||
public void removeBeans(String projectName, String docURI) {
|
||||
public void removeElements(String projectName, String docURI) {
|
||||
ProjectElement project = projectRootElements.get(projectName);
|
||||
if (project != null) {
|
||||
project.removeDocument(docURI);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* Copyright (c) 2023, 2025 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
|
||||
@@ -11,19 +11,19 @@
|
||||
package org.springframework.ide.vscode.boot.java.beans;
|
||||
|
||||
import org.springframework.ide.vscode.boot.index.cache.AbstractIndexCacheable;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
|
||||
public class CachedBean extends AbstractIndexCacheable {
|
||||
|
||||
private final Bean bean;
|
||||
private final SpringIndexElement element;
|
||||
|
||||
public CachedBean(String docURI, Bean bean) {
|
||||
public CachedBean(String docURI, SpringIndexElement bean) {
|
||||
super(docURI);
|
||||
this.bean = bean;
|
||||
this.element = bean;
|
||||
}
|
||||
|
||||
public Bean getBean() {
|
||||
return this.bean;
|
||||
public SpringIndexElement getBean() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.Classpath;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -320,7 +320,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
// dependencyTracker.dump();
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
List<SpringIndexElement> beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toList();
|
||||
List<Diagnostic> diagnostics = generatedDiagnostics.stream().filter(cachedDiagnostics -> cachedDiagnostics.getDiagnostic() != null).map(cachedDiagnostic -> cachedDiagnostic.getDiagnostic()).collect(Collectors.toList());
|
||||
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans, diagnostics);
|
||||
@@ -436,7 +436,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
}
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
Map<String, List<SpringIndexElement>> beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).collect(Collectors.groupingBy(CachedBean::getDocURI, Collectors.mapping(CachedBean::getBean, Collectors.toList())));
|
||||
Map<String, List<Diagnostic>> diagnosticsByDoc = generatedDiagnostics.stream().filter(cachedDiagnostic -> cachedDiagnostic.getDiagnostic() != null).collect(Collectors.groupingBy(CachedDiagnostics::getDocURI, Collectors.mapping(CachedDiagnostics::getDiagnostic, Collectors.toList())));
|
||||
addEmptyDiagnostics(diagnosticsByDoc, javaFiles);
|
||||
symbolHandler.addSymbols(project, symbols, beans, diagnosticsByDoc);
|
||||
@@ -548,7 +548,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
if (symbols != null && beans != null) {
|
||||
EnhancedSymbolInformation[] enhancedSymbols = Arrays.stream(symbols).map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
Map<String, List<SpringIndexElement>> allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).collect(Collectors.groupingBy(CachedBean::getDocURI, Collectors.mapping(CachedBean::getBean, Collectors.toList())));
|
||||
Map<String, List<Diagnostic>> diagnosticsByDoc = Arrays.stream(diagnostics).filter(cachedDiagnostic -> cachedDiagnostic.getDiagnostic() != null).collect(Collectors.groupingBy(CachedDiagnostics::getDocURI, Collectors.mapping(CachedDiagnostics::getDiagnostic, Collectors.toList())));
|
||||
addEmptyDiagnostics(diagnosticsByDoc, javaFiles);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, allBeans, diagnosticsByDoc);
|
||||
|
||||
@@ -41,7 +41,7 @@ import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
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.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -142,7 +142,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
|
||||
if (symbols != null && beans != null) {
|
||||
EnhancedSymbolInformation[] enhancedSymbols = Arrays.stream(symbols).map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
Map<String, List<SpringIndexElement>> allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).collect(Collectors.groupingBy(CachedBean::getDocURI, Collectors.mapping(CachedBean::getBean, Collectors.toList())));
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, allBeans, null);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
this.cache.update(beansCacheKey, file, updatedDoc.getLastModified(), generatedBeans, null, CachedBean.class);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
List<SpringIndexElement> beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toList();
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans, null);
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
this.cache.update(beansCacheKey, file, updatedDoc.getLastModified(), generatedBeans, null, CachedBean.class);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
List<SpringIndexElement> beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toList();
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,15 @@ import java.util.Map;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public interface SymbolHandler {
|
||||
|
||||
void addSymbols(IJavaProject project, String docURI, EnhancedSymbolInformation[] enhancedSymbols, Bean[] beanDefinitions, List<Diagnostic> diagnostics);
|
||||
void addSymbols(IJavaProject project, EnhancedSymbolInformation[] enhancedSymbols, Bean[] beanDefinitions, Map<String, List<Diagnostic>> diagnosticsByDoc);
|
||||
void addSymbols(IJavaProject project, String docURI, EnhancedSymbolInformation[] enhancedSymbols, List<SpringIndexElement> beanDefinitions, List<Diagnostic> diagnostics);
|
||||
void addSymbols(IJavaProject project, EnhancedSymbolInformation[] enhancedSymbols, Map<String, List<SpringIndexElement>> beanDefinitionsByDoc, Map<String, List<Diagnostic>> diagnosticsByDoc);
|
||||
|
||||
void removeSymbols(IJavaProject project, String docURI);
|
||||
|
||||
|
||||
@@ -136,13 +136,13 @@ public class SpringMetamodelIndexTest {
|
||||
Bean bean2 = new Bean("beanName2", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, false);
|
||||
Bean bean3 = new Bean("beanName3", "beanType", locationForDoc2, emptyInjectionPoints, emptySupertypes, emptyAnnotations, false);
|
||||
|
||||
index.updateBeans("someProject", locationForDoc1.getUri(), new Bean[] {bean1, bean2});
|
||||
index.updateBeans("someProject", locationForDoc2.getUri(), new Bean[] {bean3});
|
||||
index.updateElements("someProject", locationForDoc1.getUri(), new Bean[] {bean1, bean2});
|
||||
index.updateElements("someProject", locationForDoc2.getUri(), new Bean[] {bean3});
|
||||
|
||||
Bean updatedBean1 = new Bean("updated1", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, false);
|
||||
Bean updatedBean2 = new Bean("updated2", "beanType", locationForDoc1, emptyInjectionPoints, emptySupertypes, emptyAnnotations, false);
|
||||
|
||||
index.updateBeans("someProject", locationForDoc1.getUri(), new Bean[] {updatedBean1, updatedBean2});
|
||||
index.updateElements("someProject", locationForDoc1.getUri(), new Bean[] {updatedBean1, updatedBean2});
|
||||
|
||||
Bean[] beans = index.getBeansOfProject("someProject");
|
||||
assertNotNull(beans);
|
||||
@@ -192,7 +192,7 @@ public class SpringMetamodelIndexTest {
|
||||
index.updateBeans("someProject1", new Bean[] {bean1, bean2});
|
||||
index.updateBeans("someProject2", new Bean[] {bean3});
|
||||
|
||||
index.removeBeans("someProject1");
|
||||
index.removeProject("someProject1");
|
||||
|
||||
Bean[] beans = index.getBeansOfProject("someProject2");
|
||||
assertNotNull(beans);
|
||||
@@ -214,7 +214,7 @@ public class SpringMetamodelIndexTest {
|
||||
Bean bean3 = new Bean("beanName3", "beanType", locationForDoc2, emptyInjectionPoints, emptySupertypes, emptyAnnotations, false);
|
||||
|
||||
index.updateBeans("someProject", new Bean[] {bean1, bean2, bean3});
|
||||
index.removeBeans("someProject", locationForDoc1.getUri());
|
||||
index.removeElements("someProject", locationForDoc1.getUri());
|
||||
|
||||
Bean[] beans = index.getBeansOfProject("someProject");
|
||||
assertNotNull(beans);
|
||||
|
||||
@@ -143,7 +143,7 @@ public class DependsOnDefinitionProviderTest {
|
||||
|
||||
List<Bean> beansOfDoc = new ArrayList<>(List.of(springIndex.getBeansOfDocument(expectedDefinitionUri)));
|
||||
beansOfDoc.add(new Bean("bean1", "type", new Location(expectedDefinitionUri, new Range(new Position(20, 1), new Position(20, 10))), null, null, null, false));
|
||||
springIndex.updateBeans(project.getElementName(), expectedDefinitionUri, beansOfDoc.toArray(new Bean[0]));
|
||||
springIndex.updateElements(project.getElementName(), expectedDefinitionUri, beansOfDoc.toArray(new Bean[0]));
|
||||
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), "bean1");
|
||||
assertEquals(2, beans.length);
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ResourceDefinitionProviderTest {
|
||||
|
||||
List<Bean> beansOfDoc = new ArrayList<>(List.of(springIndex.getBeansOfDocument(expectedDefinitionUri)));
|
||||
beansOfDoc.add(new Bean("bean1", "type", new Location(expectedDefinitionUri, new Range(new Position(20, 1), new Position(20, 10))), null, null, null, false));
|
||||
springIndex.updateBeans(project.getElementName(), expectedDefinitionUri, beansOfDoc.toArray(new Bean[0]));
|
||||
springIndex.updateElements(project.getElementName(), expectedDefinitionUri, beansOfDoc.toArray(new Bean[0]));
|
||||
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), "bean1");
|
||||
assertEquals(2, beans.length);
|
||||
|
||||
Reference in New Issue
Block a user