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

io.katharsis.jackson.serializer.BaseResponseSerializer Maven / Gradle / Ivy

There is a newer version: 2.6.3
Show newest version
package io.katharsis.jackson.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import io.katharsis.jackson.serializer.include.IncludedRelationshipExtractor;
import io.katharsis.jackson.serializer.include.ResourceDigest;
import io.katharsis.resource.registry.ResourceRegistry;
import io.katharsis.response.*;

import java.io.IOException;
import java.util.*;

/**
 * Serializes top-level JSON object and provides ability to include compound documents
 */
public class BaseResponseSerializer extends JsonSerializer {

    private static final String INCLUDED_FIELD_NAME = "included";
    private static final String DATA_FIELD_NAME = "data";
    private static final String META_FIELD_NAME = "meta";
    private static final String LINKS_FIELD_NAME = "links";
    private static final String ERRORS_FIELD_NAME = "errors";

    private final IncludedRelationshipExtractor includedRelationshipExtractor;

    public BaseResponseSerializer(ResourceRegistry resourceRegistry) {
        this.includedRelationshipExtractor = new IncludedRelationshipExtractor(resourceRegistry);
    }

    @Override
    public void serialize(BaseResponseContext context, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        JsonApiResponse response = context.getResponse();

        gen.writeStartObject();

        if (isLinkageContainer(context)) {
            gen.writeObjectField(DATA_FIELD_NAME, response.getEntity());
        } else {
            writeResponseWithResources(context, gen);
        }

        if (response.getMetaInformation() != null) {
            gen.writeObjectField(META_FIELD_NAME, response.getMetaInformation());
        }
        if (response.getLinksInformation() != null) {
            gen.writeObjectField(LINKS_FIELD_NAME, response.getLinksInformation());
        }
        if (response.getErrors() != null) {
            gen.writeObjectField(ERRORS_FIELD_NAME, response.getErrors());
        }

        gen.writeEndObject();
    }

    private boolean isLinkageContainer(BaseResponseContext context) {
        if (context instanceof ResourceResponseContext) {
            return context.getResponse().getEntity() instanceof LinkageContainer;
        } else if (context instanceof CollectionResponseContext) {
            Iterable data = (Iterable) context.getResponse().getEntity();
            if (data == null) {
                return false;
            } else {
                Iterator iterator = data.iterator();
                return iterator.hasNext() && iterator.next() instanceof LinkageContainer;
            }
        } else {
            throw new IllegalArgumentException(String.format("JsonApiResponse can be either %s or %s. Got %s",
                    ResourceResponseContext.class, CollectionResponseContext.class, context.getClass()));
        }
    }

    private void writeResponseWithResources(BaseResponseContext value, JsonGenerator gen) throws IOException {
        Map includedResources;
        if (value instanceof ResourceResponseContext) {
            includedResources = serializeSingle((ResourceResponseContext) value, gen);
        } else if (value instanceof CollectionResponseContext) {
            includedResources = serializeResourceCollection((CollectionResponseContext) value, gen);
        } else {
            throw new IllegalArgumentException(String.format("JsonApiResponse can be either %s or %s. Got %s",
                    ResourceResponseContext.class, CollectionResponseContext.class, value.getClass()));
        }

        gen.writeObjectField(INCLUDED_FIELD_NAME, includedResources.values());
    }

    private Map serializeSingle(ResourceResponseContext responseContext, JsonGenerator gen)
            throws IOException {
        Object value = responseContext.getResponse().getEntity();
        gen.writeObjectField(DATA_FIELD_NAME, new Container(value, responseContext, ContainerType.TOP));

        if (value != null) {
            return includedRelationshipExtractor.extractIncludedResources(value, responseContext);
        } else {
            return Collections.emptyMap();
        }
    }

    private Map serializeResourceCollection(CollectionResponseContext responseContext, JsonGenerator gen)
            throws IOException {
        Iterable values = (Iterable) responseContext.getResponse().getEntity();
        Map includedFields = new HashMap();
        List containers = new ArrayList();

        if (values == null) {
            values = Collections.emptyList();
        }

        for (Object value : values) {
            //noinspection unchecked
            includedFields.putAll(includedRelationshipExtractor.extractIncludedResources(value, responseContext));
            containers.add(new Container(value, responseContext, ContainerType.TOP));
        }

        gen.writeObjectField(DATA_FIELD_NAME, containers);

        return includedFields;
    }

    public Class handledType() {
        return BaseResponseContext.class;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy