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

com.aliyun.datahub.client.http.converter.ProtobufConverterFactory Maven / Gradle / Ivy

There is a newer version: 2.25.6
Show newest version
package com.aliyun.datahub.client.http.converter;

import com.google.protobuf.Message;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

import javax.annotation.Nullable;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ProtobufConverterFactory extends Converter.Factory {
    private boolean enablePbCrc;

    public ProtobufConverterFactory(boolean enablePbCrc) {
        this.enablePbCrc = enablePbCrc;
    }

    public static ProtobufConverterFactory create(boolean enableCrc) {
        return new ProtobufConverterFactory(enableCrc);
    }

    @Nullable
    @Override
    @SuppressWarnings("unchecked")
    public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (!(type instanceof Class)) {
            return null;
        }
        Class cls = (Class) type;
        if (!isAssignableFrom(cls)) {
            return null;
        }
        return new ProtobufResponseBodyConverter<>(enablePbCrc, (Class) cls);
    }

    @Nullable
    @Override
    public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (!(type instanceof Class)) {
            return null;
        }
        Class cls = (Class) type;
        if (!isAssignableFrom(cls)) {
            return null;
        }
        return new ProtobufRequestBodyConverter<>(enablePbCrc);
    }

    private boolean isAssignableFrom(Class type) {
        return BaseProtobufModel.class.isAssignableFrom(type);
    }

    private static class ProtobufResponseBodyConverter implements Converter {
        private final static Map, Method> METHOD_CACHE = new ConcurrentHashMap<>();

        private boolean enablePbCrc;
        private Class cls;

        public ProtobufResponseBodyConverter(boolean enablePbCrc, Class cls) {
            this.enablePbCrc = enablePbCrc;
            this.cls = cls;
        }

        @Nullable
        @Override
        public T convert(ResponseBody value) throws IOException {
            try {
                MessageInputStream buffer = new MessageInputStream(value.byteStream(), enablePbCrc);
                Message.Builder builder = (Message.Builder) getNewBuilder(cls).invoke(cls);
                Message message = builder.mergeFrom(buffer).build();
                T model = cls.newInstance();
                model.setMessage(message);
                return model;
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            } finally {
                value.close();
            }
        }

        private Method getNewBuilder(Class aClass) throws NoSuchMethodException {
            Method builder = METHOD_CACHE.get(aClass);
            if (builder == null) {
                builder = aClass.getMethod("newBuilder");
                METHOD_CACHE.put(aClass, builder);
            }
            return builder;
        }
    }

    private static class ProtobufRequestBodyConverter implements Converter {
        private boolean enablePbCrc;

        public ProtobufRequestBodyConverter(boolean enablePbCrc) {
            this.enablePbCrc = enablePbCrc;
        }

        @Nullable
        @Override
        public RequestBody convert(T value) throws IOException {
            MediaType mediaType = MediaType.get(value.getContentType());
            MessageOutputStream buffer = new MessageOutputStream(enablePbCrc);
            Message message = value.getMessage();
            buffer.writeInt(message.getSerializedSize());
            message.writeTo(buffer);
            return RequestBody.create(mediaType, buffer.toByteArray());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy