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