// jTDS JDBC Driver for Microsoft SQL Server and Sybase
// Copyright (C) 2004 The jTDS Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package net.sourceforge.jtds.jdbcx;
import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import net.sourceforge.jtds.jdbc.DefaultProperties;
import net.sourceforge.jtds.jdbc.Driver;
import net.sourceforge.jtds.jdbc.Messages;
import net.sourceforge.jtds.jdbc.Support;
import net.sourceforge.jtds.util.Logger;
/**
* The jTDS <code>DataSource</code>, <code>ConnectionPoolDataSource</code> and
* <code>XADataSource</code> implementation.
*
* @author
* Alin Sinplean, Holger Rehn
*
* @since
* jTDS 0.3
*/
public class JtdsDataSource implements DataSource, ConnectionPoolDataSource, XADataSource, Referenceable, Serializable
{
/**
* serial version UID
*/
static final long serialVersionUID = 01010001L;
static final String DESCRIPTION = "description";
private final HashMap _Config;
/**
* Driver instance used for obtaining connections.
*/
private static final Driver _Driver = new Driver();
/**
* Constructs a configured DataSource.
*/
JtdsDataSource( HashMap config )
{
// no need to clone, only called by JtdsObjectFactory
_Config = config;
}
/**
* Constructs a new DataSource.
*/
public JtdsDataSource()
{
// Do not set default property values here. Properties whose default
// values depend on server type will likely be incorrect unless the
// user specified them explicitly.
_Config = new HashMap();
}
/**
* Returns a new XA database connection.
*
* @return a new database connection
* @throws SQLException
* if an error occurs
*/
public XAConnection getXAConnection()
throws SQLException
{
return new JtdsXAConnection( this, getConnection( (String) _Config.get( Driver.USER ), (String) _Config.get( Driver.PASSWORD ) ) );
}
/**
* Returns a new XA database connection for the user and password specified.
*
* @param user
* the user name to connect with
* @param password
* the password to connect with
* @return a new database connection
* @throws SQLException
* if an error occurs
*/
public XAConnection getXAConnection( String user, String password )
throws SQLException
{
return new JtdsXAConnection( this, getConnection( user, password ) );
}
/**
* Returns a new database connection.
*
* @return a new database connection
* @throws SQLException
* if an error occurs
*/
public Connection getConnection()
throws SQLException
{
return getConnection( (String) _Config.get( Driver.USER ), (String) _Config.get( Driver.PASSWORD ) );
}
/**
* Returns a new database connection for the user and password specified.
*
* @param user
* the user name to connect with
* @param password
* the password to connect with
* @return a new database connection
* @throws SQLException
* if an error occurs
*/
public Connection getConnection( String user, String password )
throws SQLException
{
String servername = (String) _Config.get( Driver.SERVERNAME );
String servertype = (String) _Config.get( Driver.SERVERTYPE );
String logfile = (String) _Config.get( Driver.LOGFILE );
if( servername == null || servername.length() == 0 ) throw new SQLException( Messages.get( "error.connection.nohost" ), "08001" );
// this may be the only way to initialize the logging subsystem
// with some containers such as JBOSS.
if( getLogWriter() == null && logfile != null && logfile.length() > 0 )
{
// try to initialize a PrintWriter
try
{
setLogWriter( new PrintWriter( new FileOutputStream( logfile ), true ) );
}
catch( IOException e )
{
System.err.println( "jTDS: Failed to set log file " + e );
}
}
Properties props = new Properties();
addNonNullProperties( props, user, password );
String url;
try
{
// Determine the server type (for the URL stub) or use the default
int serverTypeDef = (servertype == null) ? 0 : Integer.parseInt( servertype );
url = "jdbc:jtds:" + DefaultProperties.getServerTypeWithDefault( serverTypeDef ) + ':';
}
catch( RuntimeException ex )
{
SQLException sqlException = new SQLException( Messages.get( "error.connection.servertype", ex.toString() ), "08001" );
Support.linkException( sqlException, ex );
throw sqlException;
}
// Connect with the URL stub and set properties. The defaults will be
// filled in by connect().
return _Driver.connect( url, props );
}
public Reference getReference()
{
Reference ref = new Reference( getClass().getName(), JtdsObjectFactory.class.getName(), null );
Iterator it = _Config.entrySet().iterator();
while( it.hasNext() )
{
Entry e = (Entry) it.next();
String key = (String) e.getKey();
String val = (String) e.getValue();
ref.add( new StringRefAddr( key, val ) );
}
return ref;
}
//
// ConnectionPoolDataSource methods
//
/**
* Returns a new pooled database connection.
*
* @return a new pooled database connection
* @throws SQLException
* if an error occurs
*/
public javax.sql.PooledConnection getPooledConnection()
throws SQLException
{
return getPooledConnection( (String) _Config.get( Driver.USER ), (String) _Config.get( Driver.PASSWORD ) );
}
/**
* Returns a new pooled database connection for the user and password
* specified.
*
* @param user
* the user name to connect with
* @param password
* the password to connect with
* @return a new pooled database connection
* @throws SQLException
* if an error occurs
*/
public synchronized javax.sql.PooledConnection getPooledConnection( String user, String password )
throws SQLException
{
return new net.sourceforge.jtds.jdbcx.PooledConnection( getConnection( user, password ) );
}
//
// Getters and setters
//
public void setLogWriter( PrintWriter out )
{
Logger.setLogWriter( out );
}
public PrintWriter getLogWriter()
{
return Logger.getLogWriter();
}
public void setLoginTimeout( int loginTimeout )
{
_Config.put( Driver.LOGINTIMEOUT, String.valueOf( loginTimeout ) );
}
public int getLoginTimeout()
{
return getIntProperty( Driver.LOGINTIMEOUT );
}
public void setSocketTimeout( int socketTimeout )
{
_Config.put( Driver.SOTIMEOUT, String.valueOf( socketTimeout ) );
}
public int getSocketTimeout()
{
return getIntProperty( Driver.SOTIMEOUT );
}
public void setSocketKeepAlive( boolean socketKeepAlive )
{
_Config.put( Driver.SOKEEPALIVE, String.valueOf( socketKeepAlive ) );
}
public boolean getSocketKeepAlive()
{
return Boolean.valueOf( (String) _Config.get( Driver.SOKEEPALIVE ) ).booleanValue();
}
public void setProcessId( String processId )
{
_Config.put( Driver.PROCESSID, processId );
}
public String getProcessId()
{
return (String) _Config.get( Driver.PROCESSID );
}
public void setDatabaseName( String databaseName )
{
_Config.put( Driver.DATABASENAME, databaseName );
}
public String getDatabaseName()
{
return (String) _Config.get( Driver.DATABASENAME );
}
public void setDescription( String description )
{
_Config.put( DESCRIPTION, description );
}
public String getDescription()
{
return (String) _Config.get( DESCRIPTION );
}
public void setPassword( String password )
{
_Config.put( Driver.PASSWORD, password );
}
public String getPassword()
{
return (String) _Config.get( Driver.PASSWORD );
}
public void setPortNumber( int portNumber )
{
_Config.put( Driver.PORTNUMBER, String.valueOf( portNumber ) );
}
public int getPortNumber()
{
return getIntProperty( Driver.PORTNUMBER );
}
public void setServerName( String serverName )
{
_Config.put( Driver.SERVERNAME, serverName );
}
public String getServerName()
{
return (String) _Config.get( Driver.SERVERNAME );
}
public void setAutoCommit( boolean autoCommit )
{
_Config.put( Driver.AUTOCOMMIT, String.valueOf( autoCommit ) );
}
public boolean getAutoCommit()
{
return Boolean.valueOf( (String) _Config.get( Driver.AUTOCOMMIT ) ).booleanValue();
}
public void setUser( String user )
{
_Config.put( Driver.USER, user );
}
public String getUser()
{
return (String) _Config.get( Driver.USER );
}
public void setTds( String tds )
{
_Config.put( Driver.TDS, tds );
}
public String getTds()
{
return (String) _Config.get( Driver.TDS );
}
public void setServerType( int serverType )
{
_Config.put( Driver.SERVERTYPE, String.valueOf( serverType ) );
}
public int getServerType()
{
return getIntProperty( Driver.SERVERTYPE );
}
public void setDomain( String domain )
{
_Config.put( Driver.DOMAIN, domain );
}
public String getDomain()
{
return (String) _Config.get( Driver.DOMAIN );
}
public void setUseNTLMV2( boolean usentlmv2 )
{
_Config.put( Driver.USENTLMV2, String.valueOf( usentlmv2 ) );
}
public boolean getUseNTLMV2()
{
return Boolean.valueOf( (String) _Config.get( Driver.USENTLMV2 ) ).booleanValue();
}
public void setUseKerberos(boolean useKerberos)
{
_Config.put( Driver.USEKERBEROS, Boolean.toString( useKerberos ) );
}
public boolean getUseKerberos()
{
return Boolean.valueOf( (String) _Config.get( Driver.USEKERBEROS ) ).booleanValue();
}
public void setInstance( String instance )
{
_Config.put( Driver.INSTANCE, instance );
}
public String getInstance()
{
return (String) _Config.get( Driver.INSTANCE );
}
public void setSendStringParametersAsUnicode( boolean sendStringParametersAsUnicode )
{
_Config.put( Driver.SENDSTRINGPARAMETERSASUNICODE, String.valueOf( sendStringParametersAsUnicode ) );
}
public boolean getSendStringParametersAsUnicode()
{
return Boolean.valueOf( (String) _Config.get( Driver.SENDSTRINGPARAMETERSASUNICODE ) ).booleanValue();
}
public void setNamedPipe( boolean namedPipe )
{
_Config.put( Driver.NAMEDPIPE, String.valueOf( namedPipe ) );
}
public boolean getNamedPipe()
{
return Boolean.valueOf( (String) _Config.get( Driver.NAMEDPIPE ) ).booleanValue();
}
public void setLastUpdateCount( boolean lastUpdateCount )
{
_Config.put( Driver.LASTUPDATECOUNT, String.valueOf( lastUpdateCount ) );
}
public boolean getLastUpdateCount()
{
return Boolean.valueOf( (String) _Config.get( Driver.LASTUPDATECOUNT ) ).booleanValue();
}
public void setXaEmulation( boolean xaEmulation )
{
_Config.put( Driver.XAEMULATION, String.valueOf( xaEmulation ) );
}
public boolean getXaEmulation()
{
return Boolean.valueOf( (String) _Config.get( Driver.XAEMULATION ) ).booleanValue();
}
public void setCharset( String charset )
{
_Config.put( Driver.CHARSET, charset );
}
public String getCharset()
{
return (String) _Config.get( Driver.CHARSET );
}
public void setLanguage( String language )
{
_Config.put( Driver.LANGUAGE, language );
}
public String getLanguage()
{
return (String) _Config.get( Driver.LANGUAGE );
}
public void setMacAddress( String macAddress )
{
_Config.put( Driver.MACADDRESS, macAddress );
}
public String getMacAddress()
{
return (String) _Config.get( Driver.MACADDRESS );
}
public void setPacketSize( int packetSize )
{
_Config.put( Driver.PACKETSIZE, String.valueOf( packetSize ) );
}
public int getPacketSize()
{
return getIntProperty( Driver.PACKETSIZE );
}
public void setTcpNoDelay( boolean tcpNoDelay )
{
_Config.put( Driver.TCPNODELAY, String.valueOf( tcpNoDelay ) );
}
public boolean getTcpNoDelay()
{
return Boolean.valueOf( (String) _Config.get( Driver.TCPNODELAY ) ).booleanValue();
}
public void setPrepareSql( int prepareSql )
{
_Config.put( Driver.PREPARESQL, String.valueOf( prepareSql ) );
}
public int getPrepareSql()
{
return getIntProperty( Driver.PREPARESQL );
}
public void setLobBuffer( long lobBuffer )
{
_Config.put( Driver.LOBBUFFER, String.valueOf( lobBuffer ) );
}
public long getLobBuffer()
{
return getLongProperty( Driver.LOBBUFFER );
}
public void setMaxStatements( int maxStatements )
{
_Config.put( Driver.MAXSTATEMENTS, String.valueOf( maxStatements ) );
}
public int getMaxStatements()
{
return getIntProperty( Driver.MAXSTATEMENTS );
}
public void setAppName( String appName )
{
_Config.put( Driver.APPNAME, appName );
}
public String getAppName()
{
return (String) _Config.get( Driver.APPNAME );
}
public void setProgName( String progName )
{
_Config.put( Driver.PROGNAME, progName );
}
public String getProgName()
{
return (String) _Config.get( Driver.PROGNAME );
}
public void setWsid( String wsid )
{
_Config.put( Driver.WSID, wsid );
}
public String getWsid()
{
return (String) _Config.get( Driver.WSID );
}
public void setLogFile( String logFile )
{
_Config.put( Driver.LOGFILE, logFile );
}
public String getLogFile()
{
return (String) _Config.get( Driver.LOGFILE );
}
public void setSsl( String ssl )
{
_Config.put( Driver.SSL, ssl );
}
public String getSsl()
{
return (String) _Config.get( Driver.SSL );
}
public void setBatchSize( int batchSize )
{
_Config.put( Driver.BATCHSIZE, String.valueOf( batchSize ) );
}
public int getBatchSize()
{
return getIntProperty( Driver.BATCHSIZE );
}
public void setBufferDir( String bufferDir )
{
_Config.put( Driver.BUFFERDIR, bufferDir );
}
public String getBufferDir()
{
return (String) _Config.get( Driver.BUFFERDIR );
}
public int getBufferMaxMemory()
{
return getIntProperty( Driver.BUFFERMAXMEMORY );
}
public void setBufferMaxMemory( int bufferMaxMemory )
{
_Config.put( Driver.BUFFERMAXMEMORY, String.valueOf( bufferMaxMemory ) );
}
public void setBufferMinPackets( int bufferMinPackets )
{
_Config.put( Driver.BUFFERMINPACKETS, String.valueOf( bufferMinPackets ) );
}
public int getBufferMinPackets()
{
return getIntProperty( Driver.BUFFERMINPACKETS );
}
public void setCacheMetaData( boolean cacheMetaData )
{
_Config.put( Driver.CACHEMETA, String.valueOf( cacheMetaData ) );
}
public boolean getCacheMetaData()
{
return Boolean.valueOf( (String) _Config.get( Driver.CACHEMETA ) ).booleanValue();
}
public void setUseCursors( boolean useCursors )
{
_Config.put( Driver.USECURSORS, String.valueOf( useCursors ) );
}
public boolean getUseCursors()
{
return Boolean.valueOf( (String) _Config.get( Driver.USECURSORS ) ).booleanValue();
}
public void setUseLOBs( boolean useLOBs )
{
_Config.put( Driver.USELOBS, String.valueOf( useLOBs ) );
}
public boolean getUseLOBs()
{
return Boolean.valueOf( (String) _Config.get( Driver.USELOBS ) ).booleanValue();
}
public void setBindAddress( String bindAddress )
{
_Config.put( Driver.BINDADDRESS, bindAddress );
}
public String getBindAddress()
{
return (String) _Config.get( Driver.BINDADDRESS );
}
public void setUseJCIFS( boolean useJCIFS )
{
_Config.put( Driver.USEJCIFS, String.valueOf( useJCIFS ) );
}
public boolean getUseJCIFS()
{
return Boolean.valueOf( (String) _Config.get( Driver.USEJCIFS ) ).booleanValue();
}
private void addNonNullProperties( Properties props, String user, String password )
{
Iterator it = _Config.entrySet().iterator();
while( it.hasNext() )
{
Entry e = (Entry) it.next();
String key = (String) e.getKey();
String val = (String) e.getValue();
if( ! key.equals( DESCRIPTION ) && val != null )
{
props.setProperty( Messages.get( key ), val );
}
}
if( user != null )
{
props.setProperty( Messages.get( Driver.USER ), user );
}
if( password != null )
{
props.setProperty( Messages.get( Driver.PASSWORD ), password );
}
}
private int getIntProperty( String key )
{
return Long.valueOf( getLongProperty( key ) ).intValue();
}
private long getLongProperty( String key )
{
String val = (String) _Config.get( key );
if( val == null )
{
return 0;
}
return Long.parseLong( val );
}
/////// JDBC4 demarcation, do NOT put any JDBC3 code below this line ///////
/*
* (non-Javadoc)
* @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
*/
public boolean isWrapperFor( Class arg0 )
{
// TODO Auto-generated method stub
throw new AbstractMethodError();
}
/*
* (non-Javadoc)
* @see java.sql.Wrapper#unwrap(java.lang.Class)
*/
public Object unwrap( Class arg0 )
{
// TODO Auto-generated method stub
throw new AbstractMethodError();
}
// // JDBC4.1 demarcation, do NOT put any JDBC3/4.0 code below this line ////
@Override
public java.util.logging.Logger getParentLogger() throws java.sql.SQLFeatureNotSupportedException
{
// TODO Auto-generated method stub
throw new AbstractMethodError();
}
}