Skip to content

Instantly share code, notes, and snippets.

@aaronanderson
Created January 23, 2018 16:03
Show Gist options
  • Save aaronanderson/96153c4c9f463dfbc47218b8065f1828 to your computer and use it in GitHub Desktop.
Save aaronanderson/96153c4c9f463dfbc47218b8065f1828 to your computer and use it in GitHub Desktop.
DynamoDBUtil AttributeValue to Json mapper with a transformer
package com.mercer.digital.wd.intlibrary;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
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 final String EXCLUDE = "@@EXCLUDE@@";
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) {
return toJson(attributeValues, Collections.EMPTY_MAP);
}
public static JsonArray toJson(List<AttributeValue> attributeValues, Map<String, Function<String, String>> transformers) {
if (attributeValues == null) {
return null;
}
JsonArrayBuilder valueBuilder = Json.createArrayBuilder();
for (AttributeValue a : attributeValues) {
addJson(toJson(a, transformers), valueBuilder);
}
return valueBuilder.build();
}
public static JsonObject toJson(Map<String, AttributeValue> attributeValues) {
return toJson(attributeValues, Collections.EMPTY_MAP);
}
public static JsonObject toJson(Map<String, AttributeValue> attributeValues, Map<String, Function<String, String>> transformers) {
if (attributeValues == null) {
return null;
}
JsonObjectBuilder valueBuilder = Json.createObjectBuilder();
for (Map.Entry<String, AttributeValue> a : attributeValues.entrySet()) {
addJson(a.getKey(), toJson(a.getValue(), transformers), valueBuilder, transformers);
}
return valueBuilder.build();
}
public static String transformedValue(String key, String value, Map<String, Function<String, String>> transformers) {
Function<String, String> transformer = transformers.get(key);
if (transformer != null) {
value = transformer.apply(value);
}
return value;
}
public static void addJson(String key, Object value, JsonObjectBuilder object, Map<String, Function<String, String>> transformers) {
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) {
String newValue = transformedValue(key, (String) value, transformers);
if (!EXCLUDE.equals(newValue)) {
if (newValue == null) {
object.add(key, JsonValue.NULL);
} else {
object.add(key, newValue);
}
}
} 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 addJson(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, Map<String, Function<String, String>> transformers) {
// 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(), transformers);
}
if (attributeValue.l() != null) {
return toJson(attributeValue.l(), transformers);
}
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment