KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > jdbc > pool > StandardXAPoolDataSource


1 /*
2  * XAPool: Open Source XA JDBC Pool
3  * Copyright (C) 2003 Objectweb.org
4  * Initial Developer: Lutris Technologies Inc.
5  * Contact: xapool-public@lists.debian-sf.objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  */

22 package org.enhydra.jdbc.pool;
23
24 import java.sql.SQLException JavaDoc;
25 import java.util.Hashtable JavaDoc;
26
27 import javax.naming.Context JavaDoc;
28 import javax.naming.InitialContext JavaDoc;
29 import javax.naming.Name JavaDoc;
30 import javax.naming.NamingException JavaDoc;
31 import javax.naming.Reference JavaDoc;
32 import javax.naming.StringRefAddr JavaDoc;
33 import javax.sql.ConnectionEvent JavaDoc;
34 import javax.sql.XAConnection JavaDoc;
35 import javax.sql.XADataSource JavaDoc;
36 import javax.transaction.TransactionManager JavaDoc;
37 import javax.transaction.Transaction JavaDoc;
38 import javax.transaction.SystemException JavaDoc;
39 import javax.transaction.xa.XAResource JavaDoc;
40 import org.enhydra.jdbc.standard.StandardXADataSource;
41 import org.enhydra.jdbc.standard.StandardXAConnection;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import java.sql.Connection JavaDoc;
45 import java.sql.Statement JavaDoc;
46 import javax.sql.PooledConnection JavaDoc;
47 import javax.transaction.Status JavaDoc;
48
49 /**
50  * StandardXAPoolDataSource class allows to make some operations on
51  * XAConnection. It implements PoolHelper for the 3 methods :<p>
52  * create : create an XAConnection<p>
53  * create(user,password) : create a PooledConnection with an other user/password<p>
54  * testThisObject : check if the object is still valid<p>
55  * checkThisObject : check if the object is closed<p>
56  * expire : kill the object<p>
57  */

