diff --git a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java index f5b2b9fb09..2cb4e3c47a 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java @@ -24,11 +24,10 @@ import java.util.Map; import java.util.Set; import javax.jms.Destination; import javax.jms.JMSException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import javax.jms.Message; import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.AbstractHeaderMapper; import org.springframework.util.StringUtils; /** @@ -51,46 +50,15 @@ import org.springframework.util.StringUtils; * * @author Mark Fisher * @author Gary Russell + * @author Stephane Nicoll * @since 4.1 */ -public class SimpleJmsHeaderMapper implements JmsHeaderMapper { +public class SimpleJmsHeaderMapper extends AbstractHeaderMapper implements JmsHeaderMapper { private static Set> SUPPORTED_PROPERTY_TYPES = new HashSet>(Arrays.asList(new Class[] { Boolean.class, Byte.class, Double.class, Float.class, Integer.class, Long.class, Short.class, String.class})); - private final Log logger = LogFactory.getLog(getClass()); - - private String inboundPrefix = ""; - - private String outboundPrefix = ""; - - - /** - * Specify a prefix to be appended to the message header name for any - * JMS property that is being mapped into the MessageHeaders. The - * default is an empty string (no prefix). - *

This does not affect the JMS properties covered by the specification/API, - * such as JMSCorrelationID, etc. The header names used for mapping such - * properties are all defined in our {@link org.springframework.jms.support.JmsHeaders}. - */ - public void setInboundPrefix(String inboundPrefix) { - this.inboundPrefix = (inboundPrefix != null ? inboundPrefix : ""); - } - - /** - * Specify a prefix to be appended to the JMS property name for any - * message header that is being mapped into the JMS Message. The - * default is an empty string (no prefix). - *

This does not affect the JMS properties covered by the specification/API, - * such as JMSCorrelationID, etc. The header names used for mapping such - * properties are all defined in our {@link org.springframework.jms.support.JmsHeaders}. - */ - public void setOutboundPrefix(String outboundPrefix) { - this.outboundPrefix = (outboundPrefix != null ? outboundPrefix : ""); - } - - @Override public void fromHeaders(MessageHeaders headers, javax.jms.Message jmsMessage) { try { @@ -106,19 +74,19 @@ public class SimpleJmsHeaderMapper implements JmsHeaderMapper { logger.info("failed to set JMSCorrelationID, skipping", e); } } - Object jmsReplyTo = headers.get(JmsHeaders.REPLY_TO); - if (jmsReplyTo instanceof Destination) { + Destination jmsReplyTo = getHeaderIfAvailable(headers, JmsHeaders.REPLY_TO, Destination.class); + if (jmsReplyTo != null) { try { - jmsMessage.setJMSReplyTo((Destination) jmsReplyTo); + jmsMessage.setJMSReplyTo(jmsReplyTo); } catch (Exception e) { logger.info("failed to set JMSReplyTo, skipping", e); } } - Object jmsType = headers.get(JmsHeaders.TYPE); - if (jmsType instanceof String) { + String jmsType = getHeaderIfAvailable(headers, JmsHeaders.TYPE, String.class); + if (jmsType != null) { try { - jmsMessage.setJMSType((String) jmsType); + jmsMessage.setJMSType(jmsType); } catch (Exception e) { logger.info("failed to set JMSType, skipping", e); @@ -266,30 +234,22 @@ public class SimpleJmsHeaderMapper implements JmsHeaderMapper { * Add the outbound prefix if necessary. *

Convert {@link MessageHeaders#CONTENT_TYPE} to content_type for JMS compliance. */ - private String fromHeaderName(String headerName) { - String propertyName = headerName; - if (StringUtils.hasText(this.outboundPrefix) && !propertyName.startsWith(this.outboundPrefix)) { - propertyName = this.outboundPrefix + headerName; + protected String fromHeaderName(String headerName) { + if (MessageHeaders.CONTENT_TYPE.equals(headerName)) { + return CONTENT_TYPE_PROPERTY; } - else if (MessageHeaders.CONTENT_TYPE.equals(headerName)) { - propertyName = CONTENT_TYPE_PROPERTY; - } - return propertyName; + return super.fromHeaderName(headerName); } /** * Add the inbound prefix if necessary. *

Convert content_type to {@link MessageHeaders#CONTENT_TYPE}. */ - private String toHeaderName(String propertyName) { - String headerName = propertyName; - if (StringUtils.hasText(this.inboundPrefix) && !headerName.startsWith(this.inboundPrefix)) { - headerName = this.inboundPrefix + propertyName; - } - else if (CONTENT_TYPE_PROPERTY.equals(propertyName)) { - headerName = MessageHeaders.CONTENT_TYPE; + protected String toHeaderName(String propertyName) { + if (CONTENT_TYPE_PROPERTY.equals(propertyName)) { + return MessageHeaders.CONTENT_TYPE; } - return headerName; + return super.toHeaderName(propertyName); } } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/AbstractHeaderMapper.java b/spring-messaging/src/main/java/org/springframework/messaging/support/AbstractHeaderMapper.java new file mode 100644 index 0000000000..7cbee5752d --- /dev/null +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/AbstractHeaderMapper.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.messaging.support; + +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.messaging.MessageHeaders; +import org.springframework.util.StringUtils; + +/** + * A base {@link HeaderMapper} implementation + * + * @author Stephane Nicoll + * @since 4.1 + */ +public abstract class AbstractHeaderMapper implements HeaderMapper { + + protected final Log logger = LogFactory.getLog(getClass()); + + private String inboundPrefix = ""; + + private String outboundPrefix = ""; + + /** + * Specify a prefix to be appended to the message header name for any + * user-defined property that is being mapped into the MessageHeaders. The + * default is an empty string (no prefix). + */ + public void setInboundPrefix(String inboundPrefix) { + this.inboundPrefix = (inboundPrefix != null ? inboundPrefix : ""); + } + + /** + * Specify a prefix to be appended to the protocol property name for any + * user-defined message header that is being mapped into the protocol-specific + * Message. The default is an empty string (no prefix). + */ + public void setOutboundPrefix(String outboundPrefix) { + this.outboundPrefix = (outboundPrefix != null ? outboundPrefix : ""); + } + + /** + * Generate the name to use to set the header defined by the specified {@code headerName} to + * the protocol specific message. + * @see #setOutboundPrefix + */ + protected String fromHeaderName(String headerName) { + String propertyName = headerName; + if (StringUtils.hasText(this.outboundPrefix) && !propertyName.startsWith(this.outboundPrefix)) { + propertyName = this.outboundPrefix + headerName; + } + return propertyName; + } + + /** + * Generate the name to use to set the header defined by the specified {@code propertyName} to + * the {@link MessageHeaders} instance. + * @see #setInboundPrefix(String) + */ + protected String toHeaderName(String propertyName) { + String headerName = propertyName; + if (StringUtils.hasText(this.inboundPrefix) && !headerName.startsWith(this.inboundPrefix)) { + headerName = this.inboundPrefix + propertyName; + } + return headerName; + } + + /** + * Return the header value or {@code null} if it does not exist or does not match + * the requested {@code type}. + */ + protected V getHeaderIfAvailable(Map headers, String name, Class type) { + Object value = headers.get(name); + if (value == null) { + return null; + } + if (!type.isAssignableFrom(value.getClass())) { + if (logger.isWarnEnabled()) { + logger.warn("Skipping header '" + name + "'expected type [" + type + "], but got [" + + value.getClass() + "]"); + } + return null; + } + else { + return type.cast(value); + } + } +}