Coverage Report - org.mule.providers.jms.JmsMessageUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
JmsMessageUtils
51%
70/138
50%
47/94
13.333
 
 1  
 /*
 2  
  * $Id: JmsMessageUtils.java 8553 2007-09-22 19:47:56Z aperepel $
 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.providers.jms;
 12  
 
 13  
 import org.mule.util.ArrayUtils;
 14  
 import org.mule.util.ClassUtils;
 15  
 import org.mule.util.StringUtils;
 16  
 
 17  
 import java.io.IOException;
 18  
 import java.io.InputStream;
 19  
 import java.io.ObjectOutputStream;
 20  
 import java.io.Serializable;
 21  
 import java.util.Enumeration;
 22  
 import java.util.Hashtable;
 23  
 import java.util.Iterator;
 24  
 import java.util.Map;
 25  
 import java.util.Vector;
 26  
 
 27  
 import javax.jms.BytesMessage;
 28  
 import javax.jms.Destination;
 29  
 import javax.jms.JMSException;
 30  
 import javax.jms.MapMessage;
 31  
 import javax.jms.Message;
 32  
 import javax.jms.MessageEOFException;
 33  
 import javax.jms.ObjectMessage;
 34  
 import javax.jms.Queue;
 35  
 import javax.jms.Session;
 36  
 import javax.jms.StreamMessage;
 37  
 import javax.jms.TextMessage;
 38  
 import javax.jms.Topic;
 39  
 
 40  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 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  541
         if (StringUtils.isEmpty(name))
 59  
         {
 60  0
             throw new IllegalArgumentException("Header name to encode must not be null or empty");
 61  
         }
 62  
     
 63  541
         int i = 0, length = name.length();
 64  9564
         while (i < length && Character.isJavaIdentifierPart(name.charAt(i)))
 65  
         {
 66  
             // zip through
 67  9023
             i++;
 68  
         }
 69  
     
 70  541
         if (i == length)
 71  
         {
 72  
             // String is already valid
 73  531
             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  152
         if (object instanceof Message)
 93  
         {
 94  8
             return (Message)object;
 95  
         }
 96  144
         else if (object instanceof String)
 97  
         {
 98  129
             return session.createTextMessage((String)object);
 99  
         }
 100  14
         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  12
         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  12
         else if (object instanceof byte[])
 136  
         {
 137  4
             BytesMessage bMsg = session.createBytesMessage();
 138  4
             bMsg.writeBytes((byte[])object);
 139  4
             return bMsg;
 140  
         }
 141  8
         else if (object instanceof Serializable)
 142  
         {
 143  8
             ObjectMessage oMsg = session.createObjectMessage();
 144  8
             oMsg.setObject((Serializable)object);
 145  8
             return oMsg;
 146  
         }
 147  
         else
 148  
         {
 149  0
             throw new JMSException(
 150  
                 "Source was not of a supported type, data must be Serializable, String, byte[], Map or InputStream, " +
 151  
                 "but was " + ClassUtils.getShortClassName(object, "<null>"));
 152  
         }
 153  
     }
 154  
 
 155  
     public static Object toObject(Message source, String jmsSpec) throws JMSException, IOException
 156  
     {
 157  90
         if (source instanceof ObjectMessage)
 158  
         {
 159  6
             return ((ObjectMessage)source).getObject();
 160  
         }
 161  86
         else if (source instanceof MapMessage)
 162  
         {
 163  2
             Hashtable map = new Hashtable();
 164  2
             MapMessage m = (MapMessage)source;
 165  
 
 166  2
             for (Enumeration e = m.getMapNames(); e.hasMoreElements();)
 167  
             {
 168  6
                 String name = (String)e.nextElement();
 169  6
                 Object obj = m.getObject(name);
 170  6
                 map.put(name, obj);
 171  6
             }
 172  
 
 173  2
             return map;
 174  
         }
 175  84
         else if (source instanceof TextMessage)
 176  
         {
 177  80
             return ((TextMessage)source).getText();
 178  
         }
 179  4
         else if (source instanceof BytesMessage)
 180  
         {
 181  4
             return toByteArray(source, jmsSpec);
 182  
         }
 183  0
         else if (source instanceof StreamMessage)
 184  
         {
 185  
             try
 186  
             {
 187  0
                 StreamMessage sMsg = (StreamMessage)source;
 188  0
                 Vector result = new Vector();
 189  
                 Object obj;
 190  0
                 while ((obj = sMsg.readObject()) != null)
 191  
                 {
 192  0
                     result.addElement(obj);
 193  
                 }
 194  0
                 return result;
 195  
             }
 196  0
             catch (MessageEOFException eof)
 197  
             {
 198  
                 // ignored
 199  
             }
 200  0
             catch (Exception e)
 201  
             {
 202  0
                 throw new JMSException("Failed to extract information from JMS Stream Message: " + e);
 203  0
             }
 204  
         }
 205  
 
 206  
         // what else is there to do?
 207  0
         return source;
 208  
     }
 209  
 
 210  
     /**
 211  
      * @param message the message to receive the bytes from. Note this only works for
 212  
      *            TextMessge, ObjectMessage, StreamMessage and BytesMessage.
 213  
      * @param jmsSpec indicates the JMS API version, either
 214  
      *            {@link JmsConstants#JMS_SPECIFICATION_102B} or
 215  
      *            {@link JmsConstants#JMS_SPECIFICATION_11}. Any other value
 216  
      *            including <code>null</code> is treated as fallback to
 217  
      *            {@link JmsConstants#JMS_SPECIFICATION_102B}.
 218  
      * @return a byte array corresponding with the message payload
 219  
      * @throws JMSException if the message can't be read or if the message passed is
 220  
      *             a MapMessage
 221  
      * @throws java.io.IOException if a failure occurs while reading the stream and
 222  
      *             converting the message data
 223  
      */
 224  
     public static byte[] toByteArray(Message message, String jmsSpec) throws JMSException, IOException
 225  
     {
 226  16
         if (message instanceof BytesMessage)
 227  
         {
 228  8
             BytesMessage bMsg = (BytesMessage)message;
 229  8
             bMsg.reset();
 230  
 
 231  8
             if (JmsConstants.JMS_SPECIFICATION_11.equals(jmsSpec))
 232  
             {
 233  2
                 long bmBodyLength = bMsg.getBodyLength();
 234  2
                 if (bmBodyLength > Integer.MAX_VALUE)
 235  
                 {
 236  0
                     throw new JMSException("Size of BytesMessage exceeds Integer.MAX_VALUE; "
 237  
                                            + "please consider using JMS StreamMessage instead");
 238  
                 }
 239  
 
 240  2
                 if (bmBodyLength > 0)
 241  
                 {
 242  0
                     byte[] bytes = new byte[(int)bmBodyLength];
 243  0
                     bMsg.readBytes(bytes);
 244  0
                     return bytes;
 245  
                 }
 246  
                 else
 247  
                 {
 248  2
                     return ArrayUtils.EMPTY_BYTE_ARRAY;
 249  
                 }
 250  
             }
 251  
             else
 252  
             {
 253  6
                 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 254  6
                 byte[] buffer = new byte[4096];
 255  
                 int len;
 256  
 
 257  10
                 while ((len = bMsg.readBytes(buffer)) != -1)
 258  
                 {
 259  4
                     baos.write(buffer, 0, len);
 260  
                 }
 261  
 
 262  6
                 if (baos.size() > 0)
 263  
                 {
 264  4
                     return baos.toByteArray();
 265  
                 }
 266  
                 else
 267  
                 {
 268  2
                     return ArrayUtils.EMPTY_BYTE_ARRAY;
 269  
                 }
 270  
             }
 271  
         }
 272  8
         else if (message instanceof StreamMessage)
 273  
         {
 274  0
             StreamMessage sMsg = (StreamMessage)message;
 275  0
             sMsg.reset();
 276  
 
 277  0
             ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 278  0
             byte[] buffer = new byte[4096];
 279  
             int len;
 280  
 
 281  0
             while ((len = sMsg.readBytes(buffer)) != -1)
 282  
             {
 283  0
                 baos.write(buffer, 0, len);
 284  
             }
 285  
 
 286  0
             return baos.toByteArray();
 287  
         }
 288  8
         else if (message instanceof ObjectMessage)
 289  
         {
 290  0
             ObjectMessage oMsg = (ObjectMessage)message;
 291  0
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 292  0
             ObjectOutputStream os = new ObjectOutputStream(baos);
 293  0
             os.writeObject(oMsg.getObject());
 294  0
             os.flush();
 295  0
             os.close();
 296  0
             return baos.toByteArray();
 297  
         }
 298  8
         else if (message instanceof TextMessage)
 299  
         {
 300  8
             TextMessage tMsg = (TextMessage)message;
 301  8
             String tMsgText = tMsg.getText();
 302  
 
 303  8
             if (null == tMsgText)
 304  
             {
 305  
                 // Avoid creating new instances of byte arrays, even empty ones. The
 306  
                 // load on this part of the code can be high.
 307  2
                 return ArrayUtils.EMPTY_BYTE_ARRAY;
 308  
             }
 309  
             else
 310  
             {
 311  6
                 return tMsgText.getBytes();
 312  
             }
 313  
         }
 314  
         else
 315  
         {
 316  0
             throw new JMSException("Cannot get bytes from Map Message");
 317  
         }
 318  
     }
 319  
 
 320  
     public static String getNameForDestination(Destination dest) throws JMSException
 321  
     {
 322  0
         if (dest instanceof Queue)
 323  
         {
 324  0
             return ((Queue)dest).getQueueName();
 325  
         }
 326  0
         else if (dest instanceof Topic)
 327  
         {
 328  0
             return ((Topic)dest).getTopicName();
 329  
         }
 330  
         else
 331  
         {
 332  0
             return null;
 333  
         }
 334  
     }
 335  
 
 336  
     public static Message copyJMSProperties(Message from, Message to, JmsConnector connector)
 337  
         throws JMSException
 338  
     {
 339  0
         if (connector.supportsProperty(JmsConstants.JMS_CORRELATION_ID))
 340  
         {
 341  0
             to.setJMSCorrelationID(from.getJMSCorrelationID());
 342  
         }
 343  0
         if (connector.supportsProperty(JmsConstants.JMS_DELIVERY_MODE))
 344  
         {
 345  0
             to.setJMSDeliveryMode(from.getJMSDeliveryMode());
 346  
         }
 347  0
         if (connector.supportsProperty(JmsConstants.JMS_DESTINATION))
 348  
         {
 349  0
             to.setJMSDestination(from.getJMSDestination());
 350  
         }
 351  0
         if (connector.supportsProperty(JmsConstants.JMS_EXPIRATION))
 352  
         {
 353  0
             to.setJMSExpiration(from.getJMSExpiration());
 354  
         }
 355  0
         if (connector.supportsProperty(JmsConstants.JMS_MESSAGE_ID))
 356  
         {
 357  0
             to.setJMSMessageID(from.getJMSMessageID());
 358  
         }
 359  0
         if (connector.supportsProperty(JmsConstants.JMS_PRIORITY))
 360  
         {
 361  0
             to.setJMSPriority(from.getJMSPriority());
 362  
         }
 363  0
         if (connector.supportsProperty(JmsConstants.JMS_REDELIVERED))
 364  
         {
 365  0
             to.setJMSRedelivered(from.getJMSRedelivered());
 366  
         }
 367  0
         if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO))
 368  
         {
 369  0
             to.setJMSReplyTo(from.getJMSReplyTo());
 370  
         }
 371  0
         if (connector.supportsProperty(JmsConstants.JMS_TIMESTAMP))
 372  
         {
 373  0
             to.setJMSTimestamp(from.getJMSTimestamp());
 374  
         }
 375  0
         if (connector.supportsProperty(JmsConstants.JMS_TYPE))
 376  
         {
 377  0
             to.setJMSType(from.getJMSType());
 378  
         }
 379  0
         return to;
 380  
     }
 381  
 
 382  
 }