Skip to content

Commit dbb7d2b

Browse files
jeffaldermillems
authored andcommitted
Add support for replacing and deprecating members
1 parent 45fe067 commit dbb7d2b

File tree

29 files changed

+980
-22
lines changed

29 files changed

+980
-22
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"category": "Amazon S3",
3+
"type": "feature",
4+
"description": "CopyObjectRequest now has `destinationBucket` and `destinationKey` properties for clarity.\nThe existing names, `bucket` and `key`, are deprecated."
5+
}

codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,20 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
197197
fillContainerTypeMemberMetadata(allC2jShapes, c2jMemberDefinition.getShape(), memberModel,
198198
protocol);
199199

200+
201+
String deprecatedName = c2jMemberDefinition.getDeprecatedName();
202+
if (StringUtils.isNotBlank(deprecatedName)) {
203+
checkForValidDeprecatedName(c2jMemberName, shape);
204+
205+
memberModel.setDeprecatedName(deprecatedName);
206+
memberModel.setDeprecatedFluentGetterMethodName(
207+
namingStrategy.getFluentGetterMethodName(deprecatedName, parentShape, shape));
208+
memberModel.setDeprecatedFluentSetterMethodName(
209+
namingStrategy.getFluentSetterMethodName(deprecatedName, parentShape, shape));
210+
memberModel.setDeprecatedBeanStyleSetterMethodName(
211+
namingStrategy.getBeanStyleSetterMethodName(deprecatedName, parentShape, shape));
212+
}
213+
200214
ParameterHttpMapping httpMapping = generateParameterHttpMapping(parentShape,
201215
c2jMemberName,
202216
c2jMemberDefinition,
@@ -219,6 +233,26 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
219233
return memberModel;
220234
}
221235

