Skip to content

Commit c6d0f49

Browse files
committed
Add EnhancedType parameters to static builder methods of StaticTableSchema and StaticImmitableTableSchema
1 parent 69dcfc4 commit c6d0f49

File tree

9 files changed

+217
-20
lines changed

9 files changed

+217
-20
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": "Add EnhancedType parameters to static builder methods of StaticTableSchema and StaticImmitableTableSchema"
6+
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ static <T> StaticTableSchema.Builder<T> builder(Class<T> itemClass) {
5353
return StaticTableSchema.builder(itemClass);
5454
}
5555

56+
/**
57+
* Returns a builder for the {@link StaticTableSchema} implementation of this interface which allows all attributes,
58+
* tags and table structure to be directly declared in the builder.
59+
*
60+
* @param itemType The {@link EnhancedType} of the item this {@link TableSchema} will map records to.
61+
* @param <T> The type of the item this {@link TableSchema} will map records to.
62+
* @return A newly initialized {@link StaticTableSchema.Builder}.
63+
*/
64+
static <T> StaticTableSchema.Builder<T> builder(EnhancedType<T> itemType) {
65+
return StaticTableSchema.builder(itemType);
66+
}
67+
5668
/**
5769
* Returns a builder for the {@link StaticImmutableTableSchema} implementation of this interface which allows all
5870
* attributes, tags and table structure to be directly declared in the builder.
@@ -69,6 +81,22 @@ static <T, B> StaticImmutableTableSchema.Builder<T, B> builder(Class<T> immutabl
6981
return StaticImmutableTableSchema.builder(immutableItemClass, immutableBuilderClass);
7082
}
7183

84+
/**
85+
* Returns a builder for the {@link StaticImmutableTableSchema} implementation of this interface which allows all
86+
* attributes, tags and table structure to be directly declared in the builder.
87+
*
88+
* @param immutableItemType The {@link EnhancedType} of the immutable item this {@link TableSchema} will map records to.
89+
* @param immutableBuilderType The {@link EnhancedType} of the class that can be used to construct immutable items this
90+
* {@link TableSchema} maps records to.
91+
* @param <T> The type of the immutable item this {@link TableSchema} will map records to.
92+
* @param <B> The type of the builder used by this {@link TableSchema} to construct immutable items with.
93+
* @return A newly initialized {@link StaticImmutableTableSchema.Builder}
94+
*/
95+
static <T, B> StaticImmutableTableSchema.Builder<T, B> builder(EnhancedType<T> immutableItemType,
96+
EnhancedType<B> immutableBuilderType) {
97+
return StaticImmutableTableSchema.builder(immutableItemType, immutableBuilderType);
98+
}
99+
72100
/**
73101
* Scans a bean class that has been annotated with DynamoDb bean annotations and then returns a
74102
* {@link BeanTableSchema} implementation of this interface that can map records to and from items of that bean

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ public static <T, B, R> Builder<T, B, R> builder(Class<T> itemClass,
9191
return new Builder<>(attributeType);
9292
}
9393

94+
/**
95+
* Constructs a new builder for this class using supplied types.
96+
* @param itemType The {@link EnhancedType} of the immutable item that this attribute composes.
97+
* @param builderType The {@link EnhancedType} of the builder for the immutable item that this attribute composes.
98+
* @param attributeType A {@link EnhancedType} that represents the type of the value this attribute stores.
99+
* @return A new typed builder for an attribute.
100+
*/
101+
public static <T, B, R> Builder<T, B, R> builder(EnhancedType<T> itemType,
102+
EnhancedType<B> builderType,
103+
EnhancedType<R> attributeType) {
104+
return new Builder<>(attributeType);
105+
}
106+
94107
/**
95108
* Constructs a new builder for this class using supplied types.
96109
* @param itemClass The class of the item that this attribute composes.

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,17 @@ private StaticAttribute(Builder<T, R> builder) {
6969
* @return A new typed builder for an attribute.
7070
*/
7171
public static <T, R> Builder<T, R> builder(Class<T> itemClass, EnhancedType<R> attributeType) {
72-
return new Builder<>(itemClass, attributeType);
72+
return new Builder<>(EnhancedType.of(itemClass), attributeType);
73+
}
74+
75+
/**
76+
* Constructs a new builder for this class using supplied types.
77+
* @param itemType The {@link EnhancedType} of the item that this attribute composes.
78+
* @param attributeType A {@link EnhancedType} that represents the type of the value this attribute stores.
79+
* @return A new typed builder for an attribute.
80+
*/
81+
public static <T, R> Builder<T, R> builder(EnhancedType<T> itemType, EnhancedType<R> attributeType) {
82+
return new Builder<>(itemType, attributeType);
7383
}
7484

