Remove rewrite reconcile related classes and cleanup
This commit is contained in:
@@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemCategory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemTypes;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
public class HelloMethodRenameProblemDescriptor implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String LABEL = "Switch hello method into bye";
|
||||
private static final String RECIPE_ID = "org.springframework.rewrite.test.HelloMethodRenameRecipe";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaIsoVisitor<>() {
|
||||
|
||||
@Override
|
||||
public MethodDeclaration visitMethodDeclaration(MethodDeclaration method, ExecutionContext p) {
|
||||
MethodDeclaration m = super.visitMethodDeclaration(method, p);
|
||||
if ("hello".equals(method.getSimpleName())) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFixes(
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.NODE))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(m.getMarkers().findFirst(Range.class).get()),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
);
|
||||
m = m.withName(m.getName().withMarkers(m.getName().getMarkers().add(marker)));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return ProblemTypes.create("Hello Method!", ProblemSeverity.ERROR, ProblemCategory.NO_CATEGORY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.CodeActionRepository;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
|
||||
public class StsTestCodeActionRepo extends CodeActionRepository {
|
||||
|
||||
@Override
|
||||
public List<RecipeCodeActionDescriptor> getCodeActionDescriptors() {
|
||||
return List.of(new HelloMethodRenameProblemDescriptor());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.rewrite.config;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.internal.RecipeIntrospectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ClassInfo;
|
||||
import io.github.classgraph.ScanResult;
|
||||
|
||||
public class CodeActionRepoLoader {
|
||||
|
||||
final static Logger log = LoggerFactory.getLogger(CodeActionRepoLoader.class);
|
||||
|
||||
private final List<CodeActionRepository> codeActionRepos = new ArrayList<>();
|
||||
|
||||
public CodeActionRepoLoader(String... acceptPackages) {
|
||||
scanClasses(new ClassGraph().acceptPackages(acceptPackages), getClass().getClassLoader());
|
||||
}
|
||||
|
||||
public CodeActionRepoLoader(Path p, ClassLoader classLoader) {
|
||||
if (Files.isDirectory(p)) {
|
||||
String dir = p.toString();
|
||||
|
||||
scanClasses(new ClassGraph().acceptPaths(dir).ignoreParentClassLoaders().overrideClassLoaders(classLoader),
|
||||
classLoader);
|
||||
|
||||
} else {
|
||||
String jarName = p.toFile().getName();
|
||||
|
||||
scanClasses(
|
||||
new ClassGraph().acceptJars(jarName).ignoreParentClassLoaders().overrideClassLoaders(classLoader),
|
||||
classLoader);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void scanClasses(ClassGraph classGraph, ClassLoader classLoader) {
|
||||
try (ScanResult result = classGraph.ignoreClassVisibility().overrideClassLoaders(classLoader).scan()) {
|
||||
|
||||
for (ClassInfo classInfo : result.getSubclasses(CodeActionRepository.class.getName())) {
|
||||
Class<?> codeActionRepoClass = classInfo.loadClass();
|
||||
Constructor<?> primaryConstructor = RecipeIntrospectionUtils
|
||||
.getZeroArgsConstructor(codeActionRepoClass);
|
||||
if (primaryConstructor == null) {
|
||||
// TODO: error!!!
|
||||
} else {
|
||||
try {
|
||||
CodeActionRepository repo = (CodeActionRepository) primaryConstructor.newInstance();
|
||||
codeActionRepos.add(repo);
|
||||
} catch (Throwable t) {
|
||||
log.warn("Unable to configure " + codeActionRepoClass.getName(), t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<CodeActionRepository> listCodeActionDescriptorsRepositories() {
|
||||
return codeActionRepos;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.commons.rewrite.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CodeActionRepository {
|
||||
|
||||
public abstract List<RecipeCodeActionDescriptor> getCodeActionDescriptors();
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.rewrite.config;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
public record DefaultMarkerVisitorContext(ApplicationContext appContext, IJavaProject project) implements MarkerVisitorContext {
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.rewrite.config;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
public interface MarkerVisitorContext {
|
||||
|
||||
IJavaProject project();
|
||||
|
||||
ApplicationContext appContext();
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.commons.rewrite.config;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
|
||||
public interface RecipeCodeActionDescriptor {
|
||||
|
||||
default String getId() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context);
|
||||
|
||||
boolean isApplicable(IJavaProject project);
|
||||
|
||||
default ProblemType getProblemType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static String buildLabel(String label, RecipeScope s) {
|
||||
switch (s) {
|
||||
case FILE:
|
||||
return label + " in file";
|
||||
case PROJECT:
|
||||
return label + " in project";
|
||||
default:
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.rewrite.config;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.openrewrite.Recipe;
|
||||
import org.openrewrite.config.Environment;
|
||||
import org.openrewrite.config.RecipeDescriptor;
|
||||
import org.openrewrite.config.ResourceLoader;
|
||||
|
||||
public class StsEnvironment {
|
||||
|
||||
final private Supplier<Stream<CodeActionRepository>> codeActionRepos;
|
||||
final private Environment env;
|
||||
|
||||
private StsEnvironment(Environment env, List<CodeActionRepoLoader> loaders) {
|
||||
this.env = env;
|
||||
codeActionRepos = () -> loaders.stream().flatMap(l -> l.listCodeActionDescriptorsRepositories().stream());
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private List<CodeActionRepoLoader> loaders = new ArrayList<>();
|
||||
private Environment.Builder envBuilder = new Environment.Builder(new Properties());;
|
||||
|
||||
public Builder scanRuntimeClasspath(String... acceptPackages) {
|
||||
loaders.add(new CodeActionRepoLoader(acceptPackages));
|
||||
envBuilder.scanRuntimeClasspath(acceptPackages);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder scanJar(Path jar, ClassLoader classLoader) {
|
||||
loaders.add(new CodeActionRepoLoader(jar, classLoader));
|
||||
envBuilder.scanJar(jar, Collections.emptyList(), classLoader);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StsEnvironment build() {
|
||||
return new StsEnvironment(envBuilder.build(), loaders);
|
||||
}
|
||||
|
||||
public void load(ResourceLoader loader) {
|
||||
envBuilder.load(loader, Collections.emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<RecipeCodeActionDescriptor> listCodeActionDescriptors() {
|
||||
return codeActionRepos.get().flatMap(r -> r.getCodeActionDescriptors().stream()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Collection<Recipe> listRecipes() {
|
||||
return env.listRecipes();
|
||||
}
|
||||
|
||||
public Collection<RecipeDescriptor> listRecipeDescriptors() {
|
||||
return env.listRecipeDescriptors();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.commons.rewrite.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.config.ResourceLoader;
|
||||
|
||||
public interface StsResourceLoader extends ResourceLoader {
|
||||
|
||||
List<CodeActionRepository> listCodeActionDescriptorsRepositories();
|
||||
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JdtReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteCodeActionHandler;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteCompilationUnitCache;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRecipeRepository;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRefactorings;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.SpringBootUpgrade;
|
||||
@@ -32,11 +31,6 @@ public class RewriteConfig {
|
||||
return new RewriteRecipeRepository(server, projectFinder, config);
|
||||
}
|
||||
|
||||
@ConditionalOnBean(RewriteRecipeRepository.class)
|
||||
@Bean RewriteCompilationUnitCache orcuCache(SimpleLanguageServer server, BootLanguageServerParams params) {
|
||||
return new RewriteCompilationUnitCache(params.projectFinder, server, params.projectObserver);
|
||||
}
|
||||
|
||||
@ConditionalOnBean(RewriteRecipeRepository.class)
|
||||
@Bean RewriteRefactorings rewriteRefactorings(SimpleLanguageServer server, JavaProjectFinder projectFinder, RewriteRecipeRepository recipeRepo) {
|
||||
return new RewriteRefactorings(server, projectFinder, recipeRepo);
|
||||
@@ -51,15 +45,5 @@ public class RewriteConfig {
|
||||
@Bean SpringBootUpgrade springBootUpgrade(SimpleLanguageServer server, RewriteRecipeRepository recipeRepo, JavaProjectFinder projectFinder) {
|
||||
return new SpringBootUpgrade(server, recipeRepo, projectFinder);
|
||||
}
|
||||
|
||||
// @ConditionalOnBean(RewriteRecipeRepository.class)
|
||||
// @Bean RewriteReconciler rewriteJavaReconciler(RewriteRecipeRepository recipeRepo, RewriteCompilationUnitCache cuCache, SimpleLanguageServer server, BootJavaConfig config) {
|
||||
// return new RewriteReconciler(
|
||||
// recipeRepo,
|
||||
// cuCache,
|
||||
// server.getQuickfixRegistry(),
|
||||
// config
|
||||
// );
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,16 +47,16 @@ public abstract class AbstractSecurityLamdaDslReconciler implements JdtAstReconc
|
||||
MethodInvocation topMethodInvocation = findTopLevelMethodInvocation(node);
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), getProblemLabel(), topMethodInvocation.getStartPosition(), topMethodInvocation.getLength());
|
||||
String uri = docUri.toASCIIString();
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(getRecipeId(), List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(getFixLabel(), RecipeScope.NODE))
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, topMethodInvocation))
|
||||
ReconcileUtils.buildLabel(getFixLabel(), RecipeScope.NODE))
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, topMethodInvocation))
|
||||
.withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(getRecipeId(), List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(getFixLabel(), RecipeScope.FILE))
|
||||
ReconcileUtils.buildLabel(getFixLabel(), RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(getRecipeId(), List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(getFixLabel(), RecipeScope.PROJECT))
|
||||
ReconcileUtils.buildLabel(getFixLabel(), RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
@@ -69,7 +69,7 @@ public abstract class AbstractSecurityLamdaDslReconciler implements JdtAstReconc
|
||||
});
|
||||
|
||||
} else {
|
||||
if (RewriteQuickFixUtils.isAnyTypeUsed(cu, List.of(getTargetTypeFqName()))) {
|
||||
if (ReconcileUtils.isAnyTypeUsed(cu, List.of(getTargetTypeFqName()))) {
|
||||
throw new RequiredCompleteAstException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), PROBLEM_LABEL,
|
||||
nameAst.getStartPosition(), nameAst.getLength());
|
||||
|
||||
RewriteQuickFixUtils.setRewriteFixes(quickfixRegistry, problem,
|
||||
ReconcileUtils.setRewriteFixes(quickfixRegistry, problem,
|
||||
List.of(new FixDescriptor(ID, List.of(docUri.toASCIIString()),
|
||||
RewriteQuickFixUtils.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
ReconcileUtils.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(docUri.toASCIIString()),
|
||||
RewriteQuickFixUtils.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
ReconcileUtils.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)));
|
||||
|
||||
problemCollector.accept(problem);
|
||||
@@ -137,7 +137,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
if (applicationContext != null) {
|
||||
SpringSymbolIndex index = applicationContext.getBean(SpringSymbolIndex.class);
|
||||
if (index != null) {
|
||||
final String beanClassName = RewriteQuickFixUtils.getDeepErasureType(classDecl.resolveBinding()).getQualifiedName();
|
||||
final String beanClassName = ReconcileUtils.getDeepErasureType(classDecl.resolveBinding()).getQualifiedName();
|
||||
for (EnhancedSymbolInformation s : index.getEnhancedSymbols(project)) {
|
||||
SymbolAddOnInformation[] additionalInformation = s.getAdditionalInformation();
|
||||
if (additionalInformation != null) {
|
||||
|
||||
@@ -71,14 +71,14 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
|
||||
AUTHORIZE_REQUESTS_PROBLEM_LABEL, node.getName().getStartPosition(),
|
||||
node.getName().getLength());
|
||||
String uri = docUri.toASCIIString();
|
||||
RewriteQuickFixUtils
|
||||
ReconcileUtils
|
||||
.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL,
|
||||
ReconcileUtils.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL,
|
||||
RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL,
|
||||
ReconcileUtils.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL,
|
||||
RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)));
|
||||
problemCollector.accept(problem);
|
||||
@@ -91,10 +91,10 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
|
||||
@Override
|
||||
public boolean visit(SimpleType node) {
|
||||
String replacementClass = null;
|
||||
if (RewriteQuickFixUtils.isApplicableTypeWithoutResolving(cu,
|
||||
if (ReconcileUtils.isApplicableTypeWithoutResolving(cu,
|
||||
List.of(FQN_AUTH_REQ_CONFIG, FQN_EXPR_AUTH_CONFIG), node.getName())) {
|
||||
replacementClass = "AuthorizeHttpRequestsConfigurer";
|
||||
} else if (RewriteQuickFixUtils.isApplicableTypeWithoutResolving(cu, List.of(FQN_EXPR_INTERCEPT_REG),
|
||||
} else if (ReconcileUtils.isApplicableTypeWithoutResolving(cu, List.of(FQN_EXPR_INTERCEPT_REG),
|
||||
node.getName())) {
|
||||
replacementClass = "AuthorizationManagerRequestMatcherRegistry";
|
||||
}
|
||||
@@ -103,14 +103,14 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
|
||||
"Use of type '" + node.getName().getFullyQualifiedName() + "' is outdated",
|
||||
node.getName().getStartPosition(), node.getName().getLength());
|
||||
String uri = docUri.toASCIIString();
|
||||
RewriteQuickFixUtils
|
||||
ReconcileUtils
|
||||
.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(String.format(CLASS_FIX_LABEL_TEMPLATE,
|
||||
ReconcileUtils.buildLabel(String.format(CLASS_FIX_LABEL_TEMPLATE,
|
||||
replacementClass), RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RewriteQuickFixUtils.buildLabel(
|
||||
ReconcileUtils.buildLabel(
|
||||
String.format(CLASS_FIX_LABEL_TEMPLATE, replacementClass),
|
||||
RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)));
|
||||
@@ -122,7 +122,7 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
|
||||
|
||||
});
|
||||
} else {
|
||||
boolean needsFullAst = RewriteQuickFixUtils.isAnyTypeUsed(cu, List.of(
|
||||
boolean needsFullAst = ReconcileUtils.isAnyTypeUsed(cu, List.of(
|
||||
FQN_HTTP_SECURITY,
|
||||
FQN_AUTH_REQ_CONFIG,
|
||||
FQN_EXPR_AUTH_CONFIG,
|
||||
|
||||
@@ -70,7 +70,7 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
|
||||
@Override
|
||||
public boolean visit(FieldDeclaration field) {
|
||||
if (field.fragments().size() == 1) {
|
||||
Annotation annotation = RewriteQuickFixUtils.findAnnotation(field, Annotations.AUTOWIRED,
|
||||
Annotation annotation = ReconcileUtils.findAnnotation(field, Annotations.AUTOWIRED,
|
||||
false);
|
||||
if (annotation != null && field.getParent() instanceof TypeDeclaration) {
|
||||
TypeDeclaration typeDecl = (TypeDeclaration) field.getParent();
|
||||
@@ -94,7 +94,7 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
|
||||
}
|
||||
} else {
|
||||
List<MethodDeclaration> autowiredConstructors = constructors.stream()
|
||||
.filter(constr -> RewriteQuickFixUtils.findAnnotation(constr,
|
||||
.filter(constr -> ReconcileUtils.findAnnotation(constr,
|
||||
Annotations.AUTOWIRED, true) != null)
|
||||
.limit(2).collect(Collectors.toList());
|
||||
if (autowiredConstructors.size() == 1) {
|
||||
@@ -129,9 +129,9 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
|
||||
String typeFqName = (cu.getPackage() != null && cu.getPackage().getName() != null
|
||||
? cu.getPackage().getName().getFullyQualifiedName() + "."
|
||||
: "") + typeDecl.getName().getFullyQualifiedName();
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem,
|
||||
ReconcileUtils.setRewriteFixes(registry, problem,
|
||||
List.of(new FixDescriptor(ID, List.of(docUri.toASCIIString()), LABEL)
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, typeDecl))
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, typeDecl))
|
||||
.withParameters(Map.of("classFqName", typeFqName, "fieldName", fieldName))
|
||||
.withRecipeScope(RecipeScope.NODE)));
|
||||
return problem;
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixTy
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
@@ -106,15 +105,15 @@ public class BeanMethodNotPublicReconciler implements JdtAstReconciler {
|
||||
|
||||
FixDescriptor fix1 = new FixDescriptor(ID, List.of(docUri.toASCIIString()), LABEL)
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, method));
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, method));
|
||||
|
||||
Range methodRange = RewriteQuickFixUtils.createOpenRewriteRange(cu, method);
|
||||
Range methodRange = ReconcileUtils.createOpenRewriteRange(cu, method);
|
||||
fix1 = fix1.withRangeScope(methodRange);
|
||||
|
||||
FixDescriptor fix2 = new FixDescriptor(ID, List.of(docUri.toASCIIString()), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
FixDescriptor fix2 = new FixDescriptor(ID, List.of(docUri.toASCIIString()), ReconcileUtils.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE);
|
||||
|
||||
FixDescriptor fix3 = new FixDescriptor(ID, List.of(docUri.toASCIIString()), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
FixDescriptor fix3 = new FixDescriptor(ID, List.of(docUri.toASCIIString()), ReconcileUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT);
|
||||
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ public class BeanPostProcessingIgnoreInAotReconciler implements JdtAstReconciler
|
||||
|
||||
if (markProblem) {
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), LABEL, typeDecl.getName().getStartPosition(), typeDecl.getName().getLength());
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(RECIPE_ID, List.of(docUri.toASCIIString()), RewriteQuickFixUtils.buildLabel(LABEL, RecipeScope.NODE))
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, typeDecl))
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(RECIPE_ID, List.of(docUri.toASCIIString()), ReconcileUtils.buildLabel(LABEL, RecipeScope.NODE))
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, typeDecl))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
@@ -98,7 +98,7 @@ public class BeanPostProcessingIgnoreInAotReconciler implements JdtAstReconciler
|
||||
}
|
||||
|
||||
private boolean isApplicable(ITypeBinding type) {
|
||||
return RewriteQuickFixUtils.implementsType(RUNTIME_BEAN_POST_PROCESSOR, type) && RewriteQuickFixUtils.implementsType(COMPILE_BEAN_POST_PROCESSOR, type);
|
||||
return ReconcileUtils.implementsType(RUNTIME_BEAN_POST_PROCESSOR, type) && ReconcileUtils.implementsType(COMPILE_BEAN_POST_PROCESSOR, type);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -70,15 +70,15 @@ public class NoAutowiredOnConstructorReconciler implements JdtAstReconciler {
|
||||
}
|
||||
|
||||
if (constructor != null) {
|
||||
Annotation autowiredAnnotation = RewriteQuickFixUtils.findAnnotation(constructor,
|
||||
Annotation autowiredAnnotation = ReconcileUtils.findAnnotation(constructor,
|
||||
Annotations.AUTOWIRED, false);
|
||||
if (autowiredAnnotation != null) {
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), LABEL,
|
||||
autowiredAnnotation.getStartPosition(), autowiredAnnotation.getLength());
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem,
|
||||
ReconcileUtils.setRewriteFixes(registry, problem,
|
||||
List.of(new FixDescriptor(ID, List.of(docUri.toASCIIString()), LABEL)
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, typeDecl))));
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, typeDecl))));
|
||||
problemCollector.accept(problem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ 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.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
@@ -62,16 +61,16 @@ public class NoRepoAnnotationReconciler implements JdtAstReconciler {
|
||||
if (type != null && isRepo(type)) {
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), LABEL, a.getStartPosition(), a.getLength());
|
||||
String uri = docUri.toASCIIString();
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
// new FixDescriptor(ID, List.of(uri), LABEL)
|
||||
// .withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, typeDecl))
|
||||
// .withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
ReconcileUtils.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
ReconcileUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRe
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
@@ -75,13 +74,13 @@ public class NoRequestMappingAnnotationReconciler implements JdtAstReconciler {
|
||||
if (a.getParent() instanceof MethodDeclaration && isRequestMappingAnnotation(cu, a)) {
|
||||
String uri = docUri.toASCIIString();
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), LABEL, a.getStartPosition(), a.getLength());
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
// new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.NODE))
|
||||
// .withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, a))
|
||||
// .withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
new FixDescriptor(ID, List.of(uri), ReconcileUtils.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
new FixDescriptor(ID, List.of(uri), ReconcileUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
|
||||
@@ -77,7 +77,7 @@ public class NotRegisteredBeansReconciler implements JdtAstReconciler, Applicati
|
||||
public boolean visit(TypeDeclaration node) {
|
||||
if (!node.isInterface() && !Modifier.isAbstract(node.getModifiers())) {
|
||||
ITypeBinding type = node.resolveBinding();
|
||||
if (type != null && RewriteQuickFixUtils.implementsAnyType(AOT_BEANS, type)) {
|
||||
if (type != null && ReconcileUtils.implementsAnyType(AOT_BEANS, type)) {
|
||||
String beanClassName =type.getQualifiedName();
|
||||
SpringSymbolIndex index = applicationContext.getBean(SpringSymbolIndex.class);
|
||||
List<WorkspaceSymbol> beanSymbols = index.getSymbols(data -> {
|
||||
@@ -135,7 +135,7 @@ public class NotRegisteredBeansReconciler implements JdtAstReconciler, Applicati
|
||||
}
|
||||
}
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), getProblemType().getLabel(), node.getName().getStartPosition(), node.getName().getLength());
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, fixListBuilder.build());
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, fixListBuilder.build());
|
||||
problemCollector.accept(problem);
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public class NotRegisteredBeansReconciler implements JdtAstReconciler, Applicati
|
||||
if (type.isArray()) {
|
||||
return typePattern(type.getErasure()) + "[]";
|
||||
} else {
|
||||
return RewriteQuickFixUtils.getDeepErasureType(type).getQualifiedName();
|
||||
return ReconcileUtils.getDeepErasureType(type).getQualifiedName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRe
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
@@ -91,13 +90,13 @@ public class PreciseBeanTypeReconciler implements JdtAstReconciler {
|
||||
} else if (currentReturnTypes.size() == 1 && !method.resolveBinding().getReturnType().isAssignmentCompatible(currentReturnTypes.get(0))) {
|
||||
String uri = docUri.toASCIIString();
|
||||
String replacementType = currentReturnTypes.get(0).getName();
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel("Replace return type with '" + replacementType + "'", RecipeScope.NODE))
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), ReconcileUtils.buildLabel("Replace return type with '" + replacementType + "'", RecipeScope.NODE))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(RewriteQuickFixUtils.createOpenRewriteRange(cu, method)),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRangeScope(ReconcileUtils.createOpenRewriteRange(cu, method)),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), ReconcileUtils.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), ReconcileUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
|
||||
@@ -34,7 +34,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 RewriteQuickFixUtils {
|
||||
public class ReconcileUtils {
|
||||
|
||||
public static Range createOpenRewriteRange(CompilationUnit cu, ASTNode node) {
|
||||
|
||||
@@ -139,7 +139,7 @@ public class RewriteQuickFixUtils {
|
||||
|
||||
@Override
|
||||
public boolean visit(SimpleType node) {
|
||||
if (RewriteQuickFixUtils.isApplicableTypeWithoutResolving(cu, types, node.getName())) {
|
||||
if (ReconcileUtils.isApplicableTypeWithoutResolving(cu, types, node.getName())) {
|
||||
typeUsed.set(true);
|
||||
}
|
||||
return !typeUsed.get();
|
||||
@@ -85,8 +85,8 @@ public class UnnecessarySpringExtensionReconciler implements JdtAstReconciler {
|
||||
}
|
||||
if (testAnnotation != null && extendWithAnnotation != null) {
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), LABEL, extendWithAnnotation.getStartPosition(), extendWithAnnotation.getLength());
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(ID, List.of(docUri.toASCIIString()), RewriteQuickFixUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(ID, List.of(docUri.toASCIIString()), ReconcileUtils.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
));
|
||||
problemCollector.accept(problem);
|
||||
break;
|
||||
|
||||
@@ -30,7 +30,6 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRe
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
|
||||
@@ -89,17 +88,17 @@ public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler
|
||||
Type type = typeDecl.getSuperclassType();
|
||||
if (isWebSecurityConfigurerAdapter(cu, type)) {
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), PROBLEM_LABEL, type.getStartPosition(), type.getLength());
|
||||
if (RewriteQuickFixUtils.findAnnotation(typeDecl, Annotations.CONFIGURATION, true) != null) {
|
||||
if (ReconcileUtils.findAnnotation(typeDecl, Annotations.CONFIGURATION, true) != null) {
|
||||
ITypeBinding resolveBinding = type.resolveBinding();
|
||||
String[] typeStubs = resolveBinding == null || resolveBinding.isRecovered() ? new String[] { STUB_WEB_SECURITY_CONFIG_ADAPTER } : new String[0];
|
||||
String uri = docUri.toASCIIString();
|
||||
RewriteQuickFixUtils.setRewriteFixes(registry, problem, List.of(
|
||||
ReconcileUtils.setRewriteFixes(registry, problem, List.of(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
ReconcileUtils.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE)
|
||||
.withTypeStubs(typeStubs),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
ReconcileUtils.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
.withTypeStubs(typeStubs))
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.AddConfigurationIfBeansPresentCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.AuthorizeHttpRequestsCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.AutowiredFieldIntoConstructorParameterCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.BeanMethodNotPublicProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.BeanPostProcessingIgnoreInAotProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.Boot3NotSupportedTypeProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.EntityIdForRepoProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.HttpSecurityLamdaDslCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.ModulithTypeReferenceViolation;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoAutowiredOnConstructorProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoRepoAnnotationProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NoRequestMappingAnnotationCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.NotRegisteredBeansProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.PreciseBeanTypeProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.ServerHttpSecurityLambdaDslCodeAction;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.UnnecessarySpringExtensionProblem;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.reconcile.WebSecurityConfigurerAdapterCodeAction;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.CodeActionRepository;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
|
||||
public class BootCodeActionRepository extends CodeActionRepository {
|
||||
|
||||
@Override
|
||||
public List<RecipeCodeActionDescriptor> getCodeActionDescriptors() {
|
||||
return List.of(
|
||||
new BeanMethodNotPublicProblem(),
|
||||
new NoAutowiredOnConstructorProblem(),
|
||||
new UnnecessarySpringExtensionProblem(),
|
||||
new PreciseBeanTypeProblem(),
|
||||
new BeanPostProcessingIgnoreInAotProblem(),
|
||||
new NotRegisteredBeansProblem(),
|
||||
new Boot3NotSupportedTypeProblem(),
|
||||
new NoRequestMappingAnnotationCodeAction(),
|
||||
new AutowiredFieldIntoConstructorParameterCodeAction(),
|
||||
new NoRepoAnnotationProblem(),
|
||||
new HttpSecurityLamdaDslCodeAction(),
|
||||
new ServerHttpSecurityLambdaDslCodeAction(),
|
||||
new AddConfigurationIfBeansPresentCodeAction(),
|
||||
new AuthorizeHttpRequestsCodeAction(),
|
||||
new WebSecurityConfigurerAdapterCodeAction(),
|
||||
new EntityIdForRepoProblem(),
|
||||
new ModulithTypeReferenceViolation()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.openrewrite.Parser.Input;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaParser;
|
||||
import org.openrewrite.java.marker.JavaSourceSet;
|
||||
import org.openrewrite.java.tree.J.CompilationUnit;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.utils.DocumentContentProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ServerUtils;
|
||||
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.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
|
||||
import com.google.common.cache.RemovalListener;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
|
||||
import reactor.core.Disposable;
|
||||
|
||||
public class RewriteCompilationUnitCache implements DocumentContentProvider, Disposable {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RewriteCompilationUnitCache.class);
|
||||
|
||||
private static final long CU_ACCESS_EXPIRATION = 1;
|
||||
// private JavaProjectFinder projectFinder;
|
||||
private ProjectObserver projectObserver;
|
||||
|
||||
private final ProjectObserver.Listener projectListener;
|
||||
private final SimpleTextDocumentService documentService;
|
||||
|
||||
private final Cache<URI, CompletableFuture<CompilationUnit>> uriToCu;
|
||||
private final Cache<URI, Set<URI>> projectToDocs;
|
||||
private final Cache<URI, JavaParser> javaParsers;
|
||||
|
||||
private final Cache<URI, List<JavaType.FullyQualified>> sourceSetClasspath;
|
||||
|
||||
public RewriteCompilationUnitCache(JavaProjectFinder projectFinder, SimpleLanguageServer server, ProjectObserver projectObserver) {
|
||||
// this.projectFinder = projectFinder;
|
||||
this.projectObserver = projectObserver;
|
||||
|
||||
// PT 154618835 - Avoid retaining the CU in the cache as it consumes memory if it hasn't been
|
||||
// accessed after some time
|
||||
this.uriToCu = CacheBuilder.newBuilder()
|
||||
.maximumSize(100)
|
||||
.expireAfterAccess(CU_ACCESS_EXPIRATION, TimeUnit.MINUTES)
|
||||
.removalListener(new RemovalListener<URI, CompletableFuture<CompilationUnit>>() {
|
||||
|
||||
@Override
|
||||
public void onRemoval(RemovalNotification<URI, CompletableFuture<CompilationUnit>> notification) {
|
||||
URI uri = notification.getKey();
|
||||
CompletableFuture<CompilationUnit> future = notification.getValue();
|
||||
|
||||
if (future != null) {
|
||||
if (!future.isDone() && !future.isCancelled()) {
|
||||
future.cancel(true);
|
||||
}
|
||||
Optional<IJavaProject> project = projectFinder.find(new TextDocumentIdentifier(uri.toASCIIString()));
|
||||
if (project.isPresent()) {
|
||||
|
||||
JavaParser parser = javaParsers.getIfPresent(project.get().getLocationUri());
|
||||
if (parser != null) {
|
||||
// if (future.isDone()) {
|
||||
// try {
|
||||
// CompilationUnit cu = future.get();
|
||||
// if (cu != null) {
|
||||
// parser.resetCUs(List.of(cu));
|
||||
// return;
|
||||
// }
|
||||
// } catch (Throwable t) {
|
||||
// logger.error("", t);
|
||||
// }
|
||||
// }
|
||||
// parser.reset(List.of(uri));
|
||||
parser.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
this.projectToDocs = CacheBuilder.newBuilder().build();
|
||||
this.javaParsers = CacheBuilder.newBuilder()
|
||||
.removalListener(new RemovalListener<URI, JavaParser>() {
|
||||
|
||||
@Override
|
||||
public void onRemoval(RemovalNotification<URI, JavaParser> notification) {
|
||||
logger.info("CU Cache: invalidate project {}", notification.getKey());
|
||||
sourceSetClasspath.invalidate(notification.getKey());
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
this.sourceSetClasspath = CacheBuilder.newBuilder().build();
|
||||
|
||||
this.documentService = server == null ? null : server.getTextDocumentService();
|
||||
|
||||
// IMPORTANT ===> these notifications arrive within the lsp message loop, so reactions to them have to be fast
|
||||
// and not be blocked by waiting for anything
|
||||
if (this.documentService != null) {
|
||||
this.documentService.onDidChangeContent(doc -> invalidateCuForJavaFile(doc.getDocument().getId().getUri()));
|
||||
this.documentService.onDidClose(doc -> invalidateCuForJavaFile(doc.getId().getUri()));
|
||||
}
|
||||
|
||||
// if (this.projectFinder != null) {
|
||||
// for (IJavaProject project : this.projectFinder.all()) {
|
||||
// logger.info("CU Cache: initial lookup env creation for project <{}>", project.getElementName());
|
||||
// loadJavaParser(project);
|
||||
// }
|
||||
// }
|
||||
|
||||
this.projectListener = new ProjectObserver.Listener() {
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
logger.debug("CU Cache: deleted project {}", project.getElementName());
|
||||
invalidateProject(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
logger.debug("CU Cache: created project {}", project.getElementName());
|
||||
invalidateProject(project);
|
||||
// loadJavaParser(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
logger.debug("CU Cache: changed project {}", project.getElementName());
|
||||
invalidateProject(project);
|
||||
// Load the new cache the value right away
|
||||
// loadJavaParser(project);
|
||||
}
|
||||
};
|
||||
|
||||
if (this.projectObserver != null) {
|
||||
this.projectObserver.addListener(this.projectListener);
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
ServerUtils.listenToClassFileChanges(server.getWorkspaceService().getFileObserver(), projectFinder, this::invalidateProject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (this.projectObserver != null) {
|
||||
this.projectObserver.removeListener(this.projectListener);
|
||||
}
|
||||
}
|
||||
|
||||
private JavaParser loadJavaParser(IJavaProject project) {
|
||||
try {
|
||||
return javaParsers.get(project.getLocationUri(), () -> ORAstUtils.createJavaParser(project));
|
||||
} catch (ExecutionException e) {
|
||||
logger.error("{}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateCuForJavaFile(String uriStr) {
|
||||
URI uri = URI.create(uriStr);
|
||||
uriToCu.invalidate(uri);
|
||||
}
|
||||
|
||||
private void invalidateProject(IJavaProject project) {
|
||||
Set<URI> docUris = projectToDocs.getIfPresent(project.getLocationUri());
|
||||
if (docUris != null) {
|
||||
uriToCu.invalidateAll(docUris);
|
||||
projectToDocs.invalidate(project.getLocationUri());
|
||||
}
|
||||
javaParsers.invalidate(project.getLocationUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetchContent(URI uri) throws Exception {
|
||||
if (documentService != null) {
|
||||
TextDocument document = documentService.getLatestSnapshot(uri.toASCIIString());
|
||||
if (document != null) {
|
||||
return document.get();
|
||||
}
|
||||
}
|
||||
return IOUtils.toString(uri);
|
||||
}
|
||||
|
||||
public CompilationUnit getCU(IJavaProject project, URI uri) {
|
||||
try {
|
||||
if (project != null) {
|
||||
try {
|
||||
return uriToCu.get(uri, () -> {
|
||||
CompletableFuture<CompilationUnit> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return doParse(project, uri);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}).get();
|
||||
} catch (UncheckedExecutionException e1) {
|
||||
// ignore errors from rewrite parser. There could be many parser exceptions due to
|
||||
// user incrementally typing code's text
|
||||
return null;
|
||||
} catch (InvalidCacheLoadException | CancellationException e) {
|
||||
// ignore
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to parse {}", uri, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompilationUnit doParse(IJavaProject project, URI uri) throws Exception {
|
||||
boolean newParser = javaParsers.getIfPresent(project.getLocationUri()) == null;
|
||||
JavaParser javaParser = null;
|
||||
try {
|
||||
logger.debug("Parsing CU {}", uri);
|
||||
javaParser = loadJavaParser(project);
|
||||
|
||||
Path sourcePath = Paths.get(uri);
|
||||
|
||||
Input input = new Input(sourcePath, () -> {
|
||||
try {
|
||||
return new ByteArrayInputStream(fetchContent(uri).getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unexpected error fetching document content");
|
||||
}
|
||||
});
|
||||
List<CompilationUnit> cus = ORAstUtils.parseInputs(javaParser, List.of(input), null);
|
||||
CompilationUnit cu = cus.get(0);
|
||||
|
||||
// Manually add source set
|
||||
JavaSourceSet sourceSet = createSourceSet(project, ORAstUtils.getSourceSetName(project, sourcePath));
|
||||
cu = cu.withMarkers(cu.getMarkers().computeByType(sourceSet, (original, updated) -> updated));
|
||||
|
||||
if (cu != null) {
|
||||
projectToDocs.get(project.getLocationUri(), () -> new HashSet<>()).add(uri);
|
||||
return cu;
|
||||
} else {
|
||||
throw new IllegalStateException("Failed to parse Java source");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (newParser) {
|
||||
javaParsers.invalidate(project);
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
if (javaParser != null) {
|
||||
javaParser.reset(Collections.emptyList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JavaSourceSet createSourceSet(IJavaProject project, String name) {
|
||||
List<FullyQualified> fqNames;
|
||||
try {
|
||||
fqNames = sourceSetClasspath.get(project.getLocationUri(), () -> {
|
||||
List<Path> classpath = IClasspathUtil.getAllBinaryRoots(project.getClasspath()).stream().map(f -> f.toPath()).collect(Collectors.toList());
|
||||
return JavaSourceSet.build("", classpath, null, false).getClasspath();
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
logger.error("", e);
|
||||
fqNames = Collections.emptyList();
|
||||
}
|
||||
return new JavaSourceSet(Tree.randomId(), name, fqNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not need to be via callback - kept the same in order to keep the same API to replace JDT with Rewrite in distant future
|
||||
*/
|
||||
public <T> T withCompilationUnit(IJavaProject project, URI uri, Function<CompilationUnit, T> requestor) {
|
||||
logger.info("CU Cache: work item submitted for doc {}", uri.toASCIIString());
|
||||
CompilationUnit cu = getCU(project, uri);
|
||||
if (cu != null) {
|
||||
try {
|
||||
logger.info("CU Cache: start work on AST for {}", uri.toASCIIString());
|
||||
return requestor.apply(cu);
|
||||
} catch (CancellationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
} finally {
|
||||
logger.info("CU Cache: end work on AST for {}", uri.toASCIIString());
|
||||
}
|
||||
}
|
||||
return requestor.apply(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -43,6 +44,7 @@ import org.openrewrite.Result;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Validated;
|
||||
import org.openrewrite.config.DeclarativeRecipe;
|
||||
import org.openrewrite.config.Environment;
|
||||
import org.openrewrite.config.RecipeDescriptor;
|
||||
import org.openrewrite.config.YamlResourceLoader;
|
||||
import org.openrewrite.internal.InMemoryLargeSourceSet;
|
||||
@@ -60,7 +62,6 @@ import org.springframework.ide.vscode.commons.protocol.java.ProjectBuild;
|
||||
import org.springframework.ide.vscode.commons.rewrite.LoadUtils;
|
||||
import org.springframework.ide.vscode.commons.rewrite.LoadUtils.DurationTypeConverter;
|
||||
import org.springframework.ide.vscode.commons.rewrite.ORDocUtils;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.StsEnvironment;
|
||||
import org.springframework.ide.vscode.commons.rewrite.gradle.GradleIJavaProjectParser;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
|
||||
import org.springframework.ide.vscode.commons.rewrite.maven.MavenIJavaProjectParser;
|
||||
@@ -152,7 +153,7 @@ public class RewriteRecipeRepository {
|
||||
try {
|
||||
log.info("Loading Rewrite Recipes...");
|
||||
Recipe xmlbindRecipe = null;
|
||||
StsEnvironment env = createRewriteEnvironment();
|
||||
Environment env = createRewriteEnvironment();
|
||||
for (Recipe r : env.listRecipes()) {
|
||||
if (r.getName() != null) {
|
||||
if ("org.openrewrite.java.migrate.jakarta.JavaxXmlBindMigrationToJakartaXmlBind".equals(r.getName())) {
|
||||
@@ -209,7 +210,7 @@ public class RewriteRecipeRepository {
|
||||
}
|
||||
|
||||
private static boolean isRecipeValid(Recipe r) {
|
||||
Validated validation = Validated.invalid(null, null, null);
|
||||
Validated<?> validation = Validated.invalid(null, null, null);
|
||||
try {
|
||||
validation = r.validate();
|
||||
} catch (Exception e) {
|
||||
@@ -218,8 +219,8 @@ public class RewriteRecipeRepository {
|
||||
return validation.isValid();
|
||||
}
|
||||
|
||||
private StsEnvironment createRewriteEnvironment() {
|
||||
StsEnvironment.Builder builder = StsEnvironment.builder().scanRuntimeClasspath();
|
||||
private Environment createRewriteEnvironment() {
|
||||
Environment.Builder builder = Environment.builder().scanRuntimeClasspath();
|
||||
for (String p : scanFiles) {
|
||||
try {
|
||||
Path f = Path.of(p);
|
||||
@@ -227,7 +228,7 @@ public class RewriteRecipeRepository {
|
||||
if (pathStr.endsWith(".jar")) {
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[] { f.toUri().toURL() },
|
||||
getClass().getClassLoader());
|
||||
builder.scanJar(f, classLoader);
|
||||
builder.scanJar(f, new ArrayList<>(), classLoader);
|
||||
} else if (pathStr.endsWith(".yml") || pathStr.endsWith(".yaml")) {
|
||||
builder.load(new YamlResourceLoader(new FileInputStream(f.toFile()), f.toUri(), new Properties()));
|
||||
}
|
||||
|
||||
@@ -1,349 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.InMemoryExecutionContext;
|
||||
import org.openrewrite.Parser;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.internal.ListUtils;
|
||||
import org.openrewrite.java.JavaParser;
|
||||
import org.openrewrite.java.marker.JavaSourceSet;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.CompilationUnit;
|
||||
import org.openrewrite.marker.Marker;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.JavaReconciler;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class RewriteReconciler implements JavaReconciler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RewriteReconciler.class);
|
||||
|
||||
private RewriteCompilationUnitCache cuCache;
|
||||
private QuickfixRegistry quickfixRegistry;
|
||||
private RewriteRecipeRepository recipeRepo;
|
||||
private BootJavaConfig config;
|
||||
|
||||
public RewriteReconciler(RewriteRecipeRepository recipeRepo, RewriteCompilationUnitCache cuCache, QuickfixRegistry quickfixRegistry, BootJavaConfig config) {
|
||||
this.recipeRepo = recipeRepo;
|
||||
this.cuCache = cuCache;
|
||||
this.quickfixRegistry = quickfixRegistry;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconcile(IJavaProject project, IDocument doc, IProblemCollector problemCollector) {
|
||||
// if (!config.isRewriteReconcileEnabled()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// long start = System.currentTimeMillis();
|
||||
//
|
||||
// try {
|
||||
// problemCollector.beginCollecting();
|
||||
//
|
||||
// List<RecipeCodeActionDescriptor> descriptors = getProblemRecipeDescriptors(project);
|
||||
//
|
||||
// if (!descriptors.isEmpty()) {
|
||||
// CompilationUnit cu = cuCache.getCU(project, URI.create(doc.getUri()));
|
||||
// if (cu != null) {
|
||||
// collectProblems(project, descriptors, doc, cu, problemCollector::accept);
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// if (ORAstUtils.isExceptionFromInterrupedThread(e)) {
|
||||
// log.debug("", e);
|
||||
// } else {
|
||||
// log.error("", e);
|
||||
// }
|
||||
// } finally {
|
||||
// problemCollector.endCollecting();
|
||||
// log.info("reconciling (OpenRewrite): " + doc.getUri() + " done in " + (System.currentTimeMillis() - start) + "ms");
|
||||
// }
|
||||
}
|
||||
|
||||
// private List<ReconcileProblem> createProblems(IDocument doc, FixAssistMarker m, J astNode) {
|
||||
// if (astNode != null) {
|
||||
// Range range = astNode.getMarkers().findFirst(Range.class).orElse(null);
|
||||
// if (range != null) {
|
||||
// RecipeCodeActionDescriptor recipeFixDescriptor = recipeRepo.getCodeActionRecipeDescriptor(m.getDescriptorId());
|
||||
// if (recipeFixDescriptor != null) {
|
||||
// return List.of(createProblem(doc, recipeFixDescriptor, m, range));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
//
|
||||
// private ReconcileProblemImpl createProblem(IDocument doc, RecipeCodeActionDescriptor recipeFixDescriptor,
|
||||
// FixAssistMarker m, Range range) {
|
||||
// ProblemType problemType = recipeFixDescriptor.getProblemType();
|
||||
// ReconcileProblemImpl problem = new ReconcileProblemImpl(problemType, m.getLabel() == null ? problemType.getLabel() : m.getLabel(), range.getStart().getOffset(), range.getEnd().getOffset() - range.getStart().getOffset());
|
||||
// QuickfixType quickfixType = quickfixRegistry.getQuickfixType(RewriteRefactorings.REWRITE_RECIPE_QUICKFIX);
|
||||
// if (quickfixType != null) {
|
||||
// for (FixDescriptor f : m.getFixes()) {
|
||||
// if (recipeRepo.getRecipe(f.getRecipeId()).isPresent()) {
|
||||
// problem.addQuickfix(new QuickfixData<>(
|
||||
// quickfixType,
|
||||
// f,
|
||||
// f.getLabel()
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return problem;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Map<IDocument, Collection<ReconcileProblem>> reconcile(IJavaProject project, List<TextDocument> docs, Runnable incrementProgress) {
|
||||
|
||||
// if (!config.isJavaSourceReconcileEnabled()) {
|
||||
// return Collections.emptyMap();
|
||||
// }
|
||||
//
|
||||
// long start = System.currentTimeMillis();
|
||||
//
|
||||
// Map<IDocument, Collection<ReconcileProblem>> allProblems = new HashMap<>();
|
||||
// List<Path> testSourceFolders = IClasspathUtil.getProjectTestJavaSources(project.getClasspath()).map(f -> f.toPath()).collect(Collectors.toList());
|
||||
// List<TextDocument> testSources = new ArrayList<>(docs.size());
|
||||
// List<TextDocument> mainSources = new ArrayList<>(docs.size());
|
||||
// for (TextDocument d : docs) {
|
||||
// Path p = Paths.get(URI.create(d.getUri()));
|
||||
// if (testSourceFolders.stream().anyMatch(t -> p.startsWith(t))) {
|
||||
// testSources.add(d);
|
||||
// } else {
|
||||
// mainSources.add(d);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// List<Path> classpath = IClasspathUtil.getAllBinaryRoots(project.getClasspath()).stream().map(f -> f.toPath()).collect(Collectors.toList());
|
||||
// JavaParser javaParser = ORAstUtils.createJavaParser(() -> JavaParser.fromJavaVersion().classpath(classpath));
|
||||
//
|
||||
// // Pass in source sets created from classpath. (Perhaps it is a good idea to have separate classpath and parsers for test and main, TBD)
|
||||
// // Perhaps it is even better to create empty classpath java source sets as reconcile step seem to only need name of the java source set
|
||||
// // Usually java source set classpath is required to figure out how to organize imports for sources
|
||||
// JavaSourceSet mainJavaSourceSet = JavaSourceSet.build(ProjectParser.MAIN, classpath, null, false);
|
||||
// JavaSourceSet testJavaSourceSet = new JavaSourceSet(Tree.randomId(), ProjectParser.TEST, mainJavaSourceSet.getClasspath());
|
||||
// allProblems.putAll(doReconcile(project, mainSources, javaParser, mainJavaSourceSet, incrementProgress));
|
||||
// allProblems.putAll(doReconcile(project, testSources, javaParser, testJavaSourceSet, incrementProgress));
|
||||
//
|
||||
// long end = System.currentTimeMillis();
|
||||
// log.info("reconciling project (OpenRewrite): " + project.getElementName() + " - " + docs.size() + " done in " + (end - start) + "ms");
|
||||
//
|
||||
// return allProblems;
|
||||
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
||||
// Parse all at once
|
||||
// private Map<IDocument, Collection<ReconcileProblem>> doReconcile(IJavaProject project, List<TextDocument> docs,
|
||||
// Function<TextDocument, IProblemCollector> problemCollectorFactory, JavaParser javaParser) {
|
||||
// Map<IDocument, Collection<ReconcileProblem>> allProblems = new HashMap<>();
|
||||
//
|
||||
// if (javaParser != null && config.isRewriteReconcileEnabled()) {
|
||||
// try {
|
||||
// List<RecipeCodeActionDescriptor> descriptors = getProblemRecipeDescriptors(project);
|
||||
//
|
||||
// List<CompilationUnit> cus = ORAstUtils.parseInputs(javaParser,
|
||||
// docs.stream().map(d -> new Parser.Input(Paths.get(URI.create(d.getUri())), () -> {
|
||||
// return new ByteArrayInputStream(d.get().getBytes());
|
||||
// })).collect(Collectors.toList()));
|
||||
//
|
||||
// if (!descriptors.isEmpty()) {
|
||||
//
|
||||
// for (int i = 0; i < cus.size(); i++) {
|
||||
// final IDocument doc = docs.get(i);
|
||||
// List<ReconcileProblem> problems = new ArrayList<>();
|
||||
// collectProblems(descriptors, doc, cus.get(i), problems::add);
|
||||
// if (!problems.isEmpty()) {
|
||||
// allProblems.put(doc, problems);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// if (ORAstUtils.isExceptionFromInterrupedThread(e)) {
|
||||
// log.debug("", e);
|
||||
// } else {
|
||||
// log.error("", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return allProblems;
|
||||
// }
|
||||
|
||||
// Parse One-by-one and share the parser
|
||||
// private Map<IDocument, Collection<ReconcileProblem>> doReconcile(IJavaProject project, List<TextDocument> docs,
|
||||
// Function<TextDocument, IProblemCollector> problemCollectorFactory, JavaParser javaParser) {
|
||||
// Map<IDocument, Collection<ReconcileProblem>> allProblems = new HashMap<>();
|
||||
//
|
||||
// if (javaParser != null && config.isRewriteReconcileEnabled()) {
|
||||
// try {
|
||||
// List<RecipeCodeActionDescriptor> descriptors = getProblemRecipeDescriptors(project);
|
||||
//
|
||||
// if (!descriptors.isEmpty()) {
|
||||
//
|
||||
// for (IDocument doc : docs) {
|
||||
// List<ReconcileProblem> problems = new ArrayList<>();
|
||||
// CompilationUnit source = ORAstUtils.parseInputs(javaParser, List.of(new Parser.Input(Paths.get(URI.create(doc.getUri())), () -> {
|
||||
// return new ByteArrayInputStream(doc.get().getBytes());
|
||||
// }))).get(0);
|
||||
// collectProblems(descriptors, doc, source, problems::add);
|
||||
// if (!problems.isEmpty()) {
|
||||
// allProblems.put(doc, problems);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// if (ORAstUtils.isExceptionFromInterrupedThread(e)) {
|
||||
// log.debug("", e);
|
||||
// } else {
|
||||
// log.error("", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return allProblems;
|
||||
// }
|
||||
|
||||
private static final int BATCH = 50;
|
||||
|
||||
// Parse in batches and share the parser
|
||||
// private Map<IDocument, Collection<ReconcileProblem>> doReconcile(IJavaProject project, List<TextDocument> docs, JavaParser javaParser, JavaSourceSet javaSourceSet, Runnable incrementProgress) {
|
||||
// Map<IDocument, Collection<ReconcileProblem>> allProblems = new HashMap<>();
|
||||
// if (javaParser != null && config.isJavaSourceReconcileEnabled()) {
|
||||
// try {
|
||||
// List<RecipeCodeActionDescriptor> descriptors = getProblemRecipeDescriptors(project);
|
||||
//
|
||||
//
|
||||
// if (!descriptors.isEmpty()) {
|
||||
//
|
||||
// for (int i = 0; i < docs.size(); i += BATCH) {
|
||||
// List<TextDocument> batchList = docs.subList(i, Math.min(i + BATCH, docs.size()));
|
||||
//
|
||||
// List<CompilationUnit> cus = ORAstUtils.parseInputs(javaParser,
|
||||
// batchList.stream().map(d -> new Parser.Input(Paths.get(URI.create(d.getUri())), () -> {
|
||||
// return new ByteArrayInputStream(d.get().getBytes());
|
||||
// })).collect(Collectors.toList()), source -> incrementProgress.run());
|
||||
//
|
||||
// cus = ListUtils.map(cus, cu -> cu.withMarkers(cu.getMarkers().computeByType(javaSourceSet, (original, updated) -> updated)));
|
||||
//
|
||||
// /*
|
||||
// * If exception occurs during parsing inputs the list of inputs would become shorter than the list of corresponding documents
|
||||
// */
|
||||
//
|
||||
// for (int j = 0, k = 0; j < batchList.size() && k < cus.size(); j++) {
|
||||
// final IDocument doc = batchList.get(j);
|
||||
// List<ReconcileProblem> problems = new ArrayList<>();
|
||||
// CompilationUnit cu = cus.get(k);
|
||||
// Path sourcePath = Paths.get(URI.create(doc.getUri()));
|
||||
// if (cu.getSourcePath().equals(sourcePath)) {
|
||||
// k++;
|
||||
// collectProblems(project, descriptors, doc, cu, problems::add);
|
||||
// if (!problems.isEmpty()) {
|
||||
// allProblems.put(doc, problems);
|
||||
// }
|
||||
// } else {
|
||||
// log.warn("(OpenRewrite) Failed to parse source for " + sourcePath);
|
||||
// }
|
||||
// incrementProgress.run();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// if (ORAstUtils.isExceptionFromInterrupedThread(e)) {
|
||||
// log.debug("", e);
|
||||
// } else {
|
||||
// log.error("", e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return allProblems;
|
||||
// }
|
||||
//
|
||||
// private List<RecipeCodeActionDescriptor> getProblemRecipeDescriptors(IJavaProject project)
|
||||
// throws InterruptedException, ExecutionException {
|
||||
// return recipeRepo.getProblemRecipeDescriptors().stream().filter(d -> d.getProblemType() != null).filter(d -> {
|
||||
// switch (config.getProblemApplicability(d.getProblemType())) {
|
||||
// case ON:
|
||||
// return SpringProjectUtil.isBootProject(project);
|
||||
// case OFF:
|
||||
// return false;
|
||||
// default: // AUTO
|
||||
// return d.isApplicable(project);
|
||||
// }
|
||||
// }).collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
// private void collectProblems(IJavaProject project, List<RecipeCodeActionDescriptor> descriptors, IDocument doc, CompilationUnit compilationUnit, Consumer<ReconcileProblem> problemHandler) {
|
||||
// CompilationUnit cu = recipeRepo.mark(project, descriptors, compilationUnit);
|
||||
// if (compilationUnit != cu) {
|
||||
// new JavaMarkerVisitor<ExecutionContext>() {
|
||||
//
|
||||
// @Override
|
||||
// public J visit(Tree tree, ExecutionContext context) {
|
||||
// J t = super.visit(tree, context);
|
||||
// if (t instanceof J) {
|
||||
// for (Marker m : t.getMarkers().entries()) {
|
||||
// if (m instanceof FixAssistMarker) {
|
||||
// for (ReconcileProblem problem : createProblems(doc, (FixAssistMarker) m, t)) {
|
||||
// problemHandler.accept(problem);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return t;
|
||||
// }
|
||||
//
|
||||
// }.visit(cu, new InMemoryExecutionContext(e -> log.error("", e)));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public int getTotalWorkUnits(List<TextDocument> docs) {
|
||||
// return docs.size() * 2;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot2.AddConfigurationAnnotationIfBeansPresent;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.J.VariableDeclarations;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class AddConfigurationIfBeansPresentCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = AddConfigurationAnnotationIfBeansPresent.class.getName();
|
||||
|
||||
private static final String PROBLEM_LABEL = "'@Configuration' is missing on a class defining Spring Beans";
|
||||
|
||||
private static final String FIX_LABEL = "Add missing '@Configuration' annotations over classes";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public MethodDeclaration visitMethodDeclaration(MethodDeclaration method, ExecutionContext p) {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclarations visitVariableDeclarations(VariableDeclarations multiVariable,
|
||||
ExecutionContext p) {
|
||||
return multiVariable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) {
|
||||
ClassDeclaration c = super.visitClassDeclaration(classDecl, p);
|
||||
if (AddConfigurationAnnotationIfBeansPresent.isApplicableClass(classDecl, getCursor())) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), ID).withLabel(PROBLEM_LABEL)
|
||||
.withFixes(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT));
|
||||
c = c.withName(c.getName().withMarkers(c.getName().getMarkers().add(marker)));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-context");
|
||||
return version != null && version.compareTo(new Version(3, 0, 0, null)) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.MethodMatcher;
|
||||
import org.openrewrite.java.spring.boot2.AuthorizeHttpRequests;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.J.VariableDeclarations;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class AuthorizeHttpRequestsCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = AuthorizeHttpRequests.class.getName();
|
||||
|
||||
private static final MethodMatcher MATCH_AUTHORIZE_REQUESTS = new MethodMatcher(
|
||||
"org.springframework.security.config.annotation.web.builders.HttpSecurity authorizeRequests(..)");
|
||||
|
||||
private static final String AUTHORIZE_REQUESTS_PROBLEM_LABEL = "HttpSecurity API 'authorizeRequests(...)' is outdated";
|
||||
|
||||
private static final String AUTHORIZE_REQUESTS_FIX_LABEL = "Replace with 'authorizeHttpRequests(...)' and related types";
|
||||
|
||||
private static final String CLASS_FIX_LABEL_TEMPLATE = "Replace with %s and use 'HttpSecurity.authorizeHttpRequests(...) and related types";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
|
||||
@Override
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) {
|
||||
MethodInvocation m = super.visitMethodInvocation(method, p);
|
||||
if (MATCH_AUTHORIZE_REQUESTS.matches(method)) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withLabel(AUTHORIZE_REQUESTS_PROBLEM_LABEL).withFixes(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL,
|
||||
RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor
|
||||
.buildLabel(AUTHORIZE_REQUESTS_FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT));
|
||||
m = m.withName(m.getName().withMarkers(m.getName().getMarkers().add(marker)));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclarations visitVariableDeclarations(VariableDeclarations multiVariable,
|
||||
ExecutionContext p) {
|
||||
VariableDeclarations mv = super.visitVariableDeclarations(multiVariable, p);
|
||||
FullyQualified type = mv.getTypeAsFullyQualified();
|
||||
if (type != null) {
|
||||
String replacementClass = null;
|
||||
switch (type.getFullyQualifiedName()) {
|
||||
case "org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer":
|
||||
case "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer":
|
||||
replacementClass = "AuthorizeHttpRequestsConfigurer";
|
||||
break;
|
||||
case "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$ExpressionInterceptUrlRegistry":
|
||||
replacementClass = "AuthorizationManagerRequestMatcherRegistry";
|
||||
}
|
||||
if (replacementClass != null) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri()
|
||||
.toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withLabel("Use of type '" + type.getClassName() + "' is outdated").withFixes(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(
|
||||
String.format(CLASS_FIX_LABEL_TEMPLATE, replacementClass),
|
||||
RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(
|
||||
String.format(CLASS_FIX_LABEL_TEMPLATE, replacementClass),
|
||||
RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT));
|
||||
|
||||
mv = mv.withTypeExpression(
|
||||
mv.getTypeExpression().withMarkers(mv.getTypeExpression().getMarkers().add(marker)));
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
|
||||
return version != null && version.compareTo(new Version(5, 6, 0, null)) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openrewrite.Cursor;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.marker.JavaSourceSet;
|
||||
import org.openrewrite.java.spring.AutowiredFieldIntoConstructorParameterVisitor;
|
||||
import org.openrewrite.java.tree.J.Block;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.CompilationUnit;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.J.VariableDeclarations;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ConvertAutowiredFieldIntoConstructorParameter;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
|
||||
|
||||
public class AutowiredFieldIntoConstructorParameterCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String LABEL = "Convert @Autowired field into Constructor Parameter";
|
||||
private static final String ID = ConvertAutowiredFieldIntoConstructorParameter.class.getName();
|
||||
private static final String AUTOWIRED = "org.springframework.beans.factory.annotation.Autowired";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
|
||||
@Override
|
||||
public CompilationUnit visitCompilationUnit(CompilationUnit cu, ExecutionContext p) {
|
||||
JavaSourceSet sourceSet = cu.getMarkers().findFirst(JavaSourceSet.class).orElse(null);
|
||||
if (sourceSet != null && ProjectParser.TEST.equals(sourceSet.getName())) {
|
||||
return cu;
|
||||
}
|
||||
return super.visitCompilationUnit(cu, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclarations visitVariableDeclarations(VariableDeclarations multiVariable,
|
||||
ExecutionContext p) {
|
||||
VariableDeclarations m = super.visitVariableDeclarations(multiVariable, p);
|
||||
Cursor blockCursor = getCursor().dropParentUntil(Block.class::isInstance);
|
||||
if (multiVariable.getVariables().size() == 1
|
||||
&& multiVariable.getLeadingAnnotations().stream().anyMatch(a -> TypeUtils.isOfClassType(a.getType(), AUTOWIRED))
|
||||
&& blockCursor.getParent().getValue() instanceof ClassDeclaration) {
|
||||
ClassDeclaration classDeclaration = (ClassDeclaration) blockCursor.getParent().getValue();
|
||||
FullyQualified fqType = TypeUtils.asFullyQualified(classDeclaration.getType());
|
||||
if (fqType != null && isApplicableType(fqType)) {
|
||||
List<MethodDeclaration> constructors = ORAstUtils.getMethods(classDeclaration).stream().filter(c -> c.isConstructor()).limit(2).collect(Collectors.toList());
|
||||
String fieldName = multiVariable.getVariables().get(0).getSimpleName();
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFix(
|
||||
new FixDescriptor(ID, List.of(uri), LABEL)
|
||||
.withRangeScope(classDeclaration.getMarkers().findFirst(Range.class).get())
|
||||
.withParameters(Map.of("classFqName", fqType.getFullyQualifiedName(), "fieldName", fieldName))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
);
|
||||
if (constructors.size() == 0) {
|
||||
m = m.withMarkers(m.getMarkers().add(marker));
|
||||
} else if (constructors.size() == 1 && AutowiredFieldIntoConstructorParameterVisitor.isNotConstructorInitializingField(constructors.get(0), fieldName)) {
|
||||
m = m.withMarkers(m.getMarkers().add(marker));
|
||||
} else {
|
||||
List<MethodDeclaration> autowiredConstructors = constructors.stream().filter(constr -> constr.getLeadingAnnotations().stream()
|
||||
.map(a -> TypeUtils.asFullyQualified(a.getType()))
|
||||
.filter(Objects::nonNull)
|
||||
.map(FullyQualified::getFullyQualifiedName)
|
||||
.anyMatch(AUTOWIRED::equals)
|
||||
)
|
||||
.limit(2)
|
||||
.collect(Collectors.toList());
|
||||
if (autowiredConstructors.size() == 1 && AutowiredFieldIntoConstructorParameterVisitor.isNotConstructorInitializingField(autowiredConstructors.get(0), fieldName)) {
|
||||
m = m.withMarkers(m.getMarkers().add(marker));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
private boolean isApplicableType(FullyQualified type) {
|
||||
return !AnnotationHierarchies
|
||||
.getTransitiveSuperAnnotations(type, fq -> fq.getFullyQualifiedName().startsWith("java."))
|
||||
.contains("org.springframework.boot.test.context.SpringBootTest");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_CONSTRUCTOR_PARAMETER_INJECTION;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.internal.ListUtils;
|
||||
import org.openrewrite.java.AnnotationMatcher;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.BeanMethodsNotPublic;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class BeanMethodNotPublicProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = BeanMethodsNotPublic.class.getName();
|
||||
|
||||
private static final String LABEL = "Remove 'public' from @Bean method";
|
||||
|
||||
private static final AnnotationMatcher BEAN_ANNOTATION_MATCHER = new AnnotationMatcher("@org.springframework.context.annotation.Bean");
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext executionContext) {
|
||||
J.MethodDeclaration m = super.visitMethodDeclaration(method, executionContext);
|
||||
|
||||
if (m.getAllAnnotations().stream().anyMatch(BEAN_ANNOTATION_MATCHER::matches)
|
||||
&& Boolean.FALSE.equals(TypeUtils.isOverride(method.getMethodType()))) {
|
||||
// mark public modifier
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker fixAssistMarker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFixes(
|
||||
new FixDescriptor(ID, List.of(uri), LABEL)
|
||||
.withRangeScope(m.getMarkers().findFirst(Range.class).get())
|
||||
.withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
|
||||
);
|
||||
m = m.withModifiers(ListUtils.map(m.getModifiers(), modifier -> {
|
||||
if (modifier.getType() == J.Modifier.Type.Public) {
|
||||
return modifier.withMarkers(modifier.getMarkers().add(fixAssistMarker));
|
||||
}
|
||||
return modifier;
|
||||
}));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return SpringProjectUtil.getDependencyVersion(project, SpringProjectUtil.SPRING_BOOT) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boot2JavaProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_PUBLIC_BEAN_METHOD;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.BeanPostProcessingIgnoreInAot;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class BeanPostProcessingIgnoreInAotProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String RECIPE_ID = BeanPostProcessingIgnoreInAot.class.getName();
|
||||
private static final String LABEL = "Add method 'isBeanExcludedFromAotProcessing' that returns 'false'";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) {
|
||||
ClassDeclaration c = super.visitClassDeclaration(classDecl, p);
|
||||
if (BeanPostProcessingIgnoreInAot.isApplicableClass(classDecl)) {
|
||||
List<MethodDeclaration> methods = classDecl.getBody().getStatements().stream()
|
||||
.filter(MethodDeclaration.class::isInstance).map(MethodDeclaration.class::cast)
|
||||
.filter(BeanPostProcessingIgnoreInAot::isApplicableMethod)
|
||||
.collect(Collectors.toList());
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFixes(
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.NODE))
|
||||
.withRangeScope(classDecl.getMarkers().findFirst(Range.class).orElse(null))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
);
|
||||
if (methods.isEmpty()) {
|
||||
// Didn't find a method. Default implementation return true therefore mark it.
|
||||
c = c.withName(c.getName().withMarkers(c.getName().getMarkers().add(marker)));
|
||||
} else {
|
||||
MethodDeclaration m = methods.stream().filter(BeanPostProcessingIgnoreInAot::isReturnTrue).findFirst().orElse(null);
|
||||
// Found method that return true explicitly
|
||||
if (m != null) {
|
||||
c = c.withName(c.getName().withMarkers(c.getName().getMarkers().add(marker)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return SpringAotJavaProblemType.JAVA_BEAN_POST_PROCESSOR_IGNORED_IN_AOT;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.openrewrite.java.tree.NameTree;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.Boot3JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class Boot3NotSupportedTypeProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final List<String> TYPE_FQNAMES = List.of(
|
||||
"org.springframework.web.multipart.commons.CommonsMultipartResolver",
|
||||
"java.lang.SecurityManager",
|
||||
"java.security.AccessControlException"
|
||||
);
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
@Override
|
||||
public J.Identifier visitIdentifier(J.Identifier ident, ExecutionContext executionContext) {
|
||||
if (ident.getType() != null &&
|
||||
getCursor().firstEnclosing(J.Import.class) == null &&
|
||||
getCursor().firstEnclosing(J.FieldAccess.class) == null &&
|
||||
!(getCursor().getParentOrThrow().getValue() instanceof J.ParameterizedType)) {
|
||||
JavaType.FullyQualified type = TypeUtils.asFullyQualified(ident.getType());
|
||||
for (String fqName : TYPE_FQNAMES) {
|
||||
if (typeMatches(true, fqName, type) &&
|
||||
ident.getSimpleName().equals(type.getClassName())) {
|
||||
return ident.withMarkers(ident.getMarkers().add(new FixAssistMarker(Tree.randomId(), getId()).withLabel(createLabel(fqName))));
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visitIdentifier(ident, executionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <N extends NameTree> N visitTypeName(N name, ExecutionContext ctx) {
|
||||
N n = super.visitTypeName(name, ctx);
|
||||
JavaType.FullyQualified type = TypeUtils.asFullyQualified(n.getType());
|
||||
for (String fqName : TYPE_FQNAMES) {
|
||||
if (typeMatches(true, fqName, type) &&
|
||||
getCursor().firstEnclosing(J.Import.class) == null) {
|
||||
return n.withMarkers(n.getMarkers().add(new FixAssistMarker(Tree.randomId(), getId()).withLabel(createLabel(fqName))));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess, ExecutionContext ctx) {
|
||||
J.FieldAccess fa = (J.FieldAccess) super.visitFieldAccess(fieldAccess, ctx);
|
||||
JavaType.FullyQualified type = TypeUtils.asFullyQualified(fa.getTarget().getType());
|
||||
for (String fqName : TYPE_FQNAMES) {
|
||||
if (typeMatches(true, fqName, type) &&
|
||||
fa.getName().getSimpleName().equals("class")) {
|
||||
return fa.withMarkers(fa.getMarkers().add(new FixAssistMarker(Tree.randomId(), getId()).withLabel(createLabel(fqName))));
|
||||
}
|
||||
}
|
||||
return fa;
|
||||
}
|
||||
|
||||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
|
||||
MethodInvocation m = super.visitMethodInvocation(method, ctx);
|
||||
Method methodType = m.getMethodType();
|
||||
if (methodType != null) {
|
||||
FullyQualified fqType = TypeUtils.asFullyQualified(methodType.getReturnType());
|
||||
if (fqType != null) {
|
||||
for (String fqName : TYPE_FQNAMES) {
|
||||
if (typeMatches(true, fqName, fqType)) {
|
||||
return m.withMarkers(m.getMarkers().add(new FixAssistMarker(Tree.randomId(), getId()).withLabel(createLabel(fqName))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String createLabel(String type) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("'");
|
||||
sb.append(type);
|
||||
sb.append("' not supported as of Spring Boot 3");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static boolean typeMatches(boolean checkAssignability, String fqName, JavaType.FullyQualified test) {
|
||||
return test != null && (checkAssignability ? test.isAssignableTo(fqName) : fqName.equals(test.getFullyQualifiedName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot3JavaProblemType.JAVA_TYPE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot2.search.EntityIdForRepositoryVisitor;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.marker.Marker;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
|
||||
public class EntityIdForRepoProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = EntityIdForRepositoryVisitor.class.getName();
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
boolean considerIdField = context.project() != null && SpringProjectUtil.hasSpecificLibraryOnClasspath(context.project(), "spring-data-mongodb-", true);
|
||||
return new EntityIdForRepositoryVisitor<>(considerIdField) {
|
||||
@Override
|
||||
protected Marker createMarker(JavaType domainIdType) {
|
||||
return new FixAssistMarker(Tree.randomId(), ID).withLabel("Expected Domain ID type is '" + domainIdType + "'");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.DOMAIN_ID_FOR_REPOSITORY;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot2.ConvertToSecurityDslVisitor;
|
||||
import org.openrewrite.java.spring.boot2.HttpSecurityLambdaDsl;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class HttpSecurityLamdaDslCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String PROBLEM_LABEL = "Consider switching to 'HttpSecurity' Lambda DSL syntax";
|
||||
|
||||
private static final String FIX_LABEL = "Switch to 'HttpSecurity` Lambda DSL syntax";
|
||||
|
||||
private HttpSecurityLambdaDsl recipe = new HttpSecurityLambdaDsl();
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) {
|
||||
if (((ConvertToSecurityDslVisitor<?>) recipe.getVisitor()).isApplicableTopLevelMethodInvocation(method)) {
|
||||
// Don't step into the method any further
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId()).withLabel(PROBLEM_LABEL)
|
||||
.withFixes(
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.NODE))
|
||||
.withRangeScope(method.getMarkers().findFirst(Range.class).get())
|
||||
.withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT));
|
||||
|
||||
return method.withMarkers(method.getMarkers().add(marker));
|
||||
}
|
||||
return super.visitMethodInvocation(method, p);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
|
||||
return version != null && version.compareTo(new Version(5, 2, 0, null)) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_LAMBDA_DSL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.marker.JavaSourceSet;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.CompilationUnit;
|
||||
import org.openrewrite.java.tree.J.FieldAccess;
|
||||
import org.openrewrite.java.tree.J.Identifier;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.Boot3JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.modulith.AppModules;
|
||||
import org.springframework.ide.vscode.boot.modulith.ModulithService;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
|
||||
|
||||
public class ModulithTypeReferenceViolation implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String MSG_PKG_NAME = "packageName";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
ModulithService modulithService = context.appContext().getBean(ModulithService.class);
|
||||
AppModules appModules = modulithService.getModulesData(context.project());
|
||||
|
||||
return new JavaIsoVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public CompilationUnit visitCompilationUnit(CompilationUnit cu, ExecutionContext p) {
|
||||
if (appModules == null) {
|
||||
return cu;
|
||||
} else {
|
||||
JavaSourceSet sourceSet = cu.getMarkers().findFirst(JavaSourceSet.class).orElse(null);
|
||||
if (sourceSet != null && ProjectParser.TEST.equals(sourceSet.getName())) {
|
||||
return cu;
|
||||
}
|
||||
String pkgName = cu.getPackageDeclaration() == null ? "" : cu.getPackageDeclaration().getPackageName();
|
||||
p.putMessage(MSG_PKG_NAME, pkgName);
|
||||
return super.visitCompilationUnit(cu, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public FieldAccess visitFieldAccess(FieldAccess fieldAccess, ExecutionContext p) {
|
||||
FieldAccess fa = super.visitFieldAccess(fieldAccess, p);
|
||||
return process(fa, p.getMessage(MSG_PKG_NAME), TypeUtils.asFullyQualified(fa.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier visitIdentifier(Identifier identifier, ExecutionContext p) {
|
||||
Identifier i = super.visitIdentifier(identifier, p);
|
||||
if (getCursor().getParent().firstEnclosingOrThrow(J.class) instanceof J.FieldAccess) {
|
||||
return i;
|
||||
}
|
||||
// check if identifier is a simple name of the type
|
||||
FullyQualified type = TypeUtils.asFullyQualified(identifier.getType());
|
||||
if (type != null && identifier.getSimpleName().equals(type.getClassName())) {
|
||||
return process(i, p.getMessage(MSG_PKG_NAME), type);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private <T extends J> T process(T node, String packageName, FullyQualified type) {
|
||||
if (type != null) {
|
||||
Optional<T> opt = appModules.getModuleNotExposingType(packageName, type.getFullyQualifiedName()).map(module -> {
|
||||
FixAssistMarker fixMarker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withLabel("Cannot use type in this package. Type is not exposed in module '" + module.name() + "'." );
|
||||
return node.withMarkers(node.getMarkers().add(fixMarker));
|
||||
});
|
||||
return opt.orElse(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return ModulithService.isModulithDependentProject(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot3JavaProblemType.MODULITH_TYPE_REF_VIOLATION;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.internal.ListUtils;
|
||||
import org.openrewrite.java.AnnotationMatcher;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.NoAutowiredOnConstructor;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.Statement;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class NoAutowiredOnConstructorProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final AnnotationMatcher BOOT_TEST_ANNOTATION_MATCHER = new AnnotationMatcher(
|
||||
"@org.springframework.boot.test.context.SpringBootTest", true);
|
||||
private static final String ID = NoAutowiredOnConstructor.class.getName();
|
||||
private static final String LABEL = "Remove Unnecessary @Autowired";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext context) {
|
||||
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, context);
|
||||
|
||||
int constructorCount = 0;
|
||||
for (Statement s : cd.getBody().getStatements()) {
|
||||
if (isConstructor(s)) {
|
||||
constructorCount++;
|
||||
if (constructorCount > 1) {
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FullyQualified type = TypeUtils.asFullyQualified(classDecl.getType());
|
||||
if (type != null && isApplicableType(type)) {
|
||||
return cd.withBody(cd.getBody().withStatements(ListUtils.map(cd.getBody().getStatements(), s -> {
|
||||
if (!isConstructor(s)) {
|
||||
return s;
|
||||
}
|
||||
MethodDeclaration constructor = (MethodDeclaration) s;
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri()
|
||||
.toASCIIString();
|
||||
FixAssistMarker fixAssistMarker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFix(new FixDescriptor(ID, List.of(uri), LABEL).withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(getCursor().firstEnclosing(ClassDeclaration.class).getMarkers()
|
||||
.findFirst(Range.class).get()));
|
||||
constructor = constructor
|
||||
.withLeadingAnnotations(ListUtils.map(constructor.getLeadingAnnotations(), a -> {
|
||||
if (TypeUtils.isOfClassType(a.getType(), Annotations.AUTOWIRED)) {
|
||||
a = a.withMarkers(a.getMarkers().add(fixAssistMarker));
|
||||
}
|
||||
return a;
|
||||
}));
|
||||
return constructor;
|
||||
})));
|
||||
}
|
||||
return cd;
|
||||
}
|
||||
|
||||
private boolean isApplicableType(FullyQualified type) {
|
||||
for (FullyQualified annotationType : type.getAnnotations()) {
|
||||
if (BOOT_TEST_ANNOTATION_MATCHER.matchesAnnotationOrMetaAnnotation(annotationType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FullyQualified superType = type.getSupertype();
|
||||
return superType == null ? true : isApplicableType(superType);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boot2JavaProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_AUTOWIRED_CONSTRUCTOR;
|
||||
}
|
||||
|
||||
private static boolean isConstructor(Statement s) {
|
||||
return s instanceof J.MethodDeclaration && ((J.MethodDeclaration) s).isConstructor();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.internal.ListUtils;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.NoRepoAnnotationOnRepoInterface;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class NoRepoAnnotationProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = NoRepoAnnotationOnRepoInterface.class.getName();
|
||||
private static final String LABEL = "Remove Unnecessary @Repository";
|
||||
private static final String INTERFACE_REPOSITORY = "org.springframework.data.repository.Repository";
|
||||
private static final String ANNOTATION_REPOSITORY = Annotations.REPOSITORY;
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl,
|
||||
ExecutionContext executionContext) {
|
||||
J.ClassDeclaration c = super.visitClassDeclaration(classDecl, executionContext);
|
||||
if (c.getKind() == ClassDeclaration.Kind.Type.Interface) {
|
||||
final J.Annotation repoAnnotation = c.getLeadingAnnotations().stream().filter(annotation -> {
|
||||
if (annotation.getArguments() == null || annotation.getArguments().isEmpty()
|
||||
|| annotation.getArguments().get(0) instanceof J.Empty) {
|
||||
JavaType.FullyQualified type = TypeUtils.asFullyQualified(annotation.getType());
|
||||
return type != null && ANNOTATION_REPOSITORY.equals(type.getFullyQualifiedName());
|
||||
}
|
||||
return false;
|
||||
}).findFirst().orElse(null);
|
||||
if (repoAnnotation != null && TypeUtils.isAssignableTo(INTERFACE_REPOSITORY, c.getType())) {
|
||||
c = c.withLeadingAnnotations(ListUtils.map(c.getLeadingAnnotations(), a -> {
|
||||
if (a == repoAnnotation) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri()
|
||||
.toASCIIString();
|
||||
FixAssistMarker fixAssistMarker = new FixAssistMarker(Tree.randomId(), getId()).withFixes(
|
||||
new FixDescriptor(ID, List.of(uri), LABEL)
|
||||
.withRangeScope(classDecl.getMarkers().findFirst(Range.class).get())
|
||||
.withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
|
||||
);
|
||||
return a.withMarkers(a.getMarkers().add(fixAssistMarker));
|
||||
}
|
||||
return a;
|
||||
}));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boot2JavaProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_REPOSITORY;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.AnnotationMatcher;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.NoRequestMappingAnnotation;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class NoRequestMappingAnnotationCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String LABEL = "Replace @RequestMapping with specific @GetMapping, @PostMapping etc.";
|
||||
private static final String ID = NoRequestMappingAnnotation.class.getName();
|
||||
private static final AnnotationMatcher REQUEST_MAPPING_ANNOTATION_MATCHER = new AnnotationMatcher("@org.springframework.web.bind.annotation.RequestMapping");
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
@Override
|
||||
public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) {
|
||||
J.Annotation a = super.visitAnnotation(annotation, ctx);
|
||||
if (REQUEST_MAPPING_ANNOTATION_MATCHER.matches(a) && getCursor().getParentOrThrow().getValue() instanceof J.MethodDeclaration) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker fixAssistMarker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFixes(
|
||||
// new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.NODE))
|
||||
// .withRangeScope(a.getMarkers().findFirst(Range.class).get())
|
||||
// .withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
);
|
||||
a = a.withMarkers(a.getMarkers().add(fixAssistMarker));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_PRECISE_REQUEST_MAPPING;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022, 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ConfigBeanSymbolAddOnInformation;
|
||||
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.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.DefineMethod;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class NotRegisteredBeansProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String DEFINE_METHOD_RECIPE = DefineMethod.class.getName();
|
||||
|
||||
private static final List<String> AOT_BEANS = List.of(
|
||||
"org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor",
|
||||
"org.springframework.beans.factory.aot.BeanRegistrationAotProcessor"
|
||||
);
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) {
|
||||
ClassDeclaration c = super.visitClassDeclaration(classDecl, p);
|
||||
FullyQualified type = c.getType();
|
||||
if (type != null) {
|
||||
String beanClassName = type.getFullyQualifiedName();
|
||||
boolean applicable = AOT_BEANS.stream().filter(fqName -> TypeUtils.isAssignableTo(fqName, type)).findFirst().isPresent();
|
||||
if (applicable) {
|
||||
SpringSymbolIndex index = context.appContext().getBean(SpringSymbolIndex.class);
|
||||
List<WorkspaceSymbol> beanSymbols = index.getSymbols(data -> {
|
||||
SymbolAddOnInformation[] additionalInformation = data.getAdditionalInformation();
|
||||
if (additionalInformation != null) {
|
||||
for (SymbolAddOnInformation info : additionalInformation) {
|
||||
if (info instanceof BeansSymbolAddOnInformation) {
|
||||
BeansSymbolAddOnInformation info2 = (BeansSymbolAddOnInformation) info;
|
||||
return beanClassName.equals(info2.getBeanType());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).limit(1).collect(Collectors.toList());
|
||||
Builder<FixDescriptor> fixListBuilder = ImmutableList.builder();
|
||||
List<JavaType.Method> constructors = c.getType().getMethods().stream().filter(m -> m.isConstructor()).collect(Collectors.toList());
|
||||
if (beanSymbols.isEmpty()) {
|
||||
SourceFile source = getCursor().firstEnclosing(SourceFile.class);
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId());
|
||||
IJavaProject project = context.project();
|
||||
if (project != null) {
|
||||
|
||||
for (EnhancedSymbolInformation s : index.getEnhancedSymbols(project)) {
|
||||
if (s.getAdditionalInformation() != null) {
|
||||
ConfigBeanSymbolAddOnInformation configInfo = Arrays.stream(s.getAdditionalInformation()).filter(ConfigBeanSymbolAddOnInformation.class::isInstance).map(ConfigBeanSymbolAddOnInformation.class::cast).findFirst().orElse(null);
|
||||
if (configInfo != null) {
|
||||
for (JavaType.Method constructor : constructors) {
|
||||
String constructorParamsSignature = "(" + constructor.getParameterTypes().stream().map(pt -> typePattern(pt)).collect(Collectors.joining(",")) + ")";
|
||||
String beanMethodName = "get" + type.getClassName();
|
||||
String pattern = beanMethodName + constructorParamsSignature;
|
||||
String contructorParamsLabel = "(" + constructor.getParameterTypes().stream().map(NotRegisteredBeansProblem::typeStr).collect(Collectors.joining(", ")) + ")";
|
||||
|
||||
Builder<String> paramBuilder = ImmutableList.builder();
|
||||
for (int i = 0; i < constructor.getParameterNames().size() && i < constructor.getParameterTypes().size(); i++) {
|
||||
JavaType paramType = constructor.getParameterTypes().get(i);
|
||||
String paramName = constructor.getParameterNames().get(i);
|
||||
paramBuilder.add(typeStr(paramType) + ' ' + paramName);
|
||||
}
|
||||
String paramsStr = String.join(", ", paramBuilder.build().toArray(String[]::new));
|
||||
|
||||
fixListBuilder.add(new FixDescriptor(DEFINE_METHOD_RECIPE, List.of(s.getSymbol().getLocation().getLeft().getUri()), "Define bean in config '" + configInfo.getBeanID() + "' with constructor " + contructorParamsLabel)
|
||||
.withRecipeScope(RecipeScope.FILE)
|
||||
.withParameters(Map.of(
|
||||
"targetFqName", configInfo.getBeanType(),
|
||||
"signature", pattern,
|
||||
"template", "@Bean\n"
|
||||
+ type.getClassName() + " " + beanMethodName + "(" + paramsStr + ") {\n"
|
||||
+ "return new " + type.getClassName() + "(" + constructor.getParameterNames().stream().collect(Collectors.joining(", ")) + ");\n"
|
||||
+ "}\n",
|
||||
"imports", allFQTypes(constructor).toArray(String[]::new),
|
||||
"typeStubs", new String[] { source.printAll() },
|
||||
"classpath", IClasspathUtil.getAllBinaryRoots(project.getClasspath()).stream().map(f -> f.toPath().toString()).toArray(String[]::new)
|
||||
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
marker.withFixes(fixListBuilder.build().toArray(FixDescriptor[]::new));
|
||||
c = c.withName(c.getName().withMarkers(c.getName().getMarkers().add(marker)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private static Set<String> allFQTypes(JavaType type) {
|
||||
ImmutableSet.Builder<String> b = ImmutableSet.builder();
|
||||
if (type instanceof JavaType.FullyQualified) {
|
||||
b.add(((JavaType.FullyQualified) type).getFullyQualifiedName());
|
||||
if (type instanceof JavaType.Parameterized) {
|
||||
((JavaType.Parameterized) type).getTypeParameters().forEach(t -> b.addAll(allFQTypes(t)));
|
||||
}
|
||||
} else if (type instanceof JavaType.Array) {
|
||||
b.addAll(allFQTypes(((JavaType.Array) type).getElemType()));
|
||||
} else if (type instanceof JavaType.Method) {
|
||||
JavaType.Method m = (JavaType.Method) type;
|
||||
b.addAll(allFQTypes(m.getDeclaringType()));
|
||||
b.addAll(allFQTypes(m.getReturnType()));
|
||||
m.getParameterTypes().forEach(pt -> b.addAll(allFQTypes(pt)));
|
||||
}
|
||||
return b.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return SpringAotJavaProblemType.JAVA_BEAN_NOT_REGISTERED_IN_AOT;
|
||||
}
|
||||
|
||||
private static String typePattern(JavaType type) {
|
||||
if (type instanceof JavaType.Primitive) {
|
||||
if (type.equals(JavaType.Primitive.String)) {
|
||||
return ((JavaType.Primitive) type).getClassName();
|
||||
}
|
||||
return ((JavaType.Primitive) type).getKeyword();
|
||||
} else if (type instanceof JavaType.FullyQualified) {
|
||||
return ((JavaType.FullyQualified) type).getFullyQualifiedName();
|
||||
} else if (type instanceof JavaType.Array) {
|
||||
JavaType elemType = ((JavaType.Array) type).getElemType();
|
||||
return typePattern(elemType) + "[]";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String typeStr(JavaType type) {
|
||||
if (type instanceof JavaType.Primitive) {
|
||||
if (type.equals(JavaType.Primitive.String)) {
|
||||
return ((JavaType.Primitive) type).getClassName();
|
||||
}
|
||||
return ((JavaType.Primitive) type).getKeyword();
|
||||
} else if (type instanceof JavaType.Parameterized) {
|
||||
JavaType.Parameterized parametereized = (JavaType.Parameterized) type;
|
||||
return parametereized.getClassName() + "<" + parametereized.getTypeParameters().stream().map(NotRegisteredBeansProblem::typeStr).collect(Collectors.joining(", ")) + ">";
|
||||
} else if (type instanceof JavaType.FullyQualified) {
|
||||
return ((JavaType.FullyQualified) type).getClassName();
|
||||
} else if (type instanceof JavaType.Array) {
|
||||
JavaType elemType = ((JavaType.Array) type).getElemType();
|
||||
return typeStr(elemType) + "[]";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.Cursor;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot3.PreciseBeanType;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.Return;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.SpringAotJavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class PreciseBeanTypeProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String RECIPE_ID = PreciseBeanType.class.getName();
|
||||
|
||||
private static final String LABEL = "Ensure concrete bean type";
|
||||
|
||||
private static final String MSG_KEY = "returnType";
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
|
||||
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext executionContext) {
|
||||
J.MethodDeclaration m = super.visitMethodDeclaration(method, executionContext);
|
||||
if (m.getLeadingAnnotations().stream().anyMatch(a -> TypeUtils.isOfClassType(a.getType(), "org.springframework.context.annotation.Bean"))) {
|
||||
Object o = getCursor().pollMessage(MSG_KEY);
|
||||
if (o != null && !areTypesEqual((JavaType) o, m.getReturnTypeExpression().getType())) {
|
||||
if ((o instanceof JavaType.FullyQualified && m.getReturnTypeExpression().getType() instanceof JavaType.FullyQualified)
|
||||
|| (o instanceof JavaType.Array && m.getReturnTypeExpression().getType() instanceof JavaType.Array)) {
|
||||
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFixes(
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.NODE))
|
||||
.withRecipeScope(RecipeScope.NODE)
|
||||
.withRangeScope(m.getMarkers().findFirst(Range.class).get()),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(RECIPE_ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
);
|
||||
m = m.withReturnTypeExpression(m.getReturnTypeExpression().withMarkers(m.getReturnTypeExpression().getMarkers().add(marker)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Return visitReturn(Return _return, ExecutionContext executionContext) {
|
||||
Cursor methodCursor = getCursor();
|
||||
if (_return.getExpression() != null) {
|
||||
while (methodCursor != null && !(methodCursor.getValue() instanceof J.Lambda || methodCursor.getValue() instanceof J.MethodDeclaration)) {
|
||||
methodCursor = methodCursor.getParent();
|
||||
}
|
||||
if (methodCursor != null && methodCursor.getValue() instanceof J.MethodDeclaration) {
|
||||
methodCursor.putMessage(MSG_KEY, _return.getExpression().getType());
|
||||
}
|
||||
}
|
||||
return super.visitReturn(_return, executionContext);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean areTypesEqual(JavaType a, JavaType b) {
|
||||
if (a instanceof JavaType.Parameterized && b instanceof JavaType.Parameterized) {
|
||||
JavaType.Parameterized ap = (JavaType.Parameterized) a;
|
||||
JavaType.Parameterized bp = (JavaType.Parameterized) b;
|
||||
if (ap.getTypeParameters().size() != bp.getTypeParameters().size()) {
|
||||
return false;
|
||||
}
|
||||
if (areTypesEqual(ap.getType(), bp.getType())) {
|
||||
for (int i = 0; i < ap.getTypeParameters().size(); i++) {
|
||||
if (!areTypesEqual(ap.getTypeParameters().get(i), bp.getTypeParameters().get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (a instanceof JavaType.Parameterized && b instanceof JavaType.FullyQualified) {
|
||||
return areTypesEqual(((JavaType.Parameterized) a).getType(), b);
|
||||
} else if (a instanceof JavaType.FullyQualified && b instanceof JavaType.Parameterized) {
|
||||
return areTypesEqual(a, ((JavaType.Parameterized) b).getType());
|
||||
} else if (a instanceof JavaType.Array && b instanceof JavaType.Array) {
|
||||
return areTypesEqual(((JavaType.Array) a).getElemType(), ((JavaType.Array) b).getElemType());
|
||||
}
|
||||
if (a instanceof JavaType.GenericTypeVariable || b instanceof JavaType.GenericTypeVariable) {
|
||||
return true;
|
||||
}
|
||||
if (a == JavaType.Primitive.String && b instanceof JavaType.FullyQualified) {
|
||||
return JavaType.Primitive.String.getClassName().equals(((JavaType.FullyQualified) b).getFullyQualifiedName());
|
||||
}
|
||||
if (b == JavaType.Primitive.String && b instanceof JavaType.FullyQualified) {
|
||||
return JavaType.Primitive.String.getClassName().equals(((JavaType.FullyQualified) a).getFullyQualifiedName());
|
||||
}
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpringAotJavaProblemType getProblemType() {
|
||||
return SpringAotJavaProblemType.JAVA_CONCRETE_BEAN_TYPE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot2.ConvertToSecurityDslVisitor;
|
||||
import org.openrewrite.java.spring.boot2.ServerHttpSecurityLambdaDsl;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class ServerHttpSecurityLambdaDslCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String PROBLEM_LABEL = "Consider switching to 'ServerHttpSecurity' Lambda DSL syntax";
|
||||
|
||||
private static final String FIX_LABEL = "Switch to 'ServerHttpSecurity` Lambda DSL syntax";
|
||||
|
||||
private ServerHttpSecurityLambdaDsl recipe = new ServerHttpSecurityLambdaDsl();
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<ExecutionContext>() {
|
||||
|
||||
@Override
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) {
|
||||
if (((ConvertToSecurityDslVisitor<?>)recipe.getVisitor()).isApplicableTopLevelMethodInvocation(method)) {
|
||||
// Don't step into the method any further
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), getId()).withLabel(PROBLEM_LABEL)
|
||||
.withFixes(
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.NODE))
|
||||
.withRangeScope(method.getMarkers().findFirst(Range.class).get())
|
||||
.withRecipeScope(RecipeScope.NODE),
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE),
|
||||
new FixDescriptor(recipe.getName(), List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT));
|
||||
return method.withMarkers(method.getMarkers().add(marker));
|
||||
}
|
||||
return super.visitMethodInvocation(method, p);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
|
||||
return version != null && version.compareTo(new Version(5, 2, 0, null)) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_LAMBDA_DSL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 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.rewrite.reconcile;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.java.SpringProjectUtil.springBootVersionGreaterOrEqual;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.internal.ListUtils;
|
||||
import org.openrewrite.java.AnnotationMatcher;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.boot2.UnnecessarySpringExtension;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class UnnecessarySpringExtensionProblem implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String LABEL = "Remove unnecessary @SpringExtension";
|
||||
private static final String ID = UnnecessarySpringExtension.class.getName();
|
||||
private static final List<String> SPRING_BOOT_TEST_ANNOTATIONS = Arrays.asList(
|
||||
"org.springframework.boot.test.context.SpringBootTest",
|
||||
"org.springframework.boot.test.autoconfigure.jdbc.JdbcTest",
|
||||
"org.springframework.boot.test.autoconfigure.web.client.RestClientTest",
|
||||
"org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest",
|
||||
"org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest",
|
||||
"org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest",
|
||||
"org.springframework.boot.test.autoconfigure.webservices.client.WebServiceClientTest",
|
||||
"org.springframework.boot.test.autoconfigure.jooq.JooqTest",
|
||||
"org.springframework.boot.test.autoconfigure.json.JsonTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest",
|
||||
"org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest"
|
||||
);
|
||||
private static final AnnotationMatcher SPRING_EXTENSION_ANNOTATIN_MATCHER = new AnnotationMatcher("@org.junit.jupiter.api.extension.ExtendWith(org.springframework.test.context.junit.jupiter.SpringExtension.class)");
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) {
|
||||
ClassDeclaration c = super.visitClassDeclaration(classDecl, p);
|
||||
if (c.getLeadingAnnotations().stream().anyMatch(a -> {
|
||||
FullyQualified fq = TypeUtils.asFullyQualified(a.getType());
|
||||
return fq != null && SPRING_BOOT_TEST_ANNOTATIONS.contains(fq.getFullyQualifiedName());
|
||||
})) {
|
||||
c = c.withLeadingAnnotations(ListUtils.map(c.getLeadingAnnotations(), a -> {
|
||||
if (SPRING_EXTENSION_ANNOTATIN_MATCHER.matches(a)) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
FixAssistMarker fixMarker = new FixAssistMarker(Tree.randomId(), getId())
|
||||
.withFix(new FixDescriptor(ID, List.of(uri), RecipeCodeActionDescriptor.buildLabel(LABEL, RecipeScope.PROJECT)));
|
||||
return a.withMarkers(a.getMarkers().add(fixMarker));
|
||||
}
|
||||
return a;
|
||||
}));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return springBootVersionGreaterOrEqual(2, 1, 0).test(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boot2JavaProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.JAVA_TEST_SPRING_EXTENSION;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.rewrite.reconcile;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.SourceFile;
|
||||
import org.openrewrite.Tree;
|
||||
import org.openrewrite.java.JavaVisitor;
|
||||
import org.openrewrite.java.spring.security5.WebSecurityConfigurerAdapter;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.TypeTree;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.Version;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.MarkerVisitorContext;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
|
||||
|
||||
public class WebSecurityConfigurerAdapterCodeAction implements RecipeCodeActionDescriptor {
|
||||
|
||||
private static final String ID = WebSecurityConfigurerAdapter.class.getName();
|
||||
|
||||
private static final String FQN_WEB_SECURITY_CONFIGURER_ADAPTER = "org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter";
|
||||
|
||||
private static final String PROBLEM_LABEL = "Class extends 'WebSecurityConfigurerAdapter' which is removed in Spring-Security 6.x";
|
||||
|
||||
private static final String FIX_LABEL = "Refactor class into a Configuration bean not extending 'WebSecurityConfigurerAdapter'";
|
||||
|
||||
private static final String STUB_WEB_SECURITY_CONFIG_ADAPTER = """
|
||||
package org.springframework.security.config.annotation.web.configuration;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
||||
public abstract class WebSecurityConfigurerAdapter {
|
||||
|
||||
public void init(WebSecurity web) throws Exception {}
|
||||
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception { return null; }
|
||||
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception { return null; }
|
||||
|
||||
protected void configure(HttpSecurity http) throws Exception {}
|
||||
|
||||
public void configure(WebSecurity web) throws Exception {}
|
||||
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {}
|
||||
}
|
||||
""";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return Boot2JavaProblemType.WEB_SECURITY_CONFIGURER_ADAPTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaVisitor<ExecutionContext> getMarkerVisitor(MarkerVisitorContext context) {
|
||||
return new JavaMarkerVisitor<>() {
|
||||
|
||||
@Override
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) {
|
||||
ClassDeclaration c = super.visitClassDeclaration(classDecl, p);
|
||||
TypeTree superClass = c.getExtends();
|
||||
boolean isExtendingWebSecurityConfigurerAdapter = false;
|
||||
boolean isUnresolved = false;
|
||||
if (superClass != null) {
|
||||
if (superClass.getType() instanceof JavaType.Unknown) {
|
||||
String strType = superClass.printTrimmed(getCursor());
|
||||
isExtendingWebSecurityConfigurerAdapter = "WebSecurityConfigurerAdapter".equals(strType) || FQN_WEB_SECURITY_CONFIGURER_ADAPTER.equals(strType);
|
||||
isUnresolved = true;
|
||||
} else if (superClass.getType() instanceof JavaType.FullyQualified) {
|
||||
isExtendingWebSecurityConfigurerAdapter = FQN_WEB_SECURITY_CONFIGURER_ADAPTER.equals( ((JavaType.FullyQualified)superClass.getType()).getFullyQualifiedName());
|
||||
}
|
||||
}
|
||||
if (isExtendingWebSecurityConfigurerAdapter) {
|
||||
if (isAnnotatedWith(c.getLeadingAnnotations(), Annotations.CONFIGURATION)) {
|
||||
String uri = getCursor().firstEnclosing(SourceFile.class).getSourcePath().toUri().toASCIIString();
|
||||
String[] typeStubs = new String[0];
|
||||
if (isUnresolved) {
|
||||
typeStubs = new String[] { STUB_WEB_SECURITY_CONFIG_ADAPTER };
|
||||
}
|
||||
FixAssistMarker marker = new FixAssistMarker(Tree.randomId(), ID).withLabel(PROBLEM_LABEL)
|
||||
.withFixes(
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.FILE))
|
||||
.withRecipeScope(RecipeScope.FILE)
|
||||
.withTypeStubs(typeStubs),
|
||||
new FixDescriptor(ID, List.of(uri),
|
||||
RecipeCodeActionDescriptor.buildLabel(FIX_LABEL, RecipeScope.PROJECT))
|
||||
.withRecipeScope(RecipeScope.PROJECT)
|
||||
.withTypeStubs(typeStubs));
|
||||
c = c.withName(c.getName().withMarkers(c.getName().getMarkers().add(marker)));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
|
||||
return version != null && version.compareTo(new Version(5, 7, 0, null)) >= 0 && version.compareTo(new Version(6, 1, 0, null)) < 0;
|
||||
}
|
||||
|
||||
private static boolean isAnnotatedWith(Collection<J.Annotation> annotations, String annotationType) {
|
||||
return annotations.stream().anyMatch(a -> TypeUtils.isOfClassType(a.getType(), annotationType));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user