All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.ugli.durian.j.json.jackson.JsonSerializer Maven / Gradle / Ivy

package se.ugli.durian.j.json.jackson;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import se.ugli.durian.j.dom.node.Attribute;
import se.ugli.durian.j.dom.node.Element;
import se.ugli.durian.j.json.jackson.fieldvaluefactories.ByValueFieldValueFactory;

public final class JsonSerializer {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final FieldValueFactory fieldValueFactory;

    private JsonSerializer(final FieldValueFactory fieldValueFactory) {
        this.fieldValueFactory = fieldValueFactory;
    }

    public static JsonSerializer apply() {
        return new JsonSerializer(new ByValueFieldValueFactory());
    }

    public static JsonSerializer apply(final FieldValueFactory fieldValueFactory) {
        return new JsonSerializer(fieldValueFactory);
    }

    public String serialize(final Element element) {
        try {
            final JsonNode jsonNode = createJsonNode(element);
            final StringWriter stringWriter = new StringWriter();
            objectMapper.writeValue(stringWriter, jsonNode);
            return stringWriter.toString();
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    private JsonNode createJsonNode(final Element element) {
        if (element instanceof JsonArrayElement)
            return createArrayFromArrayElement(element);
        final ObjectNode objectNode = objectMapper.createObjectNode();
        element.attributes().forEach(attribute -> {
            putAttribute(objectNode, attribute);
        });
        final Map> childElementNameMap = createElementNameMap(element);
        for (final String fieldName : childElementNameMap.keySet()) {
            final List childElementByName = childElementNameMap.get(fieldName);
            if (childElementByName.isEmpty())
                throw new IllegalStateException();
            else if (childElementByName.size() == 1)
                objectNode.set(fieldName, createJsonNode(childElementByName.get(0)));
            else {
                final ArrayNode arrayNode = objectNode.arrayNode();
                for (final Element arrayElement : childElementByName)
                    arrayNode.add(createJsonNode(arrayElement));
                objectNode.set(fieldName, arrayNode);
            }
        }
        return objectNode;
    }

    private static Map> createElementNameMap(final Element element) {
        final Map> map = new LinkedHashMap<>();
        element.elements().forEach(childElement -> {
            final String fieldName;
            if (childElement instanceof JsonArrayElement)
                fieldName = ((JsonArrayElement) childElement).arrayName;
            else
                fieldName = childElement.name();
            List list;
            if (map.containsKey(fieldName))
                list = map.get(fieldName);
            else {
                list = new ArrayList<>();
                map.put(fieldName, list);
            }
            list.add(childElement);
        });
        return map;
    }

    private void putAttribute(final ObjectNode objectNode, final Attribute attribute) {
        final String fieldName = attribute.name();
        final Object value = fieldValueFactory.create(attribute);
        if (value == null)
            objectNode.putNull(fieldName);
        else if (value instanceof Boolean)
            objectNode.put(fieldName, (Boolean) value);
        else if (value instanceof Long)
            objectNode.put(fieldName, (Long) value);
        else if (value instanceof Double)
            objectNode.put(fieldName, (Double) value);
        else
            objectNode.put(fieldName, value.toString());
    }

    private JsonNode createArrayFromArrayElement(final Element element) {
        final ArrayNode arrayNode = objectMapper.createArrayNode();
        element.elements().forEach(childElement -> {
            arrayNode.add(createJsonNode(childElement));
        });
        element.texts().forEach(text -> {
            final Object textValue = fieldValueFactory.create(text);
            if (textValue == null)
                arrayNode.addNull();
            else if (textValue instanceof Boolean)
                arrayNode.add((Boolean) textValue);
            else if (textValue instanceof Long)
                arrayNode.add((Long) textValue);
            else if (textValue instanceof Double)
                arrayNode.add((Double) textValue);
            else
                arrayNode.add(textValue.toString());
        });
        return arrayNode;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy