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