Skip to content

Commit b67ed0a

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

File tree

3 files changed

+114
-4
lines changed

3 files changed

+114
-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,90 @@
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<Animal> animalConverter = EnumAttributeConverter.create(Animal.class);
29+
AttributeValue attribute = animalConverter.transformFrom(Animal.CAT);
30+
31+
assertThat(attribute.s()).isEqualTo("I am a Cat!");
32+
}
33+
34+
@Test
35+
public void transformToDefault_returnsEnum() {
36+
EnumAttributeConverter<Animal> animalConverter = EnumAttributeConverter.create(Animal.class);
37+
38+
Animal dog = animalConverter.transformTo(AttributeValue.fromS("I am a Dog!"));
39+
40+
assertThat(dog).isEqualTo(Animal.DOG);
41+
}
42+
43+
@Test
44+
public void transformFromWithNames_returnsName() {
45+
EnumAttributeConverter<Person> personConverter = EnumAttributeConverter.createWithNameAsKeys(Person.class);
46+
AttributeValue attribute = personConverter.transformFrom(Person.JANE);
47+
48+
assertThat(attribute.s()).isEqualTo("JANE");
49+
50+
assertThat(Person.JANE.toString()).isEqualTo("I am a cool person");
51+
}
52+
53+
@Test
54+
public void transformToWithNames_returnsEnum() {
55+
EnumAttributeConverter<Person> personConverter = EnumAttributeConverter.createWithNameAsKeys(Person.class);
56+
57+
Person john = personConverter.transformTo(AttributeValue.fromS("JOHN"));
58+
59+
assertThat(Person.JOHN.toString()).isEqualTo("I am a cool person");
60+
61+
assertThat(john).isEqualTo(Person.JOHN);
62+
}
63+
64+
private static enum Animal {
65+
DOG,
66+
CAT;
67+
68+
@Override
69+
public String toString() {
70+
switch (this) {
71+
case DOG:
72+
return "I am a Dog!";
73+
case CAT:
74+
return "I am a Cat!";
75+
default:
76+
return null;
77+
}
78+
}
79+
}
80+
81+
private static enum Person {
82+
JOHN,
83+
JANE;
84+
85+
@Override
86+
public String toString() {
87+
return "I am a cool person";
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)