Skip to content

Commit a147003

Browse files
authored
PreconditionCheck for usage of removed DatabaseDriver.GAE (#244)
1 parent 9579aba commit a147003

File tree

16 files changed

+433
-25
lines changed

16 files changed

+433
-25
lines changed

applications/spring-shell/src/main/java/org/springframework/sbm/shell/ApplyShellCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class ApplyShellCommand {
4747

4848
@ShellMethod(key = {"apply", "a"}, value = "Apply a given recipe to the target application.")
4949
@ShellMethodAvailability("availabilityCheck")
50-
public AttributedString apply(@ShellOption(help = "The name of the recipe to apply.") String recipeName) {
50+
public AttributedString apply(@ShellOption(arity = 1, help = "The name of the recipe to apply.") String recipeName) {
5151
AttributedStringBuilder header = buildHeader(recipeName);
5252
System.out.println(header.toAnsi());
5353

applications/spring-shell/src/main/java/org/springframework/sbm/shell/ScanShellCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class ScanShellCommand {
4949
@ShellMethod(key = {"scan", "s"},
5050
value = "Scans the target project directory and get the list of applicable recipes.")
5151
public String scan(
52-
@ShellOption(defaultValue = ".", help = "The root directory of the target application.")
52+
@ShellOption(arity = 1, defaultValue = ".", help = "The root directory of the target application.")
5353
//@Pattern(regexp = "")
5454
String projectRoot) {
5555

components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ public void commitWhenGitAvailable(ProjectContext context, String appliedRecipeN
249249
public static Optional<String> getBranchName(File repo) {
250250
Git git = initGit(repo);
251251
try {
252-
return Optional.of(git.getRepository().getBranch());
252+
return Optional.ofNullable(git.getRepository().getBranch());
253253
} catch (IOException e) {
254254
return Optional.empty();
255255
}

components/sbm-core/src/main/java/org/springframework/sbm/engine/precondition/DoesGitDirExistWhenGitSupportEnabledPreconditionCheck.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,9 @@ class DoesGitDirExistWhenGitSupportEnabledPreconditionCheck extends Precondition
5656
@Override
5757
public PreconditionCheckResult verify(Path projectRoot, List<Resource> projectResources) {
5858
if (sbmApplicationProperties.isGitSupportEnabled()) {
59-
if (noGitDirExists(projectRoot)) {
59+
if(! isUnderGit(projectRoot)) {
6060
return new PreconditionCheckResult(FAILED, NO_GIT_DIR_EXISTS);
61-
}
62-
else if (! isGitStatusClean(projectRoot)) {
61+
} else if(! isGitStatusClean(projectRoot)) {
6362
return new PreconditionCheckResult(FAILED, HAS_UNCOMMITTED_CHANGES);
6463
} else {
6564
return new PreconditionCheckResult(PASSED, String.format(CHECK_PASSED, getBranch(projectRoot)));
@@ -68,6 +67,10 @@ else if (! isGitStatusClean(projectRoot)) {
6867
return new PreconditionCheckResult(PASSED, CHECK_IGNORED);
6968
}
7069

70+
private boolean isUnderGit(Path projectRoot) {
71+
return gitSupport.repoExists(projectRoot.toFile());
72+
}
73+
7174
private String getBranch(Path projectRoot) {
7275
File repo = projectRoot.normalize().toAbsolutePath().toFile();
7376
Optional<String> branchName = gitSupport.getBranchName(repo);
@@ -83,14 +86,4 @@ private boolean isGitStatusClean(Path projectRoot) {
8386
return status.isClean();
8487
}
8588

86-
private boolean noGitDirExists(Path projectRoot) {
87-
Path path = projectRoot.resolve(".git").normalize().toAbsolutePath();
88-
if (!path.toFile().exists() || !path.toFile().isDirectory()) {
89-
return true;
90-
}
91-
else {
92-
return false;
93-
}
94-
}
95-
9689
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,6 @@ public interface ProjectJavaSources {
5050
List<MethodCall> findMethodCalls(String pattern);
5151

5252
List<JavaSourceAndType> findTypesImplementing(String jpaRepositoryInterface);
53+
54+
List<? extends JavaSource> findClassesUsingType(String databaseDriverGAE);
5355
}

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
package org.springframework.sbm.java.impl;
1717

1818
import lombok.extern.slf4j.Slf4j;
19+
import org.apache.commons.lang3.exception.ExceptionContext;
20+
import org.openrewrite.ExecutionContext;
1921
import org.openrewrite.Recipe;
2022
import org.openrewrite.java.ChangeType;
2123
import org.openrewrite.java.MethodMatcher;
2224
import org.openrewrite.java.search.FindMethods;
25+
import org.openrewrite.java.search.UsesType;
2326
import org.openrewrite.java.tree.J;
2427
import org.openrewrite.java.tree.JavaType;
2528
import org.openrewrite.java.tree.TypeUtils;
@@ -28,10 +31,12 @@
2831
import org.springframework.sbm.java.refactoring.JavaGlobalRefactoring;
2932
import org.springframework.sbm.project.resource.ProjectResourceSet;
3033
import org.springframework.sbm.project.resource.RewriteSourceFileHolder;
34+
import org.springframework.sbm.support.openrewrite.GenericOpenRewriteRecipe;
3135

3236
import java.util.ArrayList;
3337
import java.util.List;
3438
import java.util.Optional;
39+
import java.util.stream.Collectors;
3540
import java.util.stream.Stream;
3641

3742
@Slf4j
@@ -119,6 +124,18 @@ public List<JavaSourceAndType> findTypesImplementing(String type) {
119124
return matches;
120125
}
121126

127+
@Override
128+
public List<? extends JavaSource> findClassesUsingType(String fqName) {
129+
UsesType<ExecutionContext> usesType = new UsesType<>(fqName);
130+
GenericOpenRewriteRecipe<UsesType<ExecutionContext>> recipe = new GenericOpenRewriteRecipe<>(() -> usesType);
131+
return find(recipe).stream()
132+
.filter(RewriteSourceFileHolder.class::isInstance)
133+
.map(RewriteSourceFileHolder.class::cast)
134+
.filter(r -> r.getType().isAssignableFrom(J.CompilationUnit.class))
135+
.map(r -> (OpenRewriteJavaSource)r)
136+
.collect(Collectors.toList());
137+
}
138+
122139
private boolean hasTypeImplementing(J.ClassDeclaration c, String type) {
123140
try {
124141
return c.getImplements() != null &&
@@ -128,8 +145,8 @@ private boolean hasTypeImplementing(J.ClassDeclaration c, String type) {
128145
JavaType.FullyQualified fullyQualified = TypeUtils.asFullyQualified(
129146
intaface.getType()
130147
);
131-
if(fullyQualified == null) {
132-
log.error("Could not resolve implemented type '" + ((J.Identifier)intaface).getSimpleName() + "'");
148+
if(fullyQualified == null && J.Identifier.class.isInstance(intaface)) {
149+
log.error(String.format("Could not calculate if class '%s' implements an interface compatible to '%s'. Type of interface '%s' could not be resolved and was '%s'", c, type, intaface, intaface.getType().toString()));
133150
return false;
134151
}
135152
return fullyQualified

components/sbm-core/src/test/java/org/springframework/sbm/java/impl/RewriteJavaParserTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ void shouldDelegateParsingErrorsToExceptionHandler() throws ClassNotFoundExcepti
4949

5050
String out = sysOutBuffer.toString();
5151
System.setOut(realSysOut);
52-
assertThat(out)
53-
.containsPattern(".*ReloadableJava11Parser - Foo.java:1: error: cannot find symbol.*")
54-
.containsPattern(".*ReloadableJava11Parser - public class Foo \\{a\\}.*");
52+
assertThat(out).containsPattern(".*Foo.java:1: error: cannot find symbol.*");
5553
}
5654

5755
}

components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade/common/conditions/IsAnyMatchingSpringBootVersion.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ public String getDescription() {
4040
@Override
4141
public boolean evaluate(ProjectContext context) {
4242
return versionPatterns.stream()
43-
.map(IsMatchingSpringBootVersion::new)
44-
.anyMatch(isMatchingSpringBootVersion -> isMatchingSpringBootVersion.evaluate(context));
43+
.anyMatch(p -> new IsMatchingSpringBootVersion(p).evaluate(context));
4544
}
4645

4746
public void setVersionPatterns(String versionPatterns) {

components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/CrudRepositoryExtension.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.openrewrite.java.JavaIsoVisitor;
2424
import org.openrewrite.java.tree.J;
2525
import org.openrewrite.java.tree.JavaType;
26+
import org.springframework.sbm.boot.upgrade_27_30.helperrecipe.ImplementTypedInterface;
2627

2728
import java.util.List;
2829
import java.util.Optional;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
17+
package org.springframework.sbm.boot.upgrade_27_30;
18+
19+
import org.springframework.sbm.engine.context.ProjectContext;
20+
21+
public interface Sbu30_PreconditionCheck {
22+
Sbu30_PreconditionCheckResult run(ProjectContext context);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
17+
package org.springframework.sbm.boot.upgrade_27_30;
18+
19+
import lombok.Getter;
20+
import lombok.RequiredArgsConstructor;
21+
import org.springframework.sbm.engine.precondition.PreconditionCheck;
22+
23+
@Getter
24+
@RequiredArgsConstructor
25+
public class Sbu30_PreconditionCheckResult {
26+
private final PreconditionCheck.ResultState state;
27+
private final String message;
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
17+
package org.springframework.sbm.boot.upgrade_27_30;
18+
19+
import com.fasterxml.jackson.annotation.JsonIgnore;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.sbm.engine.context.ProjectContext;
22+
import org.springframework.sbm.engine.precondition.PreconditionCheck;
23+
import org.springframework.sbm.engine.recipe.AbstractAction;
24+
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
import java.util.stream.Collectors;
28+
29+
public class Sbu30_PreconditionChecks extends AbstractAction {
30+
31+
@Autowired
32+
@JsonIgnore
33+
private List<Sbu30_PreconditionCheck> checks = new ArrayList<>();
34+
35+
@Override
36+
public void apply(ProjectContext context) {
37+
List<Sbu30_PreconditionCheckResult> results = checks.stream()
38+
.map(sbu30_preconditionCheck -> sbu30_preconditionCheck.run(context))
39+
.collect(Collectors.toList());
40+
41+
results.forEach(this::render);
42+
43+
if(results.stream().anyMatch(c -> c.getState().equals(PreconditionCheck.ResultState.FAILED))) {
44+
// TODO: ask user to proceed, fail/end otherwise
45+
}
46+
47+
}
48+
49+
private void render(Sbu30_PreconditionCheckResult result) {
50+
System.out.println(result.getMessage());
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
17+
package org.springframework.sbm.boot.upgrade_27_30.checks;
18+
19+
import org.openrewrite.java.tree.JavaType;
20+
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheck;
21+
import org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionCheckResult;
22+
import org.springframework.sbm.build.api.ApplicationModule;
23+
import org.springframework.sbm.engine.context.ProjectContext;
24+
import org.springframework.sbm.engine.precondition.PreconditionCheck;
25+
import org.springframework.sbm.java.api.JavaSource;
26+
import org.springframework.sbm.java.impl.OpenRewriteJavaSource;
27+
import org.springframework.stereotype.Component;
28+
29+
import java.util.List;
30+
import java.util.Set;
31+
import java.util.stream.Collectors;
32+
import java.util.stream.Stream;
33+
34+
@Component
35+
public class DatabaseDriverGaeCheck implements Sbu30_PreconditionCheck {
36+
37+
@Override
38+
public Sbu30_PreconditionCheckResult run(ProjectContext context) {
39+
40+
Set<ApplicationModule> collect = context.getApplicationModules()
41+
.stream()
42+
.filter(this::hasClassAppEngineDriverOnClasspath)
43+
.collect(Collectors.toSet());
44+
45+
if(collect.isEmpty()) {
46+
return new Sbu30_PreconditionCheckResult(PreconditionCheck.ResultState.PASSED, "No dependency to Google AppEngine's AppEngineDriver found.");
47+
} else {
48+
String message = "Dependencies containing 'com.google.appengine.api.rdbms.AppEngineDriver' were found in these modules: '" + collect.stream().map(m -> m.getBuildFile().getCoordinates()).collect(Collectors.joining("', '")) + "'";
49+
return new Sbu30_PreconditionCheckResult(PreconditionCheck.ResultState.FAILED, message);
50+
}
51+
}
52+
53+
private boolean hasClassAppEngineDriverOnClasspath(ApplicationModule m) {
54+
return Stream.concat(m.getTestJavaSourceSet().stream(), m.getMainJavaSourceSet().stream())
55+
.anyMatch(js -> {
56+
if (dependsOn(js, "com.google.appengine.api.rdbms.AppEngineDriver")) {
57+
return true;
58+
} else {
59+
return false;
60+
}
61+
});
62+
}
63+
64+
private boolean dependsOn(JavaSource js, String s) {
65+
if (OpenRewriteJavaSource.class.isInstance(js)) {
66+
OpenRewriteJavaSource javaSource = OpenRewriteJavaSource.class.cast(js);
67+
return javaSource.getSourceFile().getMarkers().findFirst(org.openrewrite.java.marker.JavaSourceSet.class).get()
68+
.getClasspath()
69+
.stream()
70+
.map(JavaType.FullyQualified::getFullyQualifiedName)
71+
.anyMatch(fq -> s.equals(fq));
72+
}
73+
return false;
74+
}
75+
}

0 commit comments

Comments
 (0)