Skip to content

Commit e8051b0

Browse files
committed
fixed an issue with the index not correctly updated when all spring index elements should be gone after an update
1 parent ca4fc3c commit e8051b0

File tree

7 files changed

+83
-29
lines changed

7 files changed

+83
-29
lines changed

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/SpringMetamodelIndex.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@ public void updateElements(String projectName, String docURI, SpringIndexElement
3737
ProjectElement project = this.projectRootElements.computeIfAbsent(projectName, name -> new ProjectElement(name));
3838
project.removeDocument(docURI);
3939

40-
DocumentElement document = new DocumentElement(docURI);
41-
for (SpringIndexElement bean : elements) {
42-
document.addChild(bean);
43-
}
40+
if (elements != null && elements.length > 0) {
41+
DocumentElement document = new DocumentElement(docURI);
42+
for (SpringIndexElement bean : elements) {
43+
document.addChild(bean);
44+
}
45+
46+
project.addChild(document);
47+
}
4448

45-
project.addChild(document);
4649
}
4750

4851
public void removeElements(String projectName, String docURI) {

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.util.Arrays;
1414
import java.util.Collection;
1515
import java.util.HashSet;
16-
import java.util.List;
1716
import java.util.Set;
1817
import java.util.stream.Collectors;
1918
import java.util.stream.Stream;
@@ -32,13 +31,10 @@
3231
import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two;
3332
import org.slf4j.Logger;
3433
import org.slf4j.LoggerFactory;
35-
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
36-
import org.springframework.ide.vscode.boot.java.Annotations;
3734
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
3835
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
3936
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
4037
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
41-
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationAttributeValue;
4238
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
4339
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
4440
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
@@ -60,28 +56,13 @@ public void addSymbols(Annotation node, ITypeBinding annotationType, Collection<
6056

6157
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
6258
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
63-
64-
markNewFeignConfigTypeForReconciling(beanDefinition, context);
6559
}
6660
}
6761
catch (BadLocationException e) {
6862
log.error("", e);
6963
}
7064
}
7165

72-
private void markNewFeignConfigTypeForReconciling(Bean beanDefinition, SpringIndexerJavaContext context) {
73-
List<String> configurationTypes = Arrays.stream(beanDefinition.getAnnotations())
74-
.filter(annotation -> annotation.getAnnotationType().equals(Annotations.FEIGN_CLIENT))
75-
.map(annotation -> annotation.getAttributes())
76-
.filter(attributes -> attributes.containsKey("configuration"))
77-
.map(attributes -> attributes.get("configuration"))
78-
.flatMap(attributeValues -> Arrays.stream(attributeValues))
79-
.map(attributeValue -> attributeValue.getName())
80-
.toList();
81-
82-
83-
}
84-
8566
private Two<WorkspaceSymbol, Bean> createSymbol(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
8667
String annotationTypeName = annotationType.getName();
8768
Collection<String> metaAnnotationNames = metaAnnotations.stream()

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,8 @@ public void acceptAST(String sourceFilePath, CompilationUnit cu) {
712712
IndexCacheKey diagnosticsCacheKey = getCacheKey(project, DIAGNOSTICS_KEY);
713713
this.cache.update(diagnosticsCacheKey, javaFiles, modificationTimestamps, reconcilingResult.getGeneratedDiagnostics(), dependencyTracker.getAllDependencies(), CachedDiagnostics.class);
714714

715-
// publish
716-
reconcilingResult.publishResults(symbolHandler);
715+
// publish diagnostics
716+
reconcilingResult.publishDiagnosticsOnly(symbolHandler);
717717
}
718718

719719
private void scanAST(final SpringIndexerJavaContext context, boolean includeReconcile) {

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJavaScanResult.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,30 @@ public void publishResults(SymbolHandler symbolHandler) {
110110
Map<String, List<SpringIndexElement>> allBeans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).collect(Collectors.groupingBy(CachedBean::getDocURI, Collectors.mapping(CachedBean::getBean, Collectors.toList())));
111111
Map<String, List<Diagnostic>> diagnosticsByDoc = generatedDiagnostics.stream().filter(cachedDiagnostic -> cachedDiagnostic.getDiagnostic() != null).collect(Collectors.groupingBy(CachedDiagnostics::getDocURI, Collectors.mapping(CachedDiagnostics::getDiagnostic, Collectors.toList())));
112112

113-
addEmptyDiagnostics(diagnosticsByDoc, javaFiles); // to make sure that files without diagnostics publish an empty array of diagnostics
113+
// to make sure that files without index elements or diagnostics publish an empty array of diagnostics
114+
addEmptyDiagnostics(diagnosticsByDoc, javaFiles);
115+
addEmptyIndexElements(allBeans, javaFiles);
114116

115117
symbolHandler.addSymbols(this.project, enhancedSymbols, allBeans, diagnosticsByDoc);
116118
}
117119

120+
public void publishDiagnosticsOnly(SymbolHandler symbolHandler) {
121+
Map<String, List<Diagnostic>> diagnosticsByDoc = generatedDiagnostics.stream().filter(cachedDiagnostic -> cachedDiagnostic.getDiagnostic() != null).collect(Collectors.groupingBy(CachedDiagnostics::getDocURI, Collectors.mapping(CachedDiagnostics::getDiagnostic, Collectors.toList())));
122+
addEmptyDiagnostics(diagnosticsByDoc, javaFiles); // to make sure that files without index elements or diagnostics publish an empty array of diagnostics
123+
symbolHandler.addSymbols(this.project, null, null, diagnosticsByDoc);
124+
}
125+
126+
private void addEmptyIndexElements(Map<String, List<SpringIndexElement>> allBeans, String[] javaFiles) {
127+
for (int i = 0; i < javaFiles.length; i++) {
128+
File file = new File(javaFiles[i]);
129+
String docURI = UriUtil.toUri(file).toASCIIString();
130+
131+
if (!allBeans.containsKey(docURI)) {
132+
allBeans.put(docURI, Collections.emptyList());
133+
}
134+
}
135+
}
136+
118137
private void addEmptyDiagnostics(Map<String, List<Diagnostic>> diagnosticsByDoc, String[] javaFiles) {
119138
for (int i = 0; i < javaFiles.length; i++) {
120139
File file = new File(javaFiles[i]);

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/index/test/SpringMetamodelIndexingTest.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
package org.springframework.ide.vscode.boot.index.test;
1212

1313
import static org.junit.jupiter.api.Assertions.assertEquals;
14-
import static org.junit.jupiter.api.Assertions.assertNull;
1514

1615
import java.io.File;
1716
import java.net.URI;
@@ -46,7 +45,7 @@
4645
@Import(SymbolProviderTestConf.class)
4746
public class SpringMetamodelIndexingTest {
4847

49-
public static final int NO_OF_EXPECTED_BEANS = 28;
48+
public static final int NO_OF_EXPECTED_BEANS = 29;
5049

5150
@Autowired private BootLanguageServerHarness harness;
5251
@Autowired private JavaProjectFinder projectFinder;
@@ -142,6 +141,22 @@ void testUpdateChangedDocument() throws Exception {
142141
assertEquals(2, harness.getIndexUpdatedCount()); // 1x project created, 1x document updated
143142
}
144143

144+
@Test
145+
void testUpdatedDocumentHasNoIndexElementsAnymore() throws Exception {
146+
String changedDocURI = directory.toPath().resolve("src/main/java/org/test/SimpleComponentClass.java").toUri().toString();
147+
148+
Bean[] beans = springIndex.getBeansOfDocument(changedDocURI);
149+
assertEquals(1, beans.length);
150+
assertEquals("simpleComponentClass", beans[0].getName());
151+
152+
String newContent = FileUtils.readFileToString(new File(new URI(changedDocURI)), Charset.defaultCharset()).replace("@Component", "");
153+
CompletableFuture<Void> updateFuture = indexer.updateDocument(changedDocURI, newContent, "test triggered");
154+
updateFuture.get(5, TimeUnit.SECONDS);
155+
156+
Bean[] updatedBeans = springIndex.getBeansOfDocument(changedDocURI);
157+
assertEquals(0, updatedBeans.length);
158+
}
159+
145160
@Test
146161
void testNewDocumentCreated() throws Exception {
147162

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/reconcilers/test/AddConfigurationIfBeansPresentAdvancedReconcilingTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,32 @@ void testErrorAppearsWhenFeignClientNotMentionsFeignConfigAnymore() throws Excep
145145
assertEquals(Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION.getCode(), diagnostics.get(0).getCode().getLeft());
146146
}
147147

148+
@Test
149+
void testErrorAppearsWhenFeignClientAnnotationDoesAwayEntirely() throws Exception {
150+
String feignClientDocUri = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignClientExample.java").toUri().toString();
151+
String feignConfigRegisterd = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigExample.java").toUri().toString();
152+
153+
// now change the config class source code and update doc
154+
TestFileScanListener fileScanListener = new TestFileScanListener();
155+
indexer.getJavaIndexer().setFileScanListener(fileScanListener);
156+
157+
String feignClientSource = FileUtils.readFileToString(UriUtil.toFile(feignClientDocUri), Charset.defaultCharset());
158+
String updatedFeignClientSource = feignClientSource.replace("@FeignClient(name = \"stores\", configuration = FeignConfigExample.class)",
159+
"");
160+
161+
CompletableFuture<Void> updateFuture = indexer.updateDocument(feignClientDocUri, updatedFeignClientSource, "test triggered");
162+
updateFuture.get(5, TimeUnit.SECONDS);
163+
164+
// check if the bean registrar files have been re-scanned
165+
fileScanListener.assertScannedUri(feignClientDocUri, 1);
166+
fileScanListener.assertScannedUri(feignConfigRegisterd, 1);
167+
fileScanListener.assertFileScanCount(2);
168+
169+
// check diagnostics result
170+
PublishDiagnosticsParams diagnosticsResult = harness.getDiagnostics(feignConfigRegisterd);
171+
List<Diagnostic> diagnostics = diagnosticsResult.getDiagnostics();
172+
assertEquals(1, diagnostics.size());
173+
assertEquals(Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION.getCode(), diagnostics.get(0).getCode().getLeft());
174+
}
175+
148176
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.test;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
@Component
6+
public class SimpleComponentClass {
7+
8+
}

0 commit comments

Comments
 (0)