org.h2.jdbcx.JdbcDataSource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of h2-mvstore Show documentation
Show all versions of h2-mvstore Show documentation
Fork of h2database to maintain Java 8 compatibility
The newest version!
/*
* Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbcx;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Logger;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import javax.sql.PooledConnection;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException;
import org.h2.message.TraceObject;
import org.h2.util.StringUtils;
/**
* A data source for H2 database connections. It is a factory for XAConnection
* and Connection objects. This class is usually registered in a JNDI naming
* service. To create a data source object and register it with a JNDI service,
* use the following code:
*
*
* import org.h2.jdbcx.JdbcDataSource;
* import javax.naming.Context;
* import javax.naming.InitialContext;
* JdbcDataSource ds = new JdbcDataSource();
* ds.setURL("jdbc:h2:˜/test");
* ds.setUser("sa");
* ds.setPassword("sa");
* Context ctx = new InitialContext();
* ctx.bind("jdbc/dsName", ds);
*
*
* To use a data source that is already registered, use the following code:
*
*
* import java.sql.Connection;
* import javax.sql.DataSource;
* import javax.naming.Context;
* import javax.naming.InitialContext;
* Context ctx = new InitialContext();
* DataSource ds = (DataSource) ctx.lookup("jdbc/dsName");
* Connection conn = ds.getConnection();
*
*
* In this example the user name and password are serialized as
* well; this may be a security problem in some cases.
*/
public final class JdbcDataSource extends TraceObject implements XADataSource, DataSource, ConnectionPoolDataSource,
Serializable, Referenceable, JdbcDataSourceBackwardsCompat {
private static final long serialVersionUID = 1288136338451857771L;
private transient JdbcDataSourceFactory factory;
private transient PrintWriter logWriter;
private int loginTimeout;
private String userName = "";
private char[] passwordChars = { };
private String url = "";
private String description;
/**
* The public constructor.
*/
public JdbcDataSource() {
initFactory();
int id = getNextId(TraceObject.DATA_SOURCE);
setTrace(factory.getTrace(), TraceObject.DATA_SOURCE, id);
}
/**
* Called when de-serializing the object.
*
* @param in the input stream
* @throws IOException on failure
* @throws ClassNotFoundException on failure
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
initFactory();
in.defaultReadObject();
}
private void initFactory() {
factory = new JdbcDataSourceFactory();
}
/**
* Get the login timeout in seconds, 0 meaning no timeout.
*
* @return the timeout in seconds
*/
@Override
public int getLoginTimeout() {
debugCodeCall("getLoginTimeout");
return loginTimeout;
}
/**
* Set the login timeout in seconds, 0 meaning no timeout.
* The default value is 0.
* This value is ignored by this database.
*
* @param timeout the timeout in seconds
*/
@Override
public void setLoginTimeout(int timeout) {
debugCodeCall("setLoginTimeout", timeout);
this.loginTimeout = timeout;
}
/**
* Get the current log writer for this object.
*
* @return the log writer
*/
@Override
public PrintWriter getLogWriter() {
debugCodeCall("getLogWriter");
return logWriter;
}
/**
* Set the current log writer for this object.
* This value is ignored by this database.
*
* @param out the log writer
*/
@Override
public void setLogWriter(PrintWriter out) {
debugCodeCall("setLogWriter(out)");
logWriter = out;
}
/**
* Open a new connection using the current URL, user name and password.
*
* @return the connection
*/
@Override
public Connection getConnection() throws SQLException {
debugCodeCall("getConnection");
return new JdbcConnection(url, null, userName, StringUtils.cloneCharArray(passwordChars), false);
}
/**
* Open a new connection using the current URL and the specified user name
* and password.
*
* @param user the user name
* @param password the password
* @return the connection
*/
@Override
public Connection getConnection(String user, String password)
throws SQLException {
if (isDebugEnabled()) {
debugCode("getConnection(" + quote(user) + ", \"\")");
}
return new JdbcConnection(url, null, user, password, false);
}
/**
* Get the current URL.
*
* @return the URL
*/
public String getURL() {
debugCodeCall("getURL");
return url;
}
/**
* Set the current URL.
*
* @param url the new URL
*/
public void setURL(String url) {
debugCodeCall("setURL", url);
this.url = url;
}
/**
* Get the current URL.
* This method does the same as getURL, but this methods signature conforms
* the JavaBean naming convention.
*
* @return the URL
*/
public String getUrl() {
debugCodeCall("getUrl");
return url;
}
/**
* Set the current URL.
* This method does the same as setURL, but this methods signature conforms
* the JavaBean naming convention.
*
* @param url the new URL
*/
public void setUrl(String url) {
debugCodeCall("setUrl", url);
this.url = url;
}
/**
* Set the current password.
*
* @param password the new password.
*/
public void setPassword(String password) {
debugCodeCall("setPassword", "");
this.passwordChars = password == null ? null : password.toCharArray();
}
/**
* Set the current password in the form of a char array.
*
* @param password the new password in the form of a char array.
*/
public void setPasswordChars(char[] password) {
if (isDebugEnabled()) {
debugCode("setPasswordChars(new char[0])");
}
this.passwordChars = password;
}
private static String convertToString(char[] a) {
return a == null ? null : new String(a);
}
/**
* Get the current password.
*
* @return the password
*/
public String getPassword() {
debugCodeCall("getPassword");
return convertToString(passwordChars);
}
/**
* Get the current user name.
*
* @return the user name
*/
public String getUser() {
debugCodeCall("getUser");
return userName;
}
/**
* Set the current user name.
*
* @param user the new user name
*/
public void setUser(String user) {
debugCodeCall("setUser", user);
this.userName = user;
}
/**
* Get the current description.
*
* @return the description
*/
public String getDescription() {
debugCodeCall("getDescription");
return description;
}
/**
* Set the description.
*
* @param description the new description
*/
public void setDescription(String description) {
debugCodeCall("getDescription", description);
this.description = description;
}
/**
* Get a new reference for this object, using the current settings.
*
* @return the new reference
*/
@Override
public Reference getReference() {
debugCodeCall("getReference");
String factoryClassName = JdbcDataSourceFactory.class.getName();
Reference ref = new Reference(getClass().getName(), factoryClassName, null);
ref.add(new StringRefAddr("url", url));
ref.add(new StringRefAddr("user", userName));
ref.add(new StringRefAddr("password", convertToString(passwordChars)));
ref.add(new StringRefAddr("loginTimeout", Integer.toString(loginTimeout)));
ref.add(new StringRefAddr("description", description));
return ref;
}
/**
* Open a new XA connection using the current URL, user name and password.
*
* @return the connection
*/
@Override
public XAConnection getXAConnection() throws SQLException {
debugCodeCall("getXAConnection");
return new JdbcXAConnection(factory, getNextId(XA_DATA_SOURCE),
new JdbcConnection(url, null, userName, StringUtils.cloneCharArray(passwordChars), false));
}
/**
* Open a new XA connection using the current URL and the specified user
* name and password.
*
* @param user the user name
* @param password the password
* @return the connection
*/
@Override
public XAConnection getXAConnection(String user, String password)
throws SQLException {
if (isDebugEnabled()) {
debugCode("getXAConnection(" + quote(user) + ", \"\")");
}
return new JdbcXAConnection(factory, getNextId(XA_DATA_SOURCE),
new JdbcConnection(url, null, user, password, false));
}
/**
* Open a new pooled connection using the current URL, user name and
* password.
*
* @return the connection
*/
@Override
public PooledConnection getPooledConnection() throws SQLException {
debugCodeCall("getPooledConnection");
return getXAConnection();
}
/**
* Open a new pooled connection using the current URL and the specified user
* name and password.
*
* @param user the user name
* @param password the password
* @return the connection
*/
@Override
public PooledConnection getPooledConnection(String user, String password)
throws SQLException {
if (isDebugEnabled()) {
debugCode("getPooledConnection(" + quote(user) + ", \"\")");
}
return getXAConnection(user, password);
}
/**
* Return an object of this class if possible.
*
* @param iface the class
* @return this
*/
@Override
@SuppressWarnings("unchecked")
public T unwrap(Class iface) throws SQLException {
try {
if (isWrapperFor(iface)) {
return (T) this;
}
throw DbException.getInvalidValueException("iface", iface);
} catch (Exception e) {
throw logAndConvert(e);
}
}
/**
* Checks if unwrap can return an object of this class.
*
* @param iface the class
* @return whether or not the interface is assignable from this class
*/
@Override
public boolean isWrapperFor(Class> iface) throws SQLException {
return iface != null && iface.isAssignableFrom(getClass());
}
/**
* [Not supported]
*/
@Override
public Logger getParentLogger() {
return null;
}
/**
* INTERNAL
*/
@Override
public String toString() {
return getTraceObjectName() + ": url=" + url + " user=" + userName;
}
}