Skip to content

Commit 3a90e8d

Browse files
authored
Add enum getters and casing transforms (#5393)
* Fix enum getters and casing * Fix enum getters and casing * Fix enum getters and casing * Fix unit test * Address comments * Address comments
1 parent 6f33595 commit 3a90e8d

File tree

18 files changed

+928
-26
lines changed

18 files changed

+928
-26
lines changed

build-tools/src/main/resources/software/amazon/awssdk/spotbugs-suppressions.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,10 @@
312312
<Match>
313313
<Bug pattern="EI_EXPOSE_REP2,EI_EXPOSE_REP,MS_EXPOSE_REP,MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR,SA_FIELD_SELF_ASSIGNMENT,DCN_NULLPOINTER_EXCEPTION"/>
314314
</Match>
315+
316+
<!-- False positive -->
317+
<Match>
318+
<Class name="software.amazon.awssdk.v2migration.EnumCasingToV2$Visitor"/>
319+
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
320+
</Match>
315321
</FindBugsFilter>

test/v2-migration-tests/src/test/resources/maven/after/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
<artifactId>sqs</artifactId>
4343
<version>V2_VERSION</version>
4444
</dependency>
45+
<dependency>
46+
<groupId>software.amazon.awssdk</groupId>
47+
<artifactId>sqs</artifactId>
48+
<version>V2_VERSION</version>
49+
</dependency>
4550
<dependency>
4651
<groupId>software.amazon.awssdk</groupId>
4752
<artifactId>apache-client</artifactId>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package foo.bar;
17+
import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
18+
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
19+
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
20+
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
public class Enums {
25+
26+
public static void main(String... args) {
27+
QueueAttributeName qan = QueueAttributeName.DELAY_SECONDS;
28+
QueueAttributeName qan2 = QueueAttributeName.ALL;
29+
System.out.println(qan);
30+
System.out.println(qan2);
31+
32+
ReceiveMessageRequest v1Request = ReceiveMessageRequest.builder().build();
33+
List<String> attributes = v1Request.attributeNamesAsStrings();
34+
System.out.println(attributes);
35+
36+
SendMessageRequest v2Request = SendMessageRequest.builder().build();
37+
Map<String, MessageAttributeValue> messageAttributes = v2Request.messageAttributes();
38+
System.out.println(messageAttributes);
39+
}
40+
}

test/v2-migration-tests/src/test/resources/maven/before/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
</dependencyManagement>
3838

3939
<dependencies>
40+
<dependency>
41+
<groupId>software.amazon.awssdk</groupId>
42+
<artifactId>sqs</artifactId>
43+
<version>V2_VERSION</version>
44+
</dependency>
4045
<dependency>
4146
<groupId>com.amazonaws</groupId>
4247
<artifactId>aws-java-sdk-sqs</artifactId>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package foo.bar;
17+
18+
import com.amazonaws.services.sqs.model.QueueAttributeName;
19+
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
20+
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
21+
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
22+
import java.util.List;
23+
import java.util.Map;
24+
25+
public class Enums {
26+
27+
public static void main(String... args) {
28+
QueueAttributeName qan = QueueAttributeName.DelaySeconds;
29+
QueueAttributeName qan2 = QueueAttributeName.All;
30+
System.out.println(qan);
31+
System.out.println(qan2);
32+
33+
ReceiveMessageRequest v1Request = new ReceiveMessageRequest();
34+
List<String> attributes = v1Request.getAttributeNames();
35+
System.out.println(attributes);
36+
37+
SendMessageRequest v2Request = SendMessageRequest.builder().build();
38+
Map<String, MessageAttributeValue> messageAttributes = v2Request.messageAttributes();
39+
System.out.println(messageAttributes);
40+
}
41+
}

test/v2-migration-tests/src/test/resources/run-test

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ BEFORE_DIR_MAVEN = os.path.join(RESOURCE_DIR, "maven/before")
1414
AFTER_DIR_MAVEN = os.path.join(RESOURCE_DIR, "maven/after")
1515
TARGET_DIR_MAVEN = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(os.path.join(__file__, "../../")))), "target/generated-test-sources/maven/project")
1616
TARGET_AFTER_DIR_MAVEN = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(os.path.join(__file__, "../../")))), "target/generated-test-sources/maven/after")
17+
BEFORE_POM = os.path.join(TARGET_DIR_MAVEN, "pom.xml")
1718
AFTER_POM = os.path.join(TARGET_AFTER_DIR_MAVEN, "pom.xml")
1819

