early steps towards content-assist for bean references in Spring XML config files

This commit is contained in:
Martin Lippert
2019-04-16 10:48:37 +02:00
parent ca88c6de4e
commit fe65fb9b58
13 changed files with 241 additions and 15 deletions

View File

@@ -79,7 +79,7 @@ public class BootLanguageServerInitializer implements InitializingBean {
CompositeLanguageServerComponents.Builder builder = new CompositeLanguageServerComponents.Builder();
builder.add(new BootPropertiesLanguageServerComponents(server, params, javaElementLocationProvider, parser, yamlStructureProvider, yamlAssistContextProvider, sourceLinks));
builder.add(new BootJavaLanguageServerComponents(server, params, sourceLinks, cuCache, adHocProperties, symbolCache, config, springIndexer, runningAppProvider));
builder.add(new SpringXMLLanguageServerComponents(server, params));
builder.add(new SpringXMLLanguageServerComponents(server, springIndexer, params));
components = builder.build(server);
params.projectObserver.addListener(reconcileOpenDocuments(server, components));

View File

@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
/**
* @author Martin Lippert
*/
public class BeansSymbolAddOnInformation implements SymbolAddOnInformation {
private final String beanID;
public BeansSymbolAddOnInformation(String beanID) {
this.beanID = beanID;
}
public String getBeanID() {
return beanID;
}
}

View File

@@ -29,6 +29,7 @@ import org.eclipse.lsp4j.SymbolKind;
import org.springframework.ide.vscode.boot.java.Annotations;
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
@@ -66,7 +67,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
beanLabel(isFunction, nameAndRegion.getT1(), beanType, "@Bean" + markerString),
SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()))),
null
new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(nameAndRegion.getT1())}
);
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
@@ -88,7 +89,8 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(functionBean.getT3())));
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), new EnhancedSymbolInformation(symbol, null)));
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(),
new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(functionBean.getT1())})));
} catch (BadLocationException e) {
Log.log(e);

View File

@@ -22,6 +22,7 @@ import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
import org.springframework.ide.vscode.commons.util.BadLocationException;
@@ -56,7 +57,10 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider {
SymbolInformation symbol = new SymbolInformation(
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType), SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
return new EnhancedSymbolInformation(symbol, null);
SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(beanName)};
return new EnhancedSymbolInformation(symbol, addon);
}
protected String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {

View File

@@ -18,8 +18,10 @@ import org.eclipse.lsp4j.SymbolKind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
@@ -47,7 +49,10 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider {
beanLabel(true, repositoryBean.getT1(), repositoryBean.getT2(), repositoryBean.getT3()),
SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(repositoryBean.getT4())));
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null);
SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(repositoryBean.getT1())};
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, addon);
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
} catch (BadLocationException e) {
log.error("error creating data repository symbol for a specific range", e);

View File

@@ -20,7 +20,9 @@ import org.eclipse.lsp4j.SymbolKind;
import org.eclipse.lsp4xml.dom.DOMAttr;
import org.eclipse.lsp4xml.dom.DOMNode;
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import org.springframework.lang.NonNull;
@@ -86,8 +88,9 @@ public class SpringIndexerXMLNamespaceHandlerBeans implements SpringIndexerXMLNa
}
SymbolInformation symbol = new SymbolInformation("@+ '" + beanID + "' " + beanClass, SymbolKind.Interface, new Location(docURI, range));
SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(beanID)};
EnhancedSymbolInformation fullSymbol = new EnhancedSymbolInformation(symbol, null);
EnhancedSymbolInformation fullSymbol = new EnhancedSymbolInformation(symbol, addon);
CachedSymbol cachedSymbol = new CachedSymbol(docURI, lastModified, fullSymbol);
generatedSymbols.add(cachedSymbol);

View File

