From da89df6e60a08d77e20d2e5beb9b622d17bcf269 Mon Sep 17 00:00:00 2001 From: aboyko Date: Thu, 31 Aug 2023 18:16:44 -0400 Subject: [PATCH] Remove rewrite reconcile related classes and cleanup --- .../HelloMethodRenameProblemDescriptor.java | 75 ---- .../rewrite/test/StsTestCodeActionRepo.java | 25 -- .../rewrite/config/CodeActionRepoLoader.java | 80 ---- .../rewrite/config/CodeActionRepository.java | 19 - .../config/DefaultMarkerVisitorContext.java | 18 - .../rewrite/config/MarkerVisitorContext.java | 22 -- .../config/RecipeCodeActionDescriptor.java | 43 --- .../rewrite/config/StsEnvironment.java | 81 ---- .../rewrite/config/StsResourceLoader.java | 22 -- .../ide/vscode/boot/app/RewriteConfig.java | 18 +- .../AbstractSecurityLamdaDslReconciler.java | 12 +- ...ConfigurationIfBeansPresentReconciler.java | 8 +- .../AuthorizeHttpRequestsReconciler.java | 18 +- ...eldIntoConstructorParameterReconciler.java | 8 +- .../BeanMethodNotPublicReconciler.java | 9 +- ...anPostProcessingIgnoreInAotReconciler.java | 8 +- .../NoAutowiredOnConstructorReconciler.java | 6 +- .../NoRepoAnnotationReconciler.java | 11 +- .../NoRequestMappingAnnotationReconciler.java | 7 +- .../NotRegisteredBeansReconciler.java | 6 +- .../PreciseBeanTypeReconciler.java | 11 +- ...QuickFixUtils.java => ReconcileUtils.java} | 4 +- .../UnnecessarySpringExtensionReconciler.java | 4 +- ...ebSecurityConfigurerAdapterReconciler.java | 9 +- .../rewrite/BootCodeActionRepository.java | 60 --- .../rewrite/RewriteCompilationUnitCache.java | 333 ----------------- .../java/rewrite/RewriteRecipeRepository.java | 13 +- .../boot/java/rewrite/RewriteReconciler.java | 349 ------------------ ...ConfigurationIfBeansPresentCodeAction.java | 95 ----- .../AuthorizeHttpRequestsCodeAction.java | 129 ------- ...eldIntoConstructorParameterCodeAction.java | 130 ------- .../reconcile/BeanMethodNotPublicProblem.java | 89 ----- .../BeanPostProcessingIgnoreInAotProblem.java | 87 ----- .../Boot3NotSupportedTypeProblem.java | 129 ------- .../reconcile/EntityIdForRepoProblem.java | 59 --- .../HttpSecurityLamdaDslCodeAction.java | 84 ----- .../ModulithTypeReferenceViolation.java | 110 ------ .../NoAutowiredOnConstructorProblem.java | 117 ------ .../reconcile/NoRepoAnnotationProblem.java | 101 ----- .../NoRequestMappingAnnotationCodeAction.java | 77 ---- .../reconcile/NotRegisteredBeansProblem.java | 204 ---------- .../reconcile/PreciseBeanTypeProblem.java | 136 ------- ...ServerHttpSecurityLambdaDslCodeAction.java | 83 ----- .../UnnecessarySpringExtensionProblem.java | 98 ----- ...ebSecurityConfigurerAdapterCodeAction.java | 140 ------- 45 files changed, 66 insertions(+), 3081 deletions(-) delete mode 100644 headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/HelloMethodRenameProblemDescriptor.java delete mode 100644 headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/StsTestCodeActionRepo.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepoLoader.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepository.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/DefaultMarkerVisitorContext.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/MarkerVisitorContext.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/RecipeCodeActionDescriptor.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsEnvironment.java delete mode 100644 headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsResourceLoader.java rename headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/{RewriteQuickFixUtils.java => ReconcileUtils.java} (98%) delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteCompilationUnitCache.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AddConfigurationIfBeansPresentCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AuthorizeHttpRequestsCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanMethodNotPublicProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanPostProcessingIgnoreInAotProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/Boot3NotSupportedTypeProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/EntityIdForRepoProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ModulithTypeReferenceViolation.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoAutowiredOnConstructorProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRepoAnnotationProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRequestMappingAnnotationCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NotRegisteredBeansProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/PreciseBeanTypeProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/UnnecessarySpringExtensionProblem.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/WebSecurityConfigurerAdapterCodeAction.java diff --git a/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/HelloMethodRenameProblemDescriptor.java b/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/HelloMethodRenameProblemDescriptor.java deleted file mode 100644 index e4ec96da6..000000000 --- a/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/HelloMethodRenameProblemDescriptor.java +++ /dev/null @@ -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 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); - } - -} diff --git a/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/StsTestCodeActionRepo.java b/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/StsTestCodeActionRepo.java deleted file mode 100644 index 57d26914e..000000000 --- a/headless-services/commons/commons-rewrite-test/src/main/java/org/springframework/rewrite/test/StsTestCodeActionRepo.java +++ /dev/null @@ -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 getCodeActionDescriptors() { - return List.of(new HelloMethodRenameProblemDescriptor()); - } - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepoLoader.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepoLoader.java deleted file mode 100644 index c574e47a5..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepoLoader.java +++ /dev/null @@ -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 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 listCodeActionDescriptorsRepositories() { - return codeActionRepos; - } - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepository.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepository.java deleted file mode 100644 index 25d7f41f8..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/CodeActionRepository.java +++ /dev/null @@ -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 getCodeActionDescriptors(); - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/DefaultMarkerVisitorContext.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/DefaultMarkerVisitorContext.java deleted file mode 100644 index cb9482a43..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/DefaultMarkerVisitorContext.java +++ /dev/null @@ -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 { - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/MarkerVisitorContext.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/MarkerVisitorContext.java deleted file mode 100644 index d11fddb60..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/MarkerVisitorContext.java +++ /dev/null @@ -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(); - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/RecipeCodeActionDescriptor.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/RecipeCodeActionDescriptor.java deleted file mode 100644 index 59208e6f6..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/RecipeCodeActionDescriptor.java +++ /dev/null @@ -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 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; - } - } - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsEnvironment.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsEnvironment.java deleted file mode 100644 index 53c4a28e7..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsEnvironment.java +++ /dev/null @@ -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> codeActionRepos; - final private Environment env; - - private StsEnvironment(Environment env, List loaders) { - this.env = env; - codeActionRepos = () -> loaders.stream().flatMap(l -> l.listCodeActionDescriptorsRepositories().stream()); - } - - public static class Builder { - - private List 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 listCodeActionDescriptors() { - return codeActionRepos.get().flatMap(r -> r.getCodeActionDescriptors().stream()).collect(Collectors.toList()); - } - - public Collection listRecipes() { - return env.listRecipes(); - } - - public Collection listRecipeDescriptors() { - return env.listRecipeDescriptors(); - } - - public static Builder builder() { - return new Builder(); - } - -} diff --git a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsResourceLoader.java b/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsResourceLoader.java deleted file mode 100644 index 135aaad1e..000000000 --- a/headless-services/commons/commons-rewrite/src/main/java/org/springframework/ide/vscode/commons/rewrite/config/StsResourceLoader.java +++ /dev/null @@ -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 listCodeActionDescriptorsRepositories(); - - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/RewriteConfig.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/RewriteConfig.java index 0459f5269..34b4799ce 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/RewriteConfig.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/RewriteConfig.java @@ -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 -// ); -// } - + } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AbstractSecurityLamdaDslReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AbstractSecurityLamdaDslReconciler.java index c5f6963c4..56624572d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AbstractSecurityLamdaDslReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AbstractSecurityLamdaDslReconciler.java @@ -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(); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AddConfigurationIfBeansPresentReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AddConfigurationIfBeansPresentReconciler.java index 33dd5e5d6..42d261c3d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AddConfigurationIfBeansPresentReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AddConfigurationIfBeansPresentReconciler.java @@ -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) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AuthorizeHttpRequestsReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AuthorizeHttpRequestsReconciler.java index d36c2ede0..e7e89ab3a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AuthorizeHttpRequestsReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AuthorizeHttpRequestsReconciler.java @@ -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, diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AutowiredFieldIntoConstructorParameterReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AutowiredFieldIntoConstructorParameterReconciler.java index 09ff21cd0..b23072da7 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AutowiredFieldIntoConstructorParameterReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/AutowiredFieldIntoConstructorParameterReconciler.java @@ -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 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; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanMethodNotPublicReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanMethodNotPublicReconciler.java index 48c231156..cc39da52c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanMethodNotPublicReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanMethodNotPublicReconciler.java @@ -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); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanPostProcessingIgnoreInAotReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanPostProcessingIgnoreInAotReconciler.java index fcd3496e6..ce36d2b35 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanPostProcessingIgnoreInAotReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/BeanPostProcessingIgnoreInAotReconciler.java @@ -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); } }); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoAutowiredOnConstructorReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoAutowiredOnConstructorReconciler.java index 0ea66d69d..272012a2f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoAutowiredOnConstructorReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoAutowiredOnConstructorReconciler.java @@ -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); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRepoAnnotationReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRepoAnnotationReconciler.java index fb8f398ca..cd69b54dd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRepoAnnotationReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRepoAnnotationReconciler.java @@ -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); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRequestMappingAnnotationReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRequestMappingAnnotationReconciler.java index 23274686a..246cf2dbe 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRequestMappingAnnotationReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NoRequestMappingAnnotationReconciler.java @@ -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); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NotRegisteredBeansReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NotRegisteredBeansReconciler.java index 82810bbcd..b3d17c900 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NotRegisteredBeansReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/NotRegisteredBeansReconciler.java @@ -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 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(); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/PreciseBeanTypeReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/PreciseBeanTypeReconciler.java index d2c079b32..88a5f358d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/PreciseBeanTypeReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/PreciseBeanTypeReconciler.java @@ -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); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/RewriteQuickFixUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/ReconcileUtils.java similarity index 98% rename from headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/RewriteQuickFixUtils.java rename to headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/ReconcileUtils.java index 2bd166e3e..b46a3ac2a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/RewriteQuickFixUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/ReconcileUtils.java @@ -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(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/UnnecessarySpringExtensionReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/UnnecessarySpringExtensionReconciler.java index 4a4c40d76..4f43f4ccc 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/UnnecessarySpringExtensionReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/UnnecessarySpringExtensionReconciler.java @@ -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; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/WebSecurityConfigurerAdapterReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/WebSecurityConfigurerAdapterReconciler.java index 154b1b754..8d739230c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/WebSecurityConfigurerAdapterReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/reconcilers/WebSecurityConfigurerAdapterReconciler.java @@ -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)) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java deleted file mode 100644 index f8ae96c3c..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/BootCodeActionRepository.java +++ /dev/null @@ -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 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() - ); - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteCompilationUnitCache.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteCompilationUnitCache.java deleted file mode 100644 index 8ea86f900..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteCompilationUnitCache.java +++ /dev/null @@ -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> uriToCu; - private final Cache> projectToDocs; - private final Cache javaParsers; - - private final Cache> 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>() { - - @Override - public void onRemoval(RemovalNotification> notification) { - URI uri = notification.getKey(); - CompletableFuture future = notification.getValue(); - - if (future != null) { - if (!future.isDone() && !future.isCancelled()) { - future.cancel(true); - } - Optional 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() { - - @Override - public void onRemoval(RemovalNotification 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 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 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 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 fqNames; - try { - fqNames = sourceSetClasspath.get(project.getLocationUri(), () -> { - List 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 withCompilationUnit(IJavaProject project, URI uri, Function 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); - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java index c93642d00..673ba0663 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java @@ -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())); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java deleted file mode 100644 index ee912fa9e..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java +++ /dev/null @@ -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 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 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> reconcile(IJavaProject project, List docs, Runnable incrementProgress) { - -// if (!config.isJavaSourceReconcileEnabled()) { -// return Collections.emptyMap(); -// } -// -// long start = System.currentTimeMillis(); -// -// Map> allProblems = new HashMap<>(); -// List testSourceFolders = IClasspathUtil.getProjectTestJavaSources(project.getClasspath()).map(f -> f.toPath()).collect(Collectors.toList()); -// List testSources = new ArrayList<>(docs.size()); -// List 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 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> doReconcile(IJavaProject project, List docs, -// Function problemCollectorFactory, JavaParser javaParser) { -// Map> allProblems = new HashMap<>(); -// -// if (javaParser != null && config.isRewriteReconcileEnabled()) { -// try { -// List descriptors = getProblemRecipeDescriptors(project); -// -// List 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 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> doReconcile(IJavaProject project, List docs, -// Function problemCollectorFactory, JavaParser javaParser) { -// Map> allProblems = new HashMap<>(); -// -// if (javaParser != null && config.isRewriteReconcileEnabled()) { -// try { -// List descriptors = getProblemRecipeDescriptors(project); -// -// if (!descriptors.isEmpty()) { -// -// for (IDocument doc : docs) { -// List 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> doReconcile(IJavaProject project, List docs, JavaParser javaParser, JavaSourceSet javaSourceSet, Runnable incrementProgress) { -// Map> allProblems = new HashMap<>(); -// if (javaParser != null && config.isJavaSourceReconcileEnabled()) { -// try { -// List descriptors = getProblemRecipeDescriptors(project); -// -// -// if (!descriptors.isEmpty()) { -// -// for (int i = 0; i < docs.size(); i += BATCH) { -// List batchList = docs.subList(i, Math.min(i + BATCH, docs.size())); -// -// List 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 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 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 descriptors, IDocument doc, CompilationUnit compilationUnit, Consumer problemHandler) { -// CompilationUnit cu = recipeRepo.mark(project, descriptors, compilationUnit); -// if (compilationUnit != cu) { -// new JavaMarkerVisitor() { -// -// @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 docs) { -// return docs.size() * 2; -// } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AddConfigurationIfBeansPresentCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AddConfigurationIfBeansPresentCodeAction.java deleted file mode 100644 index e5da9ced3..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AddConfigurationIfBeansPresentCodeAction.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AuthorizeHttpRequestsCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AuthorizeHttpRequestsCodeAction.java deleted file mode 100644 index 142a7afc4..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AuthorizeHttpRequestsCodeAction.java +++ /dev/null @@ -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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java deleted file mode 100644 index f71ffb2c3..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java +++ /dev/null @@ -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 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 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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanMethodNotPublicProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanMethodNotPublicProblem.java deleted file mode 100644 index bddc2e6da..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanMethodNotPublicProblem.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanPostProcessingIgnoreInAotProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanPostProcessingIgnoreInAotProblem.java deleted file mode 100644 index 4ea787323..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/BeanPostProcessingIgnoreInAotProblem.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @Override - public ClassDeclaration visitClassDeclaration(ClassDeclaration classDecl, ExecutionContext p) { - ClassDeclaration c = super.visitClassDeclaration(classDecl, p); - if (BeanPostProcessingIgnoreInAot.isApplicableClass(classDecl)) { - List 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/Boot3NotSupportedTypeProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/Boot3NotSupportedTypeProblem.java deleted file mode 100644 index fbb36903f..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/Boot3NotSupportedTypeProblem.java +++ /dev/null @@ -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 TYPE_FQNAMES = List.of( - "org.springframework.web.multipart.commons.CommonsMultipartResolver", - "java.lang.SecurityManager", - "java.security.AccessControlException" - ); - - @Override - public JavaVisitor 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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/EntityIdForRepoProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/EntityIdForRepoProblem.java deleted file mode 100644 index dca716934..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/EntityIdForRepoProblem.java +++ /dev/null @@ -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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java deleted file mode 100644 index 11b3a7930..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/HttpSecurityLamdaDslCodeAction.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ModulithTypeReferenceViolation.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ModulithTypeReferenceViolation.java deleted file mode 100644 index 34ecc447d..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ModulithTypeReferenceViolation.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - ModulithService modulithService = context.appContext().getBean(ModulithService.class); - AppModules appModules = modulithService.getModulesData(context.project()); - - return new JavaIsoVisitor() { - - @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 process(T node, String packageName, FullyQualified type) { - if (type != null) { - Optional 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoAutowiredOnConstructorProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoAutowiredOnConstructorProblem.java deleted file mode 100644 index 5ba966a88..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoAutowiredOnConstructorProblem.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - 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(); - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRepoAnnotationProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRepoAnnotationProblem.java deleted file mode 100644 index 721e139ef..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRepoAnnotationProblem.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRequestMappingAnnotationCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRequestMappingAnnotationCodeAction.java deleted file mode 100644 index 78103a2d4..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NoRequestMappingAnnotationCodeAction.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NotRegisteredBeansProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NotRegisteredBeansProblem.java deleted file mode 100644 index c6d460765..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/NotRegisteredBeansProblem.java +++ /dev/null @@ -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 AOT_BEANS = List.of( - "org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor", - "org.springframework.beans.factory.aot.BeanRegistrationAotProcessor" - ); - - @Override - public JavaVisitor getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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 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 fixListBuilder = ImmutableList.builder(); - List 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 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 allFQTypes(JavaType type) { - ImmutableSet.Builder 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; - } - - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/PreciseBeanTypeProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/PreciseBeanTypeProblem.java deleted file mode 100644 index 9126375b1..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/PreciseBeanTypeProblem.java +++ /dev/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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java deleted file mode 100644 index ba34d3cc6..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/ServerHttpSecurityLambdaDslCodeAction.java +++ /dev/null @@ -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 getMarkerVisitor(MarkerVisitorContext context) { - return new JavaMarkerVisitor() { - - @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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/UnnecessarySpringExtensionProblem.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/UnnecessarySpringExtensionProblem.java deleted file mode 100644 index fd88a7bb2..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/UnnecessarySpringExtensionProblem.java +++ /dev/null @@ -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 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 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; - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/WebSecurityConfigurerAdapterCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/WebSecurityConfigurerAdapterCodeAction.java deleted file mode 100644 index a2cb998ce..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/WebSecurityConfigurerAdapterCodeAction.java +++ /dev/null @@ -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 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 annotations, String annotationType) { - return annotations.stream().anyMatch(a -> TypeUtils.isOfClassType(a.getType(), annotationType)); - } - -}