-
-
Save aaronanderson/ef6d319220d0ff938fa3c1013c4e80de to your computer and use it in GitHub Desktop.
import java.math.BigDecimal; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import javax.json.Json; | |
import javax.json.JsonArray; | |
import javax.json.JsonArrayBuilder; | |
import javax.json.JsonNumber; | |
import javax.json.JsonObject; | |
import javax.json.JsonObjectBuilder; | |
import javax.json.JsonString; | |
import javax.json.JsonValue; | |
import software.amazon.awssdk.services.dynamodb.model.AttributeValue; | |
public class DynamoDBUtil { | |
public static void addList(String key, JsonObjectBuilder objectBuilder, List<JsonObject> items) { | |
if (!items.isEmpty()) { | |
JsonArrayBuilder builder = Json.createArrayBuilder(); | |
items.forEach(i -> builder.add(i)); | |
objectBuilder.add(key, builder.build()); | |
} | |
} | |
public static JsonArray toJson(List<AttributeValue> attributeValues) { | |
if (attributeValues == null) { | |
return null; | |
} | |
JsonArrayBuilder valueBuilder = Json.createArrayBuilder(); | |
for (AttributeValue a : attributeValues) { | |
add(toJson(a), valueBuilder); | |
} | |
return valueBuilder.build(); | |
} | |
public static JsonObject toJson(Map<String, AttributeValue> attributeValues) { | |
if (attributeValues == null) { | |
return null; | |
} | |
JsonObjectBuilder valueBuilder = Json.createObjectBuilder(); | |
for (Map.Entry<String, AttributeValue> a : attributeValues.entrySet()) { | |
add(a.getKey(), toJson(a.getValue()), valueBuilder); | |
} | |
return valueBuilder.build(); | |
} | |
public static void add(String key, Object value, JsonObjectBuilder object) { | |
if (value instanceof JsonValue) { | |
object.add(key, (JsonValue) value); | |
// with json-p 1.0 can't create JsonString or JsonNumber so simply setting JsonValue not an option. | |
} else if (value instanceof String) { | |
object.add(key, (String) value); | |
} else if (value instanceof BigDecimal) { | |
object.add(key, (BigDecimal) value); | |
} else if (value instanceof Boolean) { | |
object.add(key, (Boolean) value); | |
} else if (value.equals(JsonValue.NULL)) { | |
object.addNull(key); | |
} | |
} | |
public static void add(Object value, JsonArrayBuilder array) { | |
if (value instanceof JsonValue) { | |
array.add((JsonValue) value); | |
} else if (value instanceof String) { | |
array.add((String) value); | |
} else if (value instanceof BigDecimal) { | |
array.add((BigDecimal) value); | |
} else if (value instanceof Boolean) { | |
array.add((Boolean) value); | |
} else if (value.equals(JsonValue.NULL)) { | |
array.addNull(); | |
} | |
} | |
public static Object toJson(AttributeValue attributeValue) { | |
// with json-p 1.1 Json.createValue() can be used. | |
if (attributeValue == null) { | |
return null; | |
} | |
if (attributeValue.s() != null) { | |
return attributeValue.s(); | |
} | |
if (attributeValue.m() != null) { | |
return toJson(attributeValue.m()); | |
} | |
if (attributeValue.l() != null) { | |
return toJson(attributeValue.l()); | |
} | |
if (attributeValue.n() != null) { | |
return new BigDecimal(attributeValue.n()); | |
} | |
if (attributeValue.bool() != null) { | |
// return attributeValue.bool() ? JsonValue.TRUE : JsonValue.FALSE; | |
return attributeValue.bool(); | |
} | |
if (attributeValue.nul() != null && attributeValue.nul()) { | |
return JsonValue.NULL; | |
} | |
/* if (attributeValue.b() != null) { | |
* return Base64.getEncoder().encodeToString(attributeValue.b().array()); | |
* } */ | |
return null; | |
} | |
public static Map<String, AttributeValue> toAttribute(JsonObject jsonObject) { | |
Map<String, AttributeValue> attribute = new HashMap<>(); | |
jsonObject.entrySet().forEach(e -> { | |
attribute.put(e.getKey(), toAttribute(e.getValue())); | |
}); | |
return attribute; | |
} | |
public static List<AttributeValue> toAttribute(JsonArray jsonArray) { | |
List<AttributeValue> attributes = new LinkedList<>(); | |
jsonArray.forEach(e -> { | |
attributes.add(toAttribute(e)); | |
}); | |
return attributes; | |
} | |
public static AttributeValue toAttribute(JsonValue jsonValue) { | |
if (jsonValue == null) { | |
return null; | |
} | |
switch (jsonValue.getValueType()) { | |
case STRING: | |
return AttributeValue.builder().s(((JsonString) jsonValue).getString()).build(); | |
case OBJECT: | |
return AttributeValue.builder().m(toAttribute((JsonObject) jsonValue)).build(); | |
case ARRAY: | |
return AttributeValue.builder().l(toAttribute((JsonArray) jsonValue)).build(); | |
case NUMBER: | |
return AttributeValue.builder().n(((JsonNumber) jsonValue).toString()).build(); | |
case TRUE: | |
return AttributeValue.builder().bool(true).build(); | |
case FALSE: | |
return AttributeValue.builder().bool(false).build(); | |
case NULL: | |
return AttributeValue.builder().nul(true).build(); | |
} | |
return null; | |
} | |
} |
Thanks! That code has the same problem, though. There's a check for emptiness to distinguish maps and lists, but those are allowed to be empty, contrary to the set types. I found the solution here: aws/aws-sdk-java-v2#865. You have to check for instanceof SdkAutoConstructList/SdkAutoConstructMap instead of isEmpty().
All paths of inquiry on this topic lead back to this gist 👍 so I am posting a link to a Jackson JSON Serializer which may be useful: https://gist.github.com/nickman/991dea808b6f43e7346d6d570f3c9ffe
Hello, the new version DynamoDBUtil.java had a error with the list of string, line 124 - 126:
if (!attributeValue.ss().isEmpty()) {
return attributeValue.ss();
}
But i can solution with this code:
if (!attributeValue.ss().isEmpty()) {
JsonArrayBuilder valueBuilder = Json.createArrayBuilder();
for (String element : attributeValue.ss()) {
valueBuilder.add(element);
}
return valueBuilder.build();
}
Maybe exists a better way, but i dont have more time for think, really thanks for that DynamoDBUtil code.
This code was based on an older version of the AWS SDK 2.0 beta. Here is a more recent version: DynamoDBUtil.java