Skip to content

Commit 52dd329

Browse files
authored
Merge branch 'main' into lombok/normalize-setter
2 parents 6789157 + b741117 commit 52dd329

17 files changed

+492
-90
lines changed

gradle/wrapper/gradle-wrapper.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
3+
distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
55
networkTimeout=10000
66
validateDistributionUrl=true
77
zipStoreBase=GRADLE_USER_HOME
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (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+
* <p>
8+
* https://docs.moderne.io/licensing/moderne-source-available-license
9+
* <p>
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.openrewrite.java.migrate;
17+
18+
import org.openrewrite.ExecutionContext;
19+
import org.openrewrite.Preconditions;
20+
import org.openrewrite.Recipe;
21+
import org.openrewrite.TreeVisitor;
22+
import org.openrewrite.java.JavaVisitor;
23+
import org.openrewrite.java.MethodMatcher;
24+
import org.openrewrite.java.search.UsesJavaVersion;
25+
import org.openrewrite.java.search.UsesMethod;
26+
import org.openrewrite.java.tree.J;
27+
import org.openrewrite.java.tree.JavaType;
28+
import org.openrewrite.java.tree.Space;
29+
import org.openrewrite.marker.Markers;
30+
31+
import static org.openrewrite.Tree.randomId;
32+
33+
public class ChangeDefaultKeyStore extends Recipe {
34+
private static final MethodMatcher KEYSTORE_METHOD_REF = new MethodMatcher("java.security.KeyStore getDefaultType()", true);
35+
36+
@Override
37+
public String getDisplayName() {
38+
return "Return String `jks` when `KeyStore.getDefaultType()` is called";
39+
}
40+
41+
@Override
42+
public String getDescription() {
43+
return "In Java 11 the default keystore was updated from JKS to PKCS12. " +
44+
"As a result, applications relying on KeyStore.getDefaultType() may encounter issues after migrating," +
45+
" unless their JKS keystore has been converted to PKCS12. " +
46+
"This recipe returns default key store of `jks` when `KeyStore.getDefaultType()` method is called to" +
47+
" use the pre Java 11 default keystore.";
48+
}
49+
50+
@Override
51+
public TreeVisitor<?, ExecutionContext> getVisitor() {
52+
return Preconditions.check(
53+
Preconditions.and(
54+
new UsesJavaVersion<>(11, 11),
55+
new UsesMethod<>(KEYSTORE_METHOD_REF)),
56+
new JavaVisitor<ExecutionContext>() {
57+
@Override
58+
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
59+
if (KEYSTORE_METHOD_REF.matches(method)) {
60+
return new J.Literal(randomId(), Space.EMPTY, Markers.EMPTY, "\"jks\"", "\"jks\"", null, JavaType.Primitive.String);
61+
}
62+
return super.visitMethodInvocation(method, ctx);
63+
}
64+
});
65+
}
66+
}

src/main/java/org/openrewrite/java/migrate/UseJavaUtilBase64.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx)
117117
// Note: The sun.misc.CharacterDecoder#decodeBuffer throws an IOException, whereas the java
118118
// Base64Decoder.decode does not throw a checked exception. If this recipe converts decode, we
119119
// may need to remove the catch or completely unwrap a try/catch.
120-
doAfterVisit(new UnnecessaryCatch(false).getVisitor());
120+
doAfterVisit(new UnnecessaryCatch(false, false).getVisitor());
121121
}
122122
return m;
123123
}

src/main/java/org/openrewrite/java/migrate/joda/JodaTimeRecipe.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
import lombok.Getter;
1919
import org.jspecify.annotations.Nullable;
2020
import org.openrewrite.ExecutionContext;
21+
import org.openrewrite.Preconditions;
2122
import org.openrewrite.ScanningRecipe;
23+
import org.openrewrite.TreeVisitor;
24+
import org.openrewrite.java.search.UsesType;
2225
import org.openrewrite.java.tree.J;
2326
import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable;
2427
import org.openrewrite.java.tree.JavaType;
@@ -42,13 +45,14 @@ public Accumulator getInitialValue(ExecutionContext ctx) {
4245
}
4346