236+
private void checkForValidDeprecatedName(String c2jMemberName, Shape memberShape) {
237+
if (memberShape.getEnumValues() != null) {
238+
throw new IllegalStateException(String.format(
239+
"Member %s has enum values and a deprecated name. Codegen does not support this.",
240+
c2jMemberName));
241+
}
242+
243+
if (isListShape(memberShape)) {
244+
throw new IllegalStateException(String.format(
245+
"Member %s is a list and has a deprecated name. Codegen does not support this.",
246+
c2jMemberName));
247+
}
248+
249+
if (isMapShape(memberShape)) {
250+
throw new IllegalStateException(String.format(
251+
"Member %s is a map and has a deprecated name. Codegen does not support this.",
252+
c2jMemberName));
253+
}
254+
}
255+
222256
private boolean isSensitiveShapeOrContainer(Member member, Map<String, Shape> allC2jShapes) {
223257
if (member == null) {
224258
return false;

codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/ShapeModifiersProcessor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ private void doModifyShapeMembers(ServiceModel serviceModel, Shape shape, String
219219
member.setLocationName(memberToModify);
220220
}
221221

222+
if (modifyModel.isExistingNameDeprecated()) {
223+
member.setDeprecatedName(memberToModify);
224+
}
225+
222226
shape.getMembers().put(modifyModel.getEmitPropertyName(), member);
223227
}
224228
if (modifyModel.getEmitAsType() != null) {

codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/ModifyModelShapeModifier.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717

1818
public class ModifyModelShapeModifier {
1919

20+
/**
21+
* Indicates whether a renamed member should create getters and setters under the existing name
22+
*/
23+
private boolean existingNameDeprecated;
24+
25+
/**
26+
* Sets a name for a member used by the SDK, eliminating the existing name
27+
*/
2028
private String emitPropertyName;
2129

2230
/**
@@ -41,6 +49,14 @@ public class ModifyModelShapeModifier {
4149

4250
private String unmarshallLocationName;
4351

52+
public boolean isExistingNameDeprecated() {
53+
return existingNameDeprecated;
54+
}
55+
56+
public void setExistingNameDeprecated(boolean existingNameDeprecated) {
57+
this.existingNameDeprecated = existingNameDeprecated;
58+
}
59+
4460
public String getEmitPropertyName() {
4561
return emitPropertyName;
4662
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ public class MemberModel extends DocumentationModel {
9595

9696
private boolean xmlAttribute;
9797

98+
private String deprecatedName;
99+
100+
private String fluentDeprecatedGetterMethodName;
101+
102+
private String fluentDeprecatedSetterMethodName;
103+
104+
private String deprecatedBeanStyleSetterMethodName;
105+
98106
public String getName() {
99107
return name;
100108
}
@@ -443,6 +451,14 @@ public String getGetterDocumentation() {
443451
return docBuilder.toString();
444452
}
445453

454+
public String getDeprecatedGetterDocumentation() {
455+
String getterDocumentation = getGetterDocumentation();
456+
return getterDocumentation
457+
+ LF
458+
+ "@deprecated Use {@link #" + getFluentGetterMethodName() + "()}"
459+
+ LF;
460+
}
461+
446462
private boolean returnTypeIs(Class<?> clazz) {
447463
String returnType = this.getGetterModel().getReturnType();
448464
return returnType != null && returnType.startsWith(clazz.getName()); // Use startsWith in case it's parametrized
@@ -459,6 +475,13 @@ public String getExistenceCheckDocumentation() {
459475
return defaultExistenceCheck().replace("%s", name) + LF;
460476
}
461477

478+
public String getDeprecatedSetterDocumentation() {
479+
return getFluentSetterDocumentation()
480+
+ LF
481+
+ "@deprecated Use {@link #" + getFluentSetterMethodName() + "(" + setterModel.getSimpleType() + ")}"
482+
+ LF;
483+
}
484+
462485
public String getDefaultConsumerFluentSetterDocumentation() {
463486
return (StringUtils.isNotBlank(documentation) ? documentation : defaultSetter().replace("%s", name) + "\n")
464487
+ LF
@@ -589,6 +612,19 @@ public MemberModel withXmlAttribtue(boolean xmlAttribtue) {
589612
return this;
590613
}
591614

615+
public String getDeprecatedName() {
616+
return deprecatedName;
617+
}
618+
619+
public void setDeprecatedName(String deprecatedName) {
620+
this.deprecatedName = deprecatedName;
621+
}
622+
623+
public MemberModel withDeprecatedName(String deprecatedName) {
624+
this.deprecatedName = deprecatedName;
625+
return this;
626+
}
627+
592628
@JsonIgnore
593629
public boolean hasBuilder() {
594630
return !(isSimple() || isList() || isMap());
@@ -653,4 +689,28 @@ public Optional<ClassName> getAutoConstructClassIfExists() {
653689

654690
return Optional.empty();
655691
}
692+
693+
public void setDeprecatedFluentGetterMethodName(String fluentDeprecatedGetterMethodName) {
694+
this.fluentDeprecatedGetterMethodName = fluentDeprecatedGetterMethodName;
695+
}
696+
697+
public String getDeprecatedFluentGetterMethodName() {
698+
return fluentDeprecatedGetterMethodName;
699+
}
700+
701+
public void setDeprecatedFluentSetterMethodName(String fluentDeprecatedSetterMethodName) {
702+
this.fluentDeprecatedSetterMethodName = fluentDeprecatedSetterMethodName;
703+
}
704+
705+
public String getDeprecatedFluentSetterMethodName() {
706+
return fluentDeprecatedSetterMethodName;
707+
}
708+
709+
public String getDeprecatedBeanStyleSetterMethodName() {
710+
return deprecatedBeanStyleSetterMethodName;
711+
}
712+
713+
public void setDeprecatedBeanStyleSetterMethodName(String deprecatedBeanStyleSetterMethodName) {
714+
this.deprecatedBeanStyleSetterMethodName = deprecatedBeanStyleSetterMethodName;
715+
}
656716
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Member.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class Member {
6161

6262
private boolean xmlAttribute;
6363

64+
private String deprecatedName;
65+
6466
public String getShape() {
6567
return shape;
6668
}
@@ -212,4 +214,12 @@ public boolean isXmlAttribute() {
212214
public void setXmlAttribute(boolean xmlAttribute) {
213215
this.xmlAttribute = xmlAttribute;
214216
}
217+
218+
public void setDeprecatedName(String deprecatedName) {
219+
this.deprecatedName = deprecatedName;
220+
}
221+
222+
public String getDeprecatedName() {
223+
return deprecatedName;
224+
}
215225
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AbstractMemberSetters.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ protected MethodSpec.Builder fluentSetterBuilder(TypeName returnType) {
7373
return fluentSetterBuilder(memberAsParameter(), returnType);
7474
}
7575

76+
protected MethodSpec.Builder fluentSetterBuilder(String methodName, TypeName returnType) {
77+
return fluentSetterBuilder(methodName, memberAsParameter(), returnType);
78+
}
79+
7680
protected MethodSpec.Builder fluentSetterBuilder(ParameterSpec setterParam, TypeName returnType) {
7781
return fluentSetterBuilder(memberModel().getFluentSetterMethodName(), setterParam, returnType);
7882
}
@@ -86,11 +90,15 @@ protected MethodSpec.Builder fluentSetterBuilder(String methodName, ParameterSpe
8690
}
8791

8892
protected MethodSpec.Builder beanStyleSetterBuilder() {
89-
return beanStyleSetterBuilder(memberAsBeanStyleParameter());
93+
return beanStyleSetterBuilder(memberAsBeanStyleParameter(), memberModel().getBeanStyleSetterMethodName());
9094
}
9195

92-
protected MethodSpec.Builder beanStyleSetterBuilder(ParameterSpec setterParam) {
93-
return MethodSpec.methodBuilder(memberModel().getBeanStyleSetterMethodName())
96+
protected MethodSpec.Builder deprecatedBeanStyleSetterBuilder() {
97+
return beanStyleSetterBuilder(memberAsBeanStyleParameter(), memberModel().getDeprecatedBeanStyleSetterMethodName());
98+
}
99+
100+
protected MethodSpec.Builder beanStyleSetterBuilder(ParameterSpec setterParam, String methodName) {
101+
return MethodSpec.methodBuilder(methodName)
94102
.addParameter(setterParam)
95103
.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
96104
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AccessorsFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public List<MethodSpec> fluentSetters(MemberModel memberModel, TypeName returnTy
8080
return new NonCollectionSetters(intermediateModel, shapeModel, memberModel, typeProvider).fluent(returnType);
8181
}
8282

83-
public MethodSpec beanStyleSetter(MemberModel memberModel) {
83+
public List<MethodSpec> beanStyleSetters(MemberModel memberModel) {
8484
if (memberModel.isList()) {
8585
return new ListSetters(intermediateModel, shapeModel, memberModel, typeProvider).beanStyle();
8686
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AwsServiceModel.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
5151
import software.amazon.awssdk.core.SdkField;
5252
import software.amazon.awssdk.core.SdkPojo;
53+
import software.amazon.awssdk.utils.StringUtils;
5354
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
5455

5556
/**
@@ -355,10 +356,7 @@ private MethodSpec getValueForField() {
355356

356357
methodBuilder.beginControlFlow("switch ($L)", "fieldName");
357358

358-
shapeModel.getNonStreamingMembers().forEach(m -> methodBuilder.addCode("case $S:", m.getC2jName())
359-
.addStatement("return $T.ofNullable(clazz.cast($L()))",
360-
Optional.class,
361-
m.getFluentGetterMethodName()));
359+
shapeModel.getNonStreamingMembers().forEach(m -> addCasesForMember(methodBuilder, m));
362360

363361
methodBuilder.addCode("default:");
364362
methodBuilder.addStatement("return $T.empty()", Optional.class);
@@ -367,6 +365,20 @@ private MethodSpec getValueForField() {
367365
return methodBuilder.build();
368366
}
369367

368+
private void addCasesForMember(MethodSpec.Builder methodBuilder, MemberModel member) {
369+
methodBuilder.addCode("case $S:", member.getC2jName())
370+
.addStatement("return $T.ofNullable(clazz.cast($L()))",
371+
Optional.class,
372+
member.getFluentGetterMethodName());
373+
374+
if (shouldGenerateDeprecatedNameGetter(member)) {
375+
methodBuilder.addCode("case $S:", member.getDeprecatedName())
376+
.addStatement("return $T.ofNullable(clazz.cast($L()))",
377+
Optional.class,
378+
member.getFluentGetterMethodName());
379+
}
380+
}
381+
370382
private List<MethodSpec> memberGetters() {
371383
return shapeModel.getNonStreamingMembers().stream()
372384
.filter(m -> !m.getHttp().getIsStreaming())
@@ -384,11 +396,19 @@ private Stream<MethodSpec> memberGetters(MemberModel member) {
384396
member.getAutoConstructClassIfExists()
385397
.ifPresent(autoConstructClass -> result.add(existenceCheckGetter(member, autoConstructClass)));
386398

399+
if (shouldGenerateDeprecatedNameGetter(member)) {
400+
result.add(deprecatedMemberGetter(member));
401+
}
402+
387403
result.add(memberGetter(member));
388404

389405
return result.stream();
390406
}
391407

408+
private boolean shouldGenerateDeprecatedNameGetter(MemberModel member) {
409+
return StringUtils.isNotBlank(member.getDeprecatedName());
410+
}
411+
392412
private boolean shouldGenerateEnumGetter(MemberModel member) {
393413
return member.getEnumType() != null || MemberCopierSpec.isEnumCopyAvailable(member);
394414
}
@@ -425,6 +445,16 @@ private CodeBlock existenceCheckStatement(MemberModel member, ClassName autoCons
425445
return CodeBlock.of("return $N != null && !($N instanceof $T);", variableName, variableName, autoConstructClass);
426446
}
427447

448+
private MethodSpec deprecatedMemberGetter(MemberModel member) {
449+
return MethodSpec.methodBuilder(member.getDeprecatedFluentGetterMethodName())
450+
.addJavadoc("$L", member.getDeprecatedGetterDocumentation())
451+
.addModifiers(PUBLIC)
452+
.addAnnotation(Deprecated.class)
453+
.returns(typeProvider.returnType(member))
454+
.addCode(getterStatement(member))
455+
.build();
456+
}
457+
428458
private CodeBlock enumGetterStatement(MemberModel member) {
429459
String fieldName = member.getVariable().getVariableName();
430460
if (member.isList() || member.isMap()) {

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ListSetters.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.squareup.javapoet.TypeName;
2525
import java.util.ArrayList;
2626
import java.util.Arrays;
27+
import java.util.Collections;
2728
import java.util.List;
2829
import java.util.function.Consumer;
2930
import java.util.stream.Collectors;
@@ -117,11 +118,11 @@ public List<MethodSpec> fluent(TypeName returnType) {
117118
}
118119

119120
@Override
120-
public MethodSpec beanStyle() {
121+
public List<MethodSpec> beanStyle() {
121122
MethodSpec.Builder builder = beanStyleSetterBuilder()
122123
.addCode(memberModel().isCollectionWithBuilderMember() ? copySetterBuilderBody() : beanCopySetterBody());
123124

124-
return builder.build();
125+
return Collections.singletonList(builder.build());
125126

126127
}
127128

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MapSetters.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.squareup.javapoet.ParameterSpec;
2020
import com.squareup.javapoet.TypeName;
2121
import java.util.ArrayList;
22+
import java.util.Collections;
2223
import java.util.List;
2324
import software.amazon.awssdk.codegen.internal.Utils;
2425
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
@@ -75,11 +76,11 @@ public List<MethodSpec> fluent(TypeName returnType) {
7576
}
7677

7778
@Override
78-
public MethodSpec beanStyle() {
79+
public List<MethodSpec> beanStyle() {
7980
MethodSpec.Builder builder = beanStyleSetterBuilder()
8081
.addCode(memberModel().isCollectionWithBuilderMember() ? copySetterBuilderBody() : beanCopySetterBody());
8182

82-
return builder.build();
83+
return Collections.singletonList(builder.build());
8384
}
8485

8586
private ParameterSpec mapWithEnumAsParameter() {

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/MemberSetters.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ interface MemberSetters {
2828

2929
List<MethodSpec> fluent(TypeName returnType);
3030

31-
MethodSpec beanStyle();
31+
List<MethodSpec> beanStyle();
3232
}
3333

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ModelBuilderSpecs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ private List<MethodSpec> accessors() {
204204
.forEach(m -> {
205205
accessors.add(accessorsFactory.beanStyleGetter(m));
206206
accessors.addAll(accessorsFactory.fluentSetters(m, builderInterfaceName()));
207-
accessors.add(accessorsFactory.beanStyleSetter(m));
207+
accessors.addAll(accessorsFactory.beanStyleSetters(m));
208208
accessors.addAll(accessorsFactory.convenienceSetters(m, builderInterfaceName()));
209209
});
210210

0 commit comments

Comments
 (0)