001/*
002 * Copyright 2002-2016 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.converter;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.List;
022
023import org.springframework.lang.Nullable;
024import org.springframework.messaging.Message;
025import org.springframework.messaging.MessageHeaders;
026import org.springframework.util.Assert;
027
028/**
029 * A {@link MessageConverter} that delegates to a list of registered converters
030 * to be invoked until one of them returns a non-null result.
031 *
032 * <p>As of 4.2.1, this composite converter implements {@link SmartMessageConverter}
033 * in order to support the delegation of conversion hints.
034 *
035 * @author Rossen Stoyanchev
036 * @author Juergen Hoeller
037 * @since 4.0
038 */
039public class CompositeMessageConverter implements SmartMessageConverter {
040
041        private final List<MessageConverter> converters;
042
043
044        /**
045         * Create an instance with the given converters.
046         */
047        public CompositeMessageConverter(Collection<MessageConverter> converters) {
048                Assert.notEmpty(converters, "Converters must not be empty");
049                this.converters = new ArrayList<>(converters);
050        }
051
052
053        @Override
054        @Nullable
055        public Object fromMessage(Message<?> message, Class<?> targetClass) {
056                for (MessageConverter converter : getConverters()) {
057                        Object result = converter.fromMessage(message, targetClass);
058                        if (result != null) {
059                                return result;
060                        }
061                }
062                return null;
063        }
064
065        @Override
066        @Nullable
067        public Object fromMessage(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
068                for (MessageConverter converter : getConverters()) {
069                        Object result = (converter instanceof SmartMessageConverter ?
070                                        ((SmartMessageConverter) converter).fromMessage(message, targetClass, conversionHint) :
071                                        converter.fromMessage(message, targetClass));
072                        if (result != null) {
073                                return result;
074                        }
075                }
076                return null;
077        }
078
079        @Override
080        @Nullable
081        public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) {
082                for (MessageConverter converter : getConverters()) {
083                        Message<?> result = converter.toMessage(payload, headers);
084                        if (result != null) {
085                                return result;
086                        }
087                }
088                return null;
089        }
090
091        @Override
092        @Nullable
093        public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
094                for (MessageConverter converter : getConverters()) {
095                        Message<?> result = (converter instanceof SmartMessageConverter ?
096                                        ((SmartMessageConverter) converter).toMessage(payload, headers, conversionHint) :
097                                        converter.toMessage(payload, headers));
098                        if (result != null) {
099                                return result;
100                        }
101                }
102                return null;
103        }
104
105
106        /**
107         * Return the underlying list of delegate converters.
108         */
109        public List<MessageConverter> getConverters() {
110                return this.converters;
111        }
112
113        @Override
114        public String toString() {
115                return "CompositeMessageConverter[converters=" + getConverters() + "]";
116        }
117
118}