4447
@Override
45-
public JodaTimeScanner getScanner(Accumulator acc) {
48+
public TreeVisitor<?, ExecutionContext> getScanner(Accumulator acc) {
4649
return new JodaTimeScanner(acc);
4750
}
4851

4952
@Override
50-
public JodaTimeVisitor getVisitor(Accumulator acc) {
51-
return new JodaTimeVisitor(acc, true, new LinkedList<>());
53+
public TreeVisitor<?, ExecutionContext> getVisitor(Accumulator acc) {
54+
JodaTimeVisitor jodaTimeVisitor = new JodaTimeVisitor(acc, true, new LinkedList<>());
55+
return Preconditions.check(new UsesType<>("org.joda.time.*", true), jodaTimeVisitor);
5256
}
5357

5458
@Getter

src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
9393

9494
@Override
9595
public J visitVariable(NamedVariable variable, ExecutionContext ctx) {
96-
if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) {
96+
if (variable.getType() == null || !variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) {
9797
return super.visitVariable(variable, ctx);
9898
}
9999
// TODO: handle class variables

src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,32 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx)
5959

6060
@Override
6161
public @NonNull J visitCompilationUnit(@NonNull J.CompilationUnit cu, @NonNull ExecutionContext ctx) {
62-
maybeRemoveImport(JODA_DATE_TIME);
63-
maybeRemoveImport(JODA_DATE_TIME_ZONE);
64-
maybeRemoveImport(JODA_TIME_FORMAT);
65-
maybeRemoveImport(JODA_DURATION);
66-
maybeRemoveImport(JODA_ABSTRACT_INSTANT);
67-
maybeRemoveImport(JODA_INSTANT);
68-
maybeRemoveImport(JODA_INTERVAL);
69-
maybeRemoveImport("java.util.Locale");
62+
J j = super.visitCompilationUnit(cu, ctx);
63+
if (j != cu) {
64+
maybeRemoveImport(JODA_DATE_TIME);
65+
maybeRemoveImport(JODA_DATE_TIME_ZONE);
66+
maybeRemoveImport(JODA_TIME_FORMAT);
67+
maybeRemoveImport(JODA_DURATION);
68+
maybeRemoveImport(JODA_ABSTRACT_INSTANT);
69+
maybeRemoveImport(JODA_INSTANT);
70+
maybeRemoveImport(JODA_INTERVAL);
71+
maybeRemoveImport("java.util.Locale");
7072

71-
maybeAddImport(JAVA_DATE_TIME);
72-
maybeAddImport(JAVA_ZONE_OFFSET);
73-
maybeAddImport(JAVA_ZONE_ID);
74-
maybeAddImport(JAVA_INSTANT);
75-
maybeAddImport(JAVA_TIME_FORMATTER);
76-
maybeAddImport(JAVA_TIME_FORMAT_STYLE);
77-
maybeAddImport(JAVA_DURATION);
78-
maybeAddImport(JAVA_LOCAL_DATE);
79-
maybeAddImport(JAVA_LOCAL_TIME);
80-
maybeAddImport(JAVA_TEMPORAL_ISO_FIELDS);
81-
maybeAddImport(JAVA_CHRONO_FIELD);
82-
maybeAddImport(JAVA_UTIL_DATE);
83-
maybeAddImport(THREE_TEN_EXTRA_INTERVAL);
84-
return super.visitCompilationUnit(cu, ctx);
73+
maybeAddImport(JAVA_DATE_TIME);
74+
maybeAddImport(JAVA_ZONE_OFFSET);
75+
maybeAddImport(JAVA_ZONE_ID);
76+
maybeAddImport(JAVA_INSTANT);
77+
maybeAddImport(JAVA_TIME_FORMATTER);
78+
maybeAddImport(JAVA_TIME_FORMAT_STYLE);
79+
maybeAddImport(JAVA_DURATION);
80+
maybeAddImport(JAVA_LOCAL_DATE);
81+
maybeAddImport(JAVA_LOCAL_TIME);
82+
maybeAddImport(JAVA_TEMPORAL_ISO_FIELDS);
83+
maybeAddImport(JAVA_CHRONO_FIELD);
84+
maybeAddImport(JAVA_UTIL_DATE);
85+
maybeAddImport(THREE_TEN_EXTRA_INTERVAL);
86+
}
87+
return j;
8588
}
8689

8790
@Override
@@ -165,7 +168,8 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx)
165168
J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
166169

167170
// internal method with Joda class as return type
168-
if (!method.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN) &&
171+
if (method.getMethodType() != null &&
172+
!method.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN) &&
169173
method.getType().isAssignableFrom(JODA_CLASS_PATTERN)) {
170174
return migrateNonJodaMethod(method, m);
171175
}

