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.jms.support.converter; 018 019import java.util.Map; 020import javax.jms.JMSException; 021import javax.jms.Session; 022 023import org.springframework.beans.factory.InitializingBean; 024import org.springframework.jms.support.JmsHeaderMapper; 025import org.springframework.jms.support.SimpleJmsHeaderMapper; 026import org.springframework.messaging.Message; 027import org.springframework.messaging.MessageHeaders; 028import org.springframework.messaging.core.AbstractMessagingTemplate; 029import org.springframework.messaging.support.MessageBuilder; 030import org.springframework.util.Assert; 031 032/** 033 * Convert a {@link Message} from the messaging abstraction to and from a 034 * {@link javax.jms.Message} using an underlying {@link MessageConverter} 035 * for the payload and a {@link org.springframework.jms.support.JmsHeaderMapper} 036 * to map the JMS headers to and from standard message headers. 037 * 038 * @author Stephane Nicoll 039 * @since 4.1 040 */ 041public class MessagingMessageConverter implements MessageConverter, InitializingBean { 042 043 private MessageConverter payloadConverter; 044 045 private JmsHeaderMapper headerMapper; 046 047 048 /** 049 * Create an instance with a default payload converter. 050 * @see org.springframework.jms.support.converter.SimpleMessageConverter 051 * @see org.springframework.jms.support.SimpleJmsHeaderMapper 052 */ 053 public MessagingMessageConverter() { 054 this(new SimpleMessageConverter(), new SimpleJmsHeaderMapper()); 055 } 056 057 /** 058 * Create an instance with the specific payload converter. 059 * @param payloadConverter the payload converter to use 060 * @since 4.3.12 061 */ 062 public MessagingMessageConverter(MessageConverter payloadConverter) { 063 this(payloadConverter, new SimpleJmsHeaderMapper()); 064 } 065 066 /** 067 * Create an instance with the specified payload converter and 068 * header mapper. 069 */ 070 public MessagingMessageConverter(MessageConverter payloadConverter, JmsHeaderMapper headerMapper) { 071 Assert.notNull(payloadConverter, "PayloadConverter must not be null"); 072 Assert.notNull(headerMapper, "HeaderMapper must not be null"); 073 this.payloadConverter = payloadConverter; 074 this.headerMapper = headerMapper; 075 } 076 077 078 /** 079 * Set the {@link MessageConverter} to use to convert the payload. 080 */ 081 public void setPayloadConverter(MessageConverter payloadConverter) { 082 this.payloadConverter = payloadConverter; 083 } 084 085 /** 086 * Set the {@link JmsHeaderMapper} to use to map JMS headers to and from 087 * standard message headers. 088 */ 089 public void setHeaderMapper(JmsHeaderMapper headerMapper) { 090 this.headerMapper = headerMapper; 091 } 092 093 @Override 094 public void afterPropertiesSet() { 095 Assert.notNull(this.payloadConverter, "Property 'payloadConverter' is required"); 096 Assert.notNull(this.headerMapper, "Property 'headerMapper' is required"); 097 } 098 099 100 @Override 101 public javax.jms.Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { 102 if (!(object instanceof Message)) { 103 throw new IllegalArgumentException("Could not convert [" + object + "] - only [" + 104 Message.class.getName() + "] is handled by this converter"); 105 } 106 Message<?> input = (Message<?>) object; 107 MessageHeaders headers = input.getHeaders(); 108 Object conversionHint = (headers != null ? headers.get( 109 AbstractMessagingTemplate.CONVERSION_HINT_HEADER) : null); 110 javax.jms.Message reply = createMessageForPayload(input.getPayload(), session, conversionHint); 111 this.headerMapper.fromHeaders(headers, reply); 112 return reply; 113 } 114 115 @SuppressWarnings("unchecked") 116 @Override 117 public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { 118 if (message == null) { 119 return null; 120 } 121 Map<String, Object> mappedHeaders = extractHeaders(message); 122 Object convertedObject = extractPayload(message); 123 MessageBuilder<Object> builder = (convertedObject instanceof org.springframework.messaging.Message) ? 124 MessageBuilder.fromMessage((org.springframework.messaging.Message<Object>) convertedObject) : 125 MessageBuilder.withPayload(convertedObject); 126 return builder.copyHeadersIfAbsent(mappedHeaders).build(); 127 } 128 129 /** 130 * Extract the payload of the specified {@link javax.jms.Message}. 131 */ 132 protected Object extractPayload(javax.jms.Message message) throws JMSException { 133 return this.payloadConverter.fromMessage(message); 134 } 135 136 /** 137 * Create a JMS message for the specified payload. 138 * @see MessageConverter#toMessage(Object, Session) 139 * @deprecated as of 4.3, use {@link #createMessageForPayload(Object, Session, Object)} 140 */ 141 @Deprecated 142 protected javax.jms.Message createMessageForPayload(Object payload, Session session) throws JMSException { 143 return this.payloadConverter.toMessage(payload, session); 144 } 145 146 /** 147 * Create a JMS message for the specified payload and conversionHint. 148 * The conversion hint is an extra object passed to the {@link MessageConverter}, 149 * e.g. the associated {@code MethodParameter} (may be {@code null}}. 150 * @see MessageConverter#toMessage(Object, Session) 151 * @since 4.3 152 */ 153 @SuppressWarnings("deprecation") 154 protected javax.jms.Message createMessageForPayload(Object payload, Session session, Object conversionHint) 155 throws JMSException { 156 157 return createMessageForPayload(payload, session); 158 } 159 160 protected final MessageHeaders extractHeaders(javax.jms.Message message) { 161 return this.headerMapper.toHeaders(message); 162 } 163 164}