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