Skip to content

Commit 5c7b6dd

Browse files
Annotate and document members that are modeled as deprecated... (#2622)
* Annotate and document members that are modeled as deprecated... ...and add support for using customization to override specific members as deprecated. ## Motivation and Context As part of a recent change to repurpose the S3 CopyObjectRequest copySource parameter into more user-friendly parameters, we lacked the ability in our ShapeModifiersProcessor to also deprecate the old parameter name. Furthermore, after additional investigation, we also appear to not have been correctly honoring the different service-2.json models that tag certain members as deprecated. E.g., the following parameter is marked as deprecated: https://github.com/aws/aws-sdk-java-v2/blob/54fd5a69c74af0124e97830bef53b3690dfa2015/services/cloudwatchlogs/src/main/resources/codegen-resources/service-2.json#L1393-L1398 But the corresponding generated code and Javadoc (at the time of this writing) do not mark any of the member's methods as deprecated, or expose the deprecatedMessage: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchlogs/model/FilterLogEventsRequest.Builder.html#interleaved-java.lang.Boolean- ## Description * For service-2.json members that are marked as deprecated, correctly annotate and document these fields as deprecated in their various accessors and builder setters. * Add support to ShapeModifiersProcessor for customization.config files to be able to manually modify the `deprecated` and `deprecatedMessage` attributes. (A follow-up PR will propose marking the before-mentioned copySource parameter as deprecated.) ## Testing * Add a new operation with members that are modeled as deprecated and members that are modified as deprecated, and add accompanying expected generated code (see expected generated code for an example of how the fields are annotated as deprecated).
1 parent 54fd5a6 commit 5c7b6dd

File tree

15 files changed

+769
-11
lines changed

15 files changed

+769
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "AWS SDK for Java v2",
3+
"contributor": "",
4+
"type": "feature",
5+
"description": "Annotate and document members that are modeled as deprecated"
6+
}

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

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ protected final ShapeModel generateShapeModel(String javaClassName, String shape
7979
// contains the list of c2j member names that are required for this shape.
8080
shapeModel.setRequired(shape.getRequired());
8181
shapeModel.setDeprecated(shape.isDeprecated());
82+
shapeModel.setDeprecatedMessage(shape.getDeprecatedMessage());
8283
shapeModel.setWrapper(shape.isWrapper());
8384
shapeModel.withIsEventStream(shape.isEventstream());
8485
shapeModel.withIsEvent(shape.isEvent());
@@ -172,6 +173,7 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
172173
.withJsonValue(c2jMemberDefinition.getJsonvalue());
173174
memberModel.setDocumentation(c2jMemberDefinition.getDocumentation());
174175
memberModel.setDeprecated(c2jMemberDefinition.isDeprecated());
176+
memberModel.setDeprecatedMessage(c2jMemberDefinition.getDeprecatedMessage());
175177
memberModel.setSensitive(isSensitiveShapeOrContainer(c2jMemberDefinition, allC2jShapes));
176178
memberModel
177179
.withFluentGetterMethodName(namingStrategy.getFluentGetterMethodName(c2jMemberName, parentShape, shape))

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,13 @@ private void preprocessModifyShapeMembers(ServiceModel serviceModel, Shape shape
208208

209209
private void doModifyShapeMembers(ServiceModel serviceModel, Shape shape, String memberToModify,
210210
ModifyModelShapeModifier modifyModel) {
211-
211+
if (modifyModel.isDeprecated()) {
212+
Member member = shape.getMembers().get(memberToModify);
213+
member.setDeprecated(true);
214+
if (modifyModel.getDeprecatedMessage() != null) {
215+
member.setDeprecatedMessage(modifyModel.getDeprecatedMessage());
216+
}
217+
}
212218
// Currently only supports emitPropertyName which is to rename the member
213219
if (modifyModel.getEmitPropertyName() != null) {
214220
Member member = shape.getMembers().remove(memberToModify);

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

+26
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717

1818
public class ModifyModelShapeModifier {
1919

20+
/**
21+
* Indicates whether a member should be annotated as {@link Deprecated}.
22+
*/
23+
private boolean deprecated;
24+
25+
/**
26+
* The Javadoc message that will be included with the {@link Deprecated} annotation.
27+
*/
28+
private String deprecatedMessage;
29+
2030
/**
2131
* Indicates whether a renamed member should create getters and setters under the existing name
2232
*/
@@ -49,6 +59,22 @@ public class ModifyModelShapeModifier {
4959

5060
private String unmarshallLocationName;
5161

62+
public String getDeprecatedMessage() {
63+
return deprecatedMessage;
64+
}
65+
66+
public void setDeprecatedMessage(String deprecatedMessage) {
67+
this.deprecatedMessage = deprecatedMessage;
68+
}
69+
70+
public boolean isDeprecated() {
71+
return deprecated;
72+
}
73+
74+
public void setDeprecated(boolean deprecated) {
75+
this.deprecated = deprecated;
76+
}
77+
5278
public boolean isExistingNameDeprecated() {
5379
return existingNameDeprecated;
5480
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class MemberModel extends DocumentationModel {
5555
private ParameterHttpMapping http;
5656

5757
private boolean deprecated;
58+
59+
private String deprecatedMessage;
5860

5961
private ListModel listModel;
6062

@@ -301,6 +303,14 @@ public void setDeprecated(boolean deprecated) {
301303
this.deprecated = deprecated;
302304
}
303305

306+
public String getDeprecatedMessage() {
307+
return deprecatedMessage;
308+
}
309+
310+
public void setDeprecatedMessage(String deprecatedMessage) {
311+
this.deprecatedMessage = deprecatedMessage;
312+
}
313+
304314
public boolean isEventPayload() {
305315
return eventPayload;
306316
}

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

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class ShapeModel extends DocumentationModel implements HasDeprecation {
3737
private String shapeName;
3838
// the local variable name inside marshaller/unmarshaller implementation
3939
private boolean deprecated;
40+
private String deprecatedMessage;
4041
private String type;
4142
private List<String> required;
4243
private boolean hasPayloadMember;
@@ -94,6 +95,14 @@ public void setDeprecated(boolean deprecated) {
9495
this.deprecated = deprecated;
9596
}
9697

98+
public String getDeprecatedMessage() {
99+
return deprecatedMessage;
100+
}
101+
102+
public void setDeprecatedMessage(String deprecatedMessage) {
103+
this.deprecatedMessage = deprecatedMessage;
104+
}
105+
97106
public String getC2jName() {
98107
return c2jName;
99108
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class Member {
4141

4242
private boolean deprecated;
4343

44+
private String deprecatedMessage;
45+
4446
private boolean jsonvalue;
4547

4648
private String timestampFormat;
@@ -153,6 +155,14 @@ public void setDeprecated(boolean deprecated) {
153155
this.deprecated = deprecated;
154156
}
155157

158+
public String getDeprecatedMessage() {
159+
return deprecatedMessage;
160+
}
161+
162+
public void setDeprecatedMessage(String deprecatedMessage) {
163+
this.deprecatedMessage = deprecatedMessage;
164+
}
165+
156166
public boolean getJsonvalue() {
157167
return jsonvalue;
158168
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public class Shape {
5959
private boolean fault;
6060

6161
private boolean deprecated;
62+
63+
private String deprecatedMessage;
6264

6365
private boolean eventstream;
6466

@@ -260,6 +262,14 @@ public void setDeprecated(boolean deprecated) {
260262
this.deprecated = deprecated;
261263
}
262264

265+
public String getDeprecatedMessage() {
266+
return deprecatedMessage;
267+
}
268+
269+
public void setDeprecatedMessage(String deprecatedMessage) {
270+
this.deprecatedMessage = deprecatedMessage;
271+
}
272+
263273
public boolean isEventstream() {
264274
return eventstream;
265275
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static javax.lang.model.element.Modifier.FINAL;
1919
import static javax.lang.model.element.Modifier.PRIVATE;
2020
import static javax.lang.model.element.Modifier.PUBLIC;
21+
import static software.amazon.awssdk.codegen.poet.model.DeprecationUtils.checkDeprecated;
2122

2223
import com.squareup.javapoet.ClassName;
2324
import com.squareup.javapoet.CodeBlock;
@@ -509,7 +510,7 @@ private Stream<MethodSpec> memberGetters(MemberModel member) {
509510

510511
result.add(memberGetter(member));
511512

512-
return result.stream();
513+
return checkDeprecated(member, result).stream();
513514
}
514515

515516
private boolean shouldGenerateDeprecatedNameGetter(MemberModel member) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.codegen.poet.model;
17+
18+
import static java.util.stream.Collectors.toList;
19+
import static software.amazon.awssdk.codegen.internal.Constant.LF;
20+
21+
import com.squareup.javapoet.AnnotationSpec;
22+
import com.squareup.javapoet.MethodSpec;
23+
import java.util.List;
24+
import software.amazon.awssdk.codegen.model.intermediate.MemberModel;
25+
import software.amazon.awssdk.utils.StringUtils;
26+
27+
public final class DeprecationUtils {
28+
29+
private static final AnnotationSpec DEPRECATED = AnnotationSpec.builder(Deprecated.class).build();
30+
31+
private DeprecationUtils() {
32+
}
33+
34+
/**
35+
* If a given member is modeled as deprecated, add the {@link Deprecated} annotation to the method and, if the method
36+
* already has existing Javadoc, append a section with the {@code @deprecated} tag.
37+
*/
38+
public static MethodSpec checkDeprecated(MemberModel member, MethodSpec method) {
39+
if (!member.isDeprecated() || method.annotations.contains(DEPRECATED)) {
40+
return method;
41+
}
42+
MethodSpec.Builder builder = method.toBuilder().addAnnotation(DEPRECATED);
43+
if (!method.javadoc.isEmpty()) {
44+
builder.addJavadoc(LF + "@deprecated");
45+
if (StringUtils.isNotBlank(member.getDeprecatedMessage())) {
46+
builder.addJavadoc(" $L", member.getDeprecatedMessage());
47+
}
48+
}
49+
return builder.build();
50+
}
51+
52+
public static List<MethodSpec> checkDeprecated(MemberModel member, List<MethodSpec> methods) {
53+
return methods.stream().map(methodSpec -> checkDeprecated(member, methodSpec)).collect(toList());
54+
}
55+
}

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

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package software.amazon.awssdk.codegen.poet.model;
1717

1818
import static java.util.stream.Collectors.toList;
19+
import static software.amazon.awssdk.codegen.poet.model.DeprecationUtils.checkDeprecated;
1920

2021
import com.squareup.javapoet.ClassName;
2122
import com.squareup.javapoet.FieldSpec;
@@ -76,8 +77,10 @@ public TypeSpec builderInterface() {
7677

7778
shapeModel.getNonStreamingMembers()
7879
.forEach(m -> {
79-
builder.addMethods(accessorsFactory.fluentSetterDeclarations(m, builderInterfaceName()));
80-
builder.addMethods(accessorsFactory.convenienceSetterDeclarations(m, builderInterfaceName()));
80+
builder.addMethods(
81+
checkDeprecated(m, accessorsFactory.fluentSetterDeclarations(m, builderInterfaceName())));
82+
builder.addMethods(
83+
checkDeprecated(m, accessorsFactory.convenienceSetterDeclarations(m, builderInterfaceName())));
8184
});
8285

8386
if (isException()) {
@@ -212,13 +215,10 @@ private List<MethodSpec> accessors() {
212215
List<MethodSpec> accessors = new ArrayList<>();
213216
shapeModel.getNonStreamingMembers()
214217
.forEach(m -> {
215-
accessors.add(accessorsFactory.beanStyleGetter(m));
216-
217-
List<MethodSpec> fluentSetters = accessorsFactory.fluentSetters(m, builderInterfaceName());
218-
accessors.addAll(fluentSetters);
219-
220-
accessors.addAll(accessorsFactory.beanStyleSetters(m));
221-
accessors.addAll(accessorsFactory.convenienceSetters(m, builderInterfaceName()));
218+
accessors.add(checkDeprecated(m, accessorsFactory.beanStyleGetter(m)));
219+
accessors.addAll(checkDeprecated(m, accessorsFactory.fluentSetters(m, builderInterfaceName())));
220+
accessors.addAll(checkDeprecated(m, accessorsFactory.beanStyleSetters(m)));
221+
accessors.addAll(checkDeprecated(m, accessorsFactory.convenienceSetters(m, builderInterfaceName())));
222222
});
223223

224224
if (isException()) {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config

+10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
}
1919
}
2020
]
21+
},
22+
"OperationWithDeprecatedMemberRequest": {
23+
"modify": [
24+
{
25+
"MemberModifiedAsDeprecated": {
26+
"deprecated": true,
27+
"deprecatedMessage": "This field is modified as deprecated."
28+
}
29+
}
30+
]
2131
}
2232
},
2333
"underscoresInNameBehavior": "ALLOW"

0 commit comments

Comments
 (0)