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

com.gs.api.accelrx.web.client.reflect.AccelRxProxyMethod Maven / Gradle / Ivy

The newest version!
package com.gs.api.accelrx.web.client.reflect;

import com.google.common.base.Preconditions;
import com.gs.api.accelrx.APIContract;
import com.gs.api.accelrx.APIOperation;
import com.gs.api.accelrx.web.api.FormBody;
import com.gs.api.accelrx.web.api.Param;
import com.gs.api.accelrx.web.api.WebClientResponse;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class AccelRxProxyMethod {
    private final APIOperation apiOperation;
    private final Method method;
    private final Parameter[] parameters;

    private AccelRxProxyMethod(APIOperation apiOperation, Method method) {
        this.apiOperation = apiOperation;
        this.method = method;
        this.parameters = method.getParameters();
    }

    static AccelRxProxyMethod create(APIContract apiContract, Method method) {
        String methodName = method.getName();
        if (apiContract.operations().containsKey(methodName)) {
            return new AccelRxProxyMethod(apiContract.operation(methodName), method);
        } else if (apiContract.operations().containsKey(StringUtils.removeEnd(methodName, "Response"))) {
            return new AccelRxProxyMethod(apiContract.operation(StringUtils.removeEnd(methodName, "Response")), method);
        } else {
            throw new RuntimeException("Unknown operation from method: " + method.getName());
        }
    }

    APIOperation apiOperation() {
        return apiOperation;
    }

    Map argsMap(Object[] args) {
        if (args == null || args.length < 1) {
            return new HashMap<>();
        }

        return IntStream.range(0, args.length)
                .filter(index -> args[index] != null)
                .boxed()
                .flatMap(toParameterArgs(args))
                .collect(Collectors.toMap(AccelRxProxyMethod.ParameterArg::name, AccelRxProxyMethod.ParameterArg::value));
    }

    private Function> toParameterArgs(Object[] args) {
        if (apiOperation.isFormRequest()) {
            return index -> {
                final var parameter = parameters[index];
                final var arg = args[index];
                if (isFormParam(parameter, arg)) {
                    Map formParams = getGetFormParams(arg);
                    return formParams.entrySet().stream()
                            .map(entries -> new ParameterArg(entries.getKey(), entries.getValue()));
                } else {
                    return Stream.of(new ParameterArg(parameter, arg));
                }
            };
        } else {
            return index -> {
                final var parameter = parameters[index];
                final var arg = args[index];
                return Stream.of(new ParameterArg(parameter, arg));
            };
        }
    }

    private boolean isFormParam(Parameter parameter, Object arg) {
        return FormBody.class.isAssignableFrom(parameter.getType()) && arg instanceof FormBody;
    }

    boolean isResponseMethod() {
        if (Single.class.isAssignableFrom(method.getReturnType())) {
            ParameterizedType returnType = ((ParameterizedType) method.getGenericReturnType());
            Type responseActualType = returnType.getActualTypeArguments()[0];
            if (responseActualType instanceof Class) {
                return WebClientResponse.class.isAssignableFrom((Class) responseActualType);
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    Type responseType() {
        if (Single.class.isAssignableFrom(method.getReturnType()) || Observable.class.isAssignableFrom(method.getReturnType())) {
            return ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0];
        } else {
            return method.getGenericReturnType();
        }
    }

    boolean isBlockingMethod() {
        return !(Single.class.isAssignableFrom(method.getReturnType()) ||
                Completable.class.isAssignableFrom(method.getReturnType()) ||
                Observable.class.isAssignableFrom(method.getReturnType()));
    }

    private Map getGetFormParams(Object maybeFormBody) {
        Preconditions.checkNotNull(maybeFormBody, "form body");
        Preconditions.checkArgument(maybeFormBody instanceof FormBody, "Expected a form body but was " + maybeFormBody.getClass());
        return ((FormBody) maybeFormBody).getFormParams();
    }

    private static class ParameterArg {
        private final String name;
        private final Object value;

        ParameterArg(Parameter parameter, Object value) {
            Optional annotatedName = getParamAnnotationName(parameter);

            this.name = annotatedName.orElse(parameter.getName());
            this.value = value;
        }

        ParameterArg(String name, Object value) {
            this.name = name;
            this.value = value;
        }

        String name() {
            return name;
        }

        Object value() {
            return value;
        }

        private Optional getParamAnnotationName(Parameter parameter) {
            Param annotation = parameter.getAnnotation(Param.class);
            if (annotation != null) {
                Param param = annotation;
                return Optional.of(param.name());
            }
            return Optional.empty();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy