Example usage for org.springframework.core ResolvableType forMethodParameter

List of usage examples for org.springframework.core ResolvableType forMethodParameter

Introduction

In this page you can find the example usage for org.springframework.core ResolvableType forMethodParameter.

Prototype

public static ResolvableType forMethodParameter(MethodParameter methodParameter) 

Source Link

Document

Return a ResolvableType for the specified MethodParameter .

Usage

From source file:org.jdal.aop.config.SerializableAnnotationBeanPostProcessor.java

private ResolvableType getResolvableType(AnnotatedElement element) {
    if (element instanceof Field)
        return ResolvableType.forField((Field) element);
    else if (element instanceof Method)
        return ResolvableType.forMethodParameter(new MethodParameter((Method) element, 0));

    throw new IllegalArgumentException("SerializableProxy annotation should only be applied on types"
            + ", fields or methods but was found in [" + element.toString() + "]");
}

From source file:org.springframework.cloud.function.web.flux.response.FluxReturnValueHandler.java

private boolean isResponseEntity(MethodParameter returnType) {
    if (ResponseEntity.class.isAssignableFrom(returnType.getParameterType())) {
        Class<?> bodyType = ResolvableType.forMethodParameter(returnType).getGeneric(0).resolve();
        return bodyType != null && Flux.class.isAssignableFrom(bodyType);
    }//from   w w  w  . jav a  2s .  co  m
    return false;
}

From source file:org.springframework.cloud.stream.reactive.MessageChannelToFluxSenderParameterAdapter.java

@Override
public boolean supports(Class<?> bindingTargetType, MethodParameter methodParameter) {
    ResolvableType type = ResolvableType.forMethodParameter(methodParameter);
    return MessageChannel.class.isAssignableFrom(bindingTargetType)
            && FluxSender.class.isAssignableFrom(type.getRawClass());
}

From source file:org.springframework.jmx.access.MBeanClientInterceptor.java

/**
 * Convert the given result object (from attribute access or operation invocation)
 * to the specified target class for returning from the proxy method.
 * @param result the result object as returned by the {@code MBeanServer}
 * @param parameter the method parameter of the proxy method that's been invoked
 * @return the converted result object, or the passed-in object if no conversion
 * is necessary//from w  w w.  ja v a  2  s  .  c  om
 */
@Nullable
protected Object convertResultValueIfNecessary(@Nullable Object result, MethodParameter parameter) {
    Class<?> targetClass = parameter.getParameterType();
    try {
        if (result == null) {
            return null;
        }
        if (ClassUtils.isAssignableValue(targetClass, result)) {
            return result;
        }
        if (result instanceof CompositeData) {
            Method fromMethod = targetClass.getMethod("from", CompositeData.class);
            return ReflectionUtils.invokeMethod(fromMethod, null, result);
        } else if (result instanceof CompositeData[]) {
            CompositeData[] array = (CompositeData[]) result;
            if (targetClass.isArray()) {
                return convertDataArrayToTargetArray(array, targetClass);
            } else if (Collection.class.isAssignableFrom(targetClass)) {
                Class<?> elementType = ResolvableType.forMethodParameter(parameter).asCollection()
                        .resolveGeneric();
                if (elementType != null) {
                    return convertDataArrayToTargetCollection(array, targetClass, elementType);
                }
            }
        } else if (result instanceof TabularData) {
            Method fromMethod = targetClass.getMethod("from", TabularData.class);
            return ReflectionUtils.invokeMethod(fromMethod, null, result);
        } else if (result instanceof TabularData[]) {
            TabularData[] array = (TabularData[]) result;
            if (targetClass.isArray()) {
                return convertDataArrayToTargetArray(array, targetClass);
            } else if (Collection.class.isAssignableFrom(targetClass)) {
                Class<?> elementType = ResolvableType.forMethodParameter(parameter).asCollection()
                        .resolveGeneric();
                if (elementType != null) {
                    return convertDataArrayToTargetCollection(array, targetClass, elementType);
                }
            }
        }
        throw new InvocationFailureException(
                "Incompatible result value [" + result + "] for target type [" + targetClass.getName() + "]");
    } catch (NoSuchMethodException ex) {
        throw new InvocationFailureException(
                "Could not obtain 'from(CompositeData)' / 'from(TabularData)' method on target type ["
                        + targetClass.getName() + "] for conversion of MXBean data structure [" + result + "]");
    }
}

From source file:org.springframework.messaging.handler.annotation.reactive.PayloadMethodArgumentResolver.java

