001: /*
002: * $Id: ConnectionWrapper.java 10590 2008-01-29 01:39:47Z tcarlson $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.transport.jdbc.xa;
012:
013: import org.mule.api.transaction.Transaction;
014: import org.mule.config.i18n.CoreMessages;
015: import org.mule.transaction.IllegalTransactionStateException;
016: import org.mule.transaction.TransactionCoordination;
017: import org.mule.transaction.XaTransaction;
018:
019: import java.lang.reflect.Proxy;
020: import java.sql.CallableStatement;
021: import java.sql.Connection;
022: import java.sql.DatabaseMetaData;
023: import java.sql.PreparedStatement;
024: import java.sql.SQLException;
025: import java.sql.SQLWarning;
026: import java.sql.Savepoint;
027: import java.sql.Statement;
028: import java.util.Map;
029:
030: import javax.sql.XAConnection;
031: import javax.transaction.xa.XAResource;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
036: /**
037: * Using for unification XAConnection and Connection
038: */
039: public class ConnectionWrapper implements Connection,
040: XaTransaction.MuleXaObject {
041: private final XAConnection xaConnection;
042: private Connection connection;
043: private volatile boolean enlisted = false;
044: protected static final transient Log logger = LogFactory
045: .getLog(ConnectionWrapper.class);
046: private volatile boolean reuseObject = false;
047:
048: public ConnectionWrapper(XAConnection xaCon) throws SQLException {
049: this .xaConnection = xaCon;
050: this .connection = xaCon.getConnection();
051: }
052:
053: /*
054: * (non-Javadoc)
055: *
056: * @see java.sql.Connection#getHoldability()
057: */
058:
059: public int getHoldability() throws SQLException {
060: return connection.getHoldability();
061: }
062:
063: /*
064: * (non-Javadoc)
065: *
066: * @see java.sql.Connection#getTransactionIsolation()
067: */
068: public int getTransactionIsolation() throws SQLException {
069: return connection.getTransactionIsolation();
070: }
071:
072: /*
073: * (non-Javadoc)
074: *
075: * @see java.sql.Connection#clearWarnings()
076: */
077: public void clearWarnings() throws SQLException {
078: connection.clearWarnings();
079: }
080:
081: /*
082: * (non-Javadoc)
083: *
084: * @see java.sql.Connection#close()
085: */
086: public void close() throws SQLException {
087: connection.close();
088: }
089:
090: /*
091: * (non-Javadoc)
092: *
093: * @see java.sql.Connection#commit()
094: */
095: public void commit() throws SQLException {
096: connection.commit();
097: }
098:
099: /*
100: * (non-Javadoc)
101: *
102: * @see java.sql.Connection#rollback()
103: */
104: public void rollback() throws SQLException {
105: connection.rollback();
106: }
107:
108: /*
109: * (non-Javadoc)
110: *
111: * @see java.sql.Connection#getAutoCommit()
112: */
113: public boolean getAutoCommit() throws SQLException {
114: return connection.getAutoCommit();
115: }
116:
117: /*
118: * (non-Javadoc)
119: *
120: * @see java.sql.Connection#isClosed()
121: */
122: public boolean isClosed() throws SQLException {
123: return connection.isClosed();
124: }
125:
126: /*
127: * (non-Javadoc)
128: *
129: * @see java.sql.Connection#isReadOnly()
130: */
131: public boolean isReadOnly() throws SQLException {
132: return connection.isReadOnly();
133: }
134:
135: /*
136: * (non-Javadoc)
137: *
138: * @see java.sql.Connection#setHoldability(int)
139: */
140: public void setHoldability(int holdability) throws SQLException {
141: connection.setHoldability(holdability);
142: }
143:
144: /*
145: * (non-Javadoc)
146: *
147: * @see java.sql.Connection#setTransactionIsolation(int)
148: */
149: public void setTransactionIsolation(int level) throws SQLException {
150: connection.setTransactionIsolation(level);
151: }
152:
153: /*
154: * (non-Javadoc)
155: *
156: * @see java.sql.Connection#setAutoCommit(boolean)
157: */
158: public void setAutoCommit(boolean autoCommit) throws SQLException {
159: connection.setAutoCommit(autoCommit);
160: }
161:
162: /*
163: * (non-Javadoc)
164: *
165: * @see java.sql.Connection#setReadOnly(boolean)
166: */
167: public void setReadOnly(boolean readOnly) throws SQLException {
168: connection.setReadOnly(readOnly);
169: }
170:
171: /*
172: * (non-Javadoc)
173: *
174: * @see java.sql.Connection#getCatalog()
175: */
176: public String getCatalog() throws SQLException {
177: return connection.getCatalog();
178: }
179:
180: /*
181: * (non-Javadoc)
182: *
183: * @see java.sql.Connection#setCatalog(java.lang.String)
184: */
185: public void setCatalog(String catalog) throws SQLException {
186: connection.setCatalog(catalog);
187: }
188:
189: /*
190: * (non-Javadoc)
191: *
192: * @see java.sql.Connection#getMetaData()
193: */
194: public DatabaseMetaData getMetaData() throws SQLException {
195: return connection.getMetaData();
196: }
197:
198: /*
199: * (non-Javadoc)
200: *
201: * @see java.sql.Connection#getWarnings()
202: */
203: public SQLWarning getWarnings() throws SQLException {
204: return connection.getWarnings();
205: }
206:
207: /*
208: * (non-Javadoc)
209: *
210: * @see java.sql.Connection#setSavepoint()
211: */
212: public Savepoint setSavepoint() throws SQLException {
213: return connection.setSavepoint();
214: }
215:
216: /*
217: * (non-Javadoc)
218: *
219: * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
220: */
221: public void releaseSavepoint(Savepoint savepoint)
222: throws SQLException {
223: connection.releaseSavepoint(savepoint);
224: }
225:
226: /*
227: * (non-Javadoc)
228: *
229: * @see java.sql.Connection#rollback(java.sql.Savepoint)
230: */
231: public void rollback(Savepoint savepoint) throws SQLException {
232: connection.rollback();
233: }
234:
235: /*
236: * (non-Javadoc)
237: *
238: * @see java.sql.Connection#createStatement()
239: */
240: public Statement createStatement() throws SQLException {
241: Statement st = connection.createStatement();
242: return (Statement) Proxy.newProxyInstance(Statement.class
243: .getClassLoader(), new Class[] { Statement.class },
244: new StatementInvocationHandler(this , st));
245: }
246:
247: /*
248: * (non-Javadoc)
249: *
250: * @see java.sql.Connection#createStatement(int, int)
251: */
252: public Statement createStatement(int resultSetType,
253: int resultSetConcurrency) throws SQLException {
254: Statement st = connection.createStatement(resultSetType,
255: resultSetConcurrency);
256: return (Statement) Proxy.newProxyInstance(Statement.class
257: .getClassLoader(), new Class[] { Statement.class },
258: new StatementInvocationHandler(this , st));
259: }
260:
261: /*
262: * (non-Javadoc)
263: *
264: * @see java.sql.Connection#createStatement(int, int, int)
265: */
266: public Statement createStatement(int resultSetType,
267: int resultSetConcurrency, int resultSetHoldability)
268: throws SQLException {
269: Statement st = connection.createStatement(resultSetType,
270: resultSetConcurrency, resultSetHoldability);
271: return (Statement) Proxy.newProxyInstance(Statement.class
272: .getClassLoader(), new Class[] { Statement.class },
273: new StatementInvocationHandler(this , st));
274: }
275:
276: /*
277: * (non-Javadoc)
278: *
279: * @see java.sql.Connection#getTypeMap()
280: */
281: public Map getTypeMap() throws SQLException {
282: return connection.getTypeMap();
283: }
284:
285: /*
286: * (non-Javadoc)
287: *
288: * @see java.sql.Connection#setTypeMap(java.util.Map)
289: */
290: public void setTypeMap(Map map) throws SQLException {
291: connection.setTypeMap(map);
292: }
293:
294: /*
295: * (non-Javadoc)
296: *
297: * @see java.sql.Connection#nativeSQL(java.lang.String)
298: */
299: public String nativeSQL(String sql) throws SQLException {
300: return connection.nativeSQL(sql);
301: }
302:
303: /*
304: * (non-Javadoc)
305: *
306: * @see java.sql.Connection#prepareCall(java.lang.String)
307: */
308: public CallableStatement prepareCall(String sql)
309: throws SQLException {
310: CallableStatement cs = connection.prepareCall(sql);
311: return (CallableStatement) Proxy.newProxyInstance(
312: CallableStatement.class.getClassLoader(),
313: new Class[] { CallableStatement.class },
314: new StatementInvocationHandler(this , cs));
315: }
316:
317: /*
318: * (non-Javadoc)
319: *
320: * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
321: */
322: public CallableStatement prepareCall(String sql, int resultSetType,
323: int resultSetConcurrency) throws SQLException {
324: CallableStatement cs = connection.prepareCall(sql,
325: resultSetType, resultSetConcurrency);
326: return (CallableStatement) Proxy.newProxyInstance(
327: CallableStatement.class.getClassLoader(),
328: new Class[] { CallableStatement.class },
329: new StatementInvocationHandler(this , cs));
330: }
331:
332: /*
333: * (non-Javadoc)
334: *
335: * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
336: */
337: public CallableStatement prepareCall(String sql, int resultSetType,
338: int resultSetConcurrency, int resultSetHoldability)
339: throws SQLException {
340: CallableStatement cs = connection.prepareCall(sql,
341: resultSetType, resultSetConcurrency,
342: resultSetHoldability);
343: return (CallableStatement) Proxy.newProxyInstance(
344: CallableStatement.class.getClassLoader(),
345: new Class[] { CallableStatement.class },
346: new StatementInvocationHandler(this , cs));
347: }
348:
349: /*
350: * (non-Javadoc)
351: *
352: * @see java.sql.Connection#prepareStatement(java.lang.String)
353: */
354: public PreparedStatement prepareStatement(String sql)
355: throws SQLException {
356: PreparedStatement ps = connection.prepareStatement(sql);
357: return (PreparedStatement) Proxy.newProxyInstance(
358: PreparedStatement.class.getClassLoader(),
359: new Class[] { PreparedStatement.class },
360: new StatementInvocationHandler(this , ps));
361: }
362:
363: /*
364: * (non-Javadoc)
365: *
366: * @see java.sql.Connection#prepareStatement(java.lang.String, int)
367: */
368: public PreparedStatement prepareStatement(String sql,
369: int autoGeneratedKeys) throws SQLException {
370: PreparedStatement ps = connection.prepareStatement(sql,
371: autoGeneratedKeys);
372: return (PreparedStatement) Proxy.newProxyInstance(
373: PreparedStatement.class.getClassLoader(),
374: new Class[] { PreparedStatement.class },
375: new StatementInvocationHandler(this , ps));
376: }
377:
378: /*
379: * (non-Javadoc)
380: *
381: * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
382: */
383: public PreparedStatement prepareStatement(String sql,
384: int resultSetType, int resultSetConcurrency)
385: throws SQLException {
386: PreparedStatement ps = connection.prepareStatement(sql,
387: resultSetType, resultSetConcurrency);
388: return (PreparedStatement) Proxy.newProxyInstance(
389: PreparedStatement.class.getClassLoader(),
390: new Class[] { PreparedStatement.class },
391: new StatementInvocationHandler(this , ps));
392: }
393:
394: /*
395: * (non-Javadoc)
396: *
397: * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int)
398: */
399: public PreparedStatement prepareStatement(String sql,
400: int resultSetType, int resultSetConcurrency,
401: int resultSetHoldability) throws SQLException {
402: PreparedStatement ps = connection.prepareStatement(sql,
403: resultSetType, resultSetConcurrency,
404: resultSetHoldability);
405: return (PreparedStatement) Proxy.newProxyInstance(
406: PreparedStatement.class.getClassLoader(),
407: new Class[] { PreparedStatement.class },
408: new StatementInvocationHandler(this , ps));
409: }
410:
411: /*
412: * (non-Javadoc)
413: *
414: * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
415: */
416: public PreparedStatement prepareStatement(String sql,
417: int[] columnIndexes) throws SQLException {
418: PreparedStatement ps = connection.prepareStatement(sql,
419: columnIndexes);
420: return (PreparedStatement) Proxy.newProxyInstance(
421: PreparedStatement.class.getClassLoader(),
422: new Class[] { PreparedStatement.class },
423: new StatementInvocationHandler(this , ps));
424: }
425:
426: /*
427: * (non-Javadoc)
428: *
429: * @see java.sql.Connection#setSavepoint(java.lang.String)
430: */
431: public Savepoint setSavepoint(String name) throws SQLException {
432: return connection.setSavepoint(name);
433: }
434:
435: /*
436: * (non-Javadoc)
437: *
438: * @see java.sql.Connection#prepareStatement(java.lang.String,
439: * java.lang.String[])
440: */
441: public PreparedStatement prepareStatement(String sql,
442: String[] columnNames) throws SQLException {
443: PreparedStatement ps = connection.prepareStatement(sql,
444: columnNames);
445: return (PreparedStatement) Proxy.newProxyInstance(
446: PreparedStatement.class.getClassLoader(),
447: new Class[] { PreparedStatement.class },
448: new StatementInvocationHandler(this , ps));
449: }
450:
451: protected void enlist() throws Exception {
452: if (isEnlisted()) {
453: return;
454: }
455: if (logger.isDebugEnabled()) {
456: logger.debug("Enlistment request: " + this );
457: }
458:
459: Transaction transaction = TransactionCoordination.getInstance()
460: .getTransaction();
461: if (transaction == null) {
462: throw new IllegalTransactionStateException(CoreMessages
463: .noMuleTransactionAvailable());
464: }
465: if (!(transaction instanceof XaTransaction)) {
466: throw new IllegalTransactionStateException(CoreMessages
467: .notMuleXaTransaction(transaction));
468: }
469: if (!isEnlisted()) {
470: enlisted = ((XaTransaction) transaction)
471: .enlistResource(xaConnection.getXAResource());
472: }
473: }
474:
475: public boolean delist() throws Exception {
476: if (!isEnlisted()) {
477: return false;
478: }
479: if (logger.isDebugEnabled()) {
480: logger.debug("Delistment request: " + this );
481: }
482:
483: Transaction transaction = TransactionCoordination.getInstance()
484: .getTransaction();
485: if (transaction == null) {
486: throw new IllegalTransactionStateException(CoreMessages
487: .noMuleTransactionAvailable());
488: }
489: if (!(transaction instanceof XaTransaction)) {
490: throw new IllegalTransactionStateException(CoreMessages
491: .notMuleXaTransaction(transaction));
492: }
493: if (isEnlisted()) {
494: enlisted = !((XaTransaction) transaction).delistResource(
495: xaConnection.getXAResource(), XAResource.TMSUCCESS);
496: }
497: return !isEnlisted();
498: }
499:
500: public boolean isEnlisted() {
501: return enlisted;
502: }
503:
504: public void setEnlisted(boolean enlisted) {
505: this .enlisted = enlisted;
506: }
507:
508: public boolean isReuseObject() {
509: return reuseObject;
510: }
511:
512: public void setReuseObject(boolean reuseObject) {
513: this .reuseObject = reuseObject;
514: }
515:
516: public Object getTargetObject() {
517: return xaConnection;
518: }
519: }
|