@@ -22,6 +22,8 @@ import org.eclipse.lsp4xml.dom.DOMParser;
import org.eclipse.lsp4xml.dom.parser.Scanner;
import org.eclipse.lsp4xml.dom.parser.TokenType;
import org.eclipse.lsp4xml.dom.parser.XMLScanner;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.xml.completions.BeanRefCompletionProposalProvider;
import org.springframework.ide.vscode.boot.xml.completions.PropertyNameCompletionProposalProvider;
import org.springframework.ide.vscode.boot.xml.completions.TypeCompletionProposalProvider;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
@@ -37,17 +39,21 @@ public class SpringXMLCompletionEngine implements ICompletionEngine {
private static final String BEANS_NAMESPACE = "http://www.springframework.org/schema/beans";
private static final String BEAN_ELEMENT = "bean";
private static final String BEAN_CLASS_ATTRIBUTE = "class";
private static final String CLASS_ATTRIBUTE = "class";
private static final String PROPERTY_ELEMENT = "property";
private static final String PROPERTY_NAME_ATTRIBUTE = "name";
private static final String NAME_ATTRIBUTE = "name";
private static final String REF_ATTRIBUTE = "ref";
private final Map<XMLCompletionProviderKey, XMLCompletionProvider> completionProviders;
public SpringXMLCompletionEngine(SpringXMLLanguageServerComponents springXMLLanguageServerComponents, JavaProjectFinder projectFinder) {
public SpringXMLCompletionEngine(SpringXMLLanguageServerComponents springXMLLanguageServerComponents,
JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex) {
this.completionProviders = new HashMap<>();
this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, null, BEAN_ELEMENT, BEAN_CLASS_ATTRIBUTE), new TypeCompletionProposalProvider(projectFinder, true));
this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, BEAN_ELEMENT, PROPERTY_ELEMENT, PROPERTY_NAME_ATTRIBUTE), new PropertyNameCompletionProposalProvider(projectFinder));
this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, null, BEAN_ELEMENT, CLASS_ATTRIBUTE), new TypeCompletionProposalProvider(projectFinder, true));
this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, BEAN_ELEMENT, PROPERTY_ELEMENT, NAME_ATTRIBUTE), new PropertyNameCompletionProposalProvider(projectFinder));
this.completionProviders.put(new XMLCompletionProviderKey(BEANS_NAMESPACE, BEAN_ELEMENT, PROPERTY_ELEMENT, REF_ATTRIBUTE), new BeanRefCompletionProposalProvider(projectFinder, symbolIndex));
}
@Override

View File

