Coverage Report - org.mule.transport.jms.JmsMessageUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
JmsMessageUtils
54%
78/144
50%
50/100
13.833
 
 1  
 /*
 2  
  * $Id: JmsMessageUtils.java 12205 2008-06-30 18:25:55Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.jms;
 12  
 
 13  
 import java.io.IOException;
 14  
 import java.io.InputStream;
 15  
 import java.io.ObjectOutputStream;
 16  
 import java.io.Serializable;
 17  
 import java.util.Enumeration;
 18  
 import java.util.Hashtable;
 19  
 import java.util.Iterator;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 import java.util.Vector;
 23  
 
 24  
 import javax.jms.BytesMessage;
 25  
 import javax.jms.Destination;
 26  
 import javax.jms.JMSException;
 27  
 import javax.jms.MapMessage;
 28  
 import javax.jms.Message;
 29  
 import javax.jms.MessageEOFException;
 30  
 import javax.jms.ObjectMessage;
 31  
 import javax.jms.Queue;
 32  
 import javax.jms.Session;
 33  
 import javax.jms.StreamMessage;
 34  
 import javax.jms.TextMessage;
 35  
 import javax.jms.Topic;
 36  
 
 37  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 38  
 import org.mule.util.ArrayUtils;
 39  
 import org.mule.util.ClassUtils;
 40  
 import org.mule.util.StringUtils;
 41  
 
 42  
 /**
 43  
  * <code>JmsMessageUtils</code> contains helper method for dealing with JMS
 44  
  * messages in Mule.
 45  
  */
 46  0
 public class JmsMessageUtils
 47  
 {
 48  
     public static final char REPLACEMENT_CHAR = '_';
 49  
 
 50  
     /**
 51  
      * Encode a String so that is is a valid JMS header name
 52  
      * 
 53  
      * @param name the String to encode
 54  
      * @return a valid JMS header name
 55  
      */
 56  
     public static String encodeHeader(String name)
 57  
     {
 58  818
         if (StringUtils.isEmpty(name))
 59  
         {
 60  0
             throw new IllegalArgumentException("Header name to encode must not be null or empty");
 61  
         }
 62  
     
 63  818
         int i = 0, length = name.length();
 64  14468
         while (i < length && Character.isJavaIdentifierPart(name.charAt(i)))
 65  
         {
 66  
             // zip through
 67  13649
             i++;
 68  
         }
 69  
     
 70  818
         if (i == length)
 71  
         {
 72  
             // String is already valid
 73  807
             return name;
 74  
         }
 75  
         else
 76  
         {
 77  
             // make a copy, fix up remaining characters
 78  10
             StringBuffer sb = new StringBuffer(name);
 79  98
             for (int j = i; j < length; j++)
 80  
             {
 81  88
                 if (!Character.isJavaIdentifierPart(sb.charAt(j)))
 82  
                 {
 83  16
                     sb.setCharAt(j, REPLACEMENT_CHAR);
 84  
                 }
 85  
             }
 86  10
             return sb.toString();
 87  
         }
 88  
     }
 89  
 
 90  
     public static Message toMessage(Object object, Session session) throws JMSException
 91  
     {
 92  223
         if (object instanceof Message)
 93  
         {
 94  2
             return (Message)object;
 95  
         }
 96  220
         else if (object instanceof String)
 97  
         {
 98  187
             return session.createTextMessage((String)object);
 99  
         }
 100  34
         else if (object instanceof Map)
 101  
         {
 102  2
             MapMessage mMsg = session.createMapMessage();
 103  2
             Map src = (Map)object;
 104  
 
 105  2
             for (Iterator i = src.entrySet().iterator(); i.hasNext();)
 106  
             {
 107  6
                 Map.Entry entry = (Map.Entry)i.next();
 108  6
                 mMsg.setObject(entry.getKey().toString(), entry.getValue());
 109  6
             }
 110  
 
 111  2
             return mMsg;
 112  
         }
 113  32
         else if (object instanceof InputStream)
 114  
         {
 115  0
             StreamMessage sMsg = session.createStreamMessage();        
 116  0
             InputStream temp = (InputStream)object;
 117  
 
 118  0
             byte[] buffer = new byte[4096];
 119  
             int len;
 120  
 
 121  
             try
 122  
             {
 123  0
                 while ((len = temp.read(buffer)) != -1)
 124  
                 {
 125  0
                     sMsg.writeBytes(buffer, 0, len);
 126  
                 }
 127  
             }
 128  0
             catch (IOException e)
 129  
             {
 130  0
                 throw new JMSException("Failed to read input stream to create a stream message: " + e);
 131  0
             }
 132  
 
 133  0
             return sMsg;
 134  
         }
 135  32
         else if (object instanceof List)
 136  
         {
 137  0
             StreamMessage sMsg = session.createStreamMessage();
 138  0
             List list = (List) object;
 139  0
             for (Iterator iter = list.iterator(); iter.hasNext();)
 140  
             {
 141  0
                 sMsg.writeObject(iter.next());
 142  
             }
 143  0
             return sMsg;
 144  
         }
 145  32
         else if (object instanceof byte[])
 146  
         {
 147  20
             BytesMessage bMsg = session.createBytesMessage();
 148  20
             bMsg.writeBytes((byte[])object);
 149  20
             return bMsg;
 150  
         }
 151  12
         else if (object instanceof Serializable)
 152  
         {
 153  12
             ObjectMessage oMsg = session.createObjectMessage();
 154  12
             oMsg.setObject((Serializable)object);
 155  12
             return oMsg;
 156  
         }
 157  
         else
 158  
         {
 159  0
             throw new JMSException(
 160  
                 "Source was not of a supported type, data must be Serializable, String, byte[], Map or InputStream, " +
 161  
                 "but was " + ClassUtils.getShortClassName(object, "<null>"));
 162  
         }
 163  
     }
 164  
 
 165  
     public static Object toObject(Message source, String jmsSpec) throws JMSException, IOException
 166  
     {
 167  178
         if (source instanceof ObjectMessage)
 168  
         {
 169  4
             return ((ObjectMessage)source).getObject();
 170  
         }
 171  173
         else if (source instanceof MapMessage)
 172  
         {
 173  2
             Hashtable map = new Hashtable();
 174  2
             MapMessage m = (MapMessage)source;
 175  
 
 176  2
             for (Enumeration e = m.getMapNames(); e.hasMoreElements();)
 177  
             {
 178  6
                 String name = (String)e.nextElement();
 179  6
                 Object obj = m.getObject(name);
 180  6
                 map.put(name, obj);
 181  6
             }
 182  
 
 183  2
             return map;
 184  
         }
 185  171
         else if (source instanceof TextMessage)
 186  
         {
 187  149
             return ((TextMessage)source).getText();
 188  
         }
 189  22
         else if (source instanceof BytesMessage)
 190  
         {
 191  20
             return toByteArray(source, jmsSpec);
 192  
         }
 193  2
         else if (source instanceof StreamMessage)
 194  
         {
 195  2
             Vector result = new Vector();
 196  
             try
 197  
             {
 198  2
                 StreamMessage sMsg = (StreamMessage)source;
 199  
                 Object obj;
 200  8
                 while ((obj = sMsg.readObject()) != null)
 201  
                 {
 202  6
                     result.addElement(obj);
 203  
                 }
 204  
             }
 205  2
             catch (MessageEOFException eof)
 206  
             {
 207  
                 // ignored
 208  
             }
 209  0
             catch (Exception e)
 210  
             {
 211  0
                 throw new JMSException("Failed to extract information from JMS Stream Message: " + e);
 212  2
             }
 213  2
             return result;
 214  
         }
 215  
 
 216  
         // what else is there to do?
 217  0
         return source;
 218  
     }
 219  
 
 220  
     /**
 221  
      * @param message the message to receive the bytes from. Note this only works for
 222  
      *            TextMessge, ObjectMessage, StreamMessage and BytesMessage.
 223  
      * @param jmsSpec indicates the JMS API version, either
 224  
      *            {@link JmsConstants#JMS_SPECIFICATION_102B} or
 225  
      *            {@link JmsConstants#JMS_SPECIFICATION_11}. Any other value
 226  
      *            including <code>null</code> is treated as fallback to
 227  
      *            {@link JmsConstants#JMS_SPECIFICATION_102B}.
 228  
      * @return a byte array corresponding with the message payload
 229  
      * @throws JMSException if the message can't be read or if the message passed is
 230  
      *             a MapMessage
 231  
      * @throws java.io.IOException if a failure occurs while reading the stream and
 232  
      *             converting the message data
 233  
      */
 234  
     public static byte[] toByteArray(Message message, String jmsSpec) throws JMSException, IOException
 235  
     {
 236  26
         if (message instanceof BytesMessage)
 237  
         {
 238  24
             BytesMessage bMsg = (BytesMessage)message;
 239  24
             bMsg.reset();
 240  
 
 241  24
             if (JmsConstants.JMS_SPECIFICATION_11.equals(jmsSpec))
 242  
             {
 243  2
                 long bmBodyLength = bMsg.getBodyLength();
 244  2
                 if (bmBodyLength > Integer.MAX_VALUE)
 245  
                 {
 246  0
                     throw new JMSException("Size of BytesMessage exceeds Integer.MAX_VALUE; "
 247  
                                            + "please consider using JMS StreamMessage instead");
 248  
                 }
 249  
 
 250  2
                 if (bmBodyLength > 0)
 251  
                 {
 252  0
                     byte[] bytes = new byte[(int)bmBodyLength];
 253  0
                     bMsg.readBytes(bytes);
 254  0
                     return bytes;
 255  
                 }
 256  
                 else
 257  
                 {
 258  2
                     return ArrayUtils.EMPTY_BYTE_ARRAY;
 259  
                 }
 260  
             }
 261  
             else
 262  
             {
 263  22
                 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 264  22
                 byte[] buffer = new byte[4096];
 265  
                 int len;
 266  
 
 267  42
                 while ((len = bMsg.readBytes(buffer)) != -1)
 268  
                 {
 269  20
                     baos.write(buffer, 0, len);
 270  
                 }
 271  
 
 272  22
                 if (baos.size() > 0)
 273  
                 {
 274  20
                     return baos.toByteArray();
 275  
                 }
 276  
                 else
 277  
                 {
 278  2
                     return ArrayUtils.EMPTY_BYTE_ARRAY;
 279  
                 }
 280  
             }
 281  
         }
 282  2
         else if (message instanceof StreamMessage)
 283  
         {
 284  0
             StreamMessage sMsg = (StreamMessage)message;
 285  0
             sMsg.reset();
 286  
 
 287  0
             ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 288  0
             byte[] buffer = new byte[4096];
 289  
             int len;
 290  
 
 291  0
             while ((len = sMsg.readBytes(buffer)) != -1)
 292  
             {
 293  0
                 baos.write(buffer, 0, len);
 294  
             }
 295  
 
 296  0
             return baos.toByteArray();
 297  
         }
 298  2
         else if (message instanceof ObjectMessage)
 299  
         {
 300  0
             ObjectMessage oMsg = (ObjectMessage)message;
 301  0
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 302  0
             ObjectOutputStream os = new ObjectOutputStream(baos);
 303  0
             os.writeObject(oMsg.getObject());
 304  0
             os.flush();
 305  0
             os.close();
 306  0
             return baos.toByteArray();
 307  
         }
 308  2
         else if (message instanceof TextMessage)
 309  
         {
 310  2
             TextMessage tMsg = (TextMessage)message;
 311  2
             String tMsgText = tMsg.getText();
 312  
 
 313  2
             if (null == tMsgText)
 314  
             {
 315  
                 // Avoid creating new instances of byte arrays, even empty ones. The
 316  
                 // load on this part of the code can be high.
 317  2
                 return ArrayUtils.EMPTY_BYTE_ARRAY;
 318  
             }
 319  
             else
 320  
             {
 321  0
                 return tMsgText.getBytes();
 322  
             }
 323  
         }
 324  
         else
 325  
         {
 326  0
             throw new JMSException("Cannot get bytes from Map Message");
 327  
         }
 328  
     }
 329  
 
 330  
     public static String getNameForDestination(Destination dest) throws JMSException
 331  
     {
 332  0
         if (dest instanceof Queue)
 333  
         {
 334  0
             return ((Queue)dest).getQueueName();
 335  
         }
 336  0
         else if (dest instanceof Topic)
 337  
         {
 338  0
             return ((Topic)dest).getTopicName();
 339  
         }
 340  
         else
 341  
         {
 342  0
             return null;
 343  
         }
 344  
     }
 345  
 
 346  
     public static Message copyJMSProperties(Message from, Message to, JmsConnector connector)
 347  
         throws JMSException
 348  
     {
 349  0
         if (connector.supportsProperty(JmsConstants.JMS_CORRELATION_ID))
 350  
         {
 351  0
             to.setJMSCorrelationID(from.getJMSCorrelationID());
 352  
         }
 353  0
         if (connector.supportsProperty(JmsConstants.JMS_DELIVERY_MODE))
 354  
         {
 355  0
             to.setJMSDeliveryMode(from.getJMSDeliveryMode());
 356  
         }
 357  0
         if (connector.supportsProperty(JmsConstants.JMS_DESTINATION))
 358  
         {
 359  0
             to.setJMSDestination(from.getJMSDestination());
 360  
         }
 361  0
         if (connector.supportsProperty(JmsConstants.JMS_EXPIRATION))
 362  
         {
 363  0
             to.setJMSExpiration(from.getJMSExpiration());
 364  
         }
 365  0
         if (connector.supportsProperty(JmsConstants.JMS_MESSAGE_ID))
 366  
         {
 367  0
             to.setJMSMessageID(from.getJMSMessageID());
 368  
         }
 369  0
         if (connector.supportsProperty(JmsConstants.JMS_PRIORITY))
 370  
         {
 371  0
             to.setJMSPriority(from.getJMSPriority());
 372  
         }
 373  0
         if (connector.supportsProperty(JmsConstants.JMS_REDELIVERED))
 374  
         {
 375  0
             to.setJMSRedelivered(from.getJMSRedelivered());
 376  
         }
 377  0
         if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO))
 378  
         {
 379  0
             to.setJMSReplyTo(from.getJMSReplyTo());
 380  
         }
 381  0
         if (connector.supportsProperty(JmsConstants.JMS_TIMESTAMP))
 382  
         {
 383  0
             to.setJMSTimestamp(from.getJMSTimestamp());
 384  
         }
 385  0
         if (connector.supportsProperty(JmsConstants.JMS_TYPE))
 386  
         {
 387  0
             to.setJMSType(from.getJMSType());
 388  
         }
 389  0
         return to;
 390  
     }
 391  
 
 392  
 }