All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.sqlserver.jdbc.SQLServerDataSource Maven / Gradle / Ivy

There is a newer version: 12.8.1.jre11
Show newest version
//---------------------------------------------------------------------------------------------------------------------------------
// File: SQLServerDataSource.java
//
//
// Microsoft JDBC Driver for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""), 
//  to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
//  and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
//  IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
 
 
package com.microsoft.sqlserver.jdbc;

import javax.sql.*;
import java.sql.*;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import javax.naming.*;

/**
* This datasource lists properties specific for the SQLServerConnection class.
*/
public class SQLServerDataSource implements ISQLServerDataSource, DataSource, java.io.Serializable, javax.naming.Referenceable
{
    // dsLogger is logger used for all SQLServerDataSource instances. 
    static final java.util.logging.Logger dsLogger = java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.SQLServerDataSource");
    static final java.util.logging.Logger loggerExternal =
                            java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc.DataSource");
    final private String loggingClassName;
    private boolean trustStorePasswordStripped = false; 
    private static final long serialVersionUID = 654861379544314296L;

    private Properties connectionProps;			// Properties passed to SQLServerConnection class.
    private String dataSourceURL;				// URL for datasource.
    private String dataSourceDescription;		// Description for datasource.
    static private int baseDataSourceID = 0;	// Unique id generator for each DataSource instance (used for logging).
    final private String traceID;
    
    public SQLServerDataSource() 
    {
        connectionProps = new Properties();
        int dataSourceID = nextDataSourceID();
        String nameL = getClass().getName();
        traceID =  nameL.substring(1 + nameL.lastIndexOf('.')) + ":"  + dataSourceID;
        loggingClassName = "com.microsoft.sqlserver.jdbc." + nameL.substring(1 + nameL.lastIndexOf('.')) + ":"  + dataSourceID;
    }

    String getClassNameLogging()
    {
        return loggingClassName;
    }
    public String toString() 
    {
        return traceID;
    }

    // DataSource interface public methods

    public Connection getConnection() throws SQLServerException 
    { 
        loggerExternal.entering(getClassNameLogging(),  "getConnection");         
        Connection con = getConnectionInternal(null, null, null);
        loggerExternal.exiting(getClassNameLogging(),  "getConnection", con);
        return con;
    }
    public Connection getConnection(String username, String password) throws SQLServerException 
    {
        if (loggerExternal.isLoggable(Level.FINER)) 
            loggerExternal.entering(getClassNameLogging(),  "getConnection", new Object[]{username, "Password not traced"}); 
        Connection con = getConnectionInternal(username, password, null);
        loggerExternal.exiting(getClassNameLogging(),  "getConnection", con);
        return con;
    }

    // Sets the maximum time in seconds that this data source will wait while 
    // attempting to connect to a database.  Note default value is 0.
    public void setLoginTimeout(int loginTimeout)
    {
        setIntProperty(connectionProps, SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(), loginTimeout);
    }
    public int getLoginTimeout()
    {
 		int defaultTimeOut = SQLServerDriverIntProperty.LOGIN_TIMEOUT.getDefaultValue();   
        final int logintimeout = getIntProperty(connectionProps, SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(), defaultTimeOut);
        // even if the user explicitly sets the timeout to zero, convert to 15    
        return (logintimeout==0)?defaultTimeOut:logintimeout;
    }

    // Sets the log writer for this DataSource.
    // Currently we just hold onto this logWriter and pass it back to callers, nothing else.
    private transient PrintWriter logWriter;
    public void setLogWriter(PrintWriter out) 
    {
        loggerExternal.entering(getClassNameLogging(), "setLogWriter" ,out); 
        logWriter = out;
        loggerExternal.exiting(getClassNameLogging(),  "setLogWriter");
    }

    // Retrieves the log writer for this DataSource.
    public PrintWriter getLogWriter() 
    {
        loggerExternal.entering(getClassNameLogging(), "getLogWriter" ); 
        loggerExternal.exiting(getClassNameLogging(),  "getLogWriter", logWriter);
        return logWriter;
    }	

    public Logger getParentLogger() throws SQLFeatureNotSupportedException
    {
        DriverJDBCVersion.checkSupportsJDBC41();

    	// The driver currently does not implement JDDBC 4.1 APIs
    	throw new SQLFeatureNotSupportedException(SQLServerException.getErrString("R_notSupported"));    	    	
    }
    
    // Core Connection property setters/getters.

    // applicationName is used to identify the specific application in various SQL Server 
    // profiling and logging tools.
    public void setApplicationName(String applicationName)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_NAME.toString(), applicationName);
    }
    public String getApplicationName()
    {
        return    getStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_NAME.toString(), SQLServerDriverStringProperty.APPLICATION_NAME.getDefaultValue());
    }

    // databaseName is the name of the database to connect to. If databaseName is not set, 
    // getDatabaseName returns the default value of null.
    public void setDatabaseName(String databaseName)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.DATABASE_NAME.toString(), databaseName);
    }
    public String getDatabaseName()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.DATABASE_NAME.toString(), null);
    }

    // instanceName is the SQL Server instance name to connect to.  
    // If instanceName is not set, getInstanceName returns the default value of null.
    public void setInstanceName(String instanceName)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.INSTANCE_NAME.toString(), instanceName);
    }
    public String getInstanceName()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.INSTANCE_NAME.toString(), null);
    }

    public void setIntegratedSecurity(boolean enable)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.toString(), enable);
    }
	public void setAuthenticationScheme(String authenticationScheme)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION_SCHEME.toString(), authenticationScheme);
    }
	
	public void setAuthentication(String authentication)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION.toString(), authentication);
    }
	
	public String getAuthentication(){
		return getStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION.toString(), SQLServerDriverStringProperty.AUTHENTICATION.getDefaultValue());
	}
	
	public void setAccessToken(String accessToken)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.ACCESS_TOKEN.toString(), accessToken);
    }
	
	public String getAccessToken(){
		 return getStringProperty(connectionProps, SQLServerDriverStringProperty.ACCESS_TOKEN.toString(), null);
	}

    // If lastUpdateCount is set to true, the driver will return only the last update 
    // count from all the update counts returned by a batch.  The default of false will 
    // return all update counts.  If lastUpdateCount is not set, getLastUpdateCount 
    // returns the default value of false.
	
    public void setColumnEncryptionSetting(String columnEncryptionSetting)
    {
    	setStringProperty(connectionProps, SQLServerDriverStringProperty.COLUMN_ENCRYPTION.toString(), columnEncryptionSetting);
    }
    public String getColumnEncryptionSetting()
    {
    	return getStringProperty(connectionProps, SQLServerDriverStringProperty.COLUMN_ENCRYPTION.toString(), SQLServerDriverStringProperty.COLUMN_ENCRYPTION.getDefaultValue());
    }
	
    public void setKeyStoreAuthentication(String keyStoreAuthentication)
    {
    	setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(), keyStoreAuthentication);
    }
    public String getKeyStoreAuthentication()
    {
    	return getStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(), SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.getDefaultValue());
    }

    public void setKeyStoreSecret(String keyStoreSecret)
    {
    	setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_SECRET.toString(), keyStoreSecret);
    }
    
    public void setKeyStoreLocation(String keyStoreLocation)
    {
    	setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_LOCATION.toString(), keyStoreLocation);
    }
    public String getKeyStoreLocation()
    {
    	return getStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_LOCATION.toString(), SQLServerDriverStringProperty.KEY_STORE_LOCATION.getDefaultValue());
    }

    public void setLastUpdateCount(boolean lastUpdateCount)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString(), lastUpdateCount);
    }
    public boolean getLastUpdateCount()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString(), SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.getDefaultValue());
    }

    // Encryption
    public void setEncrypt(boolean encrypt)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENCRYPT.toString(), encrypt);
    }
    public boolean getEncrypt()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENCRYPT.toString(), SQLServerDriverBooleanProperty.ENCRYPT.getDefaultValue());
    }
    
    public void setTransparentNetworkIPResolution(boolean tnir)
    {
    	setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString(), tnir);
    }
    public boolean getTransparentNetworkIPResolution()
    {
    	return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString(), SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.getDefaultValue());
    }
    
    public void setTrustServerCertificate(boolean e)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(), e);
    }
    public boolean getTrustServerCertificate()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(), SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.getDefaultValue());
    }
    public void setTrustStore(String st)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE.toString(), st);
    }
    public String getTrustStore()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE.toString(), null);
    }
    
    public void setTrustStorePassword(String p)
    {
        // if a non value property is set 
        if (p!=null)
            trustStorePasswordStripped = false;
        setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(), p);
    }
    public void setHostNameInCertificate(String host)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(), host);
    }
    public String getHostNameInCertificate()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(), null);
    }
    
    // lockTimeout is the number of milliseconds to wait before the database reports 
    // a lock timeout.  The default value of -1 means wait forever.  If specified, 
    // this value will be the default for all statements on the connection.  Note a 
    // value of 0 means no wait.  If lockTimeout is not set, getLockTimeout returns 
    // the default of -1.	
    public void setLockTimeout(int lockTimeout)
    {
        setIntProperty(connectionProps, SQLServerDriverIntProperty.LOCK_TIMEOUT.toString(), lockTimeout);
    }
    public int getLockTimeout()
    {
        return getIntProperty(connectionProps, SQLServerDriverIntProperty.LOCK_TIMEOUT.toString(), SQLServerDriverIntProperty.LOCK_TIMEOUT.getDefaultValue());
    }

    // setPassword sets the password that will be used when connecting to SQL Server.  
    // Note getPassword is deliberately declared non-public for security reasons.  
    // If the password is not set, getPassword returns the default value of null.  
    public void setPassword(String password)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.PASSWORD.toString(), password);
    }
    String getPassword()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.PASSWORD.toString(), null);
    }

    // portNumber is the TCP-IP port number used when opening a socket connection 
    // to SQL Server.  If portNumber is not set, getPortNumber returns the default 
    // of 1433.  Note as mentioned above, setPortNumber does not do any range 
    // checking on the port value passed in, invalid port numbers like 99999 can 
    // be passed in without triggering any error.  
    public void setPortNumber(int portNumber)
    {
        setIntProperty(connectionProps, SQLServerDriverIntProperty.PORT_NUMBER.toString(), portNumber);
    }
    public int getPortNumber()
    {
        return getIntProperty(connectionProps, SQLServerDriverIntProperty.PORT_NUMBER.toString(), SQLServerDriverIntProperty.PORT_NUMBER.getDefaultValue());
    }

    // selectMethod is the default cursor type used for the result set. This 
    // property is useful when you are dealing with large result sets and don't 
    // want to store the whole result set in memory on the client side. By setting 
    // the property to "cursor" you will be able to create a server side cursor that
    // can fetch smaller chunks of data at a time.  If selectMethod is not set, 
    // getSelectMethod returns the default value of "direct".
    public void setSelectMethod(String selectMethod)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.SELECT_METHOD.toString(), selectMethod);
    }
    public String getSelectMethod()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.SELECT_METHOD.toString(), SQLServerDriverStringProperty.SELECT_METHOD.getDefaultValue() );
    }

    public void setResponseBuffering(String respo)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString(), respo);
    }
    public String getResponseBuffering()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString(), SQLServerDriverStringProperty.RESPONSE_BUFFERING.getDefaultValue());
    }

    public void setApplicationIntent(String applicationIntent)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_INTENT.toString(), applicationIntent);
    }
    public String getApplicationIntent()
    {
    	return getStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_INTENT.toString(), SQLServerDriverStringProperty.APPLICATION_INTENT.getDefaultValue());
    }

    public void setSendTimeAsDatetime(boolean sendTimeAsDatetime)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(), sendTimeAsDatetime);
    }

    public boolean getSendTimeAsDatetime()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(), SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue());
    }

    // If sendStringParametersAsUnicode is set to true (which is the default), 
    // string parameters are sent to the server in UNICODE format.  If sendStringParametersAsUnicode 
    // is set to false, string parameters are sent to the server in the native TDS collation 
    // format of the database, not in UNICODE. If sendStringParametersAsUnicode is not set, 
    // getSendStringParametersAsUnicode returns the default of true.
    public void setSendStringParametersAsUnicode(boolean sendStringParametersAsUnicode)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.toString(), sendStringParametersAsUnicode);
    }
    public boolean getSendStringParametersAsUnicode()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.toString(), SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.getDefaultValue());
    }
    // Translates the serverName from Unicode to ASCII Compatible Encoding (ACE)
    public void setServerNameAsACE(boolean serverNameAsACE)
    {
    	setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString(), serverNameAsACE);	
    }
    public boolean getServerNameAsACE()
    {
    	return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString(), SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.getDefaultValue());
    }
    // serverName is the host name of the target SQL Server.  If serverName is not set, 
    // getServerName returns the default value of null is returned.
    public void setServerName(String serverName)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_NAME.toString(), serverName);
    }
    public String getServerName()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_NAME.toString(), null);
    }
    // Specify an Service Principal Name (SPN) of the target SQL Server.
    // https://msdn.microsoft.com/en-us/library/cc280459.aspx
    public void setServerSpn(String serverSpn)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_SPN.toString(), serverSpn);
    }
    public String getServerSpn()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_SPN.toString(), null);
    }
    // serverName is the host name of the target SQL Server.  If serverName is not set, 
    // getServerName returns the default value of null is returned.
    public void setFailoverPartner(String serverName)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.FAILOVER_PARTNER.toString(), serverName);
    }
    public String getFailoverPartner()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.FAILOVER_PARTNER.toString(), null);
    }

    public void setMultiSubnetFailover(boolean multiSubnetFailover)
    {
    	setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString(), multiSubnetFailover);
    }    
    
    public boolean getMultiSubnetFailover()
    {
    	return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString(), SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.getDefaultValue());
    }

    // setUser set's the user name that will be used when connecting to SQL Server.  
    // If user is not set, getUser returns the default value of null.
    public void setUser(String user)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.USER.toString(), user);
    }
    public String getUser()
    {
        return getStringProperty(connectionProps, SQLServerDriverStringProperty.USER.toString(), null);
    }

    // workstationID is the name of the client machine (or client workstation).  
    // workstationID is the host name of the client in other words.  If workstationID 
    // is not set, the default value is constructed by calling InetAddress.getLocalHost().getHostName() 
    // or if getHostName() returns blank then getHostAddress().toString().
    public void setWorkstationID(String workstationID)
    {
        setStringProperty(connectionProps, SQLServerDriverStringProperty.WORKSTATION_ID.toString(), workstationID);
    }
    public String getWorkstationID()
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER) )    
            loggerExternal.entering(getClassNameLogging(),  "getWorkstationID");
        String getWSID = connectionProps.getProperty(SQLServerDriverStringProperty.WORKSTATION_ID.toString());
        // Per spec, return what the logon will send here if workstationID property is not set.
        if (null == getWSID) 
        {
            getWSID = Util.lookupHostName(); 
        }
        loggerExternal.exiting(getClassNameLogging(),  "getWorkstationID", getWSID);
        return getWSID;
    }

    // If xopenStates is set to true, the driver will convert SQL states to XOPEN 
    // compliant states. The default is false which causes the driver to generate SQL 99 
    // state codes.  If xopenStates is not set, getXopenStates returns the default value 
    // of false.
    public void setXopenStates(boolean xopenStates)
    {
        setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.XOPEN_STATES.toString(), xopenStates);
    }
    public boolean getXopenStates()
    {
        return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.XOPEN_STATES.toString(), SQLServerDriverBooleanProperty.XOPEN_STATES.getDefaultValue());
    }

    // The URL property is exposed for backwards compatibility reasons.  Also, several 
    // Java Application servers expect a setURL function on the DataSource and set it 
    // by default (JBoss and WebLogic).

    // Note for security reasons we do not recommend that customers include the password 
    // in the url supplied to setURL.  The reason for this is third-party Java Application 
    // Servers will very often display the value set to URL property in their DataSource 
    // configuration GUI.  We recommend instead that clients use the setPassword method 
    // to set the password value.  The Java Application Servers will not display a password 
    // that is set on the DataSource in the configuration GUI.

    // Note if setURL is not called, getURL returns the default value of "jdbc:sqlserver://".
    public void setURL(String url)
    {

         loggerExternal.entering(getClassNameLogging(), "setURL", url);
        // URL is not stored in a property set, it is maintained separately.
        dataSourceURL = url;
        loggerExternal.exiting(getClassNameLogging(),  "setURL");
    }
    public String getURL()
    {   
        String url = dataSourceURL;
        loggerExternal.entering(getClassNameLogging(), "getURL");

        if (null == dataSourceURL) 
            url = "jdbc:sqlserver://";
        loggerExternal.exiting(getClassNameLogging(),  "getURL", url);
        return url;
    }

    // DataSource specific property setters/getters.

    // Per JDBC specification 16.1.1 "...the only property that all DataSource 
    // implementations are required to support is the description property".
    public void setDescription(String description)
    {
        loggerExternal.entering(getClassNameLogging(), "setDescription", description);
        dataSourceDescription = description;
        loggerExternal.exiting(getClassNameLogging(),  "setDescription");
    }
    public String getDescription()
    {
        loggerExternal.entering(getClassNameLogging(), "getDescription");
        loggerExternal.exiting(getClassNameLogging(),  "getDescription", dataSourceDescription);
        return dataSourceDescription;
    }

    // packetSize is the size (in bytes) to use for the TCP/IP send and receive
    // buffer.  It is also the value used for the TDS packet size (SQL Server
    // Network Packet Size).  Validity of the value is checked at connect time.
    // If no value is set for this property, its default value is 4KB.
    public void setPacketSize(int packetSize)
    {
        setIntProperty(connectionProps, SQLServerDriverIntProperty.PACKET_SIZE.toString(), packetSize);
    }
    public int getPacketSize()
    {
        return getIntProperty(connectionProps, SQLServerDriverIntProperty.PACKET_SIZE.toString(), SQLServerDriverIntProperty.PACKET_SIZE.getDefaultValue());
    }

    // responseBuffering controls the driver's buffering of responses from SQL Server.
    // Possible values are:
    //
    // "full" - Fully buffer the response at execution time.
    // Advantages:
    //   100% back compat with v1.1 driver
    //   Maximizes concurrency on the server
    // Disadvantages:
    //   Consumes more client-side memory
    //   Client scalability limits with large responses
    //   More execute latency
    //
    // "adaptive" - Data Pipe adaptive buffering
    // Advantages:
    //   Buffers only when necessary, only as much as necessary
    //   Enables handling very large responses, values
    // Disadvantages
    //   Reduced concurrency on the server
    // Internal functions for setting/getting property values.

    // Set a string property value.
    // Caller will always supply a non-null props and propKey.
    // Caller may supply a null propValue, in this case no property value is set.
    private void setStringProperty(Properties props, String propKey, String propValue) 
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER) && !propKey.contains("password") &&  !propKey.contains("Password"))    
        {
            loggerExternal.entering(getClassNameLogging(),  "set"+propKey, propValue);
        }
        else 
            loggerExternal.entering(getClassNameLogging(),  "set"+propKey);
        if (null!=propValue) 
            props.setProperty(propKey, propValue);
        loggerExternal.exiting(getClassNameLogging(),  "set"+propKey);
    }

    // Reads property value in String format.
    // Caller will always supply a non-null props and propKey.
    // Returns null if the specific property value is not set.
    private String getStringProperty(Properties props, String propKey, String defaultValue) 
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.entering(getClassNameLogging(),  "get"+propKey);
        String propValue = props.getProperty(propKey);
        if (null==propValue) 
            propValue = defaultValue;
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER)&& !propKey.contains("password") &&  !propKey.contains("Password"))
            loggerExternal.exiting(getClassNameLogging(),  "get"+propKey, propValue);
        return propValue;
    }

    // Set an integer property value.
    // Caller will always supply a non-null props and propKey.
    private void setIntProperty(Properties props, String propKey, int propValue)
    {
         if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.entering(getClassNameLogging(),  "set"+propKey, new Integer(propValue));   
        props.setProperty(propKey, new Integer(propValue).toString());
        loggerExternal.exiting(getClassNameLogging(),  "set"+propKey);
    }

    // Reads a property value in int format.
    // Caller will always supply a non-null props and propKey.
    // Returns defaultValue if the specific property value is not set.
    private int getIntProperty(Properties props, String propKey, int defaultValue)
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.entering(getClassNameLogging(),  "get"+propKey);
        String propValue = props.getProperty(propKey);
        int value = defaultValue;
        if (null!=propValue) 
        {
            try
            {
                value = Integer.parseInt(propValue);
            }
            catch(NumberFormatException nfe)
            {
                // This exception cannot occur as all of our properties
                // are set internally by int -> Integer.toString.
                assert false : "Bad portNumber:-"+ propValue;
            }
        }
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.exiting(getClassNameLogging(),  "get"+propKey, new Integer(value));    
        return value;
    }

    // Set a boolean property value.
    // Caller will always supply a non-null props and propKey.
    private void setBooleanProperty(Properties props, String propKey, boolean propValue)
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.entering(getClassNameLogging(),  "set"+propKey, Boolean.valueOf(propValue));
        props.setProperty(propKey, (propValue) ? "true" : "false" );
        loggerExternal.exiting(getClassNameLogging(),  "set"+propKey);
    }

    // Reads a property value in boolean format.
    // Caller will always supply a non-null props and propKey.
    // Returns defaultValue if the specific property value is not set.
    private boolean getBooleanProperty(Properties props, String propKey, boolean defaultValue)
    {
        if(loggerExternal.isLoggable(java.util.logging.Level.FINER))    
            loggerExternal.entering(getClassNameLogging(),  "get"+propKey);
        String propValue = props.getProperty(propKey);
        Boolean value;
        if (null==propValue)
        {
            value =  defaultValue;
        }
        else
        {
            // Since we set the value of the String property ourselves to
            // "true" or "false", we can do this.
            value = Boolean.valueOf(propValue);
        }
        loggerExternal.exiting(getClassNameLogging(),  "get"+propKey, value); 
        return value.booleanValue();
    }


    // Returns a SQLServerConnection given username, password, and pooledConnection.
    // Note that the DataSource properties set to connectionProps are used when creating 
    // the connection.

    // Both username and password can be null.

    // If pooledConnection is not null, then connection returned is attached to the pooledConnection
    // and participates in connection pooling.
    SQLServerConnection getConnectionInternal(String username, String password, 
    SQLServerPooledConnection pooledConnection) throws SQLServerException 
    {
    Properties userSuppliedProps = null;
    Properties mergedProps = null;
    // Trust store password stripped and this object got created via Objectfactory referencing. 
    if(trustStorePasswordStripped)    
        SQLServerException.makeFromDriverError(null, null,
            SQLServerException.getErrString("R_referencingFailedTSP"), null, true);

    // If username or password is passed in, clone the property set so we
    // don't alter original connectionProps.
    if (null != username || null != password)
    {
        userSuppliedProps = (Properties)this.connectionProps.clone();

        // Remove user and password from connectionProps if set.
        // We want the user supplied user+password to replace
        // whatever is set in connectionProps.
        userSuppliedProps.remove(SQLServerDriverStringProperty.USER.toString());
        userSuppliedProps.remove(SQLServerDriverStringProperty.PASSWORD.toString());

        if (null != username)
            userSuppliedProps.put(SQLServerDriverStringProperty.USER.toString(), username);
        if (null != password)
            userSuppliedProps.put(SQLServerDriverStringProperty.PASSWORD.toString(), password);
    }
    else
    {
        userSuppliedProps = connectionProps;
    }

    // Merge in URL properties into userSuppliedProps if URL is set.
    if (null != dataSourceURL)
    {
        Properties urlProps = Util.parseUrl(dataSourceURL, dsLogger);
        // null returned properties means that the passed in URL is not supported.
        if(null == urlProps)	
            SQLServerException.makeFromDriverError(null, null,
        SQLServerException.getErrString("R_errorConnectionString"), null, true);
        // Manually merge URL props and user supplied props.
        mergedProps = SQLServerDriver.mergeURLAndSuppliedProperties(urlProps, userSuppliedProps);
    }
    else
    {
        mergedProps = userSuppliedProps;
    }

    // Create new connection and connect.
    if (dsLogger.isLoggable(Level.FINER))				
        dsLogger.finer(toString() + " Begin create new connection.");
    SQLServerConnection result = new SQLServerConnection(toString());
    result.connect(mergedProps, pooledConnection);
    if (dsLogger.isLoggable(Level.FINER))				
        dsLogger.finer(toString() + " End create new connection " + result.toString());
    return result;
    }

    // Implement javax.naming.Referenceable interface methods.

    public Reference getReference() 
    {
        loggerExternal.entering(getClassNameLogging(), "getReference");
        Reference ref = getReferenceInternal("com.microsoft.sqlserver.jdbc.SQLServerDataSource");
        loggerExternal.exiting(getClassNameLogging(),  "getReference", ref);
        return ref;
    }

    Reference getReferenceInternal(String dataSourceClassString)
    {
    if (dsLogger.isLoggable(Level.FINER))				
        dsLogger.finer(toString() + " creating reference for " + dataSourceClassString + ".");

    Reference ref = new Reference(this.getClass().getName(),
        "com.microsoft.sqlserver.jdbc.SQLServerDataSourceObjectFactory", null);
    if(null != dataSourceClassString)
        ref.add(new StringRefAddr("class", dataSourceClassString));
    
    if(trustStorePasswordStripped)
        ref.add(new StringRefAddr("trustStorePasswordStripped", "true"));                

    // Add each property name+value pair found in connectionProps.
    Enumeration e = connectionProps.keys();
    while (e.hasMoreElements()) 
    {
        String propertyName = (String)e.nextElement();
        // If a trustStore password is set, it is omitted and a trustStorePasswordSet flag is set.
        if(propertyName.equals(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString()))
        {
            // The property set and the variable set at the same time is not possible
            assert trustStorePasswordStripped == false;
            ref.add(new StringRefAddr("trustStorePasswordStripped", "true"));                
        }
        else
        {
            // do not add passwords to the collection. we have normal password 
            if (!propertyName.contains(SQLServerDriverStringProperty.PASSWORD.toString()))
                ref.add(new StringRefAddr(propertyName, connectionProps.getProperty(propertyName)));
        }
    }

    // Add dataSourceURL and dataSourceDescription as these will not appear in connectionProps.
    if (null != dataSourceURL)
    ref.add(new StringRefAddr("dataSourceURL", dataSourceURL));

    if (null != dataSourceDescription)
    ref.add(new StringRefAddr("dataSourceDescription", dataSourceDescription));

    return ref;
    }

    // Initialize this datasource from properties found inside the reference ref.
    // Called by SQLServerDataSourceObjectFactory to initialize new DataSource instance.
    void initializeFromReference(javax.naming.Reference ref)
    {
        // Enumerate all the StringRefAddr objects in the Reference and assign properties appropriately.
        Enumeration e = ref.getAll();
        while (e.hasMoreElements()) 
        {
            StringRefAddr addr   = (StringRefAddr) e.nextElement();
            String propertyName  = addr.getType();
            String propertyValue = (String) addr.getContent();

            // Special case dataSourceURL and dataSourceDescription.
            if (propertyName.equals("dataSourceURL"))
            {
                dataSourceURL = propertyValue;
            }
            else if (propertyName.equals("dataSourceDescription"))
            {
                dataSourceDescription = propertyValue;
            }
            else if (propertyName.equals("trustStorePasswordStripped"))
            {
                trustStorePasswordStripped = true;
            }
            // Just skip "class" StringRefAddr, it does not go into connectionProps
            else if (false == propertyName.equals("class"))
            {

                connectionProps.setProperty(propertyName, propertyValue);
            }
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException
    {
        loggerExternal.entering(getClassNameLogging(), "isWrapperFor", iface );
        DriverJDBCVersion.checkSupportsJDBC4();
        boolean f = iface.isInstance(this);
        loggerExternal.exiting(getClassNameLogging(),  "isWrapperFor", Boolean.valueOf(f));
        return f;
    }

    public  T unwrap(Class iface) throws SQLException
    {
        loggerExternal.entering(getClassNameLogging(), "unwrap", iface);
        DriverJDBCVersion.checkSupportsJDBC4();

        T t;
        try
        {
            t = iface.cast(this);
        }
        catch (ClassCastException e)
        {
            throw new SQLServerException(e.getMessage(), e);
        }
        loggerExternal.exiting(getClassNameLogging(),  "unwrap", t);
        return t;
    }

    // Returns unique id for each DataSource instance.
    private synchronized static int nextDataSourceID()
    {
        baseDataSourceID++;
        return baseDataSourceID;
    }
    private Object writeReplace() throws java.io.ObjectStreamException
    {
        return new SerializationProxy(this);
    }
    private void readObject(java.io.ObjectInputStream stream) throws java.io.InvalidObjectException
    {
        // For added security/robustness, the only way to rehydrate a serialized SQLServerDataSource
        // is to use a SerializationProxy.  Direct use of readObject() is not supported.
        throw new java.io.InvalidObjectException("");
    }

    // This code is duplicated in pooled and XA datasource classes. 
    private static class SerializationProxy  
        implements java.io.Serializable
    {
        private final Reference ref;   
        private static final long serialVersionUID = 654661379542314226L;
        
        SerializationProxy (SQLServerDataSource ds)
        {
            // We do not need the class name so pass null, serialization mechanism 
            // stores the class info.
            ref = ds.getReferenceInternal(null);
        }
        private Object readResolve()
        {
            SQLServerDataSource ds = new SQLServerDataSource();
            ds.initializeFromReference(ref);
            return ds;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy