001/*
002 * Copyright 2002-2014 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.core;
018
019import org.springframework.messaging.Message;
020import org.springframework.messaging.converter.MessageConversionException;
021import org.springframework.messaging.converter.MessageConverter;
022
023/**
024 * An extension of {@link AbstractMessageSendingTemplate} that adds support for
025 * receive style operations as defined by {@link MessageReceivingOperations}.
026 *
027 * @author Mark Fisher
028 * @author Rossen Stoyanchev
029 * @author Stephane Nicoll
030 * @since 4.1
031 */
032public abstract class AbstractMessageReceivingTemplate<D> extends AbstractMessageSendingTemplate<D>
033                implements MessageReceivingOperations<D> {
034
035        @Override
036        public Message<?> receive() {
037                return doReceive(getRequiredDefaultDestination());
038        }
039
040        @Override
041        public Message<?> receive(D destination) {
042                return doReceive(destination);
043        }
044
045        /**
046         * Actually receive a message from the given destination.
047         * @param destination the target destination
048         * @return the received message, possibly {@code null} if the message could not
049         * be received, for example due to a timeout
050         */
051        protected abstract Message<?> doReceive(D destination);
052
053
054        @Override
055        public <T> T receiveAndConvert(Class<T> targetClass) {
056                return receiveAndConvert(getRequiredDefaultDestination(), targetClass);
057        }
058
059        @Override
060        public <T> T receiveAndConvert(D destination, Class<T> targetClass) {
061                Message<?> message = doReceive(destination);
062                if (message != null) {
063                        return doConvert(message, targetClass);
064                }
065                else {
066                        return null;
067                }
068        }
069
070        /**
071         * Convert from the given message to the given target class.
072         * @param message the message to convert
073         * @param targetClass the target class to convert the payload to
074         * @return the converted payload of the reply message (never {@code null})
075         */
076        @SuppressWarnings("unchecked")
077        protected <T> T doConvert(Message<?> message, Class<T> targetClass) {
078                MessageConverter messageConverter = getMessageConverter();
079                T value = (T) messageConverter.fromMessage(message, targetClass);
080                if (value == null) {
081                        throw new MessageConversionException(message, "Unable to convert payload [" + message.getPayload() +
082                                        "] to type [" + targetClass + "] using converter [" + messageConverter + "]");
083                }
084                return value;
085        }
086
087}