58 public class StandardXAPoolDataSource extends StandardPoolDataSource {
59
60     public XADataSource JavaDoc xads; // object to build XAConnection
61
public TransactionManager JavaDoc transactionManager;
62     // the current Transaction Manager
63
public Log glog = LogFactory.getLog("org.enhydra.jdbc.xapool");
64
65     /**
66      * Constructor
67      */

68     public StandardXAPoolDataSource() {
69         super();
70     }
71
72     /**
73      * Constructor
74      */

75     public StandardXAPoolDataSource(int initSize) {
76         super(initSize);
77     }
78
79     /**
80      * Constructor
81      */

82     public StandardXAPoolDataSource(StandardXADataSource ds) {
83         super(ds);
84                 setDataSource(ds);
85     }
86
87     /**
88      * Constructor
89      */

90     public StandardXAPoolDataSource(StandardXADataSource ds, int initSize) {
91         super(ds, initSize);
92                 setDataSource(ds);
93     }
94
95     public void setTransactionManager(TransactionManager JavaDoc tm) {
96         log.debug("StandardXAPoolDataSource:setTransactionManager");
97         transactionManager = tm;
98     }
99
100     /**
101      * Invoked when the application calls close()
102      * on its representation of the connection
103      */

104     public void connectionClosed(ConnectionEvent JavaDoc event) {
105         Object JavaDoc obj = event.getSource();
106         log.debug("StandardXAPoolDataSource:connectionClosed");
107         XAConnection JavaDoc xac = (XAConnection JavaDoc) obj; // cast it into an xaConnection
108

109         Transaction JavaDoc tx = null;
110         try {
111             if (transactionManager == null) {
112                 TransactionManager JavaDoc tm =
113                     ((StandardXADataSource) xads).getTransactionManager();
114                 if (tm == null) {
115                     throw new NullPointerException JavaDoc("TM is null");
116                 } else
117                     // here we use tm instead to setup transactionManager = tm
118
// if the current transactionManager property is null, it stays
119
// there, and we continue to use the TM from the XADataSource
120
tx = tm.getTransaction();
121             } else {
122                 tx = transactionManager.getTransaction();
123             }
124             log.debug(
125                 "StandardXAPoolDataSource:connectionClosed get a transaction");
126         } catch (NullPointerException JavaDoc n) {
127             // current is null: we are not in EJBServer.
128
log.error(
129                 "StandardXAPoolDataSource:connectionClosed should not be used outside an EJBServer");
130         } catch (SystemException JavaDoc e) {
131             log.error(
132                 "StandardXAPoolDataSource:connectionClosed getTransaction failed:"
133                     + e);
134         }
135
136         // delist Resource if in transaction
137
// We must keep the connection till commit or rollback
138
if ((tx != null)
139             && (((StandardXAConnection) xac).connectionHandle.isReallyUsed)) {
140             try {
141                 tx.delistResource(xac.getXAResource(), XAResource.TMSUCCESS);
142                 // delist the xaResource
143
log.debug(
144                     "StandardXAPoolDataSource:connectionClosed the resourse is delisted");
145             } catch (Exception JavaDoc e) {
146                 log.error(
147                     "StandardXAPoolDataSource:connectionClosed Exception in connectionClosed:"
148                         + e);
149             }
150         }
151         log.debug(
152             "StandardXAPoolDataSource:connectionClosed checkIn an object to the pool");
153         pool.checkIn(obj); // return the connection to the pool
154
}
155
156     public GenerationObject create(String JavaDoc _user, String JavaDoc _password)
157         throws SQLException JavaDoc {
158         GenerationObject genObject;
159         XAConnection JavaDoc xaCon = xads.getXAConnection(_user, _password);
160         // get the xa connection
161
xaCon.addConnectionEventListener(this); // add it to the event listener
162
log.debug(
163             "StandardXAPoolDataSource:create create a object for the pool");
164         genObject =
165             new GenerationObject(xaCon, pool.getGeneration(), _user, _password);
166
167         return genObject;
168     }
169
170     /**
171      * Retrieves the Reference of this object. Used at binding time by JNDI
172      * to build a reference on this object.
173      *
174      * @return The non-null Reference of this object.
175      * @exception NamingException If a naming exception was encountered while
176      * retrieving the reference.
177      */

178     public Reference JavaDoc getReference() throws NamingException JavaDoc {
179         log.debug(
180             "StandardXAPoolDataSource:getReference return a reference of the object");
181         Reference JavaDoc ref = super.getReference();
182         ref.add(
183             new StringRefAddr JavaDoc("transactionManagerName", "TransactionManager"));
184         return ref;
185     }
186
187     /* (non-Javadoc)
188      * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
189      */

190     public Object JavaDoc getObjectInstance(
191         Object JavaDoc refObj,
192         Name JavaDoc name,
193         Context JavaDoc nameCtx,
194         Hashtable JavaDoc env)
195         throws Exception JavaDoc {
196
197         super.getObjectInstance(refObj, name, nameCtx, env);
198         Reference JavaDoc ref = (Reference JavaDoc) refObj;
199         InitialContext JavaDoc ictx = new InitialContext JavaDoc(env);
200         this.setTransactionManager(
201             (TransactionManager JavaDoc) ictx.lookup(
202                 "javax.transaction.TransactionManager"));
203         this.setDataSource((XADataSource JavaDoc) ictx.lookup(this.dataSourceName));
204         log.debug("StandardPoolDataSource:getObjectInstance: instance created");
205         return this;
206     }
207
208     /** Getter for property dataSource.
209      * @return Value of property dataSource.
210      */

211     public XADataSource JavaDoc getDataSource() {
212         return xads;
213     }
214
215     /** Setter for property dataSource.
216      * @param dataSource New value of property dataSource.
217      */

218     public void setDataSource(XADataSource JavaDoc dataSource) {
219         this.xads = dataSource;
220         if (transactionManager != null)
221             ((StandardXADataSource) dataSource).setTransactionManager(
222                 transactionManager);
223     }
224     
225     
226     public String JavaDoc toString() {
227         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
228         sb.append("StandardXAPoolDataSource:\n");
229                 if (this.transactionManager != null)
230                 sb.append(" transaction manager=<"+this.transactionManager.toString()+">\n");
231                 if (this.xads != null)
232                 sb.append(this.xads.toString());
233         sb.append(super.toString());
234         return sb.toString();
235     }
236
237     /**
238      * This method tests if a connection is valid or not. It overrides the
239      * method in StandardPoolDataSource to take into account global transactions:
240      * if global transaction is in progress - suspend it so that
241      * connection testing happens ouside of transaction.
242      * If connection testing fails - it will not affect transaction
243      * and next good connection can join the transaction
244      */

245      public boolean testThisObject(Object JavaDoc o) {
246         Connection JavaDoc ret = null;
247         log.debug(
248             "StandardPoolDataSource:testThisObject verify the current object");
249         Transaction JavaDoc suspended = null;
250         try {
251             Transaction JavaDoc tx = transactionManager == null
252                                 ? null
253                                 : transactionManager.getTransaction();
254             boolean isActive = tx == null
255                                 ? false
256                                 : tx.getStatus() == Status.STATUS_ACTIVE;
257             if (isActive) {
258                 suspended = transactionManager.suspend();
259             }
260
261
262             PooledConnection JavaDoc con = (PooledConnection JavaDoc) o;
263             ret = con.getConnection();
264
265
266
267             Statement JavaDoc s = ret.createStatement();
268             s.execute(jdbcTestStmt);
269             s.close();
270             try {
271                 ret.close();
272             } catch (Exception JavaDoc e) {
273                 log.error(
274                     "StandardPoolDataSource:checkThisObject can't closed the connection: "
275                         + e);
276             }
277             return true;
278         } catch (SQLException JavaDoc e) {
279             log.error(
280                 "StandardXAPoolDataSource:checkThisObject Error java.sql.SQLException in StandardXAPoolDataSource:testThisObject");
281             return false;
282         } catch (SystemException JavaDoc e) {
283             log.error(
284                 "StandardXAPoolDataSource:checkThisObject Error java.sql.SystemException in StandardXAPoolDataSource:testThisObject");
285             return false;
286         } finally {
287             if (suspended != null) {
288                 try {
289                     transactionManager.resume(suspended);
290                 } catch (Exception JavaDoc ex) {
291                     log.error(
292                         "StandardXAPoolDataSource:checkThisObject Error Exception in StandardXAPoolDataSource:testThisObject");
293                     return false;
294                 }
295             }
296         }
297     }
298
299 }
Popular Tags