View Javadoc

1   /*
2    * $Id: JdbcMessageReceiver.java 8212 2007-09-05 14:56:50Z marie.rizzo $
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.MuleManager;
14  import org.mule.impl.MuleMessage;
15  import org.mule.providers.ConnectException;
16  import org.mule.providers.TransactedPollingMessageReceiver;
17  import org.mule.transaction.TransactionCoordination;
18  import org.mule.umo.UMOComponent;
19  import org.mule.umo.UMOMessage;
20  import org.mule.umo.UMOTransaction;
21  import org.mule.umo.endpoint.UMOEndpoint;
22  import org.mule.umo.lifecycle.InitialisationException;
23  import org.mule.umo.provider.UMOConnector;
24  import org.mule.umo.provider.UMOMessageAdapter;
25  
26  import java.sql.Connection;
27  import java.sql.SQLException;
28  import java.util.ArrayList;
29  import java.util.List;
30  
31  /**
32   * TODO
33   */
34  public class JdbcMessageReceiver extends TransactedPollingMessageReceiver
35  {
36  
37      protected JdbcConnector connector;
38      protected String readStmt;
39      protected String ackStmt;
40      protected List readParams;
41      protected List ackParams;
42  
43      public JdbcMessageReceiver(UMOConnector connector,
44                                 UMOComponent component,
45                                 UMOEndpoint endpoint,
46                                 String readStmt,
47                                 String ackStmt) throws InitialisationException
48      {
49          super(connector, component, endpoint);
50          this.setFrequency(((JdbcConnector)connector).getPollingFrequency());
51          this.setReceiveMessagesInTransaction(false);
52  
53          this.connector = (JdbcConnector)connector;
54          this.readParams = new ArrayList();
55          this.readStmt = this.connector.parseStatement(readStmt, this.readParams);
56          this.ackParams = new ArrayList();
57          this.ackStmt = this.connector.parseStatement(ackStmt, this.ackParams);
58      }
59  
60      protected void doDispose()
61      {
62          // template method
63      }
64  
65      protected void doConnect() throws Exception
66      {
67          Connection con = null;
68          try
69          {
70              con = this.connector.getConnection();
71          }
72          catch (Exception e)
73          {
74              throw new ConnectException(e, this);
75          }
76          finally
77          {
78              JdbcUtils.close(con);
79          }
80      }
81  
82      protected void doDisconnect() throws ConnectException
83      {
84          // noop
85      }
86  
87      public void processMessage(Object message) throws Exception
88      {
89          Connection con = null;
90          UMOTransaction tx = TransactionCoordination.getInstance().getTransaction();
91          try
92          {
93              con = this.connector.getConnection();
94              UMOMessageAdapter msgAdapter = this.connector.getMessageAdapter(message);
95              UMOMessage umoMessage = new MuleMessage(msgAdapter);
96              if (this.ackStmt != null)
97              {
98  
99                  Object[] ackParams = connector.getParams(endpoint, this.ackParams, umoMessage, this.endpoint.getEndpointURI().getAddress());
100                 int nbRows = connector.createQueryRunner().update(con, this.ackStmt, ackParams);
101                 if (nbRows != 1)
102                 {
103                     logger.warn("Row count for ack should be 1 and not " + nbRows);
104                 }
105             }
106             routeMessage(umoMessage, tx, tx != null || endpoint.isSynchronous());
107 
108         }
109         catch (Exception ex)
110         {
111             if (tx != null)
112             {
113                 tx.setRollbackOnly();
114             }
115 
116             // rethrow
117             throw ex;
118         }
119         finally
120         {
121             if (MuleManager.getInstance().getTransactionManager() != null || tx == null)
122             {
123                 // We are running in an XA transaction.
124                 // This call is required here for compatibility with strict XA
125                 // DataSources
126                 // implementations, as is the case for WebSphere AS and Weblogic.
127                 // Failure to do it here may result in a connection leak.
128                 // The close() call will NOT close the connection, neither will it
129                 // return it to the pool.
130                 // It will notify the XA driver's ConnectionEventListener that the XA
131                 // connection
132                 // is no longer used by the application and is ready for the 2PC
133                 // commit.
134                 JdbcUtils.close(con);
135             }
136         }
137     }
138 
139     public List getMessages() throws Exception
140     {
141         Connection con = null;
142         try
143         {
144             try
145             {
146                 con = this.connector.getConnection();
147             }
148             catch (SQLException e)
149             {
150                 throw new ConnectException(e, this);
151             }
152 
153             Object[] readParams = connector.getParams(endpoint, this.readParams, null, this.endpoint.getEndpointURI().getAddress());
154             Object results = connector.createQueryRunner().query(con, this.readStmt, readParams,
155                 connector.createResultSetHandler());
156             return (List)results;
157         }
158         finally
159         {
160             JdbcUtils.close(con);
161         }
162     }
163 
164 }