001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.messaging.handler.invocation;
018
019import reactor.core.publisher.Mono;
020
021import org.springframework.core.MethodParameter;
022import org.springframework.core.ReactiveAdapter;
023import org.springframework.core.ReactiveAdapterRegistry;
024import org.springframework.util.concurrent.ListenableFuture;
025import org.springframework.util.concurrent.MonoToListenableFutureAdapter;
026
027/**
028 * Support for single-value reactive types (like {@code Mono} or {@code Single})
029 * as a return value type.
030 *
031 * @author Sebastien Deleuze
032 * @since 5.1
033 */
034public class ReactiveReturnValueHandler extends AbstractAsyncReturnValueHandler {
035
036        private final ReactiveAdapterRegistry adapterRegistry;
037
038
039        public ReactiveReturnValueHandler() {
040                this(ReactiveAdapterRegistry.getSharedInstance());
041        }
042
043        public ReactiveReturnValueHandler(ReactiveAdapterRegistry adapterRegistry) {
044                this.adapterRegistry = adapterRegistry;
045        }
046
047
048        @Override
049        public boolean supportsReturnType(MethodParameter returnType) {
050                return (this.adapterRegistry.getAdapter(returnType.getParameterType()) != null);
051        }
052
053        @Override
054        public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
055                ReactiveAdapter adapter = this.adapterRegistry.getAdapter(returnType.getParameterType(), returnValue);
056                return (adapter != null && !adapter.isMultiValue() && !adapter.isNoValue());
057        }
058
059        @Override
060        public ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType) {
061                ReactiveAdapter adapter = this.adapterRegistry.getAdapter(returnType.getParameterType(), returnValue);
062                if (adapter != null) {
063                        return new MonoToListenableFutureAdapter<>(Mono.from(adapter.toPublisher(returnValue)));
064                }
065                return null;
066        }
067
068}