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, RequestBody> 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 extends BaseProtobufModel>) cls);
case T_EMPTY:
return EmptyConverterFactory.responseConverter((Class extends BaseResult>) 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
}
}