Skip to content

Commit b95947d

Browse files
authored
ddb-enhanced: Annotated immutable class introspector now ignores 'toBuilder' method allowing easier integration with libraries that auto-generate this method on immutable data classes. (aws#2735)
1 parent 1450398 commit b95947d

File tree

4 files changed

+98
-3
lines changed

4 files changed

+98
-3
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "DynamoDB Enhanced Client",
3+
"contributor": "bmaizels",
4+
"type": "feature",
5+
"description": "Annotated immutable class introspector now ignores 'toBuilder' method allowing easier integration with libraries that auto-generate this method on immutable data classes."
6+
}

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/immutable/ImmutableIntrospector.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Optional;
2525
import java.util.Set;
2626
import java.util.stream.Collectors;
27+
import java.util.stream.Stream;
2728
import software.amazon.awssdk.annotations.SdkInternalApi;
2829
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbIgnore;
2930
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
@@ -32,20 +33,23 @@
3233
public class ImmutableIntrospector {
3334
private static final String BUILD_METHOD = "build";
3435
private static final String BUILDER_METHOD = "builder";
36+
private static final String TO_BUILDER_METHOD = "toBuilder";
3537
private static final String GET_PREFIX = "get";
3638
private static final String IS_PREFIX = "is";
3739
private static final String SET_PREFIX = "set";
3840

41+
private static final String[] METHODS_TO_IGNORE = { TO_BUILDER_METHOD };
42+
3943
private static volatile ImmutableIntrospector INSTANCE = null;
4044

4145
// Methods from Object are commonly overridden and confuse the mapper, automatically exclude any method with a name
4246
// that matches a method defined on Object.
4347
private final Set<String> namesToExclude;
4448

4549
private ImmutableIntrospector() {
46-
this.namesToExclude = Collections.unmodifiableSet(Arrays.stream(Object.class.getMethods())
47-
.map(Method::getName)
48-
.collect(Collectors.toSet()));
50+
this.namesToExclude = Collections.unmodifiableSet(
51+
Stream.concat(Arrays.stream(Object.class.getMethods()).map(Method::getName), Arrays.stream(METHODS_TO_IGNORE))
52+
.collect(Collectors.toSet()));
4953
}
5054

5155
public static <T> ImmutableInfo<T> getImmutableInfo(Class<T> immutableClass) {

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.FlattenedImmutableImmutable;
3434
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.NestedImmutable;
3535
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.NestedImmutableIgnoreNulls;
36+
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.ToBuilderImmutable;
3637
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
3738

3839
public class ImmutableTableSchemaTest {
@@ -281,4 +282,20 @@ public void dynamoDbIgnoreNulls_shouldOmitNulls() {
281282
assertThat(itemMap, hasEntry("innerBean1", expectedMapForInnerBean1));
282283
assertThat(itemMap.get("innerBean2").m(), hasEntry("attribute2", nullAttributeValue()));
283284
}
285+
286+
@Test
287+
public void toBuilderImmutable_ignoresToBuilderMethod() {
288+
ImmutableTableSchema<ToBuilderImmutable> toBuilderImmutableTableSchema =
289+
ImmutableTableSchema.create(ToBuilderImmutable.class);
290+
291+
ToBuilderImmutable toBuilderImmutable = ToBuilderImmutable.builder()
292+
.id("id-value")
293+
.attribute1("one")
294+
.build();
295+
296+
Map<String, AttributeValue> itemMap = toBuilderImmutableTableSchema.itemToMap(toBuilderImmutable, true);
297+
assertThat(itemMap.size(), is(2));
298+
assertThat(itemMap, hasEntry("id", stringValue("id-value")));
299+
assertThat(itemMap, hasEntry("attribute1", stringValue("one")));
300+
}
284301
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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 java.util.List;
19+
import java.util.Map;
20+
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
21+
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
22+
23+
@DynamoDbImmutable(builder = ToBuilderImmutable.Builder.class)
24+
public class ToBuilderImmutable {
25+
private final String id;
26+
private final String attribute1;
27+
28+
private ToBuilderImmutable(Builder b) {
29+
this.id = b.id;
30+
this.attribute1 = b.attribute1;
31+
}
32+
33+
@DynamoDbPartitionKey
34+
public String id() {
35+
return this.id;
36+
}
37+
38+
public String attribute1() {
39+
return attribute1;
40+
}
41+
42+
public Builder toBuilder() {
43+
return builder().id(this.id).attribute1(this.attribute1);
44+
}
45+
46+
public static Builder builder() {
47+
return new Builder();
48+
}
49+
50+
public static final class Builder {
51+
private String id;
52+
private String attribute1;
53+
54+
public Builder id(String id) {
55+
this.id = id;
56+
return this;
57+
}
58+
59+
public Builder attribute1(String attribute1) {
60+
this.attribute1 = attribute1;
61+
return this;
62+
}
63+
64+
public ToBuilderImmutable build() {
65+
return new ToBuilderImmutable(this);
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)