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

org.zodiac.netty.marshallers.JsonObjectMarshaller Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
package org.zodiac.netty.marshallers;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import org.zodiac.commons.util.serialize.JsonUtil;
import org.zodiac.sdk.toolkit.marshallers.Marshaller;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;

import java.io.DataInput;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

final class JsonObjectMarshaller implements Marshaller {

    private static final Set> wrapTypes = Collections.>unmodifiableSet(new HashSet<>(Arrays.asList(new Class[]{
        Boolean.class, Boolean.TYPE, Double.class, Double.TYPE, Float.class, Float.TYPE, String.class, CharSequence.class,
        Byte.class, Byte.TYPE, Long.class, Long.TYPE, Integer.class, Integer.TYPE, Short.class, Short.TYPE,
        Number.class
    })));

    private final ObjectMapper mapper;
    private final ObjectMapper wrappingMapper;

    JsonObjectMarshaller() {
        this(JsonUtil.getDefaultObjectMapper());
    }

    JsonObjectMarshaller(ObjectMapper mapper) {
        this.mapper = mapper;
        this.wrappingMapper = mapper.copy().configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true)
                .configure(SerializationFeature.WRAP_ROOT_VALUE, true);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Object read(ByteBuf data, Object[] hints) throws IOException {
        Class type = NettyContentMarshallers.findHint(Class.class, hints, Object.class);
        ObjectMapper m;
        boolean wrapped = false;
        if (typeNeedsWrapping(type)) {
            m = wrappingMapper;
            wrapped = true;
        } else {
            m = mapper;
        }
        try (final ByteBufInputStream in = new ByteBufInputStream(data)) {
            if (wrapped) {
                Map map = mapper.readValue((DataInput) in, Map.class);
                Object o = map.get(type.getSimpleName());
                if (o == null) {
                    return null;
                }
                return type.cast(o);
            }
            return m.readValue((DataInput) in, type);
        }
    }

    @Override
    public void write(Object obj, ByteBuf into, Object[] hints) throws IOException {
        ObjectMapper m;
        if (needsWrapping(obj)) {
            m = wrappingMapper;
        } else {
            m = mapper;
        }
        try (final ByteBufOutputStream out = new ByteBufOutputStream(into)) {
            m.writeValue((OutputStream) out, obj);
            into.resetReaderIndex();
        }
    }

    private boolean needsWrapping(Object o) {
        if (o == null) {
            return true;
        }
        return typeNeedsWrapping(o.getClass());
    }

    private boolean typeNeedsWrapping(Class type) {
        boolean result = false;
        if (type.isArray() && wrapTypes.contains(type.getComponentType())) {
            result = true;
        } else {
            for (Class t : wrapTypes) {
                if (type == t || type.isAssignableFrom(t)) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy