Skip to content

Commit 9f34a96

Browse files
committed
Use actual member name for NULL
In DynamoDB, the "NULL" member of AttributeValue is customized to "NUL" because "null" is a reserved keyword. This has the effect of generating nul() and getNul() as getters, and nul(Boolean), and setNul(Boolean) as setters for the serializable builder class. If using the serializable builder class to map from a JSON string with the correct property name "NULL", it will not be recognized. To fix this, generate an additional setter with the correct name getNull().
1 parent 4a1e926 commit 9f34a96

File tree

10 files changed

+111
-2
lines changed

10 files changed

+111
-2
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,14 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
204204
memberModel.setRequired(isRequiredMember(c2jMemberName, parentShape));
205205
memberModel.setSynthetic(shape.isSynthetic());
206206

207+
if (c2jMemberDefinition.getAlternateBeanPropertyName() != null) {
208+
String alternatePropertyName = c2jMemberDefinition.getAlternateBeanPropertyName();
209+
210+
String setter = String.format("set%s", alternatePropertyName);
211+
212+
memberModel.setAdditionalBeanStyleSetterName(setter);
213+
}
214+
207215

208216
// Pass the xmlNameSpace from the member reference
209217
if (c2jMemberDefinition.getXmlNamespace() != null) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ private void doModifyShapeMembers(ServiceModel serviceModel, Shape shape, String
224224
member.setDeprecatedMessage(modifyModel.getDeprecatedMessage());
225225
}
226226
}
227+
228+
if (modifyModel.getAlternateBeanPropertyName() != null) {
229+
shape.getMembers().get(memberToModify).setAlternateBeanPropertyName(modifyModel.getAlternateBeanPropertyName());
230+
}
231+
227232
// Currently only supports emitPropertyName which is to rename the member
228233
if (modifyModel.getEmitPropertyName() != null) {
229234
Member member = shape.getMembers().remove(memberToModify);

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class ModifyModelShapeModifier {
4949
*/
5050
private String emitEnumValue;
5151

52+
private String alternateBeanPropertyName;
53+
5254
/**
5355
* Emit as a different primitive type. Used by AWS Budget Service to change string
5456
* to BigDecimal (see API-433).
@@ -143,4 +145,12 @@ public void setIgnoreDataTypeConversionFailures(boolean ignoreDataTypeConversion
143145
public boolean isIgnoreDataTypeConversionFailures() {
144146
return ignoreDataTypeConversionFailures;
145147
}
148+
149+
public String getAlternateBeanPropertyName() {
150+
return alternateBeanPropertyName;
151+
}
152+
153+
public void setAlternateBeanPropertyName(String alternateBeanPropertyName) {
154+
this.alternateBeanPropertyName = alternateBeanPropertyName;
155+
}
146156
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ public class MemberModel extends DocumentationModel {
9090

9191
private String beanStyleSetterName;
9292

93+
private String additionalBeanStyleSetterName;
94+
9395
private String unionEnumTypeName;
9496

9597
private boolean isJsonValue;
@@ -787,6 +789,19 @@ public boolean ignoreDataTypeConversionFailures() {
787789
return ignoreDataTypeConversionFailures;
788790
}
789791

792+
public String getAdditionalBeanStyleSetterName() {
793+
return additionalBeanStyleSetterName;
794+
}
795+
796+
public void setAdditionalBeanStyleSetterName(String additionalBeanStyleSetterName) {
797+
this.additionalBeanStyleSetterName = additionalBeanStyleSetterName;
798+
}
799+
800+
public MemberModel withAdditionalBeanStyleSetterName(String additionalBeanStyleSetterName) {
801+
setAdditionalBeanStyleSetterName(additionalBeanStyleSetterName);
802+
return this;
803+
}
804+
790805
@Override
791806
public boolean equals(Object o) {
792807
if (o == null || getClass() != o.getClass()) {
@@ -834,6 +849,7 @@ public boolean equals(Object o) {
834849
&& Objects.equals(fluentDeprecatedGetterMethodName, that.fluentDeprecatedGetterMethodName)
835850
&& Objects.equals(fluentDeprecatedSetterMethodName, that.fluentDeprecatedSetterMethodName)
836851
&& Objects.equals(deprecatedBeanStyleSetterMethodName, that.deprecatedBeanStyleSetterMethodName)
852+
&& Objects.equals(additionalBeanStyleSetterName, that.additionalBeanStyleSetterName)
837853
&& Objects.equals(contextParam, that.contextParam);
838854
}
839855

@@ -878,6 +894,8 @@ public int hashCode() {
878894
result = 31 * result + Objects.hashCode(deprecatedBeanStyleSetterMethodName);
879895
result = 31 * result + Objects.hashCode(contextParam);
880896
result = 31 * result + Boolean.hashCode(ignoreDataTypeConversionFailures);
897+
result = 31 * result + Objects.hashCode(additionalBeanStyleSetterName);
898+
881899
return result;
882900
}
883901
}

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
@@ -59,6 +59,8 @@ public class Member {
5959

6060
private String deprecatedName;
6161

62+
private String alternateBeanPropertyName;
63+
6264
private ContextParam contextParam;
6365

6466
public String getShape() {
@@ -236,4 +238,12 @@ public ContextParam getContextParam() {
236238
public void setContextParam(ContextParam contextParam) {
237239
this.contextParam = contextParam;
238240
}
241+
242+
public String getAlternateBeanPropertyName() {
243+
return alternateBeanPropertyName;
244+
}
245+
246+
public void setAlternateBeanPropertyName(String alternateBeanPropertyName) {
247+
this.alternateBeanPropertyName = alternateBeanPropertyName;
248+
}
239249
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import software.amazon.awssdk.codegen.model.intermediate.MemberModel;
2525
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
2626
import software.amazon.awssdk.codegen.poet.PoetExtension;
27+
import software.amazon.awssdk.utils.StringUtils;
2728

2829
class AccessorsFactory {
2930

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ public List<MethodSpec> beanStyle() {
128128
.build());
129129
}
130130

131+
String additionalSetter = memberModel().getAdditionalBeanStyleSetterName();
132+
if (StringUtils.isNotBlank(additionalSetter)) {
133+
MethodSpec.Builder methodBuilder = beanStyleSetterBuilder();
134+
methodBuilder.setName(additionalSetter);
135+
methods.add(methodBuilder.addCode(beanCopySetterBody())
136+
.build());
137+
}
138+
131139
return methods;
132140
}
133141

services/dynamodb/src/main/resources/codegen-resources/dynamodb/customization.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"modify": [
66
{
77
"NULL": {
8-
"emitPropertyName": "NUL"
8+
"emitPropertyName": "NUL",
9+
"alternateBeanPropertyName": "Null"
910
}
1011
}
1112
],

services/dynamodb/src/main/resources/codegen-resources/dynamodbstreams/customization.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"modify": [
66
{
77
"NULL": {
8-
"emitPropertyName": "NUL"
8+
"emitPropertyName": "NUL",
9+
"alternateBeanPropertyName": "Null"
910
}
1011
}
1112
],
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.services.dynamodb;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import com.fasterxml.jackson.core.JsonProcessingException;
21+
import com.fasterxml.jackson.databind.DeserializationFeature;
22+
import com.fasterxml.jackson.databind.MapperFeature;
23+
import com.fasterxml.jackson.databind.ObjectMapper;
24+
import org.junit.jupiter.api.BeforeAll;
25+
import org.junit.jupiter.api.Test;
26+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
27+
28+
public class AttributeValueTest {
29+
private static ObjectMapper mapper;
30+
31+
@BeforeAll
32+
public static void setup() {
33+
mapper = new ObjectMapper();
34+
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
35+
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
36+
}
37+
38+
@Test
39+
void serializableBuilderClass_jsonIsNullAttributeValue_deserializesCorrectly() throws JsonProcessingException {
40+
String nullAttributeValueJson = "{\"NULL\":true}";
41+
42+
AttributeValue.Builder builder = mapper.readValue(nullAttributeValueJson, AttributeValue.serializableBuilderClass());
43+
AttributeValue attr = builder.build();
44+
45+
assertThat(attr.nul()).isTrue();
46+
}
47+
}

0 commit comments

Comments
 (0)