7585
/**
@@ -79,7 +89,7 @@ public static <T, R> Builder<T, R> builder(Class<T> itemClass, EnhancedType<R> a
7989
* @return A new typed builder for an attribute.
8090
*/
8191
public static <T, R> Builder<T, R> builder(Class<T> itemClass, Class<R> attributeClass) {
82-
return new Builder<>(itemClass, EnhancedType.of(attributeClass));
92+
return new Builder<>(EnhancedType.of(itemClass), EnhancedType.of(attributeClass));
8393
}
8494

8595
/**
@@ -146,8 +156,8 @@ ImmutableAttribute<T, T, R> toImmutableAttribute() {
146156
public static final class Builder<T, R> {
147157
private final ImmutableAttribute.Builder<T, T, R> delegateBuilder;
148158

149-
private Builder(Class<T> itemClass, EnhancedType<R> type) {
150-
this.delegateBuilder = ImmutableAttribute.builder(itemClass, itemClass, type);
159+
private Builder(EnhancedType<T> itemType, EnhancedType<R> type) {
160+
this.delegateBuilder = ImmutableAttribute.builder(itemType, itemType, type);
151161
}
152162

153163
private Builder(ImmutableAttribute.Builder<T, T, R> delegateBuilder) {

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ private StaticImmutableTableSchema(Builder<T, B> builder) {
210210
this.newBuilderSupplier = builder.newBuilderSupplier;
211211
this.buildItemFunction = builder.buildItemFunction;
212212
this.tableMetadata = tableMetadataBuilder.build();
213-
this.itemType = EnhancedType.of(builder.itemClass);
213+
this.itemType = builder.itemType;
214214
}
215215

216216
/**
@@ -220,7 +220,18 @@ private StaticImmutableTableSchema(Builder<T, B> builder) {
220220
* @return A newly initialized builder
221221
*/
222222
public static <T, B> Builder<T, B> builder(Class<T> itemClass, Class<B> builderClass) {
223-
return new Builder<>(itemClass, builderClass);
223+
return new Builder<>(EnhancedType.of(itemClass), EnhancedType.of(builderClass));
224+
}
225+
226+
/**
227+
* Creates a builder for a {@link StaticImmutableTableSchema} typed to specific immutable data item class.
228+
* @param itemType The {@link EnhancedType} of the immutable data item class object that the
229+
* {@link StaticImmutableTableSchema} is to map to.
230+
* @param builderType The builder {@link EnhancedType} that can be used to construct instances of the immutable data item.
231+
* @return A newly initialized builder
232+
*/
233+
public static <T, B> Builder<T, B> builder(EnhancedType<T> itemType, EnhancedType<B> builderType) {
234+
return new Builder<>(itemType, builderType);
224235
}
225236

226237
/**
@@ -230,8 +241,8 @@ public static <T, B> Builder<T, B> builder(Class<T> itemClass, Class<B> builderC
230241
*/
231242
@NotThreadSafe
232243
public static final class Builder<T, B> {
233-
private final Class<T> itemClass;
234-
private final Class<B> builderClass;
244+
private final EnhancedType<T> itemType;
245+
private final EnhancedType<B> builderType;
235246
private final List<ResolvedImmutableAttribute<T, B>> additionalAttributes = new ArrayList<>();
236247
private final List<FlattenedMapper<T, B, ?>> flattenedMappers = new ArrayList<>();
237248

@@ -242,9 +253,9 @@ public static final class Builder<T, B> {
242253
private List<AttributeConverterProvider> attributeConverterProviders =
243254
Collections.singletonList(ConverterProviderResolver.defaultConverterProvider());
244255

245-
private Builder(Class<T> itemClass, Class<B> builderClass) {
246-
this.itemClass = itemClass;
247-
this.builderClass = builderClass;
256+
private Builder(EnhancedType<T> itemType, EnhancedType<B> builderType) {
257+
this.itemType = itemType;
258+
this.builderType = builderType;
248259
}
249260

250261
/**
@@ -285,7 +296,7 @@ public <R> Builder<T, B> addAttribute(EnhancedType<R> attributeType,
285296
Consumer<ImmutableAttribute.Builder<T, B, R>> immutableAttribute) {
286297

287298
ImmutableAttribute.Builder<T, B, R> builder =
288-
ImmutableAttribute.builder(itemClass, builderClass, attributeType);
299+
ImmutableAttribute.builder(itemType, builderType, attributeType);
289300
immutableAttribute.accept(builder);
290301
return addAttribute(builder.build());
291302
}

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,16 @@ private StaticTableSchema(Builder<T> builder) {
7575
* @return A newly initialized builder
7676
*/
7777
public static <T> Builder<T> builder(Class<T> itemClass) {
78-
return new Builder<>(itemClass);
78+
return new Builder<>(EnhancedType.of(itemClass));
79+
}
80+
81+
/**
82+
* Creates a builder for a {@link StaticTableSchema} typed to specific data item class.
83+
* @param itemType The {@link EnhancedType} of the data item class object that the {@link StaticTableSchema} is to map to.
84+
* @return A newly initialized builder
85+
*/
86+
public static <T> Builder<T> builder(EnhancedType<T> itemType) {
87+
return new Builder<>(itemType);
7988
}
8089

8190
/**
@@ -85,11 +94,11 @@ public static <T> Builder<T> builder(Class<T> itemClass) {
8594
@NotThreadSafe
8695
public static final class Builder<T> {
8796
private final StaticImmutableTableSchema.Builder<T, T> delegateBuilder;
88-
private final Class<T> itemClass;
97+
private final EnhancedType<T> itemType;
8998

90-
private Builder(Class<T> itemClass) {
91-
this.delegateBuilder = StaticImmutableTableSchema.builder(itemClass, itemClass);
92-
this.itemClass = itemClass;
99+
private Builder(EnhancedType<T> itemType) {
100+
this.delegateBuilder = StaticImmutableTableSchema.builder(itemType, itemType);
101+
this.itemType = itemType;
93102
}
94103

95104
/**
@@ -130,7 +139,7 @@ public Builder<T> attributes(Collection<StaticAttribute<T, ?>> staticAttributes)
130139
*/
131140
public <R> Builder<T> addAttribute(EnhancedType<R> attributeType,
132141
Consumer<StaticAttribute.Builder<T, R>> staticAttribute) {
133-
StaticAttribute.Builder<T, R> builder = StaticAttribute.builder(itemClass, attributeType);
142+
StaticAttribute.Builder<T, R> builder = StaticAttribute.builder(itemType, attributeType);
134143
staticAttribute.accept(builder);
135144
this.delegateBuilder.addAttribute(builder.build().toImmutableAttribute());
136145
return this;
@@ -142,7 +151,7 @@ public <R> Builder<T> addAttribute(EnhancedType<R> attributeType,
142151
*/
143152
public <R> Builder<T> addAttribute(Class<R> attributeClass,
144153
Consumer<StaticAttribute.Builder<T, R>> staticAttribute) {
145-
StaticAttribute.Builder<T, R> builder = StaticAttribute.builder(itemClass, attributeClass);
154+
StaticAttribute.Builder<T, R> builder = StaticAttribute.builder(itemType, EnhancedType.of(attributeClass));
146155
staticAttribute.accept(builder);
147156
this.delegateBuilder.addAttribute(builder.build().toImmutableAttribute());
148157
return this;

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem;
2424
import software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema;
2525
import software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableTableSchema;
26+
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticImmutableTableSchema;
2627
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableSchema;
2728
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.InvalidBean;
2829
import software.amazon.awssdk.enhanced.dynamodb.mapper.testbeans.SimpleBean;
@@ -33,11 +34,31 @@ public class TableSchemaTest {
3334
public ExpectedException exception = ExpectedException.none();
3435

3536
@Test
36-
public void builder_constructsStaticTableSchemaBuilder() {
37+
public void builder_constructsStaticTableSchemaBuilder_fromClass() {
3738
StaticTableSchema.Builder<FakeItem> builder = TableSchema.builder(FakeItem.class);
3839
assertThat(builder).isNotNull();
3940
}
4041

42+
@Test
43+
public void builder_constructsStaticTableSchemaBuilder_fromEnhancedType() {
44+
StaticTableSchema.Builder<FakeItem> builder = TableSchema.builder(EnhancedType.of(FakeItem.class));
45+
assertThat(builder).isNotNull();
46+
}
47+
48+
@Test
49+
public void builder_constructsStaticImmutableTableSchemaBuilder_fromClass() {
50+
StaticImmutableTableSchema.Builder<SimpleImmutable, SimpleImmutable.Builder> builder =
51+
TableSchema.builder(SimpleImmutable.class, SimpleImmutable.Builder.class);
52+
assertThat(builder).isNotNull();
53+
}
54+
55+
@Test
56+
public void builder_constructsStaticImmutableTableSchemaBuilder_fromEnhancedType() {
57+
StaticImmutableTableSchema.Builder<SimpleImmutable, SimpleImmutable.Builder> builder =
58+
TableSchema.builder(EnhancedType.of(SimpleImmutable.class), EnhancedType.of(SimpleImmutable.Builder.class));
59+
assertThat(builder).isNotNull();
60+
}
61+
4162
@Test
4263
public void fromBean_constructsBeanTableSchema() {
4364
BeanTableSchema<SimpleBean> beanBeanTableSchema = TableSchema.fromBean(SimpleBean.class);

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,17 @@ public void itemType_returnsCorrectClass() {
801801
assertThat(FakeItem.getTableSchema().itemType(), is(equalTo(EnhancedType.of(FakeItem.class))));
802802
}
803803

804+
@Test
805+
public void itemType_returnsCorrectClassWhenBuiltWithEnhancedType() {
806+
StaticImmutableTableSchema<FakeMappedItem, FakeMappedItem.Builder> tableSchema =
807+
StaticImmutableTableSchema.builder(EnhancedType.of(FakeMappedItem.class),
808+
EnhancedType.of(FakeMappedItem.Builder.class))
809+
.newItemBuilder(FakeMappedItem::builder, FakeMappedItem.Builder::build)
810+
.build();
811+
812+
assertThat(tableSchema.itemType(), is(equalTo(EnhancedType.of(FakeMappedItem.class))));
813+
}
814+
804815
@Test
805816
public void getTableMetadata_hasCorrectFields() {
806817
TableMetadata tableMetadata = FakeItemWithSort.getTableSchema().tableMetadata();
@@ -1538,6 +1549,51 @@ public void noConverterProvider_handlesCorrectly_whenAttributeConvertersAreSuppl
15381549
assertThat(resultMap.get("aString").s(), is(expectedString));
15391550
}
15401551

1552+
@Test
1553+
public void builder_canBuildForGenericClassType() {
1554+
class EntityEnvelope<T> {
1555+
private final T entity;
1556+
1557+
public EntityEnvelope(T entity) {
1558+
this.entity = entity;
1559+
}
1560+
1561+
public T entity() {
1562+
return this.entity;
1563+
}
1564+
}
1565+
1566+
class EntityEnvelopeBuilder<T> {
1567+
private T entity;
1568+
1569+
public void setEntity(T entity) {
1570+
this.entity = entity;
1571+
}
1572+
1573+
public EntityEnvelope<T> build() {
1574+
return new EntityEnvelope<>(this.entity);
1575+
}
1576+
}
1577+
1578+
StaticImmutableTableSchema<EntityEnvelope<String>, EntityEnvelopeBuilder<String>> envelopeTableSchema =
1579+
StaticImmutableTableSchema.builder(new EnhancedType<EntityEnvelope<String>>() {},
1580+
new EnhancedType<EntityEnvelopeBuilder<String>>() {})
1581+
.newItemBuilder(EntityEnvelopeBuilder::new, EntityEnvelopeBuilder::build)
1582+
.addAttribute(String.class,
1583+
a -> a.name("entity")
1584+
.getter(EntityEnvelope::entity)
1585+
.setter(EntityEnvelopeBuilder::setEntity))
1586+
.build();
1587+
1588+
EntityEnvelope<String> testEnvelope = new EntityEnvelope<>("test-value");
1589+
1590+
Map<String, AttributeValue> expectedMap =
1591+
Collections.singletonMap("entity", AttributeValue.fromS("test-value"));
1592+
1593+
assertThat(envelopeTableSchema.itemToMap(testEnvelope, false), equalTo(expectedMap));
1594+
assertThat(envelopeTableSchema.mapToItem(expectedMap).entity(), equalTo("test-value"));
1595+
}
1596+
15411597
private <R> void verifyAttribute(EnhancedType<R> attributeType,
15421598
Consumer<StaticAttribute.Builder<FakeMappedItem, R>> staticAttribute,
15431599
FakeMappedItem fakeMappedItem,

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,16 @@ public void itemType_returnsCorrectClass() {
799799
assertThat(FakeItem.getTableSchema().itemType(), is(equalTo(EnhancedType.of(FakeItem.class))));
800800
}
801801

802+
@Test
803+
public void itemType_returnsCorrectClassWhenBuiltWithEnhancedType() {
804+
StaticTableSchema<FakeMappedItem> tableSchema = StaticTableSchema.builder(EnhancedType.of(FakeMappedItem.class))
805+
.newItemSupplier(FakeMappedItem::new)
806+
.attributes(ATTRIBUTES)
807+
.build();
808+
809+
assertThat(tableSchema.itemType(), is(equalTo(EnhancedType.of(FakeMappedItem.class))));
810+
}
811+
802812
@Test
803813
public void getTableMetadata_hasCorrectFields() {
804814
TableMetadata tableMetadata = FakeItemWithSort.getTableSchema().tableMetadata();
@@ -1485,6 +1495,39 @@ public void noConverterProvider_handlesCorrectly_whenAttributeConvertersAreSuppl
14851495
assertThat(resultMap.get("aString").s(), is(expectedString));
14861496
}
14871497

1498+
@Test
1499+
public void builder_canBuildForGenericClassType() {
1500+
class EntityEnvelope<T> {
1501+
private T entity;
1502+
1503+
public T getEntity() {
1504+
return this.entity;
1505+
}
1506+
1507+
public void setEntity(T entity) {
1508+
this.entity = entity;
1509+
}
1510+
}
1511+
1512+
StaticTableSchema<EntityEnvelope<String>> envelopeTableSchema =
1513+
StaticTableSchema.builder(new EnhancedType<EntityEnvelope<String>>() {})
1514+
.newItemSupplier(EntityEnvelope::new)
1515+
.addAttribute(String.class,
1516+
a -> a.name("entity")
1517+
.getter(EntityEnvelope::getEntity)
1518+
.setter(EntityEnvelope::setEntity))
1519+
.build();
1520+
1521+
EntityEnvelope<String> testEnvelope = new EntityEnvelope<>();
1522+
testEnvelope.setEntity("test-value");
1523+
1524+
Map<String, AttributeValue> expectedMap =
1525+
Collections.singletonMap("entity", AttributeValue.fromS("test-value"));
1526+
1527+
assertThat(envelopeTableSchema.itemToMap(testEnvelope, false), equalTo(expectedMap));
1528+
assertThat(envelopeTableSchema.mapToItem(expectedMap).getEntity(), equalTo("test-value"));
1529+
}
1530+
14881531
private <R> void verifyAttribute(EnhancedType<R> attributeType,
14891532
Consumer<StaticAttribute.Builder<FakeMappedItem, R>> staticAttribute,
14901533
FakeMappedItem fakeMappedItem,

0 commit comments

Comments
 (0)