1920
BEFORE_DIR_GRADLE = os.path.join(RESOURCE_DIR, "gradle/before")
@@ -43,20 +44,28 @@ def run_maven_test(version):
4344
copy_directory(BEFORE_DIR_MAVEN, TARGET_DIR_MAVEN)
4445
copy_directory(AFTER_DIR_MAVEN, TARGET_AFTER_DIR_MAVEN)
4546

47+
before_pom_file = Path(BEFORE_POM)
48+
write_version_to_pom(before_pom_file, version)
49+
4650
subprocess.run(["mvn", "org.openrewrite.maven:rewrite-maven-plugin:run",
4751
"-Drewrite.recipeArtifactCoordinates=software.amazon.awssdk:v2-migration:"+ version,
4852
"-Drewrite.activeRecipes=software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2"], cwd=TARGET_DIR_MAVEN, check=True)
4953
shutil.rmtree(os.path.join(TARGET_DIR_MAVEN, "target"))
5054

51-
pom_file = Path(AFTER_POM)
52-
pom_file.write_text(pom_file.read_text().replace('V2_VERSION', version))
55+
after_pom_file = Path(AFTER_POM)
56+
write_version_to_pom(after_pom_file, version)
5357

5458
is_same = compare_directory(filecmp.dircmp(TARGET_DIR_MAVEN, TARGET_AFTER_DIR_MAVEN))
5559
if not is_same:
5660
raise Exception("The transformed directory({}) does not match with the expected one({})".format(TARGET_DIR_MAVEN, TARGET_AFTER_DIR_MAVEN))
5761
result = subprocess.run(["mvn", "package"], cwd=TARGET_DIR_MAVEN, capture_output=True, check=True)
5862
print(result)
5963

64+
65+
def write_version_to_pom(pom_file, version):
66+
pom_file.write_text(pom_file.read_text().replace('V2_VERSION', version))
67+
68+
6069
def run_gradle_test(version):
6170
if os.path.exists(TARGET_DIR_GRADLE) and os.path.isdir(TARGET_DIR_GRADLE):
6271
shutil.rmtree(TARGET_DIR_GRADLE)

v2-migration/pom.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@
114114
</exclusion>
115115
</exclusions>
116116
</dependency>
117+
<dependency>
118+
<groupId>com.amazonaws</groupId>
119+
<artifactId>aws-java-sdk-sns</artifactId>
120+
<scope>test</scope>
121+
<exclusions>
122+
<exclusion>
123+
<groupId>com.fasterxml.jackson</groupId>
124+
<artifactId>jackson-core</artifactId>
125+
</exclusion>
126+
</exclusions>
127+
</dependency>
117128
<dependency>
118129
<groupId>com.amazonaws</groupId>
119130
<artifactId>aws-java-sdk-dynamodb</artifactId>
@@ -180,6 +191,18 @@
180191
</exclusion>
181192
</exclusions>
182193
</dependency>
194+
<dependency>
195+
<groupId>software.amazon.awssdk</groupId>
196+
<artifactId>sns</artifactId>
197+
<scope>test</scope>
198+
<version>${awsjavasdk.version}</version>
199+
<exclusions>
200+
<exclusion>
201+
<groupId>com.fasterxml.jackson</groupId>
202+
<artifactId>jackson-core</artifactId>
203+
</exclusion>
204+
</exclusions>
205+
</dependency>
183206
</dependencies>
184207

185208
<build>

