Coverage Report - org.mule.providers.jdbc.JdbcMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
JdbcMessageDispatcher
0%
0/75
0%
0/15
4.429
 
 1  
 /*
 2  
  * $Id: JdbcMessageDispatcher.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 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.jdbc;
 12  
 
 13  
 import org.mule.impl.MuleMessage;
 14  
 import org.mule.providers.AbstractMessageDispatcher;
 15  
 import org.mule.transaction.TransactionCoordination;
 16  
 import org.mule.umo.UMOEvent;
 17  
 import org.mule.umo.UMOMessage;
 18  
 import org.mule.umo.UMOTransaction;
 19  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 20  
 import org.mule.umo.provider.UMOMessageAdapter;
 21  
 import org.mule.util.StringUtils;
 22  
 
 23  
 import java.sql.Connection;
 24  
 import java.util.ArrayList;
 25  
 import java.util.List;
 26  
 
 27  
 /**
 28  
  * The Jdbc Message dispatcher is responsible for executing SQL queries against a
 29  
  * database.
 30  
  */
 31  
 public class JdbcMessageDispatcher extends AbstractMessageDispatcher
 32  
 {
 33  
 
 34  
     private JdbcConnector connector;
 35  
 
 36  
     public JdbcMessageDispatcher(UMOImmutableEndpoint endpoint)
 37  
     {
 38  0
         super(endpoint);
 39  0
         this.connector = (JdbcConnector)endpoint.getConnector();
 40  0
     }
 41  
 
 42  
     /*
 43  
      * (non-Javadoc)
 44  
      * 
 45  
      * @see org.mule.providers.AbstractMessageDispatcher#doDispose()
 46  
      */
 47  
     protected void doDispose()
 48  
     {
 49  
         // template method
 50  0
     }
 51  
 
 52  
     /*
 53  
      * (non-Javadoc)
 54  
      * 
 55  
      * @see org.mule.providers.AbstractMessageDispatcher#doDispatch(org.mule.umo.UMOEvent)
 56  
      */
 57  
     protected void doDispatch(UMOEvent event) throws Exception
 58  
     {
 59  0
         if (logger.isDebugEnabled())
 60  
         {
 61  0
             logger.debug("Dispatch event: " + event);
 62  
         }
 63  
 
 64  0
         UMOImmutableEndpoint endpoint = event.getEndpoint();
 65  0
         String writeStmt = endpoint.getEndpointURI().getAddress();
 66  
         String str;
 67  0
         if ((str = this.connector.getQuery(endpoint, writeStmt)) != null)
 68  
         {
 69  0
             writeStmt = str;
 70  
         }
 71  0
         writeStmt = StringUtils.trimToEmpty(writeStmt);
 72  0
         if (StringUtils.isBlank(writeStmt))
 73  
         {
 74  0
             throw new IllegalArgumentException("Missing a write statement");
 75  
         }
 76  0
         if (!"insert".equalsIgnoreCase(writeStmt.substring(0, 6))
 77  
             && !"update".equalsIgnoreCase(writeStmt.substring(0, 6))
 78  
             && !"delete".equalsIgnoreCase(writeStmt.substring(0, 6)))
 79  
         {
 80  0
             throw new IllegalArgumentException(
 81  
                 "Write statement should be an insert / update / delete sql statement");
 82  
         }
 83  0
         List paramNames = new ArrayList();
 84  0
         writeStmt = connector.parseStatement(writeStmt, paramNames);
 85  
 
 86  0
         Object[] paramValues = connector.getParams(endpoint, paramNames, new MuleMessage(
 87  
             event.getTransformedMessage()));
 88  
 
 89  0
         UMOTransaction tx = TransactionCoordination.getInstance().getTransaction();
 90  0
         Connection con = null;
 91  
         try
 92  
         {
 93  0
             con = this.connector.getConnection();
 94  
 
 95  0
             int nbRows = connector.createQueryRunner().update(con, writeStmt, paramValues);
 96  0
             if (nbRows != 1)
 97  
             {
 98  0
                 logger.warn("Row count for write should be 1 and not " + nbRows);
 99  
             }
 100  0
             if (tx == null)
 101  
             {
 102  0
                 JdbcUtils.commitAndClose(con);
 103  
             }
 104  0
             logger.debug("Event dispatched succesfuly");
 105  
         }
 106  0
         catch (Exception e)
 107  
         {
 108  0
             logger.debug("Error dispatching event: " + e.getMessage(), e);
 109  0
             if (tx == null)
 110  
             {
 111  0
                 JdbcUtils.rollbackAndClose(con);
 112  
             }
 113  0
             throw e;
 114  0
         }
 115  0
     }
 116  
 
 117  
     /*
 118  
      * (non-Javadoc)
 119  
      * 
 120  
      * @see org.mule.providers.AbstractMessageDispatcher#doSend(org.mule.umo.UMOEvent)
 121  
      */
 122  
     protected UMOMessage doSend(UMOEvent event) throws Exception
 123  
     {
 124  0
         doDispatch(event);
 125  0
         return event.getMessage();
 126  
     }
 127  
 
 128  
     /**
 129  
      * Make a specific request to the underlying transport
 130  
      * 
 131  
      * @param timeout the maximum time the operation should block before returning.
 132  
      *            The call should return immediately if there is data available. If
 133  
      *            no data becomes available before the timeout elapses, null will be
 134  
      *            returned
 135  
      * @return the result of the request wrapped in a UMOMessage object. Null will be
 136  
      *         returned if no data was avaialable
 137  
      * @throws Exception if the call to the underlying protocal cuases an exception
 138  
      */
 139  
     protected UMOMessage doReceive(long timeout) throws Exception
 140  
     {
 141  0
         if (logger.isDebugEnabled())
 142  
         {
 143  0
             logger.debug("Trying to receive a message with a timeout of " + timeout);
 144  
         }
 145  
 
 146  0
         String[] stmts = this.connector.getReadAndAckStatements(endpoint);
 147  0
         String readStmt = stmts[0];
 148  0
         String ackStmt = stmts[1];
 149  0
         List readParams = new ArrayList();
 150  0
         List ackParams = new ArrayList();
 151  0
         readStmt = connector.parseStatement(readStmt, readParams);
 152  0
         ackStmt = connector.parseStatement(ackStmt, ackParams);
 153  
 
 154  0
         Connection con = null;
 155  0
         long t0 = System.currentTimeMillis();
 156  
         try
 157  
         {
 158  0
             con = this.connector.getConnection();
 159  0
             if (timeout < 0)
 160  
             {
 161  0
                 timeout = Long.MAX_VALUE;
 162  
             }
 163  
             Object result;
 164  
             do
 165  
             {
 166  0
                 result = connector.createQueryRunner().query(con, readStmt,
 167  
                     connector.getParams(endpoint, readParams, null), connector.createResultSetHandler());
 168  0
                 if (result != null)
 169  
                 {
 170  0
                     if (logger.isDebugEnabled())
 171  
                     {
 172  0
                         logger.debug("Received: " + result);
 173  
                     }
 174  
                     break;
 175  
                 }
 176  0
                 long sleep = Math.min(this.connector.getPollingFrequency(),
 177  
                     timeout - (System.currentTimeMillis() - t0));
 178  0
                 if (sleep > 0)
 179  
                 {
 180  0
                     if (logger.isDebugEnabled())
 181  
                     {
 182  0
                         logger.debug("No results, sleeping for " + sleep);
 183  
                     }
 184  0
                     Thread.sleep(sleep);
 185  
                 }
 186  
                 else
 187  
                 {
 188  0
                     logger.debug("Timeout");
 189  0
                     return null;
 190  
                 }
 191  
             }
 192  0
             while (true);
 193  0
             if (ackStmt != null)
 194  
             {
 195  0
                 int nbRows = connector.createQueryRunner().update(con, ackStmt,
 196  
                     connector.getParams(endpoint, ackParams, result));
 197  0
                 if (nbRows != 1)
 198  
                 {
 199  0
                     logger.warn("Row count for ack should be 1 and not " + nbRows);
 200  
                 }
 201  
             }
 202  0
             UMOMessageAdapter msgAdapter = this.connector.getMessageAdapter(result);
 203  0
             UMOMessage message = new MuleMessage(msgAdapter);
 204  0
             JdbcUtils.commitAndClose(con);
 205  0
             return message;
 206  
         }
 207  0
         catch (Exception e)
 208  
         {
 209  0
             JdbcUtils.rollbackAndClose(con);
 210  0
             throw e;
 211  
         }
 212  
     }
 213  
 
 214  
     protected void doConnect() throws Exception
 215  
     {
 216  
         // template method
 217  0
     }
 218  
 
 219  
     protected void doDisconnect() throws Exception
 220  
     {
 221  
         // template method
 222  0
     }
 223  
 
 224  
 }