src/main/java/org/openrewrite/java/migrate/lombok/LombokUtils.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import lombok.AccessLevel;
1919
import org.jspecify.annotations.Nullable;
20+
import org.openrewrite.Cursor;
2021
import org.openrewrite.internal.StringUtils;
22+
import org.openrewrite.java.AnnotationMatcher;
23+
import org.openrewrite.java.service.AnnotationService;
2124
import org.openrewrite.java.tree.Expression;
2225
import org.openrewrite.java.tree.J;
2326
import org.openrewrite.java.tree.JavaType;
@@ -26,12 +29,20 @@
2629
import java.util.List;
2730
import java.util.stream.Collectors;
2831

32+
import java.util.List;
33+
2934
import static lombok.AccessLevel.*;
3035
import static org.openrewrite.java.tree.J.Modifier.Type.*;
3136

3237
class LombokUtils {
3338

34-
static boolean isGetter(J.MethodDeclaration method) {
39+
private static final AnnotationMatcher OVERRIDE_MATCHER = new AnnotationMatcher("java.lang.Override");
40+
41+
static boolean isGetter(Cursor cursor, AnnotationService service) {
42+
if (!(cursor.getValue() instanceof J.MethodDeclaration)) {
43+
return false;
44+
}
45+
J.MethodDeclaration method = cursor.getValue();
3546
if (method.getMethodType() == null) {
3647
return false;
3748
}
@@ -45,6 +56,10 @@ static boolean isGetter(J.MethodDeclaration method) {
4556
!(method.getBody().getStatements().get(0) instanceof J.Return)) {
4657
return false;
4758
}
59+
// Check there is no annotation except @Overwrite
60+
if (hasAnyAnnotatioOtherThanOverride(cursor, service)) {
61+
return false;
62+
}
4863
// Check field is declared on method type
4964
JavaType.FullyQualified declaringType = method.getMethodType().getDeclaringType();
5065
Expression returnExpression = ((J.Return) method.getBody().getStatements().get(0)).getExpression();
@@ -87,7 +102,12 @@ private static String deriveGetterMethodName(@Nullable JavaType type, String fie
87102
return "get" + StringUtils.capitalize(fieldName);
88103
}
89104

90-
static boolean isSetter(J.MethodDeclaration method) {
105+
static boolean isSetter(Cursor cursor, AnnotationService service) {
106+
if (!(cursor.getValue() instanceof J.MethodDeclaration)) {
107+
return false;
108+
}
109+
J.MethodDeclaration method = cursor.getValue();
110+
91111
// Check return type: void
92112
if (method.getType() != JavaType.Primitive.Void) {
93113
return false;
@@ -103,6 +123,11 @@ static boolean isSetter(J.MethodDeclaration method) {
103123
return false;
104124
}
105125

126+
// Check there is no annotation except @Overwrite
127+
if (hasAnyAnnotatioOtherThanOverride(cursor, service)) {
128+
return false;
129+
}
130+
106131
// Check there's no up/down cast between parameter and field
107132
J.VariableDeclarations.NamedVariable param = ((J.VariableDeclarations) method.getParameters().get(0)).getVariables().get(0);
108133
Expression variable = ((J.Assignment) method.getBody().getStatements().get(0)).getVariable();
@@ -181,4 +206,9 @@ static AccessLevel getAccessLevel(J.MethodDeclaration methodDeclaration) {
181206
}
182207
return PACKAGE;
183208
}
209+
210+
private static boolean hasAnyAnnotatioOtherThanOverride(Cursor cursor, AnnotationService service) {
211+
List<J.Annotation> annotations = service.getAllAnnotations(cursor);
212+
return !(annotations.isEmpty() || (annotations.size() == 1 && OVERRIDE_MATCHER.matches(annotations.get(0))));
213+
}
184214
}

src/main/java/org/openrewrite/java/migrate/lombok/UseLombokGetter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@
2323
import org.openrewrite.Recipe;
2424
import org.openrewrite.TreeVisitor;
2525
import org.openrewrite.java.JavaIsoVisitor;
26+
import org.openrewrite.java.service.AnnotationService;
2627
import org.openrewrite.java.tree.Expression;
2728
import org.openrewrite.java.tree.J;
2829

2930
import java.util.Collections;
3031
import java.util.Set;
3132

32-
import static java.util.Comparator.comparing;
33-
3433
@Value
3534
@EqualsAndHashCode(callSuper = false)
3635
public class UseLombokGetter extends Recipe {
@@ -56,7 +55,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
5655
return new JavaIsoVisitor<ExecutionContext>() {
5756
@Override
5857
public J.@Nullable MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) {
59-
if (LombokUtils.isGetter(method)) {
58+
if (LombokUtils.isGetter(getCursor(), service(AnnotationService.class))) {
6059
Expression returnExpression = ((J.Return) method.getBody().getStatements().get(0)).getExpression();
6160
if (returnExpression instanceof J.Identifier &&
6261
((J.Identifier) returnExpression).getFieldType() != null) {

src/main/java/org/openrewrite/java/migrate/lombok/UseLombokSetter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.openrewrite.Recipe;
2424
import org.openrewrite.TreeVisitor;
2525
import org.openrewrite.java.JavaIsoVisitor;
26+
import org.openrewrite.java.service.AnnotationService;
2627
import org.openrewrite.java.tree.Expression;
2728
import org.openrewrite.java.tree.J;
2829

@@ -53,7 +54,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
5354
return new JavaIsoVisitor<ExecutionContext>() {
5455
@Override
5556
public J.@Nullable MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) {
56-
if (LombokUtils.isSetter(method)) {
57+
if (LombokUtils.isSetter(getCursor(), service(AnnotationService.class))) {
5758
Expression assignmentVariable = ((J.Assignment) method.getBody().getStatements().get(0)).getVariable();
5859
if (assignmentVariable instanceof J.FieldAccess &&
5960
((J.FieldAccess) assignmentVariable).getName().getFieldType() != null) {

src/main/resources/META-INF/rewrite/java-version-11.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ recipeList:
7676
- org.openrewrite.java.migrate.ReplaceLocalizedStreamMethods
7777
- org.openrewrite.java.migrate.ArrayStoreExceptionToTypeNotPresentException
7878
- org.openrewrite.java.migrate.IllegalArgumentExceptionToAlreadyConnectedException
79-
79+
- org.openrewrite.java.migrate.ChangeDefaultKeyStore
8080
---
8181
type: specs.openrewrite.org/v1beta/recipe
8282
name: org.openrewrite.java.migrate.UpgradeBuildToJava11
@@ -292,3 +292,4 @@ recipeList:
292292
- org.openrewrite.java.ChangeMethodName:
293293
methodPattern: java.nio.file.Path get(..)
294294
newMethodName: of
295+

0 commit comments

Comments
 (0)