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