Coverage Report - org.mule.providers.jms.transformers.AbstractJmsTransformer
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractJmsTransformer
75%
44/59
50%
23/46
6.6
 
 1  
 /*
 2  
  * $Id: AbstractJmsTransformer.java 9704 2007-11-13 15:18:15Z 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.transformers;
 12  
 
 13  
 import org.mule.config.MuleProperties;
 14  
 import org.mule.impl.RequestContext;
 15  
 import org.mule.providers.jms.JmsConnector;
 16  
 import org.mule.providers.jms.JmsConstants;
 17  
 import org.mule.providers.jms.JmsMessageUtils;
 18  
 import org.mule.transaction.TransactionCoordination;
 19  
 import org.mule.transformers.AbstractTransformer;
 20  
 import org.mule.umo.UMOEventContext;
 21  
 import org.mule.umo.UMOMessage;
 22  
 import org.mule.umo.UMOTransaction;
 23  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 24  
 import org.mule.umo.provider.UMOConnector;
 25  
 import org.mule.umo.transformer.TransformerException;
 26  
 import org.mule.util.ClassUtils;
 27  
 
 28  
 import java.util.Iterator;
 29  
 
 30  
 import javax.jms.Destination;
 31  
 import javax.jms.JMSException;
 32  
 import javax.jms.Message;
 33  
 import javax.jms.Session;
 34  
 
 35  
 /**
 36  
  * <code>AbstractJmsTransformer</code> is an abstract class that should be used for
 37  
  * all transformers where a JMS message will be the transformed or transformee
 38  
  * object. It provides services for compressing and uncompressing messages.
 39  
  */
 40  
 
 41  
 public abstract class AbstractJmsTransformer extends AbstractTransformer
 42  
 {
 43  
 
 44  
     public AbstractJmsTransformer()
 45  
     {
 46  670
         super();
 47  670
     }
 48  
 
 49  
     protected Message transformToMessage(Object src) throws TransformerException
 50  
     {
 51  146
         Session session = null;
 52  
         try
 53  
         {
 54  
             Message result;
 55  
 
 56  146
             if (src instanceof Message)
 57  
             {
 58  2
                 result = (Message) src;
 59  2
                 result.clearProperties();
 60  
             }
 61  
             else
 62  
             {
 63  144
                 session = this.getSession();
 64  144
                 result = JmsMessageUtils.toMessage(src, session);
 65  
             }
 66  
 
 67  
             // set the event properties on the Message
 68  146
             UMOEventContext ctx = RequestContext.getEventContext();
 69  145
             if (ctx == null)
 70  
             {
 71  0
                 logger.warn("There is no current event context");
 72  0
                 return result;
 73  
             }
 74  
 
 75  144
             this.setJmsProperties(ctx.getMessage(), result);
 76  
 
 77  144
             return result;
 78  
         }
 79  0
         catch (TransformerException tex)
 80  
         {
 81  
             // rethrow
 82  0
             throw tex;
 83  
         }
 84  2
         catch (Exception e)
 85  
         {
 86  2
             throw new TransformerException(this, e);
 87  
         }
 88  
         finally
 89  
         {
 90  
             /*
 91  
                 session.getTransacted() would be easier in most cases, but e.g. in Weblogic 8.x
 92  
                 Java EE apps there could be some quirks, see http://forums.bea.com/thread.jspa?threadID=200007643
 93  
                 to get a picture.
 94  
 
 95  
                 Though JmsTransaction has this session.getTransacted() validation already, we're taking extra precautions
 96  
                 to cover XA cases and potentially to make up for a configuration error. E.g. omitting transaction
 97  
                 configuration from an outbound endpoint or router. Note, XA support in Mule will deliberately
 98  
                 fail with fanfares to signal this case, which is really a user error.
 99  
               */
 100  
 
 101  2
             if (session != null && endpoint != null) // endpoint can be null in some programmatic tests only in fact
 102  
             {
 103  132
                 UMOTransaction muleTx = TransactionCoordination.getInstance().getTransaction();
 104  
 
 105  133
                 final JmsConnector connector = (JmsConnector) endpoint.getConnector();
 106  133
                 if (muleTx == null)
 107  
                 {
 108  71
                     if (logger.isDebugEnabled())
 109  
                     {
 110  0
                         logger.debug("Closing non-transacted jms session: " + session);
 111  
                     }
 112  71
                     connector.closeQuietly(session);
 113  
                 }
 114  62
                 else if (!muleTx.hasResource(connector.getConnection()))
 115  
                 {
 116  
                     // this is some other session from another connection, don't let it leak
 117  0
                     if (logger.isDebugEnabled())
 118  
                     {
 119  0
                         logger.debug("Closing an orphaned, but transacted jms session: " + session +
 120  
                                     ", transaction: " + muleTx);
 121  
                     }
 122  0
                     connector.closeQuietly(session);
 123  
                 }
 124  
             }
 125  
             // aggressively killing any session refs
 126  146
             session = null;
 127  
         }
 128  
     }
 129  
 
 130  
     protected Object transformFromMessage(Message source) throws TransformerException
 131  
     {
 132  
         try
 133  
         {
 134  87
             if (logger.isDebugEnabled())
 135  
             {
 136  0
                 logger.debug("Message type received is: " +
 137  
                         ClassUtils.getSimpleName(source.getClass()));
 138  
             }
 139  
 
 140  
             // Try to figure out our endpoint's JMS Specification and fall back to
 141  
             // 1.0.2 if none is set.
 142  87
             String jmsSpec = JmsConstants.JMS_SPECIFICATION_102B;
 143  87
             UMOImmutableEndpoint endpoint = this.getEndpoint();
 144  87
             if (endpoint != null)
 145  
             {
 146  77
                 UMOConnector connector = endpoint.getConnector();
 147  77
                 if (connector instanceof JmsConnector)
 148  
                 {
 149  78
                     jmsSpec = ((JmsConnector)connector).getSpecification();
 150  
                 }
 151  
             }
 152  
 
 153  86
             return JmsMessageUtils.toObject(source, jmsSpec);
 154  
         }
 155  0
         catch (Exception e)
 156  
         {
 157  0
             throw new TransformerException(this, e);
 158  
         }
 159  
     }
 160  
 
 161  
     protected void setJmsProperties(UMOMessage umoMessage, Message msg) throws JMSException
 162  
     {
 163  143
         for (Iterator iterator = umoMessage.getPropertyNames().iterator(); iterator.hasNext();)
 164  
         {
 165  1399
             String key = iterator.next().toString();
 166  
 
 167  1397
             if (!JmsConstants.JMS_PROPERTY_NAMES.contains(key))
 168  
             {
 169  524
                 Object value = umoMessage.getProperty(key);
 170  
 
 171  524
                 if (MuleProperties.MULE_CORRELATION_ID_PROPERTY.equals(key))
 172  
                 {
 173  118
                     msg.setJMSCorrelationID(umoMessage.getCorrelationId());
 174  
                 }
 175  
 
 176  
                 // We dont want to set the ReplyTo property again as it will be set
 177  
                 // using JMSReplyTo
 178  524
                 if (!(MuleProperties.MULE_REPLY_TO_PROPERTY.equals(key) && value instanceof Destination))
 179  
                 {
 180  
                     // sanitize key as JMS header
 181  522
                     key = JmsMessageUtils.encodeHeader(key);
 182  
 
 183  
                     try
 184  
                     {
 185  523
                         msg.setObjectProperty(key, value);
 186  
                     }
 187  0
                     catch (JMSException e)
 188  
                     {
 189  
                         // Various JMS servers have slightly different rules to what
 190  
                         // can be set as an object property on the message; therefore
 191  
                         // we have to take a hit n' hope approach
 192  0
                         if (logger.isDebugEnabled())
 193  
                         {
 194  0
                             logger.debug("Unable to set property '" + key + "' of type "
 195  
                                     + ClassUtils.getSimpleName(value.getClass())
 196  
                                     + "': " + e.getMessage());
 197  
                         }
 198  521
                     }
 199  
                 }
 200  
             }
 201  1396
         }
 202  144
     }
 203  
 
 204  
     protected Session getSession() throws TransformerException, JMSException
 205  
     {
 206  134
         if (endpoint != null)
 207  
         {
 208  134
             return ((JmsConnector)endpoint.getConnector()).getSession(endpoint);
 209  
         }
 210  
         else
 211  
         {
 212  0
             throw new TransformerException(this, new IllegalStateException(
 213  
                 "This transformer needs a valid endpoint"));
 214  
         }
 215  
     }
 216  
 
 217  
 }