v2-migration/src/main/java/software/amazon/awssdk/v2migration/ChangeSdkType.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,17 @@ private JavaType updateFullyQualifiedType(JavaType currentType) {
510510

511511
Pair<JavaType.Class, JavaType> oldToNewPair = oldTypeToNewType.get(fullyQualifiedName);
512512
JavaType targetType = oldToNewPair.right();
513+
514+
if (original.getKind() == JavaType.FullyQualified.Kind.Enum) {
515+
JavaType.FullyQualified targetTypeEnum = TypeUtils.asFullyQualified(targetType);
516+
if (targetTypeEnum != null) {
517+
JavaType enumType = JavaType.ShallowClass.build(targetTypeEnum.getFullyQualifiedName())
518+
.withKind(JavaType.FullyQualified.Kind.Enum);
519+
oldNameToChangedType.put(currentType, enumType);
520+
return enumType;
521+
}
522+
}
523+
513524
oldNameToChangedType.put(currentType, targetType);
514525
return targetType;
515526
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.v2migration;
17+
18+
import static software.amazon.awssdk.utils.internal.CodegenNamingUtils.splitOnWordBoundaries;
19+
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
import org.openrewrite.ExecutionContext;
23+
import org.openrewrite.Recipe;
24+
import org.openrewrite.TreeVisitor;
25+
import org.openrewrite.java.JavaIsoVisitor;
26+
import org.openrewrite.java.tree.J;
27+
import org.openrewrite.java.tree.JavaType;
28+
import org.openrewrite.java.tree.TypeUtils;
29+
import software.amazon.awssdk.annotations.SdkInternalApi;
30+
import software.amazon.awssdk.utils.StringUtils;
31+
import software.amazon.awssdk.v2migration.internal.utils.SdkTypeUtils;
32+
33+
@SdkInternalApi
34+
public class EnumCasingToV2 extends Recipe {
35+
36+
private static Set<String> ENUMS = new HashSet<>();
37+
38+
@Override
39+
public String getDisplayName() {
40+
return "V1 Enum Casing to V2";
41+
}
42+
43+
@Override
44+
public String getDescription() {
45+
return "Transforms V1 enum constants from pascal case to screaming snake case for v2.";
46+
}
47+
48+
@Override
49+
public TreeVisitor<?, ExecutionContext> getVisitor() {
50+
return new Visitor();
51+
}
52+
53+
private static String v2Casing(String enumValue) {
54+
String result = enumValue;
55+
result = result.replaceAll("textORcsv", "TEXT_OR_CSV");
56+
result = String.join("_", splitOnWordBoundaries(result));
57+
return StringUtils.upperCase(result);
58+
}
59+
60+
private static class Visitor extends JavaIsoVisitor<ExecutionContext> {
61+
@Override
62+
public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess, ExecutionContext ctx) {
63+
J.FieldAccess fa = super.visitFieldAccess(fieldAccess, ctx);
64+
65+
if (isV2EnumValue(fa)) {
66+
String v2Casing = v2Casing(fa.getSimpleName());
67+
ENUMS.add(v2Casing);
68+
return fa.withName(fa.getName().withSimpleName(v2Casing));
69+
}
70+
71+
return fa;
72+
}
73+
74+
@Override
75+
public J.Identifier visitIdentifier(J.Identifier identifier, ExecutionContext ctx) {
76+
J.Identifier id = super.visitIdentifier(identifier, ctx);
77+
78+
if (ENUMS.contains(id.getSimpleName())) {
79+
return id.withFieldType(id.getFieldType().withName(id.getSimpleName()));
80+
}
81+
82+
return id;
83+
}
84+
85+
public boolean isV2EnumValue(J.FieldAccess fa) {
86+
JavaType javaType = fa.getTarget().getType();
87+
JavaType.FullyQualified fullyQualified = TypeUtils.asFullyQualified(javaType);
88+
if (fullyQualified != null) {
89+
return SdkTypeUtils.isV2ModelClass(javaType)
90+
&& fullyQualified.getKind() == JavaType.FullyQualified.Kind.Enum;
91+
}
92+
return false;
93+
}
94+
}
95+
}

v2-migration/src/main/resources/META-INF/rewrite/aws-sdk-java-v1-to-v2.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ recipeList:
2424
- software.amazon.awssdk.v2migration.UpgradeSdkDependencies
2525
- software.amazon.awssdk.v2migration.S3GetObjectConstructorToFluent
2626
- software.amazon.awssdk.v2migration.S3StreamingResponseToV2
27+
- software.amazon.awssdk.v2migration.EnumGettersToV2
2728
- software.amazon.awssdk.v2migration.ChangeSdkType
2829
- software.amazon.awssdk.v2migration.ChangeSdkCoreTypes
2930
# At this point, all classes should be changed to v2 equivalents
@@ -33,3 +34,4 @@ recipeList:
3334
- software.amazon.awssdk.v2migration.V1GetterToV2
3435
- software.amazon.awssdk.v2migration.HttpSettingsToHttpClient
3536
- software.amazon.awssdk.v2migration.WrapSdkClientBuilderRegionStr
37+
- software.amazon.awssdk.v2migration.EnumCasingToV2

0 commit comments

Comments
 (0)