package io.micronaut.http.bind.binders;
import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.bind.annotation.AbstractAnnotatedArgumentBinder;
import io.micronaut.core.convert.ArgumentConversionContext;
import io.micronaut.core.convert.ConversionService;
import io.micronaut.core.convert.value.ConvertibleMultiValues;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpAttributes;
import io.micronaut.http.HttpMethod;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.QueryValue;
import io.micronaut.http.uri.UriMatchInfo;
import io.micronaut.http.uri.UriMatchVariable;
import java.util.Collections;
public class QueryValueArgumentBinder<T> extends AbstractAnnotatedArgumentBinder<QueryValue, T, HttpRequest<?>> implements AnnotatedRequestArgumentBinder<QueryValue, T> {
public QueryValueArgumentBinder(ConversionService<?> conversionService) {
super(conversionService);
}
@Override
public Class<QueryValue> getAnnotationType() {
return QueryValue.class;
}
@Override
public BindingResult<T> bind(ArgumentConversionContext<T> context, HttpRequest<?> source) {
ConvertibleMultiValues<String> parameters = source.getParameters();
Argument<T> argument = context.getArgument();
HttpMethod httpMethod = source.getMethod();
boolean permitsRequestBody = HttpMethod.permitsRequestBody(httpMethod);
AnnotationMetadata annotationMetadata = argument.getAnnotationMetadata();
boolean hasAnnotation = annotationMetadata.hasAnnotation(QueryValue.class);
String parameterName = annotationMetadata.stringValue(QueryValue.class).orElse(argument.getName());
boolean bindAll = source.getAttribute(HttpAttributes.ROUTE_MATCH, UriMatchInfo.class)
.map(umi -> {
UriMatchVariable uriMatchVariable = umi.getVariableMap().get(parameterName);
return uriMatchVariable != null && uriMatchVariable.isExploded();
}).orElse(false);
BindingResult<T> result;
if (hasAnnotation || !permitsRequestBody) {
if (bindAll) {
Object value;
if (Iterable.class.isAssignableFrom(argument.getType())) {
value = doResolve(context, parameters, parameterName);
if (value == null) {
value = Collections.emptyList();
}
} else {
value = parameters.asMap();
}
result = doConvert(value, context);
} else {
result = doBind(context, parameters, parameterName);
}
} else {
result = BindingResult.EMPTY;
}
return result;
}
}