001/*
002 * Copyright 2002-2018 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 java.util.Map;
020
021import org.springframework.lang.Nullable;
022import org.springframework.messaging.Message;
023import org.springframework.util.Assert;
024
025/**
026 * An extension of {@link AbstractMessagingTemplate} that adds operations for sending
027 * messages to a resolvable destination name. Supports destination resolving as defined by
028 * the following interfaces:
029 * <ul>
030 * <li>{@link DestinationResolvingMessageSendingOperations}</li>
031 * <li>{@link DestinationResolvingMessageReceivingOperations}</li>
032 * <li>{@link DestinationResolvingMessageRequestReplyOperations}</li>
033 * </ul>
034 *
035 * @author Mark Fisher
036 * @author Rossen Stoyanchev
037 * @since 4.0
038 * @param <D> the destination type
039 */
040public abstract class AbstractDestinationResolvingMessagingTemplate<D> extends AbstractMessagingTemplate<D>
041                implements DestinationResolvingMessageSendingOperations<D>,
042                DestinationResolvingMessageReceivingOperations<D>,
043                DestinationResolvingMessageRequestReplyOperations<D> {
044
045        @Nullable
046        private DestinationResolver<D> destinationResolver;
047
048
049        /**
050         * Configure the {@link DestinationResolver} to use to resolve String destination
051         * names into actual destinations of type {@code <D>}.
052         * <p>This field does not have a default setting. If not configured, methods that
053         * require resolving a destination name will raise an {@link IllegalArgumentException}.
054         * @param destinationResolver the destination resolver to use
055         */
056        public void setDestinationResolver(@Nullable DestinationResolver<D> destinationResolver) {
057                this.destinationResolver = destinationResolver;
058        }
059
060        /**
061         * Return the configured destination resolver.
062         */
063        @Nullable
064        public DestinationResolver<D> getDestinationResolver() {
065                return this.destinationResolver;
066        }
067
068
069        @Override
070        public void send(String destinationName, Message<?> message) {
071                D destination = resolveDestination(destinationName);
072                doSend(destination, message);
073        }
074
075        protected final D resolveDestination(String destinationName) {
076
077                Assert.state(this.destinationResolver != null, "DestinationResolver is required to resolve destination names");
078                return this.destinationResolver.resolveDestination(destinationName);
079        }
080
081        @Override
082        public <T> void convertAndSend(String destinationName, T payload) {
083                convertAndSend(destinationName, payload, null, null);
084        }
085
086        @Override
087        public <T> void convertAndSend(String destinationName, T payload, @Nullable Map<String, Object> headers) {
088                convertAndSend(destinationName, payload, headers, null);
089        }
090
091        @Override
092        public <T> void convertAndSend(String destinationName, T payload, @Nullable MessagePostProcessor postProcessor) {
093                convertAndSend(destinationName, payload, null, postProcessor);
094        }
095
096        @Override
097        public <T> void convertAndSend(String destinationName, T payload,
098                        @Nullable Map<String, Object> headers, @Nullable MessagePostProcessor postProcessor) {
099
100                D destination = resolveDestination(destinationName);
101                super.convertAndSend(destination, payload, headers, postProcessor);
102        }
103
104        @Override
105        @Nullable
106        public Message<?> receive(String destinationName) {
107                D destination = resolveDestination(destinationName);
108                return super.receive(destination);
109        }
110
111        @Override
112        @Nullable
113        public <T> T receiveAndConvert(String destinationName, Class<T> targetClass) {
114                D destination = resolveDestination(destinationName);
115                return super.receiveAndConvert(destination, targetClass);
116        }
117
118        @Override
119        @Nullable
120        public Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) {
121                D destination = resolveDestination(destinationName);
122                return super.sendAndReceive(destination, requestMessage);
123        }
124
125        @Override
126        @Nullable
127        public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass) {
128                D destination = resolveDestination(destinationName);
129                return super.convertSendAndReceive(destination, request, targetClass);
130        }
131
132        @Override
133        @Nullable
134        public <T> T convertSendAndReceive(String destinationName, Object request,
135                        @Nullable Map<String, Object> headers, Class<T> targetClass) {
136
137                D destination = resolveDestination(destinationName);
138                return super.convertSendAndReceive(destination, request, headers, targetClass);
139        }
140
141        @Override
142        @Nullable
143        public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass,
144                        @Nullable MessagePostProcessor postProcessor) {
145
146                D destination = resolveDestination(destinationName);
147                return super.convertSendAndReceive(destination, request, targetClass, postProcessor);
148        }
149
150        @Override
151        @Nullable
152        public <T> T convertSendAndReceive(String destinationName, Object request,
153                        @Nullable Map<String, Object> headers, Class<T> targetClass,
154                        @Nullable MessagePostProcessor postProcessor) {
155
156                D destination = resolveDestination(destinationName);
157                return super.convertSendAndReceive(destination, request, headers, targetClass, postProcessor);
158        }
159
160}