private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message, boolean isContentRequired,
        Flux<DataBuffer> content, MimeType mimeType) {

    ResolvableType targetType = ResolvableType.forMethodParameter(parameter);
    Class<?> resolvedType = targetType.resolve();
    ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
    ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType);
    isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty());
    Consumer<Object> validator = getValidator(message, parameter);

    Map<String, Object> hints = Collections.emptyMap();

    for (Decoder<?> decoder : this.decoders) {
        if (decoder.canDecode(elementType, mimeType)) {
            if (adapter != null && adapter.isMultiValue()) {
                Flux<?> flux = content.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
                        .onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
                if (isContentRequired) {
                    flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message)));
                }//from   w w  w. j  a  v a2s .co  m
                if (validator != null) {
                    flux = flux.doOnNext(validator);
                }
                return Mono.just(adapter.fromPublisher(flux));
            } else {
                // Single-value (with or without reactive type wrapper)
                Mono<?> mono = content.next()
                        .map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
                        .onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
                if (isContentRequired) {
                    mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message)));
                }
                if (validator != null) {
                    mono = mono.doOnNext(validator);
                }
                return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
            }
        }
    }

    return Mono.error(new MethodArgumentResolutionException(message, parameter,
            "Cannot decode to [" + targetType + "]" + message));
}

From source file:org.springframework.messaging.handler.annotation.support.reactive.PayloadMethodArgumentResolver.java

private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message, boolean isContentRequired,
        Flux<DataBuffer> content, MimeType mimeType) {

    ResolvableType targetType = ResolvableType.forMethodParameter(parameter);
    Class<?> resolvedType = targetType.resolve();
    ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
    ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType);
    isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty());
    Consumer<Object> validator = getValidator(message, parameter);

    Map<String, Object> hints = Collections.emptyMap();

    for (Decoder<?> decoder : this.decoders) {
        if (decoder.canDecode(elementType, mimeType)) {
            if (adapter != null && adapter.isMultiValue()) {
                Flux<?> flux = content
                        .concatMap(buffer -> decoder.decode(Mono.just(buffer), elementType, mimeType, hints))
                        .onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
                if (isContentRequired) {
                    flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message)));
                }/* w ww  .java2  s.co m*/
                if (validator != null) {
                    flux = flux.doOnNext(validator::accept);
                }
                return Mono.just(adapter.fromPublisher(flux));
            } else {
                // Single-value (with or without reactive type wrapper)
                Mono<?> mono = decoder.decodeToMono(content.next(), targetType, mimeType, hints)
                        .onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
                if (isContentRequired) {
                    mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message)));
                }
                if (validator != null) {
                    mono = mono.doOnNext(validator::accept);
                }
                return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
            }
        }
    }

    return Mono.error(new MethodArgumentResolutionException(message, parameter,
            "Cannot decode to [" + targetType + "]" + message));
}

From source file:org.springframework.messaging.handler.invocation.reactive.AbstractEncoderMethodReturnValueHandler.java

@SuppressWarnings("unchecked")
private Flux<DataBuffer> encodeContent(@Nullable Object content, MethodParameter returnType,
        DataBufferFactory bufferFactory, @Nullable MimeType mimeType, Map<String, Object> hints) {

    ResolvableType returnValueType = ResolvableType.forMethodParameter(returnType);
    ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnValueType.resolve(), content);

    Publisher<?> publisher;/*  w  w w . ja v a  2s.  co  m*/
    ResolvableType elementType;
    if (adapter != null) {
        publisher = adapter.toPublisher(content);
        boolean isUnwrapped = KotlinDetector.isKotlinReflectPresent()
                && KotlinDetector.isKotlinType(returnType.getContainingClass())
                && KotlinDelegate.isSuspend(returnType.getMethod())
                && !COROUTINES_FLOW_CLASS_NAME.equals(returnValueType.toClass().getName());
        ResolvableType genericType = isUnwrapped ? returnValueType : returnValueType.getGeneric();
        elementType = getElementType(adapter, genericType);
    } else {
        publisher = Mono.justOrEmpty(content);
        elementType = (returnValueType.toClass() == Object.class && content != null
                ? ResolvableType.forInstance(content)
                : returnValueType);
    }

    if (elementType.resolve() == void.class || elementType.resolve() == Void.class) {
        return Flux.from(publisher).cast(DataBuffer.class);
    }

    Encoder<?> encoder = getEncoder(elementType, mimeType);
    return Flux.from((Publisher) publisher)
            .map(value -> encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints));
}

From source file:org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.java

/**
 * Create the method argument value of the expected parameter type by reading
 * from the given HttpInputMessage./* w w  w.  j a v a2 s.  com*/
 * @param <T> the expected type of the argument value to be created
 * @param inputMessage the HTTP input message representing the current request
 * @param parameter the method parameter descriptor
 * @param targetType the target type, not necessarily the same as the method
 * parameter type, e.g. for {@code HttpEntity<String>}.
 * @return the created method argument value
 * @throws IOException if the reading from the request fails
 * @throws HttpMediaTypeNotSupportedException if no suitable message converter is found
 */
