Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.flipkart.zjsonpatch.JsonPatch;
import java.util.Map;
Expand All @@ -11,14 +11,13 @@
import uk.co.compendiumdev.thingifier.api.ermodelconversion.JsonThing;
import uk.co.compendiumdev.thingifier.api.http.ThingifierRequestContext;
import uk.co.compendiumdev.thingifier.api.http.bodyparser.ApiBodyFields;
import uk.co.compendiumdev.thingifier.api.http.bodyparser.JsonBodyValueConverter;
import uk.co.compendiumdev.thingifier.apiconfig.EntityPatchUpdateStyle;
import uk.co.compendiumdev.thingifier.core.domain.definitions.EntityDefinition;
import uk.co.compendiumdev.thingifier.core.domain.instances.EntityInstance;

public final class EntityPatchDocumentMapper {

private static final ObjectMapper JSON = new ObjectMapper();

private final ThingifierApiRuntime runtime;
private final ThingWriteRequestMapper writeMapper;

Expand Down Expand Up @@ -71,7 +70,7 @@ private ThingWriteRequestMapping mapJsonMergePatch(

JsonNode patchDocument;
try {
patchDocument = JSON.readTree(rawBody);
patchDocument = JsonBodyValueConverter.readTree(rawBody);
} catch (JsonProcessingException e) {
return malformedPatch("Malformed JSON Merge Patch document");
}
Expand All @@ -95,7 +94,7 @@ private ThingWriteRequestMapping mapJsonPatch(

JsonNode patchDocument;
try {
patchDocument = JSON.readTree(rawBody);
patchDocument = JsonBodyValueConverter.readTree(rawBody);
} catch (JsonProcessingException e) {
return malformedPatch("Malformed JSON Patch document");
}
Expand All @@ -122,19 +121,16 @@ private JsonNode applyMergePatch(final JsonNode target, final JsonNode patch) {
ObjectNode result =
target != null && target.isObject()
? ((ObjectNode) target).deepCopy()
: JSON.createObjectNode();
patch.fields()
.forEachRemaining(
entry -> {
if (entry.getValue().isNull()) {
result.remove(entry.getKey());
} else {
result.set(
entry.getKey(),
applyMergePatch(
result.get(entry.getKey()), entry.getValue()));
}
});
: JsonNodeFactory.instance.objectNode();
for (Map.Entry<String, JsonNode> entry : patch.properties()) {
if (entry.getValue().isNull()) {
result.remove(entry.getKey());
} else {
result.set(
entry.getKey(),
applyMergePatch(result.get(entry.getKey()), entry.getValue()));
}
}
return result;
}

Expand All @@ -145,12 +141,13 @@ private ThingWriteRequestMapping mapReplacement(
}

return writeMapper.mapPatchReplacingFields(
route, ApiBodyFields.fromMap(JSON.convertValue(patchedDocument, Map.class)));
route,
ApiBodyFields.fromMap(JsonBodyValueConverter.objectNodeAsMap(patchedDocument)));
}

private JsonNode jsonFor(final EntityInstance instance) {
try {
return JSON.readTree(
return JsonBodyValueConverter.readTree(
new JsonThing(runtime.apiConfig().jsonOutput())
.asJsonObject(instance)
.toString());
Expand Down Expand Up @@ -190,7 +187,7 @@ private ParseResult parseJsonObject(final String rawBody, final boolean allowEmp

JsonNode document;
try {
document = JSON.readTree(body);
document = JsonBodyValueConverter.readTree(body);
} catch (JsonProcessingException e) {
return ParseResult.error(malformedPatch("Malformed JSON document"));
}
Expand All @@ -201,7 +198,7 @@ private ParseResult parseJsonObject(final String rawBody, final boolean allowEmp
}

return ParseResult.bodyFields(
ApiBodyFields.fromMap(JSON.convertValue(document, Map.class)));
ApiBodyFields.fromMap(JsonBodyValueConverter.objectNodeAsMap(document)));
}

private ThingWriteRequestMapping malformedPatch(final String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ private BodyFieldValue.SourceType sourceTypeFor(final String sourceType) {
if ("NUMERIC".equals(sourceType)) {
return BodyFieldValue.SourceType.NUMERIC;
}
if ("OBJECT".equals(sourceType)) {
return BodyFieldValue.SourceType.OBJECT;
}
if ("ARRAY".equals(sourceType)) {
return BodyFieldValue.SourceType.ARRAY;
}
if ("NULL".equals(sourceType)) {
return BodyFieldValue.SourceType.NULL;
}
return BodyFieldValue.SourceType.SOMETHING_ELSE;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package uk.co.compendiumdev.thingifier.api.http.bodyparser;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -35,16 +37,8 @@ public Map<String, String> asStringMap() {
for (String key : fields.keySet()) {
Object value = fields.get(key);

if (value instanceof Boolean) {
stringsInMap.put(key, String.valueOf(value));
}

if (value instanceof String) {
stringsInMap.put(key, (String) value);
}

if (value instanceof Double) {
stringsInMap.put(key, String.valueOf(value));
if (isScalarValue(value)) {
stringsInMap.put(key, stringValue(value));
}
}
return stringsInMap;
Expand Down Expand Up @@ -77,17 +71,8 @@ public List<ApiBodyField> topLevelFields() {
private List<Map.Entry<String, String>> flattenToStringMap(
final String prefixKey, final Object value) {
List<Map.Entry<String, String>> stringsInMap = new ArrayList<>();
if (value instanceof String) {
stringsInMap.add(new AbstractMap.SimpleEntry<>(prefixKey, (String) value));
}
if (value instanceof Double) {
stringsInMap.add(new AbstractMap.SimpleEntry<>(prefixKey, String.valueOf(value)));
}
if (value instanceof Boolean) {
stringsInMap.add(new AbstractMap.SimpleEntry<>(prefixKey, String.valueOf(value)));
}
if (value instanceof Integer) {
stringsInMap.add(new AbstractMap.SimpleEntry<>(prefixKey, String.valueOf(value)));
if (isScalarValue(value)) {
stringsInMap.add(new AbstractMap.SimpleEntry<>(prefixKey, stringValue(value)));
}

String separator = "";
Expand All @@ -102,8 +87,8 @@ private List<Map.Entry<String, String>> flattenToStringMap(
stringsInMap.addAll(nestedValues);
}
}
if (value instanceof ArrayList) {
for (Object nestedValue : (ArrayList) value) {
if (value instanceof List) {
for (Object nestedValue : (List) value) {
List<Map.Entry<String, String>> nestedValues =
flattenToStringMap(prefixKey + separator, nestedValue);
stringsInMap.addAll(nestedValues);
Expand All @@ -112,29 +97,61 @@ private List<Map.Entry<String, String>> flattenToStringMap(
return stringsInMap;
}

private String stringValue(final Object value) {
private static boolean isScalarValue(final Object value) {
return value instanceof String || value instanceof Boolean || value instanceof Number;
}

private static String stringValue(final Object value) {
if (value instanceof String) {
return (String) value;
}
if (value instanceof Boolean || value instanceof Double || value instanceof Integer) {
if (value instanceof BigDecimal) {
return ((BigDecimal) value).toPlainString();
}
if (value instanceof Boolean || value instanceof Number) {
return String.valueOf(value);
}
return "";
}

private String sourceTypeName(final Object value) {
public static String sourceTypeNameFor(final Object value) {
if (value == null) {
return "NULL";
}
if (value instanceof String) {
return "STRING";
}
if (value instanceof Boolean) {
return "BOOLEAN";
}
if (value instanceof Integer) {
if (isIntegralNumber(value)) {
return "INTEGER";
}
if (value instanceof Float || value instanceof Double) {
if (isDecimalNumber(value)) {
return "NUMERIC";
}
if (value instanceof Map) {
return "OBJECT";
}
if (value instanceof List) {
return "ARRAY";
}
return "Something Else";
}

private static boolean isIntegralNumber(final Object value) {
return value instanceof Byte
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long
|| value instanceof BigInteger;
}

private static boolean isDecimalNumber(final Object value) {
return value instanceof Float || value instanceof Double || value instanceof BigDecimal;
}

private String sourceTypeName(final Object value) {
return sourceTypeNameFor(value);
}
}
Loading
Loading