Skip to content

Commit dfc6406

Browse files
committed
issue #5039 - added support for fluent setters in dynamodb enhanced client
1 parent 7ca84b8 commit dfc6406

File tree

4 files changed

+111
-0
lines changed

4 files changed

+111
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "Amazon DynamoDB Enhanced Client",
4+
"contributor": "",
5+
"description": "Added support for fluent setters in bean descriptors when the default setter is missing."
6+
}

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchema.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ private static <T> StaticTableSchema<T> createStaticTableSchema(Class<T> beanCla
182182

183183
try {
184184
beanInfo = Introspector.getBeanInfo(beanClass);
185+
enhanceDescriptorsWithFluentSetters(beanClass, beanInfo);
185186
} catch (IntrospectionException e) {
186187
throw new IllegalArgumentException(e);
187188
}
@@ -225,6 +226,34 @@ private static <T> StaticTableSchema<T> createStaticTableSchema(Class<T> beanCla
225226
return builder.build();
226227
}
227228

229+
// Enhance beanInfo descriptors with fluent setter when the default set method is absent
230+
private static <T> void enhanceDescriptorsWithFluentSetters(Class<T> beanClass, BeanInfo beanInfo) {
231+
Arrays.stream(beanInfo.getPropertyDescriptors())
232+
.filter(descriptor -> descriptor.getWriteMethod() == null)
233+
.forEach(descriptor -> findFluentSetter(beanClass, descriptor.getName())
234+
.ifPresent(method -> {
235+
try {
236+
descriptor.setWriteMethod(method);
237+
} catch (IntrospectionException e) {
238+
throw new RuntimeException("Failed to set write method for " + descriptor.getName(), e);
239+
}
240+
}));
241+
}
242+
243+
private static Optional<Method> findFluentSetter(Class<?> beanClass, String propertyName) {
244+
String setterName = "set" + capitalize(propertyName);
245+
246+
return Arrays.stream(beanClass.getMethods())
247+
.filter(m -> m.getName().equals(setterName)
248+
&& m.getParameterCount() == 1
249+
&& m.getReturnType().equals(beanClass))
250+
.findFirst();
251+
}
252+
253+
private static String capitalize(String name) {
254+
return Character.toUpperCase(name.charAt(0)) + name.substring(1);
255+
}
256+
228257
private static AttributeConfiguration resolveAttributeConfiguration(PropertyDescriptor propertyDescriptor) {
229258
boolean shouldPreserveEmptyObject = getPropertyAnnotation(propertyDescriptor,
230259
DynamoDbPreserveEmptyObject.class) != null;

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchemaTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.ExtendedBean;
5656
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FlattenedBeanBean;
5757
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FlattenedImmutableBean;
58+
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FluentSetterBean;
5859
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.IgnoredAttributeBean;
5960
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.InvalidBean;
6061
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.ListBean;
@@ -1160,4 +1161,22 @@ public void emptyConverterProviderList_correct_whenAttributeConvertersAreSupplie
11601161
assertThat(reverse.getId(), is(equalTo("id-value-custom")));
11611162
assertThat(reverse.getIntegerAttribute(), is(equalTo(133)));
11621163
}
1164+
1165+
@Test
1166+
public void fluentSetterBean_correctlyMapsBeanAttributes() {
1167+
BeanTableSchema<FluentSetterBean> beanTableSchema =
1168+
BeanTableSchema.create(FluentSetterBean.class);
1169+
1170+
FluentSetterBean fluentSetterBean = new FluentSetterBean()
1171+
.setAttribute1(1)
1172+
.setAttribute2("testAttribute2")
1173+
.setAttribute3("testAttribute3");
1174+
1175+
Map<String, AttributeValue> itemMap = beanTableSchema.itemToMap(fluentSetterBean, false);
1176+
1177+
assertThat(itemMap.size(), is(3));
1178+
assertThat(itemMap, hasEntry("attribute1", numberValue(1)));
1179+
assertThat(itemMap, hasEntry("attribute2", stringValue("testAttribute2")));
1180+
assertThat(itemMap, hasEntry("attribute3", stringValue("testAttribute3")));
1181+
}
11631182
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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.enhanced.dynamodb.mapper.testbeans;
17+
18+
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
19+
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
20+
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
21+
22+
@DynamoDbBean
23+
public class FluentSetterBean {
24+
25+
private Integer attribute1;
26+
private String attribute2;
27+
private String attribute3;
28+
29+
@DynamoDbPartitionKey
30+
public Integer getAttribute1() {
31+
return attribute1;
32+
}
33+
34+
public FluentSetterBean setAttribute1(Integer attribute1) {
35+
this.attribute1 = attribute1;
36+
return this;
37+
}
38+
39+
@DynamoDbSortKey
40+
public String getAttribute2() {
41+
return attribute2;
42+
}
43+
44+
public FluentSetterBean setAttribute2(String attribute2) {
45+
this.attribute2 = attribute2;
46+
return this;
47+
}
48+
49+
public String getAttribute3() {
50+
return attribute3;
51+
}
52+
53+
public FluentSetterBean setAttribute3(String attribute3) {
54+
this.attribute3 = attribute3;
55+
return this;
56+
}
57+
}

0 commit comments

Comments
 (0)