org.springframework.jms.support.SimpleJmsHeaderMapper.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.jms.support.SimpleJmsHeaderMapper.java

Source

/*
 * 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.jms.support;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
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 org.springframework.messaging.MessageHeaders;
import org.springframework.util.StringUtils;

/**
 * Simple implementation of {@link JmsHeaderMapper}.
 *
 * <p>This implementation copies JMS API headers (e.g. JMSReplyTo) to and from
 * {@link org.springframework.messaging.Message Messages}. Any user-defined
 * properties will also be copied from a JMS Message to a Message, and any
 * other headers on a Message (beyond the JMS API headers) will likewise
 * be copied to a JMS Message. Those other headers will be copied to the
 * general properties of a JMS Message whereas the JMS API headers are passed
 * to the appropriate setter methods (e.g. setJMSReplyTo).
 *
 * <p>Constants for the JMS API headers are defined in {@link JmsHeaders}.
 * Note that most of the JMS headers are read-only: the JMSDestination,
 * JMSDeliveryMode, JMSExpiration, JMSMessageID, JMSPriority, JMSRedelivered
 * and JMSTimestamp flags are only copied <em>from</em> a JMS Message. Those
 * values will <em>not</em> be passed along from a Message to an outbound
 * JMS Message.
 *
 * @author Mark Fisher
 * @author Gary Russell
 * @since 4.1
 */
public class SimpleJmsHeaderMapper implements JmsHeaderMapper {

    private static Set<Class<?>> SUPPORTED_PROPERTY_TYPES = new HashSet<Class<?>>(
            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).
     * <p>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).
     * <p>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 {
            Object jmsCorrelationId = headers.get(JmsHeaders.CORRELATION_ID);
            if (jmsCorrelationId instanceof Number) {
                jmsCorrelationId = jmsCorrelationId.toString();
            }
            if (jmsCorrelationId instanceof String) {
                try {
                    jmsMessage.setJMSCorrelationID((String) jmsCorrelationId);
                } catch (Exception e) {
                    logger.info("failed to set JMSCorrelationID, skipping", e);
                }
            }
            Object jmsReplyTo = headers.get(JmsHeaders.REPLY_TO);
            if (jmsReplyTo instanceof Destination) {
                try {
                    jmsMessage.setJMSReplyTo((Destination) jmsReplyTo);
                } catch (Exception e) {
                    logger.info("failed to set JMSReplyTo, skipping", e);
                }
            }
            Object jmsType = headers.get(JmsHeaders.TYPE);
            if (jmsType instanceof String) {
                try {
                    jmsMessage.setJMSType((String) jmsType);
                } catch (Exception e) {
                    logger.info("failed to set JMSType, skipping", e);
                }
            }
            Set<String> headerNames = headers.keySet();
            for (String headerName : headerNames) {
                if (StringUtils.hasText(headerName) && !headerName.startsWith(JmsHeaders.PREFIX)) {
                    Object value = headers.get(headerName);
                    if (value != null && SUPPORTED_PROPERTY_TYPES.contains(value.getClass())) {
                        try {
                            String propertyName = this.fromHeaderName(headerName);
                            jmsMessage.setObjectProperty(propertyName, value);
                        } catch (Exception e) {
                            if (headerName.startsWith("JMSX")) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace(
                                            "skipping reserved header, it cannot be set by client: " + headerName);
                                }
                            } else if (logger.isWarnEnabled()) {
                                logger.warn("failed to map Message header '" + headerName + "' to JMS property", e);
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("error occurred while mapping from MessageHeaders to JMS properties", ex);
            }
        }
    }

    @Override
    public MessageHeaders toHeaders(javax.jms.Message jmsMessage) {
        Map<String, Object> headers = new HashMap<String, Object>();
        try {
            try {
                String correlationId = jmsMessage.getJMSCorrelationID();
                if (correlationId != null) {
                    headers.put(JmsHeaders.CORRELATION_ID, correlationId);
                }
            } catch (Exception ex) {
                logger.info("failed to read JMSCorrelationID property, skipping", ex);
            }
            try {
                Destination destination = jmsMessage.getJMSDestination();
                if (destination != null) {
                    headers.put(JmsHeaders.DESTINATION, destination);
                }
            } catch (Exception ex) {
                logger.info("failed to read JMSDestination property, skipping", ex);
            }
            try {
                int deliveryMode = jmsMessage.getJMSDeliveryMode();
                headers.put(JmsHeaders.DELIVERY_MODE, deliveryMode);
            } catch (Exception ex) {
                logger.info("failed to read JMSDeliveryMode property, skipping", ex);
            }
            try {
                long expiration = jmsMessage.getJMSExpiration();
                headers.put(JmsHeaders.EXPIRATION, expiration);
            } catch (Exception ex) {
                logger.info("failed to read JMSExpiration property, skipping", ex);
            }
            try {
                String messageId = jmsMessage.getJMSMessageID();
                if (messageId != null) {
                    headers.put(JmsHeaders.MESSAGE_ID, messageId);
                }
            } catch (Exception ex) {
                logger.info("failed to read JMSMessageID property, skipping", ex);
            }
            try {
                headers.put(JmsHeaders.PRIORITY, jmsMessage.getJMSPriority());
            } catch (Exception ex) {
                logger.info("failed to read JMSPriority property, skipping", ex);
            }
            try {
                Destination replyTo = jmsMessage.getJMSReplyTo();
                if (replyTo != null) {
                    headers.put(JmsHeaders.REPLY_TO, replyTo);
                }
            } catch (Exception ex) {
                logger.info("failed to read JMSReplyTo property, skipping", ex);
            }
            try {
                headers.put(JmsHeaders.REDELIVERED, jmsMessage.getJMSRedelivered());
            } catch (Exception ex) {
                logger.info("failed to read JMSRedelivered property, skipping", ex);
            }
            try {
                String type = jmsMessage.getJMSType();
                if (type != null) {
                    headers.put(JmsHeaders.TYPE, type);
                }
            } catch (Exception ex) {
                logger.info("failed to read JMSType property, skipping", ex);
            }
            try {
                headers.put(JmsHeaders.TIMESTAMP, jmsMessage.getJMSTimestamp());
            } catch (Exception ex) {
                logger.info("failed to read JMSTimestamp property, skipping", ex);
            }

            Enumeration<?> jmsPropertyNames = jmsMessage.getPropertyNames();
            if (jmsPropertyNames != null) {
                while (jmsPropertyNames.hasMoreElements()) {
                    String propertyName = jmsPropertyNames.nextElement().toString();
                    try {
                        String headerName = this.toHeaderName(propertyName);
                        headers.put(headerName, jmsMessage.getObjectProperty(propertyName));
                    } catch (Exception ex) {
                        if (logger.isWarnEnabled()) {
                            logger.warn("Error occurred while mapping JMS property '" + propertyName
                                    + "' to Message header", ex);
                        }
                    }
                }
            }
        } catch (JMSException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Error occurred while mapping from JMS properties to MessageHeaders", ex);
            }
        }
        return new MessageHeaders(headers);
    }

    /**
     * Add the outbound prefix if necessary.
     * <p>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;
        } else if (MessageHeaders.CONTENT_TYPE.equals(headerName)) {
            propertyName = CONTENT_TYPE_PROPERTY;
        }
        return propertyName;
    }

    /**
     * Add the inbound prefix if necessary.
     * <p>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;
        }
        return headerName;
    }

}