@@ -15,6 +15,7 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.boot.app.BootLanguageServerParams;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
@@ -36,13 +37,17 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen
private final SimpleLanguageServer server;
private final BootLanguageServerParams serverParams;
private final JavaProjectFinder projectFinder;
private final SpringSymbolIndex symbolIndex;
public SpringXMLLanguageServerComponents(
SimpleLanguageServer server,
SpringSymbolIndex springIndexer,
BootLanguageServerParams serverParams) {
this.server = server;
this.serverParams = serverParams;
this.projectFinder = serverParams.projectFinder;
this.symbolIndex = springIndexer;
server.doOnInitialized(this::initialized);
server.onShutdown(this::shutdown);
@@ -55,7 +60,7 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen
@Override
public ICompletionEngine getCompletionEngine() {
return new SpringXMLCompletionEngine(this, projectFinder);
return new SpringXMLCompletionEngine(this, projectFinder, symbolIndex);
}
@Override

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.xml.completions;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4xml.dom.DOMAttr;
import org.eclipse.lsp4xml.dom.DOMNode;
import org.eclipse.lsp4xml.dom.parser.Scanner;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.boot.xml.XMLCompletionProvider;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import reactor.util.function.Tuple2;
import reactor.util.function.TupleExtensionsKt;
import reactor.util.function.Tuples;
/**
* @author Martin Lippert
*/
public class BeanRefCompletionProposalProvider implements XMLCompletionProvider {
private final JavaProjectFinder projectFinder;
private final SpringSymbolIndex symbolIndex;
public BeanRefCompletionProposalProvider(JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex) {
this.projectFinder = projectFinder;
this.symbolIndex = symbolIndex;
}
@Override
public Collection<ICompletionProposal> getCompletions(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt,
Scanner scanner, int offset) {
int tokenOffset = scanner.getTokenOffset();
int tokenEnd = scanner.getTokenEnd();
String tokenText = scanner.getTokenText();
Optional<IJavaProject> foundProject = this.projectFinder.find(doc.getId());
if (foundProject.isPresent()) {
IJavaProject project = foundProject.get();
String prefix = tokenText.substring(0, offset - tokenOffset);
if (prefix.startsWith("\"")) {
prefix = prefix.substring(1);
}
final String searchPrefix = prefix;
List<SymbolAddOnInformation> addonInfos = symbolIndex.getAllAdditionalInformation(addonInfo -> addonInfo instanceof BeansSymbolAddOnInformation);
return addonInfos.stream()
.map(info -> (BeansSymbolAddOnInformation) info)
.map(beanInfo -> beanInfo.getBeanID())
.filter(beanID -> beanID != null && beanID.length() > 0)
.map(beanID -> Tuples.of(beanID, FuzzyMatcher.matchScore(searchPrefix, beanID)))
.filter(tuple -> tuple.getT2() != 0.0)
.map(tuple -> createProposal(tuple.getT1(), doc, offset, tokenOffset, tokenEnd, tuple.getT2()))
.collect(Collectors.toList());
};
return Collections.emptyList();
}
private ICompletionProposal createProposal(String beanID, TextDocument doc, int offset, int tokenStart, int tokenEnd, Double score) {
CompletionItemKind kind = CompletionItemKind.Reference;
DocumentEdits edits = new DocumentEdits(doc);
edits.replace(tokenStart, tokenEnd, "\"" + beanID + "\"");
Renderable renderable = null;
return new TypeCompletionProposal(beanID, kind, edits, beanID, renderable, score);
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 Pivotal, Inc.
* Copyright (c) 2017, 2019 Pivotal, 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
@@ -10,9 +10,13 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans.test;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.junit.Before;
@@ -24,6 +28,8 @@ import org.springframework.ide.vscode.boot.app.BootLanguageServerInitializer;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
@@ -66,6 +72,19 @@ public class SpringIndexerBeansTest {
SpringIndexerHarness.symbol("@Configuration", "@+ 'simpleConfiguration' (@Configuration <: @Component) SimpleConfiguration"),
SpringIndexerHarness.symbol("@Bean", "@+ 'simpleBean' (@Bean) BeanClass")
);
List<? extends SymbolAddOnInformation> addon = indexer.getAdditonalInformation(docUri);
assertEquals(2, addon.size());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "simpleConfiguration".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "simpleBean".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
}
@Test public void testScanSpecialConfigurationClass() throws Exception {

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 Pivotal, Inc.
* Copyright (c) 2017, 2019 Pivotal, 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
@@ -10,7 +10,10 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans.test;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@@ -23,6 +26,8 @@ import org.springframework.context.annotation.Import;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
@@ -64,6 +69,19 @@ public class SpringIndexerFunctionBeansTest {
SpringIndexerHarness.symbol("@Configuration", "@+ 'functionClass' (@Configuration <: @Component) FunctionClass"),
SpringIndexerHarness.symbol("@Bean", "@> 'uppercase' (@Bean) Function<String,String>")
);
List<? extends SymbolAddOnInformation> addon = indexer.getAdditonalInformation(docUri);
assertEquals(2, addon.size());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "functionClass".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "uppercase".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
}
@Test

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018 Pivotal, Inc.
* Copyright (c) 2018, 2019 Pivotal, 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
@@ -29,6 +29,8 @@ import org.springframework.context.annotation.Import;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
@@ -68,6 +70,11 @@ public class DataRepositorySymbolProviderTest {
List<? extends SymbolInformation> symbols = indexer.getSymbols(docUri);
assertEquals(1, symbols.size());
assertTrue(containsSymbol(symbols, "@+ 'customerRepository' (Customer) Repository<Customer,Long>", docUri, 6, 17, 6, 35));
List<? extends SymbolAddOnInformation> addon = indexer.getAdditonalInformation(docUri);
assertEquals(1, addon.size());
assertEquals("customerRepository", ((BeansSymbolAddOnInformation)addon.get(0)).getBeanID());
}
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {

View File

@@ -29,6 +29,8 @@ import org.springframework.context.annotation.Import;
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
@@ -78,8 +80,36 @@ public class SpringIndexerXMLProjectTest {
assertTrue(containsSymbol(allSymbols, "@+ 'namedParameterJdbcTemplate' NamedParameterJdbcTemplate", docUri, 12, 14, 12, 45));
assertTrue(containsSymbol(allSymbols, "@+ 'persistenceExceptionTranslationPostProcessor' PersistenceExceptionTranslationPostProcessor", docUri, 18, 10, 18, 97));
List<? extends SymbolAddOnInformation> addon = indexer.getAdditonalInformation(docUri);
assertEquals(4, addon.size());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "transactionManager".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "jdbcTemplate".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "namedParameterJdbcTemplate".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
assertEquals(1, addon.stream()
.filter(info -> info instanceof BeansSymbolAddOnInformation)
.filter(info -> "persistenceExceptionTranslationPostProcessor".equals(((BeansSymbolAddOnInformation)info).getBeanID()))
.count());
String beansOnClasspathDocUri = directory.toPath().resolve("src/main/resources/beans.xml").toUri().toString();
assertTrue(containsSymbol(allSymbols, "@+ 'sb' SimpleBean", beansOnClasspathDocUri, 6, 14, 6, 21));
addon = indexer.getAdditonalInformation(beansOnClasspathDocUri);
assertEquals(1, addon.size());
assertEquals("sb", ((BeansSymbolAddOnInformation)addon.get(0)).getBeanID());
}
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {