Skip to content

Commit f10404f

Browse files
committed
EnumAttributeConverter: enums can be identified by toString() or name(). toString() is the default for backward compatibility
1 parent 58278f6 commit f10404f

File tree

3 files changed

+137
-4
lines changed

3 files changed

+137
-4
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "Amazon DynamoDB",
3+
"contributor": "martinKindall",
4+
"type": "bugfix",
5+
"description": "Created static method EnumAttributeConverter::createWithNameAsKeys which creates a converter based on the Enum::name method to identify enums, rather than Enum::toString. This is preferable because Enum::name is final and cannot be overwritten, as opposed to Enum::toString. EnumAttributeConverter::create is kept as it is, for backward compatibility."
6+
}

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/EnumAttributeConverter.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Collections;
2020
import java.util.LinkedHashMap;
2121
import java.util.Map;
22+
import java.util.function.Function;
2223
import software.amazon.awssdk.annotations.SdkInternalApi;
2324
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter;
2425
import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType;
@@ -33,6 +34,12 @@
3334
* This stores values in DynamoDB as a string.
3435
*
3536
* <p>
37+
* Use EnumAttributeConverter::create in order to use Enum::toString as the enum identifier
38+
*
39+
* <p>
40+
* Use EnumAttributeConverter::createWithNameAsKeys in order to use Enum::name as the enum identifier
41+
*
42+
* <p>
3643
* This can be created via {@link #create(Class)}.
3744
*/
3845
@SdkInternalApi
@@ -41,23 +48,30 @@ public class EnumAttributeConverter<T extends Enum<T>> implements AttributeConve
4148
private final Class<T> enumClass;
4249
private final Map<String, T> enumValueMap;
4350

44-
private EnumAttributeConverter(Class<T> enumClass) {
51+
private final Function<T, String> keyExtractor;
52+
53+
private EnumAttributeConverter(Class<T> enumClass, Function<T, String> keyExtractor) {
4554
this.enumClass = enumClass;
55+
this.keyExtractor = keyExtractor;
4656

4757
Map<String, T> mutableEnumValueMap = new LinkedHashMap<>();
4858
Arrays.stream(enumClass.getEnumConstants())
49-
.forEach(enumConstant -> mutableEnumValueMap.put(enumConstant.toString(), enumConstant));
59+
.forEach(enumConstant -> mutableEnumValueMap.put(keyExtractor.apply(enumConstant), enumConstant));
5060

5161
this.enumValueMap = Collections.unmodifiableMap(mutableEnumValueMap);
5262
}
5363

5464
public static <T extends Enum<T>> EnumAttributeConverter<T> create(Class<T> enumClass) {
55-
return new EnumAttributeConverter<>(enumClass);
65+
return new EnumAttributeConverter<>(enumClass, Enum::toString);
66+
}
67+
68+
public static <T extends Enum<T>> EnumAttributeConverter<T> createWithNameAsKeys(Class<T> enumClass) {
69+
return new EnumAttributeConverter<>(enumClass, Enum::name);
5670
}
5771

5872
@Override
5973
public AttributeValue transformFrom(T input) {
60-
return AttributeValue.builder().s(input.toString()).build();
74+
return AttributeValue.builder().s(keyExtractor.apply(input)).build();
6175
}
6276

6377
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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.converters.attribute;
17+
18+
import org.junit.jupiter.api.Test;
19+
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnumAttributeConverter;
20+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
24+
public class EnumAttributeConverterTest {
25+
26+
@Test
27+
public void transformFromDefault_returnsToString() {
28+
EnumAttributeConverter<Vehicle> vehicleConverter = EnumAttributeConverter.create(Vehicle.class);
29+
AttributeValue attribute = vehicleConverter.transformFrom(Vehicle.TRUCK);
30+
31+
assertThat(attribute.s()).isEqualTo("TRUCK");
32+
}
33+
34+
@Test
35+
public void transformToDefault_returnsEnum() {
36+
EnumAttributeConverter<Vehicle> vehicleConverter = EnumAttributeConverter.create(Vehicle.class);
37+
38+
Vehicle bike = vehicleConverter.transformTo(AttributeValue.fromS("BIKE"));
39+
40+
assertThat(bike).isEqualTo(Vehicle.BIKE);
41+
}
42+
43+
@Test
44+
public void transformFromDefault_returnsToString_2() {
45+
EnumAttributeConverter<Animal> animalConverter = EnumAttributeConverter.create(Animal.class);
46+
AttributeValue attribute = animalConverter.transformFrom(Animal.CAT);
47+
48+
assertThat(attribute.s()).isEqualTo("I am a Cat!");
49+
}
50+
51+
@Test
52+
public void transformToDefault_returnsEnum_2() {
53+
EnumAttributeConverter<Animal> animalConverter = EnumAttributeConverter.create(Animal.class);
54+
55+
Animal dog = animalConverter.transformTo(AttributeValue.fromS("I am a Dog!"));
56+
57+
assertThat(dog).isEqualTo(Animal.DOG);
58+
}
59+
60+
@Test
61+
public void transformFromWithNames_returnsName() {
62+
EnumAttributeConverter<Person> personConverter = EnumAttributeConverter.createWithNameAsKeys(Person.class);
63+
AttributeValue attribute = personConverter.transformFrom(Person.JANE);
64+
65+
assertThat(attribute.s()).isEqualTo("JANE");
66+
67+
assertThat(Person.JANE.toString()).isEqualTo("I am a cool person");
68+
}
69+
70+
@Test
71+
public void transformToWithNames_returnsEnum() {
72+
EnumAttributeConverter<Person> personConverter = EnumAttributeConverter.createWithNameAsKeys(Person.class);
73+
74+
Person john = personConverter.transformTo(AttributeValue.fromS("JOHN"));
75+
76+
assertThat(Person.JOHN.toString()).isEqualTo("I am a cool person");
77+
78+
assertThat(john).isEqualTo(Person.JOHN);
79+
}
80+
81+
private static enum Vehicle {
82+
CAR,
83+
BIKE,
84+
TRUCK
85+
}
86+
87+
private static enum Animal {
88+
DOG,
89+
CAT;
90+
91+
@Override
92+
public String toString() {
93+
switch (this) {
94+
case DOG:
95+
return "I am a Dog!";
96+
case CAT:
97+
return "I am a Cat!";
98+
default:
99+
return null;
100+
}
101+
}
102+
}
103+
104+
private static enum Person {
105+
JOHN,
106+
JANE;
107+
108+
@Override
109+
public String toString() {
110+
return "I am a cool person";
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)