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

com.aliyun.datahub.client.http.protocol.ProtocolConverterFactory Maven / Gradle / Ivy

The newest version!
package com.aliyun.datahub.client.http.protocol;

import com.aliyun.datahub.client.http.protocol.converter.EmptyConverterFactory;
import com.aliyun.datahub.client.http.protocol.converter.PbConverterFactory;
import com.aliyun.datahub.client.model.BaseProtobufModel;
import com.aliyun.datahub.client.model.BaseResult;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import org.jetbrains.annotations.Nullable;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.*;

public class ProtocolConverterFactory extends Converter.Factory {
    private final static JacksonConverterFactory jsonConvertFactory =
        JacksonConverterFactory.create(new ObjectMapper() {{
            setSerializationInclusion(JsonInclude.Include.NON_NULL);
            disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            disable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        }});

    private final static Map, Boolean> EMPTY_CLASS = new HashMap<>();

    public static ProtocolConverterFactory create() {
        return new ProtocolConverterFactory();
    }

    @Nullable
    @Override
    public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (!(type instanceof Class)) {
            return null;
        }

        ClassType classType = parseClassType((Class) type);
        switch (classType) {
            case T_JSON:
                return jsonConvertFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
            case T_PB:
                return PbConverterFactory.requestConverter();
            case T_EMPTY:
                return EmptyConverterFactory.requestConverter();
            default:
                return null;
        }
    }

    @Nullable
    @Override
    public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (!(type instanceof Class)) {
            return null;
        }

        Class cls = (Class) type;
        ClassType classType = parseClassType(cls);
        switch (classType) {
            case T_JSON:
                return jsonConvertFactory.responseBodyConverter(type, annotations, retrofit);
            case T_PB:
                return PbConverterFactory.responseConverter((Class) cls);
            case T_EMPTY:
                return EmptyConverterFactory.responseConverter((Class) cls);
            default:
                return null;
        }
    }

    private ClassType parseClassType(Class cls) {
        // check pb first
        if (BaseProtobufModel.class.isAssignableFrom(cls)) {
            return ClassType.T_PB;
        }

        if (BaseResult.class.isAssignableFrom(cls) && isEmptyBody(cls)) {
            return ClassType.T_EMPTY;
        }

        return ClassType.T_JSON;
    }

    private boolean isEmptyBody(Class cls) {
        Boolean bRet = EMPTY_CLASS.get(cls);
        if (bRet == null) {
            synchronized (EMPTY_CLASS) {
                bRet = EMPTY_CLASS.get(cls);
                if (bRet == null) {
                    bRet = checkEmptyBody(cls);
                    EMPTY_CLASS.put(cls, bRet);
                }
            }
        }
        return bRet;
    }

    private boolean checkEmptyBody(Class cls) {
        List fields = getAllFields(cls);
        if (fields.size() >= 1) {
            int dataFields = 0;
            for (Field field : fields) {
                if (!"requestId".equalsIgnoreCase(field.getName()) &&
                        !field.getName().contains("$") &&
                        !Modifier.isStatic(field.getModifiers())) {
                    ++dataFields;
                }
            }
            return dataFields == 0;
        }
        return false;
    }

    private List getAllFields(Class cls) {
        List fields = new ArrayList<>() ;
        while (cls != null) {
            fields.addAll(Arrays.asList(cls.getDeclaredFields()));
            cls = cls.getSuperclass();
        }
        return fields;
    }

    private enum ClassType {
        T_ERROR,
        T_EMPTY,
        T_JSON,
        T_PB
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy