Skip to content

Commit

Permalink
Add recipe to convert builder varitions to standard builder method
Browse files Browse the repository at this point in the history
  • Loading branch information
zoewangg committed Apr 29, 2024
1 parent abb9d2c commit dc7b572
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,19 @@ public final class SdkTypeUtils {

private static final Pattern V1_SERVICE_CLIENT_CLASS_PATTERN =
Pattern.compile("com\\.amazonaws\\.services\\.[a-zA-Z0-9]+\\.[a-zA-Z0-9]+");
private static final Pattern V1_SERVICE_CLIENT_BUILDER_CLASS_PATTERN =
Pattern.compile("com\\.amazonaws\\.services\\.[a-zA-Z0-9]+\\.[a-zA-Z0-9]+Builder");

private static final Pattern V2_MODEL_BUILDER_PATTERN =
Pattern.compile("software\\.amazon\\.awssdk\\.services\\.[a-zA-Z0-9]+\\.model\\.[a-zA-Z0-9]+\\.Builder");
private static final Pattern V2_MODEL_CLASS_PATTERN = Pattern.compile(
"software\\.amazon\\.awssdk\\.services\\.[a-zA-Z0-9]+\\.model\\..[a-zA-Z0-9]+");
private static final Pattern V2_CLIENT_CLASS_PATTERN = Pattern.compile(
"software\\.amazon\\.awssdk\\.services\\.[a-zA-Z0-9]+\\.[a-zA-Z0-9]+");

private static final Pattern V2_ASYNC_CLIENT_CLASS_PATTERN = Pattern.compile(
"software\\.amazon\\.awssdk\\.services\\.[a-zA-Z0-9]+\\.[a-zA-Z0-9]+AsyncClient");

/**
* V2 core classes with a builder
*/
Expand Down Expand Up @@ -107,6 +113,11 @@ public static boolean isV2ClientClass(JavaType type) {
&& type.isAssignableFrom(V2_CLIENT_CLASS_PATTERN);
}

public static boolean isV2AsyncClientClass(JavaType type) {
return type != null
&& type.isAssignableFrom(V2_ASYNC_CLIENT_CLASS_PATTERN);
}

public static boolean isV2ClientBuilder(JavaType type) {
return type != null
&& type.isAssignableFrom(V2_CLIENT_BUILDER_PATTERN);
Expand Down Expand Up @@ -137,4 +148,13 @@ public static JavaType.FullyQualified v2Builder(JavaType.FullyQualified type) {

return TypeUtils.asFullyQualified(JavaType.buildType(fqcn));
}

public static JavaType.FullyQualified v2ClientFromClientBuilder(JavaType.FullyQualified type) {
if (!isV2ClientBuilder(type)) {
throw new IllegalArgumentException(String.format("%s is not a client builder", type));
}

String builder = type.getFullyQualifiedName().replace("Builder", "");
return TypeUtils.asFullyQualified(JavaType.buildType(builder));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
import java.util.Set;
import java.util.Stack;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.RemoveImport;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.Flag;
import org.openrewrite.java.tree.J;
Expand Down Expand Up @@ -72,7 +70,7 @@ public String getDescription() {

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>("com.amazonaws.*", true), new ChangeTypeVisitor());
return new ChangeTypeVisitor();
}

private static class ChangeTypeVisitor extends JavaVisitor<ExecutionContext> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.migration.recipe;

import static software.amazon.awssdk.migration.internal.utils.SdkTypeUtils.isV2AsyncClientClass;
import static software.amazon.awssdk.migration.internal.utils.SdkTypeUtils.isV2ClientBuilder;

import java.util.Collections;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.Tree;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JContainer;
import org.openrewrite.java.tree.JRightPadded;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.Space;
import org.openrewrite.java.tree.TypeUtils;
import org.openrewrite.marker.Markers;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.migration.internal.utils.SdkTypeUtils;

/**
* Internal recipe that renames V1 client builder variations. For example: {@code SqsClientBuilder.standard().build()} to
* {@code SqsClient.builder().build()} and {@code SqsAsyncClient.asyncBuilder().build()} to
* {@code SqsAsyncClient.builder().build()}.
*/
@SdkInternalApi
public class V1BuilderVariationsToV2Builder extends Recipe {

@Override
public String getDisplayName() {
return "V1 client builder variations to builder()";
}

@Override
public String getDescription() {
return "Transforms V1 builder variations to builder()";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new Visitor();
}

private static class Visitor extends JavaIsoVisitor<ExecutionContext> {

@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
method = super.visitMethodInvocation(method, executionContext);

JavaType selectType = null;

Expression select = method.getSelect();
if (select != null) {
selectType = select.getType();
}

if (selectType == null || !shouldChangeMethod(selectType)) {
return method;
}

if (isV2AsyncClientClass(selectType)) {
return renameAsyncBuilderToBuilder(method, selectType);
}

if (isV2ClientBuilder(selectType)) {
return renameStandardToBuilder(method, selectType);
}

return method;
}

private static boolean shouldChangeMethod(JavaType selectType) {
return isV2ClientBuilder(selectType) || isV2AsyncClientClass(selectType);
}

private J.MethodInvocation renameStandardToBuilder(J.MethodInvocation method, JavaType selectType) {
String methodName = method.getSimpleName();
JavaType.Method mt = method.getMethodType();
JavaType.FullyQualified fullyQualified = TypeUtils.asFullyQualified(selectType);

if (mt == null || !"standard".equals(methodName) || fullyQualified == null) {
return method;
}

methodName = "builder";

JavaType.FullyQualified v2Client = SdkTypeUtils.v2ClientFromClientBuilder(fullyQualified);
J.Identifier id = new J.Identifier(
Tree.randomId(),
Space.EMPTY,
Markers.EMPTY,
Collections.emptyList(),
v2Client.getClassName(),
v2Client,
null
);

J.Identifier builderMethod = new J.Identifier(
Tree.randomId(),
Space.EMPTY,
Markers.EMPTY,
Collections.emptyList(),
methodName,
null,
null
);

JavaType.Method methodType = new JavaType.Method(
null,
0L,
v2Client,
methodName,
v2Client,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList()
);

J.MethodInvocation builderInvoke = new J.MethodInvocation(
Tree.randomId(),
Space.EMPTY,
Markers.EMPTY,
JRightPadded.build(id),
null,
builderMethod,
JContainer.empty(),
methodType
);

maybeRemoveImport(fullyQualified);
maybeAddImport(v2Client);
return builderInvoke;
}

private J.MethodInvocation renameAsyncBuilderToBuilder(J.MethodInvocation method, JavaType selectType) {
String methodName = method.getSimpleName();
JavaType.Method mt = method.getMethodType();
JavaType.FullyQualified fullyQualified = TypeUtils.asFullyQualified(selectType);

if (mt == null || fullyQualified == null) {
return method;
}

if ("asyncBuilder".equals(methodName)) {
methodName = "builder";
}

mt = mt.withName(methodName)
.withReturnType(selectType)
.withDeclaringType(fullyQualified);

method = method.withName(method.getName()
.withSimpleName(methodName)
.withType(mt))
.withMethodType(mt);
return method;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ recipeList:
- software.amazon.awssdk.UpgradeSdkDependencies
- software.amazon.awssdk.migration.recipe.ChangeSdkType
- software.amazon.awssdk.ChangeSdkCoreTypes
- software.amazon.awssdk.migration.recipe.V1BuilderVariationsToV2Builder
- software.amazon.awssdk.migration.recipe.NewClassToBuilderPattern
- software.amazon.awssdk.migration.recipe.NewClassToStaticFactory
- software.amazon.awssdk.migration.recipe.NewClassToStaticFactory
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ recipeList:
newGroupId: software.amazon.awssdk
newArtifactId: servicecatalog
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-timestreaminfluxdb
newGroupId: software.amazon.awssdk
newArtifactId: timestreaminfluxdb
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-lakeformation
Expand Down Expand Up @@ -587,6 +593,12 @@ recipeList:
newGroupId: software.amazon.awssdk
newArtifactId: paymentcryptography
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-chatbot
newGroupId: software.amazon.awssdk
newArtifactId: chatbot
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-fms
Expand Down Expand Up @@ -833,6 +845,12 @@ recipeList:
newGroupId: software.amazon.awssdk
newArtifactId: transfer
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-deadline
newGroupId: software.amazon.awssdk
newArtifactId: deadline
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-braket
Expand Down Expand Up @@ -1691,6 +1709,12 @@ recipeList:
newGroupId: software.amazon.awssdk
newArtifactId: internetmonitor
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-artifact
newGroupId: software.amazon.awssdk
newArtifactId: artifact
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-iotsitewise
Expand Down Expand Up @@ -2153,6 +2177,12 @@ recipeList:
newGroupId: software.amazon.awssdk
newArtifactId: ram
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-codeconnections
newGroupId: software.amazon.awssdk
newArtifactId: codeconnections
newVersion: 2.23.16-SNAPSHOT
- org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId:
oldGroupId: com.amazonaws
oldArtifactId: aws-java-sdk-efs
Expand Down

0 comments on commit dc7b572

Please sign in to comment.