@SuppressWarnings("unchecked")
@Nullable
protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter,
        Type targetType)
        throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {

    MediaType contentType;
    boolean noContentType = false;
    try {
        contentType = inputMessage.getHeaders().getContentType();
    } catch (InvalidMediaTypeException ex) {
        throw new HttpMediaTypeNotSupportedException(ex.getMessage());
    }
    if (contentType == null) {
        noContentType = true;
        contentType = MediaType.APPLICATION_OCTET_STREAM;
    }

    Class<?> contextClass = parameter.getContainingClass();
    Class<T> targetClass = (targetType instanceof Class ? (Class<T>) targetType : null);
    if (targetClass == null) {
        ResolvableType resolvableType = ResolvableType.forMethodParameter(parameter);
        targetClass = (Class<T>) resolvableType.resolve();
    }

    HttpMethod httpMethod = (inputMessage instanceof HttpRequest ? ((HttpRequest) inputMessage).getMethod()
            : null);
    Object body = NO_VALUE;

    EmptyBodyCheckingHttpInputMessage message;
    try {
        message = new EmptyBodyCheckingHttpInputMessage(inputMessage);

        for (HttpMessageConverter<?> converter : this.messageConverters) {
            Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter
                    .getClass();
            GenericHttpMessageConverter<?> genericConverter = (converter instanceof GenericHttpMessageConverter
                    ? (GenericHttpMessageConverter<?>) converter
                    : null);
            if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType)
                    : (targetClass != null && converter.canRead(targetClass, contentType))) {
                if (logger.isDebugEnabled()) {
                    logger.debug(
                            "Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
                }
                if (message.hasBody()) {
                    HttpInputMessage msgToUse = getAdvice().beforeBodyRead(message, parameter, targetType,
                            converterType);
                    body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse)
                            : ((HttpMessageConverter<T>) converter).read(targetClass, msgToUse));
                    body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);
                } else {
                    body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);
                }
                break;
            }
        }
    } catch (IOException ex) {
        throw new HttpMessageNotReadableException("I/O error while reading input message", ex);
    }

    if (body == NO_VALUE) {
        if (httpMethod == null || !SUPPORTED_METHODS.contains(httpMethod)
                || (noContentType && !message.hasBody())) {
            return null;
        }
        throw new HttpMediaTypeNotSupportedException(contentType, this.allSupportedMediaTypes);
    }

    return body;
}

From source file:org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler.java

/**
 * Process the given reactive return value and decide whether to adapt it
 * to a {@link ResponseBodyEmitter} or a {@link DeferredResult}.
 * @return an emitter for streaming or {@code null} if handled internally
 * with a {@link DeferredResult}./*from   ww w . java 2s . c o m*/
 */
@Nullable
public ResponseBodyEmitter handleValue(Object returnValue, MethodParameter returnType,
        ModelAndViewContainer mav, NativeWebRequest request) throws Exception {

    Assert.notNull(returnValue, "Expected return value");
    ReactiveAdapter adapter = this.reactiveRegistry.getAdapter(returnValue.getClass());
    Assert.state(adapter != null, "Unexpected return value: " + returnValue);

    ResolvableType elementType = ResolvableType.forMethodParameter(returnType).getGeneric(0);
    Class<?> elementClass = elementType.resolve(Object.class);

    Collection<MediaType> mediaTypes = getMediaTypes(request);
    Optional<MediaType> mediaType = mediaTypes.stream().filter(MimeType::isConcrete).findFirst();

    if (adapter.isMultiValue()) {
        if (mediaTypes.stream().anyMatch(MediaType.TEXT_EVENT_STREAM::includes)
                || ServerSentEvent.class.isAssignableFrom(elementClass)) {
            SseEmitter emitter = new SseEmitter(STREAMING_TIMEOUT_VALUE);
            new SseEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
            return emitter;
        }
        if (CharSequence.class.isAssignableFrom(elementClass)) {
            ResponseBodyEmitter emitter = getEmitter(mediaType.orElse(MediaType.TEXT_PLAIN));
            new TextEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
            return emitter;
        }
        if (mediaTypes.stream().anyMatch(MediaType.APPLICATION_STREAM_JSON::includes)) {
            ResponseBodyEmitter emitter = getEmitter(MediaType.APPLICATION_STREAM_JSON);
            new JsonEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
            return emitter;
        }
    }

    // Not streaming...
    DeferredResult<Object> result = new DeferredResult<>();
    new DeferredResultSubscriber(result, adapter, elementType).connect(adapter, returnValue);
    WebAsyncUtils.getAsyncManager(request).startDeferredResultProcessing(result, mav);

    return null;
}

From source file:org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterReturnValueHandler.java

@Override
public boolean supportsReturnType(MethodParameter returnType) {

    Class<?> bodyType = ResponseEntity.class.isAssignableFrom(returnType.getParameterType())
            ? ResolvableType.forMethodParameter(returnType).getGeneric(0).resolve()
            : returnType.getParameterType();

    return bodyType != null && (ResponseBodyEmitter.class.isAssignableFrom(bodyType)
            || this.reactiveHandler.isReactiveType(bodyType));
}