001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.jdbcx;
007:
008: import java.io.IOException;
009: import java.io.PrintWriter;
010: import java.sql.Connection;
011: import java.sql.SQLException;
012: import java.util.Properties;
013:
014: //#ifdef JDK14
015: import java.io.Serializable;
016: import javax.naming.NamingException;
017: import javax.naming.Reference;
018: import javax.naming.Referenceable;
019: import javax.naming.StringRefAddr;
020: import javax.sql.ConnectionPoolDataSource;
021: import javax.sql.DataSource;
022: import javax.sql.PooledConnection;
023: import javax.sql.XAConnection;
024: import javax.sql.XADataSource; //#endif
025:
026: import org.h2.jdbc.JdbcConnection;
027: import org.h2.message.TraceObject;
028:
029: //#ifdef JDK16
030: /*
031: import org.h2.message.Message;
032: */
033: //#endif
034: /**
035: * A data source for H2 database connections. It is a factory for XAConnection
036: * and Connection objects. This class is usually registered in a JNDI naming
037: * service. To create a data source object and register it with a JNDI service,
038: * use the following code:
039: *
040: * <pre>
041: * import org.h2.jdbcx.JdbcDataSource;
042: * import javax.naming.Context;
043: * import javax.naming.InitialContext;
044: * JdbcDataSource ds = new JdbcDataSource();
045: * ds.setURL("jdbc:h2:˜/test");
046: * ds.setUser("sa");
047: * ds.setPassword("sa");
048: * Context ctx = new InitialContext();
049: * ctx.bind("jdbc/dsName", ds);
050: * </pre>
051: *
052: * To use a data source that is already registered, use the following code:
053: *
054: * <pre>
055: * import java.sql.Connection;
056: * import javax.sql.DataSource;
057: * import javax.naming.Context;
058: * import javax.naming.InitialContext;
059: * Context ctx = new InitialContext();
060: * DataSource ds = (DataSource) ctx.lookup("jdbc/dsName");
061: * Connection conn = ds.getConnection();
062: * </pre>
063: *
064: * In this example the user name and password are serialized as
065: * well; this may be a security problem in some cases.
066: */
067: public class JdbcDataSource extends TraceObject
068: //#ifdef JDK14
069: implements XADataSource, DataSource, ConnectionPoolDataSource,
070: Serializable, Referenceable
071: //#endif
072: {
073:
074: private static final long serialVersionUID = 1288136338451857771L;
075:
076: private transient JdbcDataSourceFactory factory;
077: private transient PrintWriter logWriter;
078: private int loginTimeout;
079: private String user = "";
080: private String password = "";
081: private String url = "";
082:
083: static {
084: org.h2.Driver.load();
085: }
086:
087: /**
088: * The public constructor.
089: */
090: public JdbcDataSource() {
091: initFactory();
092: int id = getNextId(TraceObject.DATA_SOURCE);
093: setTrace(factory.getTrace(), TraceObject.DATA_SOURCE, id);
094: }
095:
096: private void readObject(java.io.ObjectInputStream in)
097: throws IOException, ClassNotFoundException {
098: initFactory();
099: in.defaultReadObject();
100: }
101:
102: private void initFactory() {
103: factory = new JdbcDataSourceFactory();
104: }
105:
106: /**
107: * Get the login timeout in seconds, 0 meaning no timeout.
108: *
109: * @return the timeout in seconds
110: */
111: public int getLoginTimeout() throws SQLException {
112: debugCodeCall("getLoginTimeout");
113: return loginTimeout;
114: }
115:
116: /**
117: * Set the login timeout in seconds, 0 meaning no timeout.
118: * The default value is 0.
119: * This value is ignored by this database.
120: *
121: * @param timeout the timeout in seconds
122: */
123: public void setLoginTimeout(int timeout) throws SQLException {
124: debugCodeCall("setLoginTimeout", timeout);
125: this .loginTimeout = timeout;
126: }
127:
128: /**
129: * Get the current log writer for this object.
130: *
131: * @return the log writer
132: */
133: public PrintWriter getLogWriter() throws SQLException {
134: debugCodeCall("getLogWriter");
135: return logWriter;
136: }
137:
138: /**
139: * Set the current log writer for this object.
140: * This value is ignored by this database.
141: *
142: * @param out the log writer
143: */
144: public void setLogWriter(PrintWriter out) throws SQLException {
145: debugCodeCall("setLogWriter(out)");
146: logWriter = out;
147: }
148:
149: /**
150: * Open a new connection using the current URL, user name and password.
151: *
152: * @return the connection
153: */
154: public Connection getConnection() throws SQLException {
155: debugCodeCall("getConnection");
156: return getJdbcConnection(user, password);
157: }
158:
159: /**
160: * Open a new connection using the current URL and the specified user name
161: * and password.
162: *
163: * @param user the user name
164: * @param password the password
165: * @return the connection
166: */
167: public Connection getConnection(String user, String password)
168: throws SQLException {
169: debugCode("getConnection(" + quote(user) + ", "
170: + quote(password) + ");");
171: return getJdbcConnection(user, password);
172: }
173:
174: private JdbcConnection getJdbcConnection(String user,
175: String password) throws SQLException {
176: debugCode("getJdbcConnection(" + quote(user) + ", "
177: + quote(password) + ");");
178: Properties info = new Properties();
179: info.setProperty("user", user);
180: info.setProperty("password", password);
181: return new JdbcConnection(url, info);
182: }
183:
184: /**
185: * Get the current URL.
186: *
187: * @return the URL
188: */
189: public String getURL() {
190: debugCodeCall("getURL");
191: return url;
192: }
193:
194: /**
195: * Set the current URL.
196: *
197: * @param url the new URL
198: */
199: public void setURL(String url) {
200: debugCodeCall("setURL", url);
201: this .url = url;
202: }
203:
204: /**
205: * Set the current password
206: *
207: * @param password the new password.
208: */
209: public void setPassword(String password) {
210: debugCodeCall("setPassword", password);
211: this .password = password;
212: }
213:
214: /**
215: * Get the current password.
216: *
217: * @return the password
218: */
219: public String getPassword() {
220: debugCodeCall("getPassword");
221: return password;
222: }
223:
224: /**
225: * Get the current user name.
226: *
227: * @return the user name
228: */
229: public String getUser() {
230: debugCodeCall("getUser");
231: return user;
232: }
233:
234: /**
235: * Set the current user name.
236: *
237: * @param user the new user name
238: */
239: public void setUser(String user) {
240: debugCodeCall("setUser", user);
241: this .user = user;
242: }
243:
244: /**
245: * Get a new reference for this object, using the current settings.
246: *
247: * @return the new reference
248: */
249: //#ifdef JDK14
250: public Reference getReference() throws NamingException {
251: debugCodeCall("getReference");
252: String factoryClassName = JdbcDataSourceFactory.class.getName();
253: Reference ref = new Reference(getClass().getName(),
254: factoryClassName, null);
255: ref.add(new StringRefAddr("url", url));
256: ref.add(new StringRefAddr("user", user));
257: ref.add(new StringRefAddr("password", password));
258: ref.add(new StringRefAddr("loginTimeout", String
259: .valueOf(loginTimeout)));
260: return ref;
261: }
262:
263: //#endif
264:
265: /**
266: * Open a new XA connection using the current URL, user name and password.
267: *
268: * @return the connection
269: */
270: //#ifdef JDK14
271: public XAConnection getXAConnection() throws SQLException {
272: debugCodeCall("getXAConnection");
273: int id = getNextId(XA_DATA_SOURCE);
274: return new JdbcXAConnection(factory, id, url, user, password);
275: }
276:
277: //#endif
278:
279: /**
280: * Open a new XA connection using the current URL and the specified user
281: * name and password.
282: *
283: * @param user the user name
284: * @param password the password
285: * @return the connection
286: */
287: //#ifdef JDK14
288: public XAConnection getXAConnection(String user, String password)
289: throws SQLException {
290: debugCode("getXAConnection(" + quote(user) + ", "
291: + quote(password) + ");");
292: int id = getNextId(XA_DATA_SOURCE);
293: return new JdbcXAConnection(factory, id, url, user, password);
294: }
295:
296: //#endif
297:
298: /**
299: * Open a new XA connection using the current URL, user name and password.
300: *
301: * @return the connection
302: */
303: //#ifdef JDK14
304: public PooledConnection getPooledConnection() throws SQLException {
305: debugCodeCall("getPooledConnection");
306: return getXAConnection();
307: }
308:
309: //#endif
310:
311: /**
312: * Open a new XA connection using the current URL and the specified user
313: * name and password.
314: *
315: * @param user the user name
316: * @param password the password
317: * @return the connection
318: */
319: //#ifdef JDK14
320: public PooledConnection getPooledConnection(String user,
321: String password) throws SQLException {
322: debugCode("getPooledConnection(" + quote(user) + ", "
323: + quote(password) + ");");
324: return getXAConnection(user, password);
325: }
326:
327: //#endif
328:
329: /**
330: * [Not supported] Return an object of this class if possible.
331: *
332: * @param iface the class
333: */
334: //#ifdef JDK16
335: /*
336: public <T> T unwrap(Class<T> iface) throws SQLException {
337: throw Message.getUnsupportedException();
338: }
339: */
340: //#endif
341: /**
342: * [Not supported] Checks if unwrap can return an object of this class.
343: *
344: * @param iface the class
345: */
346: //#ifdef JDK16
347: /*
348: public boolean isWrapperFor(Class< ? > iface) throws SQLException {
349: throw Message.getUnsupportedException();
350: }
351: */
352: //#endif
353: /**
354: * INTERNAL
355: */
356: public String toString() {
357: return getTraceObjectName() + ": url=" + url + " user=" + user;
358: }
359:
360: }
|