001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.jms;
018    
019    import java.io.File;
020    import java.util.Enumeration;
021    import java.util.Map;
022    
023    import javax.jms.Destination;
024    import javax.jms.JMSException;
025    import javax.jms.Message;
026    import javax.jms.Queue;
027    import javax.jms.Topic;
028    
029    import org.apache.camel.impl.DefaultMessage;
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    
033    /**
034     * Represents a {@link org.apache.camel.Message} for working with JMS
035     * 
036     * @version $Revision:520964 $
037     */
038    public class JmsMessage extends DefaultMessage {
039        private static final transient Log LOG = LogFactory.getLog(JmsMessage.class);
040        private Message jmsMessage;
041    
042        public JmsMessage() {
043        }
044    
045        public JmsMessage(Message jmsMessage) {
046            setJmsMessage(jmsMessage);
047        }
048    
049        @Override
050        public String toString() {
051            if (jmsMessage != null) {
052                return "JmsMessage: " + jmsMessage;
053            } else {
054                return "JmsMessage: " + getBody();
055            }
056        }
057    
058        /**
059         * Returns the underlying JMS message
060         * 
061         * @return the underlying JMS message
062         */
063        public Message getJmsMessage() {
064            return jmsMessage;
065        }
066    
067        public void setJmsMessage(Message jmsMessage) {
068            this.jmsMessage = jmsMessage;
069            try {
070                String id = getDestinationAsString(jmsMessage.getJMSDestination());
071                id += getSanitizedString(jmsMessage.getJMSMessageID());
072                setMessageId(id);
073            } catch (JMSException e) {
074                LOG.error("Failed to get message id from message " + jmsMessage, e);
075            }
076        }
077    
078        public Object getHeader(String name) {
079            Object answer = null;
080            
081            // we will exclude using JMS-prefixed headers here to avoid strangeness with some JMS providers
082            // e.g. ActiveMQ returns the String not the Destination type for "JMSReplyTo"!
083            if (jmsMessage != null && !name.startsWith("JMS")) {
084                try {
085                    answer = jmsMessage.getObjectProperty(name);
086                } catch (JMSException e) {
087                    throw new MessagePropertyAccessException(name, e);
088                }
089            }
090            if (answer == null) {
091                answer = super.getHeader(name);
092            }
093            return answer;
094        }
095    
096        @Override
097        public JmsMessage newInstance() {
098            return new JmsMessage();
099        }
100    
101        @Override
102        protected Object createBody() {
103            if (jmsMessage != null && getExchange() instanceof JmsExchange) {
104                JmsExchange exchange = (JmsExchange)getExchange();
105                return exchange.getBinding().extractBodyFromJms(exchange, jmsMessage);
106            }
107            return null;
108        }
109    
110        @Override
111        protected void populateInitialHeaders(Map<String, Object> map) {
112            if (jmsMessage != null) {
113                // lets populate the standard JMS message headers
114                try {
115                    map.put("JMSCorrelationID", jmsMessage.getJMSCorrelationID());
116                    map.put("JMSDeliveryMode", jmsMessage.getJMSDeliveryMode());
117                    map.put("JMSDestination", jmsMessage.getJMSDestination());
118                    map.put("JMSExpiration", jmsMessage.getJMSExpiration());
119                    map.put("JMSMessageID", jmsMessage.getJMSMessageID());
120                    map.put("JMSPriority", jmsMessage.getJMSPriority());
121                    map.put("JMSRedelivered", jmsMessage.getJMSRedelivered());
122                    map.put("JMSReplyTo", jmsMessage.getJMSReplyTo());
123                    map.put("JMSTimestamp", jmsMessage.getJMSTimestamp());
124                    map.put("JMSType", jmsMessage.getJMSType());
125                }
126                catch (JMSException e) {
127                    throw new MessageJMSPropertyAccessException(e);
128                }
129    
130                Enumeration names;
131                try {
132                    names = jmsMessage.getPropertyNames();
133                } catch (JMSException e) {
134                    throw new MessagePropertyNamesAccessException(e);
135                }
136                while (names.hasMoreElements()) {
137                    String name = names.nextElement().toString();
138                    try {
139                        Object value = jmsMessage.getObjectProperty(name);
140                        map.put(name, value);
141                    } catch (JMSException e) {
142                        throw new MessagePropertyAccessException(name, e);
143                    }
144                }
145            }
146        }
147    
148        private String getDestinationAsString(Destination destination) throws JMSException {
149            String result = "";
150            if (destination == null) {
151                result = "null destination!";
152            } else if (destination instanceof Topic) {
153                result += "topic" + File.separator + getSanitizedString(((Topic)destination).getTopicName());
154            } else {
155                result += "queue" + File.separator + getSanitizedString(((Queue)destination).getQueueName());
156            }
157            result += File.separator;
158            return result;
159        }
160    
161        private String getSanitizedString(Object value) {
162            return value != null ? value.toString().replaceAll("[^a-zA-Z0-9\\.\\_\\-]", "_") : "";
163        }
164    }