FeignClient config exception for Add @Configuration reconciler
This commit is contained in:
@@ -12,12 +12,12 @@ package org.springframework.ide.vscode.boot.app;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCache;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.beans.FeignClientSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.DataRepositorySymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider;
|
||||
@@ -71,6 +71,8 @@ public class SpringSymbolIndexerConfig {
|
||||
|
||||
providers.put(Annotations.REPOSITORY, dataRepositorySymbolProvider);
|
||||
providers.put("", webfluxRouterSymbolProvider);
|
||||
|
||||
providers.put(Annotations.FEIGN_CLIENT, new FeignClientSymbolProvider());
|
||||
|
||||
return providers;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ public class Annotations {
|
||||
public static final String CONDITIONAL_ON_JNDI = "org.springframework.boot.autoconfigure.condition.ConditionalOnJndi";
|
||||
public static final String CONDITIONAL_ON_SINGLE_CANDIDATE = "org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate";
|
||||
|
||||
public static final String FEIGN_CLIENT = "org.springframework.cloud.openfeign.FeignClient";
|
||||
|
||||
public static final String VALUE = "org.springframework.beans.factory.annotation.Value";
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 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
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.beans;
|
||||
|
||||
public class FeignClientBeanSymbolAddOnInformation extends BeansSymbolAddOnInformation {
|
||||
|
||||
final public String[] configClasses;
|
||||
|
||||
public FeignClientBeanSymbolAddOnInformation(String beanID, String beanType, String... configClasses) {
|
||||
super(beanID, beanType);
|
||||
this.configClasses = configClasses;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 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
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.beans;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ArrayInitializer;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeLiteral;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class FeignClientSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FeignClientSymbolProvider.class);
|
||||
|
||||
@Override
|
||||
protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations,
|
||||
SpringIndexerJavaContext context, TextDocument doc) {
|
||||
try {
|
||||
if (node != null && node.getParent() != null && node.getParent() instanceof TypeDeclaration) {
|
||||
Two<EnhancedSymbolInformation, Bean> result = createSymbol(node, annotationType, metaAnnotations, doc);
|
||||
|
||||
EnhancedSymbolInformation enhancedSymbol = result.getFirst();
|
||||
Bean beanDefinition = result.getSecond();
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Two<EnhancedSymbolInformation, Bean> createSymbol(Annotation node, ITypeBinding annotationType,
|
||||
Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
String annotationTypeName = annotationType.getName();
|
||||
Collection<String> metaAnnotationNames = metaAnnotations.stream()
|
||||
.map(ITypeBinding::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
TypeDeclaration type = (TypeDeclaration) node.getParent();
|
||||
|
||||
String beanName = getBeanName(node, type);
|
||||
ITypeBinding beanType = type.resolveBinding();
|
||||
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType == null ? "" : beanType.getName()), SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new FeignClientBeanSymbolAddOnInformation(beanName, beanType == null ? "" : beanType.getQualifiedName(), getConfigClass(node))};
|
||||
|
||||
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(type, doc);
|
||||
|
||||
Set<String> supertypes = new HashSet<>();
|
||||
ASTUtils.findSupertypes(beanType, supertypes);
|
||||
|
||||
String[] annotations = Stream.concat(Stream.of(annotationType), metaAnnotations.stream()).map(t -> t.getQualifiedName()).toArray(String[]::new);
|
||||
|
||||
Bean beanDefinition = new Bean(beanName, beanType == null ? "" : beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), annotations);
|
||||
|
||||
return Tuple.two(new EnhancedSymbolInformation(symbol, addon), beanDefinition);
|
||||
}
|
||||
|
||||
protected String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
|
||||
StringBuilder symbolLabel = new StringBuilder();
|
||||
symbolLabel.append("@");
|
||||
symbolLabel.append(searchPrefix);
|
||||
symbolLabel.append(' ');
|
||||
symbolLabel.append('\'');
|
||||
symbolLabel.append(beanName);
|
||||
symbolLabel.append('\'');
|
||||
symbolLabel.append(" (@");
|
||||
symbolLabel.append(annotationTypeName);
|
||||
if (!metaAnnotationNames.isEmpty()) {
|
||||
symbolLabel.append(" <: ");
|
||||
boolean first = true;
|
||||
for (String ma : metaAnnotationNames) {
|
||||
if (!first) {
|
||||
symbolLabel.append(", ");
|
||||
}
|
||||
symbolLabel.append("@");
|
||||
symbolLabel.append(ma);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
symbolLabel.append(") ");
|
||||
symbolLabel.append(beanType);
|
||||
return symbolLabel.toString();
|
||||
}
|
||||
|
||||
private String getBeanName(Annotation node, TypeDeclaration typeDecl) {
|
||||
if (node.isSingleMemberAnnotation()) {
|
||||
Object o = ((SingleMemberAnnotation)node).getValue().resolveConstantExpressionValue();
|
||||
if (o instanceof String) {
|
||||
return (String) o;
|
||||
}
|
||||
} else if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normalAnnotation = (NormalAnnotation) node;
|
||||
for (Object o : normalAnnotation.values()) {
|
||||
if (o instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) o;
|
||||
switch (pair.getName().getIdentifier()) {
|
||||
case "name":
|
||||
case "value":
|
||||
Object obj = pair.getValue().resolveConstantExpressionValue();
|
||||
if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return BeanUtils.getBeanNameFromType(typeDecl.getName().getIdentifier());
|
||||
}
|
||||
|
||||
private String[] getConfigClass(Annotation node) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normalAnnotation = (NormalAnnotation) node;
|
||||
for (Object o : normalAnnotation.values()) {
|
||||
if (o instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) o;
|
||||
if ("configuration".equals(pair.getName().getIdentifier())) {
|
||||
if (pair.getValue() instanceof TypeLiteral) {
|
||||
ITypeBinding b = ((TypeLiteral) pair.getValue()).getType().resolveBinding();
|
||||
return new String[] { b.getQualifiedName() };
|
||||
} else if (pair.getValue() instanceof ArrayInitializer){
|
||||
List<?> expressions = (List<?>) ((ArrayInitializer) pair.getValue()).expressions();
|
||||
return expressions.stream()
|
||||
.filter(TypeLiteral.class::isInstance)
|
||||
.map(TypeLiteral.class::cast)
|
||||
.map(tl -> tl.getType().resolveBinding())
|
||||
.filter(Objects::nonNull)
|
||||
.map(b -> b.getQualifiedName())
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,9 +24,17 @@ import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.openrewrite.java.spring.boot2.AddConfigurationAnnotationIfBeansPresent;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.beans.FeignClientBeanSymbolAddOnInformation;
|
||||
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.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
@@ -37,7 +45,7 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.Reconcile
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconciler {
|
||||
public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconciler, ApplicationContextAware {
|
||||
|
||||
private static final String ID = AddConfigurationAnnotationIfBeansPresent.class.getName();
|
||||
|
||||
@@ -47,6 +55,8 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
|
||||
private QuickfixRegistry quickfixRegistry;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public AddConfigurationIfBeansPresentReconciler(QuickfixRegistry quickfixRegistry) {
|
||||
this.quickfixRegistry = quickfixRegistry;
|
||||
}
|
||||
@@ -58,7 +68,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
|
||||
@Override
|
||||
public boolean visit(TypeDeclaration classDecl) {
|
||||
if (isApplicableClass(cu, classDecl)) {
|
||||
if (isApplicableClass(project, cu, classDecl)) {
|
||||
SimpleName nameAst = classDecl.getName();
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), PROBLEM_LABEL,
|
||||
nameAst.getStartPosition(), nameAst.getLength());
|
||||
@@ -79,7 +89,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isApplicableClass(CompilationUnit cu, TypeDeclaration classDecl) {
|
||||
private boolean isApplicableClass(IJavaProject project, CompilationUnit cu, TypeDeclaration classDecl) {
|
||||
if (classDecl.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
@@ -112,16 +122,47 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// No '@Configuration' present. Check if any methods have '@Bean' annotation
|
||||
for (MethodDeclaration m : classDecl.getMethods()) {
|
||||
if (isBeanMethod(m)) {
|
||||
if (isBeanMethod(m) && !isException(project, classDecl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isException(IJavaProject project, TypeDeclaration classDecl) {
|
||||
if (applicationContext != null) {
|
||||
SpringSymbolIndex index = applicationContext.getBean(SpringSymbolIndex.class);
|
||||
if (index != null) {
|
||||
final String beanClassName = RewriteQuickFixUtils.getDeepErasureType(classDecl.resolveBinding()).getQualifiedName();
|
||||
for (EnhancedSymbolInformation s : index.getEnhancedSymbols(project)) {
|
||||
SymbolAddOnInformation[] additionalInformation = s.getAdditionalInformation();
|
||||
if (additionalInformation != null) {
|
||||
for (SymbolAddOnInformation info : additionalInformation) {
|
||||
if (info instanceof BeansSymbolAddOnInformation) {
|
||||
BeansSymbolAddOnInformation info2 = (BeansSymbolAddOnInformation) info;
|
||||
if (beanClassName.equals(info2.getBeanType())) {
|
||||
return true;
|
||||
}
|
||||
if (info instanceof FeignClientBeanSymbolAddOnInformation) {
|
||||
FeignClientBeanSymbolAddOnInformation feign = (FeignClientBeanSymbolAddOnInformation) info;
|
||||
for (String configBean : feign.configClasses) {
|
||||
if (beanClassName.equals(configBean)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isBeanMethod(MethodDeclaration m) {
|
||||
for (Iterator<?> itr = m.modifiers().iterator(); itr.hasNext();) {
|
||||
@@ -149,4 +190,9 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
return Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 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
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ConfigBeanSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.beans.FeignClientBeanSymbolAddOnInformation;
|
||||
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.reconcilers.AddConfigurationIfBeansPresentReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtAstReconciler;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
|
||||
public class AddConfigurationIfBeansPresentReconcilerTest extends BaseReconcilerTest {
|
||||
|
||||
@Override
|
||||
protected String getFolder() {
|
||||
return "addconfiguration";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProjectName() {
|
||||
return "test-spring-validations";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdtAstReconciler getReconciler() {
|
||||
return new AddConfigurationIfBeansPresentReconciler(new QuickfixRegistry());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
void basicCase() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
class A {
|
||||
|
||||
@Bean
|
||||
String myBean() {
|
||||
return "my-bean";
|
||||
}
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile("A.java", source, false);
|
||||
|
||||
assertEquals(1, problems.size());
|
||||
|
||||
ReconcileProblem problem = problems.get(0);
|
||||
|
||||
assertEquals(Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION, problem.getType());
|
||||
|
||||
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
|
||||
assertEquals("A", markedStr);
|
||||
|
||||
assertEquals(2, problem.getQuickfixes().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanCase() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
class A {
|
||||
|
||||
@Bean
|
||||
String myBean() {
|
||||
return "my-bean";
|
||||
}
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile(() -> {
|
||||
AddConfigurationIfBeansPresentReconciler r = new AddConfigurationIfBeansPresentReconciler(new QuickfixRegistry());
|
||||
|
||||
WorkspaceSymbol workspaceSymbol = new WorkspaceSymbol("testConfig", SymbolKind.Class, Either.forLeft(new Location("file:///someUri", new Range())));
|
||||
ConfigBeanSymbolAddOnInformation beanSymbolAddOn = new ConfigBeanSymbolAddOnInformation("a", "example.demo.A");
|
||||
EnhancedSymbolInformation beanSymbol = new EnhancedSymbolInformation(workspaceSymbol, new SymbolAddOnInformation[] { beanSymbolAddOn });
|
||||
|
||||
SpringSymbolIndex mockSymbolIndex = mock(SpringSymbolIndex.class);
|
||||
|
||||
when(mockSymbolIndex.getEnhancedSymbols(any(IJavaProject.class))).thenReturn(List.of(beanSymbol));
|
||||
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
when(context.getBean(SpringSymbolIndex.class)).thenReturn(mockSymbolIndex);
|
||||
|
||||
r.setApplicationContext(context);
|
||||
|
||||
return r;
|
||||
}, "A.java", source, false);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void feignClientConfigCase() throws Exception {
|
||||
String source = """
|
||||
package example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
class A {
|
||||
|
||||
@Bean
|
||||
String myBean() {
|
||||
return "my-bean";
|
||||
}
|
||||
|
||||
}
|
||||
""";
|
||||
List<ReconcileProblem> problems = reconcile(() -> {
|
||||
AddConfigurationIfBeansPresentReconciler r = new AddConfigurationIfBeansPresentReconciler(new QuickfixRegistry());
|
||||
|
||||
WorkspaceSymbol workspaceSymbol = new WorkspaceSymbol("testConfig", SymbolKind.Class, Either.forLeft(new Location("file:///someUri", new Range())));
|
||||
FeignClientBeanSymbolAddOnInformation beanSymbolAddOn = new FeignClientBeanSymbolAddOnInformation("b", "example.demo.B", "example.demo.A");
|
||||
EnhancedSymbolInformation beanSymbol = new EnhancedSymbolInformation(workspaceSymbol, new SymbolAddOnInformation[] { beanSymbolAddOn });
|
||||
|
||||
SpringSymbolIndex mockSymbolIndex = mock(SpringSymbolIndex.class);
|
||||
|
||||
when(mockSymbolIndex.getEnhancedSymbols(any(IJavaProject.class))).thenReturn(List.of(beanSymbol));
|
||||
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
when(context.getBean(SpringSymbolIndex.class)).thenReturn(mockSymbolIndex);
|
||||
|
||||
r.setApplicationContext(context);
|
||||
|
||||
return r;
|
||||
}, "A.java", source, false);
|
||||
|
||||
assertEquals(0, problems.size());
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user