KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > minerva > pool > jdbc > xa > XAPoolDataSource


1 /*
2  * Licensed under the X license (see http://www.x.org/terms.htm)
3  */

4 package org.ofbiz.minerva.pool.jdbc.xa;
5
6
7 import javax.naming.Context JavaDoc;
8 import javax.naming.InitialContext JavaDoc;
9 import javax.naming.Name JavaDoc;
10 import javax.naming.NamingException JavaDoc;
11 import javax.naming.RefAddr JavaDoc;
12 import javax.naming.Reference JavaDoc;
13 import javax.naming.Referenceable JavaDoc;
14 import javax.naming.StringRefAddr JavaDoc;
15 import javax.naming.spi.ObjectFactory JavaDoc;
16 import javax.sql.DataSource JavaDoc;
17 import javax.sql.XAConnection JavaDoc;
18 import javax.sql.XADataSource JavaDoc;
19 import javax.transaction.TransactionManager JavaDoc;
20 import java.io.InvalidObjectException JavaDoc;
21 import java.io.ObjectStreamException JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.io.Serializable JavaDoc;
24 import java.sql.Connection JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Hashtable JavaDoc;
29
30 import org.apache.log4j.Logger;
31 import org.ofbiz.base.util.Log4jLoggerWriter;
32 import org.ofbiz.minerva.pool.ObjectPool;
33
34 /**
35  * DataSource for transactional JDBC pools. This handles configuration
36  * parameters for both the pool and the JDBC connection. It is important that
37  * you set all the configuration parameters before you initialize the DataSource,
38  * and you must initialize it before you use it. All the configuration
39  * parameters are not documented here; you are instead referred to ObjectPool
40  * and XAConnectionFactory.
41  * @see org.ofbiz.minerva.pool.ObjectPool
42  * @see org.ofbiz.minerva.pool.jdbc.xa.XAConnectionFactory
43  *
44  * @author Aaron Mulder (ammulder@alumni.princeton.edu)
45  * @author <a HREF="mailto:danch@nvisia.com">danch (Dan Christopherson)</a>
46  * @author <a HREF="mailto:bill@burkecentral.com">Bill Burke</a>
47  *
48  * Revision:
49  * 20010701 danch added code for timeout in blocking.
50  * 20010703 bill added code for transaction isolation and setting the ps cache size
51  */

52 public class XAPoolDataSource implements DataSource JavaDoc, Referenceable JavaDoc, ObjectFactory JavaDoc, Serializable JavaDoc
53         //just including Serializable to strongly indicate serialization support
54
{
55
56     private transient static Logger log = Logger.getLogger(XAPoolDataSource.class);
57     private transient static HashMap JavaDoc sources = new HashMap JavaDoc();
58
59     /**
60      * Gets all the current JDBC pool data sources.
61      */

62     public static Collection JavaDoc getDataSources() {
63         return new HashSet JavaDoc(sources.values());
64     }
65
66     /**
67      * Gets a specific JDBC pool data source by pool name.
68      */

69     public static XAPoolDataSource getDataSource(String JavaDoc poolName) {
70         return (XAPoolDataSource) sources.get(poolName);
71     }
72
73     private transient ObjectPool pool;
74     private transient XAConnectionFactory factory;
75     private transient PrintWriter JavaDoc logWriter;
76     private transient int timeout;
77     private transient boolean initialized = false;
78     //Unused cruft.
79
private transient String JavaDoc jndiName;
80     //what is actually used to bind in jndi by XADataSourceLoader.
81
private String JavaDoc name;
82
83     /**
84      * Creates a new XA pool data source. Be sure to configure it and then
85      * call initialize before you try to use it.
86      */

87     public XAPoolDataSource() {
88         log.debug("Creating XA Pool");
89         pool = new ObjectPool();
90         factory = new XAConnectionFactory();
91         log.debug("Created factory");
92
93         XAPoolDriver.instance();
94         log.debug("got driver instance");
95     }
96
97     // Unique properties
98
/**
99      * If you use this to set a JNDI name, this pool will be bound to that name
100      * using the default InitialContext. You can also do this manually if you
101      * have additional requirements.
102      */

103     public void setJNDIName(String JavaDoc name) throws NamingException JavaDoc {
104         if (log.isDebugEnabled())
105             log.debug("Binding to JNDI name " + name);
106
107         InitialContext JavaDoc ctx = new InitialContext JavaDoc();
108         if (jndiName != null && !jndiName.equals(name))
109             ctx.unbind(jndiName);
110         if (name != null)
111             ctx.bind(name, this);
112         jndiName = name;
113     }
114
115     /**
116      * Gets the JNDI name this pool is bound to. Only valid if you used
117      * setJNDIName to bind it.
118      * @see #setJNDIName
119      */

120     public String JavaDoc getJNDIName() {
121         return jndiName;
122     }
123
124     // XA properties
125
public void setDataSource(XADataSource JavaDoc ds) {
126         factory.setDataSource(ds);
127     }
128
129     public XADataSource JavaDoc getDataSource() {
130         return factory.getDataSource();
131     }
132
133     public void setTransactionManager(TransactionManager JavaDoc tm) {
134         factory.setTransactionManager(tm);
135     }
136
137     //public String getTransactionManagerJNDIName() {return factory.getTransactionManagerJNDIName();}
138
public void setJDBCUser(String JavaDoc user) {
139         factory.setUser(user);
140     }
141
142     public String JavaDoc getJDBCUser() {
143         return factory.getUser();
144     }
145
146     public void setJDBCPassword(String JavaDoc password) {
147         factory.setPassword(password);
148     }
149
150     public String JavaDoc getJDBCPassword() {
151         return factory.getPassword();
152     }
153
154     public int getTransactionIsolation() {
155         return factory.getTransactionIsolation();
156     }
157
158     public void setTransactionIsolation(int iso) {
159         factory.setTransactionIsolation(iso);
160     }
161
162     public void setTransactionIsolation(String JavaDoc iso) {
163         factory.setTransactionIsolation(iso);
164     }
165
166     public int getPSCacheSize() {
167         return factory.getPSCacheSize();
168     }
169
170     public void setPSCacheSize(int size) {
171         factory.setPSCacheSize(size);
172     }
173
174     public boolean getReleaseOnCommit() {
175         return factory.getReleaseOnCommit();
176     }
177
178     public void setReleaseOnCommit(boolean rel) {
179         factory.setReleaseOnCommit(rel);
180     }
181
182     /**
183      * Have XAClientConnections save a stack trace on creation
184      * This is useful for debugging non-closed connections.
185      * It must be used with ReleaseOnCommit option
186      */

187     public boolean getSaveStackTrace() {
188         return factory.getSaveStackTrace();
189     }
190
191     public void setSaveStackTrace(boolean save) {
192         factory.setSaveStackTrace(save);
193     }
194
195
196     // Pool properties
197
public void setPoolName(String JavaDoc name) {
198         //remember the name so we can look ourselves up on deserialization.
199
this.name = name;
200         pool.setName(name);
201         sources.put(pool.getName(), this);
202     }
203
204     public String JavaDoc getPoolName() {
205         return name;
206     }
207
208     public void setMinSize(int size) {
209         pool.setMinSize(size);
210     }
211
212     public int getMinSize() {
213         return pool.getMinSize();
214     }
215
216     public void setMaxSize(int size) {
217         pool.setMaxSize(size);
218     }
219
220     public int getMaxSize() {
221         return pool.getMaxSize();
222     }
223
224     public void setBlocking(boolean blocking) {
225         pool.setBlocking(blocking);
226     }
227
228     public boolean isBlocking() {
229         return pool.isBlocking();
230     }
231
232     public void setBlockingTimeout(int blockingTimeout) {
233         pool.setBlockingTimeout(blockingTimeout);
234     }
235
236     public int getBlockingTimeout() {
237         return pool.getBlockingTimeout();
238     }
239
240     public void setIdleTimeoutEnabled(boolean allowShrinking) {
241         pool.setIdleTimeoutEnabled(allowShrinking);
242     }
243
244     public boolean isIdleTimeoutEnabled() {
245         return pool.isIdleTimeoutEnabled();
246     }
247
248     public void setGCEnabled(boolean allowGC) {
249         pool.setGCEnabled(allowGC);
250     }
251
252     public boolean isGCEnabled() {
253         return pool.isGCEnabled();
254     }
255
256     public void setMaxIdleTimeoutPercent(float percent) {
257         pool.setMaxIdleTimeoutPercent(percent);
258     }
259
260     public float getMaxIdleTimeoutPercent() {
261         return pool.getMaxIdleTimeoutPercent();
262     }
263
264     public void setIdleTimeout(long millis) {
265         pool.setIdleTimeout(millis);
266     }
267
268     public long getIdleTimeout() {
269         return pool.getIdleTimeout();
270     }
271
272     public void setGCMinIdleTime(long millis) {
273         pool.setGCMinIdleTime(millis);
274     }
275
276     public long getGCMinIdleTime() {
277         return pool.getGCMinIdleTime();
278     }
279
280     public void setGCInterval(long millis) {
281         pool.setGCInterval(millis);
282     }
283
284     public long getGCInterval() {
285         return pool.getGCInterval();
286     }
287
288     public void setInvalidateOnError(boolean invalidate) {
289         pool.setInvalidateOnError(invalidate);
290     }
291
292     public boolean isInvalidateOnError() {
293         return pool.isInvalidateOnError();
294     }
295
296     public void setTimestampUsed(boolean timestamp) {
297         pool.setTimestampUsed(timestamp);
298     }
299
300     public boolean isTimestampUsed() {
301         return pool.isTimestampUsed();
302     }
303
304     // Other methods
305

306     /**
307      * Initializes the pool. You need to have configured all the pool and
308      * XA properties first.
309      */

310     public void initialize() {
311         initialized = true;
312         pool.setObjectFactory(factory);
313         pool.initialize();
314     }
315
316     /**
317      * Returns a string describing the pool status (number of connections
318      * created, used, and maximum).
319      */

320     public String JavaDoc getPoolStatus() {
321         return pool.toString();
322     }
323
324     /**
325      * Shuts down this data source and the underlying pool. If you used
326      * setJNDI name to bind it in JNDI, it is unbound.
327      */

328     public void close() {
329         if (log.isDebugEnabled())
330             log.debug("Closing DataSource");
331
332         try {
333             setJNDIName(null);
334         } catch (NamingException JavaDoc e) {
335             log.warn("Can't unbind from JNDI", e);
336         }
337         sources.remove(pool.getName());
338         pool.shutDown();
339         pool = null;
340         factory = null;
341     }
342
343     /**
344      * Gets a connection from the pool.
345      * Since no userid or password is specified, we get a connection using the default
346      * userid and password, specified when the factory was created.
347      */

348     public Connection JavaDoc getConnection() throws java.sql.SQLException JavaDoc {
349         if (!initialized) initialize();
350
351         log.debug("Getting a Connection");
352         String JavaDoc user = factory.getUser();
353         String JavaDoc password = factory.getPassword();
354         String JavaDoc[] params = {user, password};
355         XAConnection JavaDoc xaConn = (XAConnection JavaDoc) pool.getObject(params);
356         return xaConn.getConnection();
357     }
358
359     /**
360      * Gets a new connection from the pool. If a new connection must be
361      * created, it will use the specified user name and password. If there is
362      * a connection available in the pool, it will be used, regardless of the
363      * user name and password use to created it initially.
364      */

365     public Connection JavaDoc getConnection(String JavaDoc user, String JavaDoc password) throws java.sql.SQLException JavaDoc {
366         if (!initialized) initialize();
367
368         log.debug("Getting a connection for user " + user + " with password " + password);
369         String JavaDoc[] params = {user, password};
370         XAConnection JavaDoc xaConn = (XAConnection JavaDoc) pool.getObject(params);
371         return xaConn.getConnection();
372     }
373
374     /**
375      * Gets a log writer used to record pool events.
376      */

377     public PrintWriter JavaDoc getLogWriter() throws java.sql.SQLException JavaDoc {
378         return logWriter;
379     }
380
381     /**
382      * Sets a log writer used to record pool events.
383      */

384     public void setLogWriter(PrintWriter JavaDoc writer) throws java.sql.SQLException JavaDoc {
385         if (writer == null) {
386             logWriter = null;
387         } else {
388             if (logWriter == null) {
389                 logWriter = new Log4jLoggerWriter(log);
390             }
391         }
392     }
393
394     /**
395      * This property is not used by this implementation.
396      */

397     public int getLoginTimeout() throws java.sql.SQLException JavaDoc {
398         return timeout;
399     }
400
401     /**
402      * This property is not used by this implementation.
403      */

404     public void setLoginTimeout(int timeout) throws java.sql.SQLException JavaDoc {
405         this.timeout = timeout;
406     }
407
408     // Referenceable implementation ----------------------------------
409
/**
410      * Gets a reference to this data source.
411      */

412     public Reference JavaDoc getReference() {
413         return new Reference JavaDoc(getClass().getName(), new StringRefAddr JavaDoc("XAPool", pool.getName()), getClass().getName(), null);
414     }
415
416     // ObjectFactory implementation ----------------------------------
417
/**
418      * Decodes a reference to a specific pool data source.
419      */

420     public Object JavaDoc getObjectInstance(Object JavaDoc obj, Name JavaDoc name, Context JavaDoc nameCtx, Hashtable JavaDoc environment) {
421         if (obj instanceof Reference JavaDoc) {
422             Reference JavaDoc ref = (Reference JavaDoc) obj;
423             if (ref.getClassName().equals(getClass().getName())) {
424                 RefAddr JavaDoc addr = ref.get("XAPool");
425                 return sources.get(addr.getContent());
426             }
427         }
428         return null;
429     }
430
431     //deserialization to correct instance support
432

433     private Object JavaDoc readResolve() throws ObjectStreamException JavaDoc {
434         try {
435             InitialContext JavaDoc ctx = new InitialContext JavaDoc();
436             return ctx.lookup("java:/" + name);
437         } catch (NamingException JavaDoc e) {
438             throw new InvalidObjectException JavaDoc("problem finding correct datasource instance" + e);
439         } // end of try-catch
440

441     }
442 }
443
444 /*
445 vim:tabstop=3:et:shiftwidth=3
446 */

447
Popular Tags