Skip to content

Commit 0090e2e

Browse files
Reusable Execution Context (#792)
* It removes all programmatically created instances of ExecutionContext in main code. * The ExecutionContext is now a Spring bean with @ExecutionScope * execution scope and ends with a successful recipe run * TestProjectContext uses Spring and components scan now to create the ProjectConetxtInitializer * A new test helper ActionTest was created which allows testing actions that require the ExecutionContext that is now created together with beans to create a ProjectConetxtInitializer instance * The execution times of tests might have become even worse as potential too many beans are created when org.springframework.sbm is scanned * An ArchUnit test was introduced to flag invalid instance creations of any class implementing ExecutionContext. --------- Co-authored-by: Fabian Krüger <[email protected]> Co-authored-by: Fabian Krüger <[email protected]>
1 parent 9124b4c commit 0090e2e

File tree

139 files changed

+4117
-2498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+4117
-2498
lines changed

applications/spring-shell/pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@
124124
<artifactId>sbm-recipes-boot-upgrade</artifactId>
125125
<version>0.13.1-SNAPSHOT</version>
126126
</dependency>
127+
<dependency>
128+
<groupId>org.springframework.sbm</groupId>
129+
<artifactId>sbm-core</artifactId>
130+
<version>${project.version}</version>
131+
<classifier>tests</classifier>
132+
<scope>test</scope>
133+
</dependency>
127134
</dependencies>
128135

129136
<build>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2021 - 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.sbm.architecture;
17+
18+
import com.tngtech.archunit.core.importer.ImportOption;
19+
import com.tngtech.archunit.junit.AnalyzeClasses;
20+
import com.tngtech.archunit.junit.ArchTest;
21+
import com.tngtech.archunit.junit.ArchTests;
22+
23+
/**
24+
* @author Fabian Krüger
25+
*/
26+
@AnalyzeClasses(packages = {"org.springframework.sbm", "org.openrewrite"}, importOptions = {ImportOption.DoNotIncludeTests.class, ImportOption.DoNotIncludeJars.class})
27+
public class FindIllegalExecutionContextCreationsTest {
28+
@ArchTest
29+
static final ArchTests executionContextMustNotBeCreatedWithNew = ArchTests.in(
30+
ControlledInstantiationOfExecutionContextTest.class);
31+
}

applications/spring-shell/src/test/java/org/springframework/sbm/shell/ScanCommandHeaderRendererTest.java renamed to applications/spring-shell/src/test/java/org/springframework/sbm/shell/ApplyRecipeCommandHeaderRendererTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import static org.assertj.core.api.Assertions.assertThat;
2121

22-
class ScanCommandHeaderRendererTest {
22+
class ApplyRecipeCommandHeaderRendererTest {
2323

2424
@Test
2525
void renderHeader() {

components/openrewrite-spring-recipes/src/main/java/org/springframework/sbm/spring/migration/actions/InitDataSourceAfterJpaInitAction.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package org.springframework.sbm.spring.migration.actions;
1717

18+
import com.fasterxml.jackson.annotation.JsonIgnore;
19+
import org.openrewrite.ExecutionContext;
20+
import org.springframework.beans.factory.annotation.Autowired;
1821
import org.springframework.sbm.engine.recipe.AbstractAction;
1922
import org.springframework.sbm.engine.recipe.UserInteractions;
2023
import org.springframework.sbm.common.migration.conditions.FileExist;
@@ -28,9 +31,12 @@
2831
public class InitDataSourceAfterJpaInitAction extends AbstractAction {
2932

3033
public static final String QUESTION = "Would you rather run the SQL init scripts after JPA initialization?";
31-
3234
private final UserInteractions ui;
3335

36+
@Autowired
37+
@JsonIgnore
38+
private ExecutionContext executionContext;
39+
3440
public InitDataSourceAfterJpaInitAction(UserInteractions ui) {
3541
this.ui = ui;
3642
setCondition(FileExist.builder().fileName("data.sql").build().or(FileExist.builder().fileName("schema.sql").build()));
@@ -44,7 +50,7 @@ public void apply(ProjectContext context) {
4450
SpringBootApplicationProperties applicationProperties;
4551
if (filteredResources.isEmpty()) {
4652
Path path = context.getBuildFile().getResourceFolders().get(0).resolve("application.properties");
47-
applicationProperties = SpringBootApplicationProperties.newApplicationProperties(context.getProjectRootDirectory(), path);
53+
applicationProperties = SpringBootApplicationProperties.newApplicationProperties(context.getProjectRootDirectory(), path, executionContext);
4854
context.getProjectResources().add(applicationProperties);
4955
} else {
5056
applicationProperties = filteredResources.get(0);

components/recipe-test-support/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
<dependency>
6363
<groupId>org.springframework.sbm</groupId>
6464
<artifactId>sbm-core</artifactId>
65-
<version>0.13.1-SNAPSHOT</version>
65+
<version>${project.version}</version>
6666
<type>test-jar</type>
6767
<scope>compile</scope>
6868
</dependency>

components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import org.springframework.sbm.project.resource.ProjectResourceSetHolder;
2929
import org.springframework.sbm.project.resource.SbmApplicationProperties;
3030
import org.springframework.sbm.project.resource.ResourceHelper;
31+
import org.springframework.sbm.scopeplayground.ExecutionScope;
32+
import org.springframework.sbm.scopeplayground.ScanScope;
33+
import org.springframework.sbm.scopeplayground.ScopeConfiguration;
3134
import org.springframework.sbm.search.recipe.actions.OpenRewriteJavaSearchAction;
3235
import org.springframework.context.annotation.Bean;
3336
import org.springframework.context.annotation.Configuration;
@@ -77,7 +80,10 @@ private RecipeTestSupport() {
7780
RewriteMavenParser.class,
7881
MavenSettingsInitializer.class,
7982
MavenBuildFileRefactoringFactory.class,
80-
ProjectResourceSetHolder.class
83+
ProjectResourceSetHolder.class,
84+
ScopeConfiguration.class,
85+
ExecutionScope.class,
86+
ScanScope.class
8187
};
8288

8389

components/recipe-test-support/src/main/java/org/springframework/sbm/test/SpringBeanProvider.java

-43
This file was deleted.

components/sbm-core/pom.xml

+14-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
<artifactId>spring-boot-starter-freemarker</artifactId>
3939
</dependency>
4040

41+
<dependency>
42+
<groupId>com.tngtech.archunit</groupId>
43+
<artifactId>archunit-junit5</artifactId>
44+
<version>1.0.1</version>
45+
<scope>test</scope>
46+
</dependency>
47+
4148
<dependency>
4249
<groupId>org.springframework.boot</groupId>
4350
<artifactId>spring-boot-starter-test</artifactId>
@@ -175,7 +182,13 @@
175182
</goals>
176183
</execution>
177184
</executions>
185+
<configuration>
186+
<excludes>
187+
<!-- Would be picked up by component scan in other modules -->
188+
<exclude>**/org/springframework/sbm/archfitfun/**</exclude>
189+
</excludes>
190+
</configuration>
178191
</plugin>
179192
</plugins>
180193
</build>
181-
</project>
194+
</project>

components/sbm-core/src/main/java/org/springframework/sbm/build/api/Module.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.sbm.build.api;
1717

18+
import org.openrewrite.ExecutionContext;
1819
import org.openrewrite.java.JavaParser;
1920
import org.openrewrite.maven.tree.MavenResolutionResult;
2021
import org.springframework.sbm.build.impl.JavaSourceSetImpl;
@@ -55,6 +56,7 @@ public class Module {
5556
private final JavaRefactoringFactory javaRefactoringFactory;
5657
private final BasePackageCalculator basePackageCalculator;
5758
private final JavaParser javaParser;
59+
private final ExecutionContext executionContext;
5860

5961
public JavaSourceLocation getBaseJavaSourceLocation() {
6062
return getMainJavaSourceSet().getJavaSourceLocation();
@@ -67,7 +69,8 @@ public JavaSourceLocation getBaseTestJavaSourceLocation() {
6769
public JavaSourceSet getTestJavaSourceSet() {
6870
Path testJavaPath = Path.of("src/test/java");
6971
// FIXME: #7 JavaParser
70-
return new JavaSourceSetImpl(projectResourceSet, projectRootDir, modulePath, testJavaPath, javaRefactoringFactory, basePackageCalculator, javaParser);
72+
return new JavaSourceSetImpl(projectResourceSet, projectRootDir, modulePath, testJavaPath, javaRefactoringFactory, basePackageCalculator, javaParser,
73+
executionContext);
7174
}
7275

7376
public List<? extends JavaSource> getMainJavaSources() {
@@ -83,7 +86,8 @@ public List<? extends JavaSource> getTestJavaSources() {
8386
public JavaSourceSet getMainJavaSourceSet() {
8487
Path mainJavaPath = Path.of("src/main/java");
8588
// return new JavaSourceSetImpl(projectResourceSet, projectRootDir.resolve(modulePath).resolve(mainJavaPath), javaRefactoringFactory);
86-
return new JavaSourceSetImpl(projectResourceSet, projectRootDir, modulePath, mainJavaPath, javaRefactoringFactory, basePackageCalculator, javaParser);
89+
return new JavaSourceSetImpl(projectResourceSet, projectRootDir, modulePath, mainJavaPath, javaRefactoringFactory, basePackageCalculator, javaParser,
90+
executionContext);
8791
}
8892

8993
private List<JavaSource> cast(List<RewriteSourceFileHolder<? extends SourceFile>> filter) {
@@ -112,12 +116,12 @@ public Path getProjectRootDirectory() {
112116

113117
public ResourceSet getMainResourceSet() {
114118
Path mainResourceSet = buildFile.getMainResourceFolder();
115-
return new ResourceSet(projectResourceSet, projectRootDir, modulePath, mainResourceSet);
119+
return new ResourceSet(projectResourceSet, projectRootDir, modulePath, mainResourceSet, executionContext);
116120
}
117121

118122
public ResourceSet getTestResourceSet() {
119123
Path testResourceSet = buildFile.getTestResourceFolder();
120-
return new ResourceSet(projectResourceSet, projectRootDir, modulePath, testResourceSet);
124+
return new ResourceSet(projectResourceSet, projectRootDir, modulePath, testResourceSet, executionContext);
121125
}
122126

123127
public List<Module> getModules() {
@@ -127,7 +131,7 @@ public List<Module> getModules() {
127131
return modulesMarker
128132
.stream()
129133
.map(m -> new Module(m.getPom().getGav().toString(), this.buildFile, projectRootDir, modulePath,
130-
projectResourceSet, javaRefactoringFactory, basePackageCalculator, javaParser))
134+
projectResourceSet, javaRefactoringFactory, basePackageCalculator, javaParser, executionContext))
131135
.collect(Collectors.toList());
132136
} else {
133137
return new ArrayList<>();

components/sbm-core/src/main/java/org/springframework/sbm/build/api/ResourceSet.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.sbm.build.api;
1717

18+
import org.openrewrite.ExecutionContext;
1819
import org.springframework.sbm.project.resource.ProjectResourceSet;
1920
import org.springframework.sbm.project.resource.RewriteSourceFileHolder;
2021
import org.springframework.sbm.project.resource.StringProjectResource;
@@ -30,10 +31,11 @@ public class ResourceSet {
3031
private final Path projectRoot;
3132
private final Path modulePath;
3233
private final Path resourceSetPath;
34+
private final ExecutionContext executionContext;
3335

3436
public void addStringResource(String filePath, String content) {
3537
Path absFilePath = getAbsolutePath().resolve(filePath);
36-
StringProjectResource resource = new StringProjectResource(projectRoot, absFilePath, content);
38+
StringProjectResource resource = new StringProjectResource(projectRoot, absFilePath, content, executionContext);
3739
resource.markAsChanged();
3840
projectResourceSet.add(resource);
3941
}

components/sbm-core/src/main/java/org/springframework/sbm/build/api/SpringManagedDependencies.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
*/
1616
package org.springframework.sbm.build.api;
1717

18+
import org.openrewrite.ExecutionContext;
1819
import org.openrewrite.maven.MavenDownloadingException;
1920
import org.openrewrite.maven.internal.MavenPomDownloader;
2021
import org.openrewrite.maven.tree.GroupArtifactVersion;
2122
import org.openrewrite.maven.tree.MavenRepository;
22-
import org.springframework.sbm.openrewrite.RewriteExecutionContext;
2323

2424
import java.util.Collections;
2525
import java.util.HashMap;
@@ -39,17 +39,17 @@ public class SpringManagedDependencies {
3939
private List<org.openrewrite.maven.tree.Dependency> dependencies;
4040
private static Map<GroupArtifactVersion, SpringManagedDependencies> INSTANCES = new HashMap<>();
4141

42-
public static SpringManagedDependencies by(String groupId, String artifact, String version){
42+
public static SpringManagedDependencies by(String groupId, String artifact, String version, ExecutionContext executionContext){
4343
final GroupArtifactVersion groupArtifactVersion =
4444
new GroupArtifactVersion(groupId, artifact, version);
4545

46-
INSTANCES.computeIfAbsent(groupArtifactVersion, SpringManagedDependencies::new);
46+
INSTANCES.computeIfAbsent(groupArtifactVersion, gav -> new SpringManagedDependencies(gav, executionContext));
4747
return INSTANCES.get(groupArtifactVersion);
4848
}
4949

50-
private SpringManagedDependencies(GroupArtifactVersion groupArtifactVersion){
50+
private SpringManagedDependencies(GroupArtifactVersion groupArtifactVersion, ExecutionContext executionContext){
5151
try {
52-
dependencies = new MavenPomDownloader(Collections.emptyMap(), new RewriteExecutionContext())
52+
dependencies = new MavenPomDownloader(Collections.emptyMap(), executionContext)
5353
.download(groupArtifactVersion, null, null, SPRING_REPOSITORIES)
5454
.getDependencies();
5555
} catch (MavenDownloadingException e) {

components/sbm-core/src/main/java/org/springframework/sbm/build/impl/JavaSourceSetImpl.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.sbm.build.impl;
1717

18+
import org.openrewrite.ExecutionContext;
1819
import org.springframework.sbm.build.api.JavaSourceSet;
1920
import org.springframework.sbm.java.api.JavaSource;
2021
import org.springframework.sbm.java.api.JavaSourceLocation;
@@ -44,11 +45,13 @@ public class JavaSourceSetImpl implements JavaSourceSet {
4445
private final JavaRefactoringFactory javaRefactoringFactory;
4546
private final BasePackageCalculator basePackageCalculator;
4647
private final JavaParser javaParser;
48+
private ExecutionContext executionContext;
4749

48-
public JavaSourceSetImpl(ProjectResourceSet projectResourceSet, Path projectRootDir, Path modulePath, Path mainJavaPath, JavaRefactoringFactory javaRefactoringFactory, BasePackageCalculator basePackageCalculator, JavaParser javaParser) {
50+
public JavaSourceSetImpl(ProjectResourceSet projectResourceSet, Path projectRootDir, Path modulePath, Path mainJavaPath, JavaRefactoringFactory javaRefactoringFactory, BasePackageCalculator basePackageCalculator, JavaParser javaParser, ExecutionContext executionContext) {
4951
this.projectResourceSet = projectResourceSet;
5052
this.basePackageCalculator = basePackageCalculator;
5153
this.javaParser = javaParser;
54+
this.executionContext = executionContext;
5255
this.sourceSetRoot = projectRootDir.resolve(modulePath).resolve(mainJavaPath);
5356
this.filter = (r) -> {
5457
return r.getAbsolutePath().getParent().normalize().toString().startsWith(sourceSetRoot.toString());
@@ -73,7 +76,7 @@ public JavaSource addJavaSource(Path projectRoot, Path sourceFolder, String sour
7376
throw new RuntimeException("The Java class you tried to add already lives here: '" + sourceFilePath + "'.");
7477
} else {
7578
J.CompilationUnit compilationUnit = parsedCompilationUnit.withSourcePath(sourceFilePath);
76-
OpenRewriteJavaSource addedSource = new OpenRewriteJavaSource(projectRoot, compilationUnit, javaRefactoringFactory.createRefactoring(compilationUnit), javaParser);
79+
OpenRewriteJavaSource addedSource = new OpenRewriteJavaSource(projectRoot, compilationUnit, javaRefactoringFactory.createRefactoring(compilationUnit), javaParser, executionContext);
7780
addedSource.markChanged();
7881
projectResourceSet.add(addedSource);
7982
return addedSource;
@@ -94,7 +97,7 @@ public List<JavaSource> addJavaSource(Path projectRoot, Path sourceFolder, Strin
9497
Path sourceFilePath = sourceFolder.resolve(sourceFileName);
9598
if(!Files.exists(sourceFilePath)) {
9699
J.CompilationUnit compilationUnit = cu.withSourcePath(sourceFilePath);
97-
OpenRewriteJavaSource addedSource = new OpenRewriteJavaSource(projectRoot, compilationUnit, javaRefactoringFactory.createRefactoring(compilationUnit), javaParser);
100+
OpenRewriteJavaSource addedSource = new OpenRewriteJavaSource(projectRoot, compilationUnit, javaRefactoringFactory.createRefactoring(compilationUnit), javaParser, executionContext);
98101
addedSource.markChanged();
99102
projectResourceSet.add(addedSource);
100103
addedSources.add(addedSource);

components/sbm-core/src/main/java/org/springframework/sbm/build/impl/MavenBuildFileRefactoring.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@
2020
import org.jetbrains.annotations.NotNull;
2121
import org.openrewrite.*;
2222
import org.openrewrite.marker.Markers;
23-
import org.openrewrite.marker.SearchResult;
2423
import org.openrewrite.maven.MavenVisitor;
2524
import org.openrewrite.maven.tree.MavenResolutionResult;
2625
import org.openrewrite.xml.tree.Xml;
27-
import org.springframework.sbm.openrewrite.RewriteExecutionContext;
2826
import org.springframework.sbm.project.resource.ProjectResourceSet;
2927
import org.springframework.sbm.project.resource.RewriteSourceFileHolder;
3028
import org.springframework.sbm.support.openrewrite.GenericOpenRewriteRecipe;
@@ -46,6 +44,7 @@
4644
public class MavenBuildFileRefactoring<T extends SourceFile> {
4745
private final ProjectResourceSet projectResourceSet;
4846
private final RewriteMavenParser mavenParser;
47+
private final ExecutionContext executionContext;
4948

5049
/**
5150
* Applies the provided {@code Visitor}s to all Maven build files in the {@code ProjectContext}.
@@ -107,7 +106,7 @@ public void refreshPomModels() {
107106
.collect(Collectors.toList());
108107

109108
// parse buildfiles
110-
List<Xml.Document> newMavenFiles = mavenParser.parseInputs(parserInputs, null, new RewriteExecutionContext());
109+
List<Xml.Document> newMavenFiles = mavenParser.parseInputs(parserInputs, null, executionContext);
111110

112111
// replace new model in build files
113112
newMavenFiles.stream()
@@ -152,12 +151,12 @@ public BuildFileWithIndex(int index, RewriteSourceFileHolder<Xml.Document> xmlDo
152151
}
153152

154153
private List<Result> executeRecipe(Recipe recipe) {
155-
List<Result> results = recipe.run(getDocumentsWrappedInOpenRewriteMavenBuildFile(), new RewriteExecutionContext()).getResults();
154+
List<Result> results = recipe.run(getDocumentsWrappedInOpenRewriteMavenBuildFile(), executionContext).getResults();
156155
return results;
157156
}
158157

159158
private List<Result> executeRecipe(Recipe recipe, RewriteSourceFileHolder<Xml.Document> resource) {
160-
List<Result> results = recipe.run(List.of(resource.getSourceFile()), new RewriteExecutionContext()).getResults();
159+
List<Result> results = recipe.run(List.of(resource.getSourceFile()), executionContext).getResults();
161160
return results;
162161
}
163162

0 commit comments

Comments
 (0)