src.com.ibm.as400.access.AS400JDBCDriver Maven / Gradle / Ivy
Show all versions of jt400-jdk9 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: AS400JDBCDriver.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2010 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.beans.PropertyVetoException; // @B9A
import java.net.InetAddress; // @C2A
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
/*ifdef JDBC40
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
endif */
import java.util.Properties;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
A JDBC 3.0/4.0/4.2 driver that accesses DB2 for IBM i databases.
To use this driver, the application or caller must register
the driver with the JDBC DriverManager. This class also registers
itself automatically when it is loaded.
After registering the driver, applications make connection
requests to the DriverManager, which dispatches them to the
appropriate driver. This driver accepts connection requests
for databases specified by the URLs that match the following syntax:
jdbc:as400://system-name/default-schema;properties
The driver uses the specified system name to connect
to a corresponding IBM i system.
If an IPV6 address is used as the system name, it must be enclosed within braces,
i.e. [fd13:ac12:18:17::16].
If a system name is not specified, then the user will be prompted.
The default SQL schema is optional and the driver uses it to resolve
unqualified names in SQL statements. If no default SQL schema is set, then
the driver resolves unqualified names based on the naming convention
for the connection. If SQL naming is being used, and no default SQL schema
is set, then the driver resolves unqualified names using the schema with
the same name as the user. If system naming is being used, and no
default SQL schema is set, then the driver resolves unqualified names using
the server job's library list. See
JDBC properties
for more details on how to set the naming convention
and library list.
Several properties can optionally be set within the URL. They are
separated by semicolons and are in the form:
name1=value1;name2=value2;...
See
JDBC properties
for a complete list of properties supported by this driver.
The following example URL specifies a connection to the
database on system mysystem.helloworld.com with
mylibrary as the default SQL schema. The connection will
use the system naming convention and return full error messages:
jdbc:as400://mysystem.helloworld.com/mylibrary;naming=system;errors=full
**/
//
// Implementation note:
//
// 1. A goal stated in the JDBC specification is to keep
// the Driver class as small and standalone as possible,
// so that it can be quickly loaded when choosing a
// driver for a particular database.
//
// 2. It was proposed that we also accept URLs with the
// "db2" subprotocol. This would make us consistent with
// other IBM drivers. In addition, it would also allow
// developers to hardcode URLs in programs and they would
// run as-is with both this driver and the "native" driver.
//
// We realized, though, that if running on a client with
// both this driver and another DB2 client for that platform,
// how do the drivers differentiate themselves? Therefore
// we are chosing NOT to recognized the "db2" subprotocol.
// Instead, suggest to developers to externalize the URL
// to users, rather than hardcoding it.
//
//
// Note: Change log is now in Copyright.java
//
public class AS400JDBCDriver
implements java.sql.Driver
{
// Constants.
static final int MAJOR_VERSION_ = Copyright.MAJOR_VERSION;
static final int MINOR_VERSION_ = Copyright.MINOR_VERSION;
static final String DATABASE_PRODUCT_NAME_ = "DB2 UDB for AS/400"; // @D0A
static final String DRIVER_NAME_ = "AS/400 Toolbox for Java JDBC Driver"; // @D0C @C5C @C6C
static final String DRIVER_LEVEL_ = Copyright.DRIVER_LEVEL;
/* ifdef JDBC40
public static final int JDBC_MAJOR_VERSION_ = 4; // JDBC spec version: 4.0
endif */
/* ifndef JDBC40 */
public static final int JDBC_MAJOR_VERSION_ = 3; // JDBC spec version: 3.0
/* endif */
/* ifdef JAVA9
public static final int JDBC_MINOR_VERSION_ = 3;
endif JAVA9 */
/* ifndef JAVA9 */
/* ifdef JDBC42
public static final int JDBC_MINOR_VERSION_ = 2;
endif */
/* ifndef JDBC42 */
public static final int JDBC_MINOR_VERSION_ = 0;
/* endif */
/* endif JAVA9 */
// This string "9999:9999" is returned when resource
// bundle errors occur. No significance to this string,
// except that Client Access used to use it. It would
// probably be more helpful to return some other string.
//
private static final String MRI_NOT_FOUND_ = "9999:9999";
// Private data.
// Toolbox resources needed in proxy jar file. @A1C
private static ResourceBundle resources_;
// Toolbox resources NOT needed in proxy jar file. @A1A
private static ResourceBundle resources2_;
private static final String CLASSNAME = "com.ibm.as400.access.AS400JDBCDriver";
private static Driver nativeDriver = null;
/**
Static initializer. Registers the JDBC driver with the JDBC
driver manager and loads the appropriate resource bundle for
the current locale.
**/
static {
try
{
// Log where the toolbox is loaded from @B1A
if (Trace.traceOn_) Trace.logLoadPath(CLASSNAME, Trace.JDBC);
DriverManager.registerDriver (new AS400JDBCDriver ());
resources_ = ResourceBundle.getBundle ("com.ibm.as400.access.JDMRI");
resources2_ = ResourceBundle.getBundle ("com.ibm.as400.access.JDMRI2");
// Note: When using the proxy jar file, we do not expect to find JDMRI2.
}
catch (MissingResourceException e)
{
// Catch the exception. This is because exceptions
// thrown from static initializers are hard to debug.
// Instead, we will handle the error when the
// driver needs to get at particular methods.
// See getResource().
}
catch (SQLException e)
{
// Ignore.
}
}
/**
Indicates if the driver understands how to connect
to the database named by the URL.
@param url The URL for the database.
@return true if the driver understands how
to connect to the database; false
otherwise.
@exception SQLException If an error occurs.
**/
public boolean acceptsURL (String url)
throws SQLException
{
JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
return dataSourceUrl.isValid ();
}
/**
Connects to the database named by the specified URL.
There are many optional properties that can be specified.
Properties can be specified either as part of the URL or in
a java.util.Properties object. See
JDBC properties
for a complete list of properties
supported by this driver.
@param url The URL for the database.
@param info The connection properties.
@return The connection to the database or null if
the driver does not understand how to connect
to the database.
@exception SQLException If the driver is unable to make the connection.
**/
public java.sql.Connection connect (String url,
Properties info)
throws SQLException
{
// Check first thing to see if the trace property is
// turned on. This way we can trace everything, including
// the important stuff like loading the properties.
JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
Properties urlProperties = dataSourceUrl.getProperties ();
// If trace property was set to true, turn on tracing. If trace property was set to false,
// turn off tracing. If trace property was not set, do not change.
if (JDProperties.isTraceSet (urlProperties, info) == JDProperties.TRACE_SET_ON)
{ //@B5C
if (! JDTrace.isTraceOn ())
JDTrace.setTraceOn (true);
}
else if (JDProperties.isTraceSet (urlProperties, info) == JDProperties.TRACE_SET_OFF) //@B5A
{
//@B5A
if (JDTrace.isTraceOn ()) //@B5A
JDTrace.setTraceOn (false); //@B5A
} //@B5A
//@B4D Deleted lines because trace should not be set off just because property
//@B4D not specified.
//@B4D else
//@B4D JDTrace.setTraceOn (false);
// If toolbox trace is set to datastream. Turn on datastream tracing.
if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDatastreamOn(true);
}
// If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDiagnosticOn(true);
}
// If toolbox trace is set to error. Turn on error tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_ERROR)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceErrorOn(true);
}
// If toolbox trace is set to information. Turn on information tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceInformationOn(true);
}
// If toolbox trace is set to warning. Turn on warning tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_WARNING)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceWarningOn(true);
}
// If toolbox trace is set to conversion. Turn on conversion tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceConversionOn(true);
}
// If toolbox trace is set to proxy. Turn on proxy tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_PROXY)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceProxyOn(true);
}
// If toolbox trace is set to pcml. Turn on pcml tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_PCML)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTracePCMLOn(true);
}
// If toolbox trace is set to jdbc. Turn on jdbc tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_JDBC)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceJDBCOn(true);
}
// If toolbox trace is set to all. Turn on tracing for all categories.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_ALL)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceAllOn(true);
}
// If toolbox trace is set to thread. Turn on thread tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_THREAD)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceThreadOn(true);
}
// If toolbox trace is set to none. Turn off tracing.
else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_NONE)
{
//@K1A
if (Trace.isTraceOn())
{
Trace.setTraceOn(false);
}
}
if (JDTrace.isTraceOn()) {
String traceUrl = url;
int passwordIndex = url.indexOf("password=");
if (passwordIndex >= 0) {
int semicolonIndex = url.indexOf(";",passwordIndex);
if (semicolonIndex < 0) {
traceUrl = url.substring(0,passwordIndex)+"password=******";
} else {
traceUrl = url.substring(0,passwordIndex)+"password=******"+url.substring(semicolonIndex);
}
}
JDTrace.logInformation (this,"connect called with URL: "+traceUrl);
}
JDProperties jdProperties = new JDProperties (urlProperties, info);
// Initialize the connection if the URL is valid.
Connection connection = null; //@A0C
if (dataSourceUrl.isValid ())
connection = initializeConnection (dataSourceUrl, jdProperties,
info); //@A0C
return connection;
}
//@B5A
/**
Connects to the database on the specified system.
Note: Since this method is not defined in the JDBC Driver interface,
you typically need to create a Driver object in order
to call this method:
AS400JDBCDriver d = new AS400JDBCDriver();
AS400 o = new AS400(myAS400, myUserId, myPwd);
Connection c = d.connect (o);
@param system The IBM i system to connect.
@return The connection to the database or null if
the driver does not understand how to connect
to the database.
@exception SQLException If the driver is unable to make the connection.
**/
public java.sql.Connection connect (AS400 system)
throws SQLException
{
if (system == null)
throw new NullPointerException("system");
if (system instanceof SecureAS400)
return initializeConnection(new SecureAS400(system));
else
return initializeConnection(new AS400(system));
// Initialize the connection.
//@B7D Connection connection = null;
//@B7D connection = initializeConnection (o);
//@B7D return connection;
}
//@KKB
/**
Connects to the database on the specified system.
Note: Since this method is not defined in the JDBC Driver interface,
you typically need to create a Driver object in order
to call this method:
AS400JDBCDriver d = new AS400JDBCDriver();
AS400 o = new AS400(myAS400, myUserId, myPwd);
Connection c = d.connect (o, false);
@param system The IBM i system to connect.
@param clone True if the AS400 object should be cloned, false otherwises
@return The connection to the database or null if
the driver does not understand how to connect
to the database.
@exception SQLException If the driver is unable to make the connection.
**/
public java.sql.Connection connect (AS400 system, boolean clone)
throws SQLException
{
if (system == null)
throw new NullPointerException("system");
if(!clone) //Do not clone the AS400 object, use the one passed in
return initializeConnection(system);
else //clone the AS400 object
return connect(system);
}
//@D4A
/**
Connects to the database on the specified system.
Note: Since this method is not defined in the JDBC Driver interface,
you typically need to create a Driver object in order
to call this method:
AS400JDBCDriver d = new AS400JDBCDriver();
AS400 o = new AS400(myAS400, myUserId, myPwd);
String mySchema = "defaultSchema";
Properties prop = new Properties();
Connection c = d.connect (o, prop, mySchema, false);
@param system The IBM i system to connect.
@param info The connection properties.
@param schema The default SQL schema or null meaning no default SQL schema specified.
@param clone True if the AS400 object should be cloned, false otherwises
@return The connection to the database or null if
the driver does not understand how to connect
to the database.
@exception SQLException If the driver is unable to make the connection.
**/
public java.sql.Connection connect (AS400 system, Properties info, String schema, boolean clone)
throws SQLException
{
if (system == null)
throw new NullPointerException("system");
if (info == null)
throw new NullPointerException("properties");
//@PDD not needed, just pass in null to isXTraceSet(null, info) below
//Properties urlProperties = new Properties();
// Check first thing to see if the trace property is
// turned on. This way we can trace everything, including
// the important stuff like loading the properties.
// If trace property was set to true, turn on tracing. If trace property was set to false,
// turn off tracing. If trace property was not set, do not change.
if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_ON)
{
if (! JDTrace.isTraceOn ())
JDTrace.setTraceOn (true);
}
else if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_OFF)
{
if (JDTrace.isTraceOn ())
JDTrace.setTraceOn (false);
}
// If toolbox trace is set to datastream. Turn on datastream tracing.
if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDatastreamOn(true);
}
// If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDiagnosticOn(true);
}
// If toolbox trace is set to error. Turn on error tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ERROR)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceErrorOn(true);
}
// If toolbox trace is set to information. Turn on information tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceInformationOn(true);
}
// If toolbox trace is set to warning. Turn on warning tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_WARNING)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceWarningOn(true);
}
// If toolbox trace is set to conversion. Turn on conversion tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceConversionOn(true);
}
// If toolbox trace is set to proxy. Turn on proxy tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PROXY)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceProxyOn(true);
}
// If toolbox trace is set to pcml. Turn on pcml tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PCML)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTracePCMLOn(true);
}
// If toolbox trace is set to jdbc. Turn on jdbc tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_JDBC)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceJDBCOn(true);
}
// If toolbox trace is set to all. Turn on tracing for all categories.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ALL)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceAllOn(true);
}
// If toolbox trace is set to thread. Turn on thread tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_THREAD)
{
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceThreadOn(true);
}
// If toolbox trace is set to none. Turn off tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_NONE)
{
if (Trace.isTraceOn())
{
Trace.setTraceOn(false);
}
}
if(!clone) //Do not clone the AS400 object, use the one passed in
return initializeConnection(schema, info, system);
else //clone the AS400 object
{
if(system instanceof SecureAS400)
return initializeConnection(schema, info, new SecureAS400(system));
else
return initializeConnection(schema, info, new AS400(system));
}
}
//@B5A
/**
Connects to the database on the specified system.
There are many optional properties that can be specified.
Properties can be specified in
a java.util.Properties object. See
JDBC properties
for a complete list of properties
supported by this driver.
Note: Since this method is not defined in the JDBC Driver interface,
you typically need to create a Driver object in order
to call this method:
AS400JDBCDriver d = new AS400JDBCDriver();
String mySchema = "defaultSchema";
Properties p = new Properties();
AS400 o = new AS400(myAS400, myUserId, myPwd);
Connection c = d.connect (o, p, mySchema);
@param system The IBM i system to connect.
@param info The connection properties.
@param schema The default SQL schema or null meaning no default SQL schema specified.
@return The connection to the database or null if
the driver does not understand how to connect
to the database.
@exception SQLException If the driver is unable to make the connection.
**/
public java.sql.Connection connect (AS400 system, Properties info, String schema)
throws SQLException
{
if (system == null)
throw new NullPointerException("system");
if (info == null)
throw new NullPointerException("properties");
//@B7D AS400 o = new AS400(system);
//@PDD not needed, just pass in null to isXTraceSet(null, info) below
//Properties urlProperties = new Properties();
// Check first thing to see if the trace property is
// turned on. This way we can trace everything, including
// the important stuff like loading the properties.
// If trace property was set to true, turn on tracing. If trace property was set to false,
// turn off tracing. If trace property was not set, do not change.
if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_ON)
{
if (! JDTrace.isTraceOn ())
JDTrace.setTraceOn (true);
}
else if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_OFF)
{
if (JDTrace.isTraceOn ())
JDTrace.setTraceOn (false);
}
// If toolbox trace is set to datastream. Turn on datastream tracing.
if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDatastreamOn(true);
}
// If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceDiagnosticOn(true);
}
// If toolbox trace is set to error. Turn on error tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ERROR)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceErrorOn(true);
}
// If toolbox trace is set to information. Turn on information tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceInformationOn(true);
}
// If toolbox trace is set to warning. Turn on warning tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_WARNING)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceWarningOn(true);
}
// If toolbox trace is set to conversion. Turn on conversion tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceConversionOn(true);
}
// If toolbox trace is set to proxy. Turn on proxy tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PROXY)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceProxyOn(true);
}
// If toolbox trace is set to pcml. Turn on pcml tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PCML)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTracePCMLOn(true);
}
// If toolbox trace is set to jdbc. Turn on jdbc tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_JDBC)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceJDBCOn(true);
}
// If toolbox trace is set to all. Turn on tracing for all categories.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ALL)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceAllOn(true);
}
// If toolbox trace is set to thread. Turn on thread tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_THREAD)
{
//@K1A
if (! Trace.isTraceOn())
{
Trace.setTraceOn(true);
}
Trace.setTraceThreadOn(true);
}
// If toolbox trace is set to none. Turn off tracing.
else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_NONE)
{
//@K1A
if (Trace.isTraceOn())
{
Trace.setTraceOn(false);
}
}
//@PDD not used JDProperties jdProperties = new JDProperties (null, info);
if (system instanceof SecureAS400)
return initializeConnection(schema, info, new SecureAS400(system));
else
return initializeConnection(schema, info, new AS400(system));
// Initialize the connection if the URL is valid.
//@B7D Connection connection = null;
//@B7D connection = initializeConnection (schema, info, o);
//@B7D return connection;
}
/**
Returns the driver's major version number.
@return The major version number.
**/
public int getMajorVersion ()
{
return MAJOR_VERSION_;
}
/**
Returns the driver's minor version number.
@return The minor version number.
**/
public int getMinorVersion ()
{
return MINOR_VERSION_;
}
/**
Returns an array of DriverPropertyInfo objects that
describe the properties that are supported by this
driver.
@param url The URL for the database.
@param info The connection properties.
@return The descriptions of all possible properties or null if
the driver does not understand how to connect to the
database.
@exception SQLException If an error occurs.
**/
public DriverPropertyInfo[] getPropertyInfo (String url,
Properties info)
throws SQLException
{
JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
DriverPropertyInfo[] dpi = null;
if (dataSourceUrl.isValid ())
{
JDProperties properties = new JDProperties (dataSourceUrl.getProperties(), info);
dpi = properties.getInfo ();
}
return dpi;
}
/**
Returns a resource from the resource bundle.
@param key The resource key.
@param replacementVariables -- replacement variables for the message
@return The resource String.
**/
static String getResource (String key, String[] replacementVariables)
{
// If the resource bundle or resource is not found,
// do not thrown an exception. Instead, return a
// default string. This is because some JVMs will
// not recover quite right from such errors, and
// claim a security exception (e.g. Netscape starts
// looking in the client class path, which is
// not allowed.)
//
String resource;
if (resources_ == null)
resource = MRI_NOT_FOUND_;
else
{
try
{
resource = resources_.getString (key);
}
catch (MissingResourceException e)
{
if (resources2_ == null) //@A1A
resource = MRI_NOT_FOUND_; //@A1A
else
{ //@A1A
try
{ //@A1A
resource = resources2_.getString (key); //@A1A
} //@A1A
catch (MissingResourceException e1)
{ //@A1A
JDTrace.logInformation (AS400JDBCDriver.class,
"Missing resource [" + key + "]"); //@A1A
resource = MRI_NOT_FOUND_;
}
}
}
}
if (replacementVariables != null) {
resource = substitute(resource, replacementVariables);
}
return resource;
}
// Replaces substitution variables in a string.
// @param text The text string, with substitution variables (e.g. "Error &0 in table &1.")
// @param values The replacement values.
// @return The text string with all substitution variables replaced.
static String substitute (String text, Object[] values)
{
String result = text;
if (values != null) {
for (int i = 0; i < values.length; ++i) {
String variable = "&" + i;
int j = result.indexOf (variable);
if (j >= 0) {
StringBuffer buffer = new StringBuffer();
buffer.append(result.substring(0, j));
buffer.append(values[i].toString ());
buffer.append(result.substring(j + variable.length ()));
result = buffer.toString ();
}
}
}
return result;
}
//@B3A - This logic was formerly in the initializeConnection() method.
static AS400 initializeAS400(JDDataSourceURL dataSourceUrl,
JDProperties jdProperties,
Properties info)
throws SQLException //@pw1
{
// We must handle the different combinations of input
// user names and passwords.
String serverName = dataSourceUrl.getServerName();
String userName = jdProperties.getString (JDProperties.USER);
String password = jdProperties.getString (JDProperties.PASSWORD);
String prompt = jdProperties.getString (JDProperties.PROMPT); // @B8C
boolean secure = jdProperties.getBoolean (JDProperties.SECURE);
boolean useThreads = jdProperties.getBoolean(JDProperties.THREAD_USED);
//@pw1 Decided to leave connections via AS400() as-is and just implement to mimic Native JDBC
//@pw1 info contains args from DriverMangager.getConnection(args)
//@pw1 jdProperties does not represent null values. Both null and "" have a value of "".
//@pw1 if info contains id/pass of "" then they must not be "" in jdProperties (allowing jdProperties to override)
//@pw1 throw exception if info id/pass == "" and change info id/pass to "" if they are null
//@pw3 Add way to get old behavior allowing "" (!but also need to allow new behavior of allowing null is/passwd so customers can slowly migrate)
//check if "".
String secureCurrentUser = SystemProperties.getProperty (SystemProperties.JDBC_SECURE_CURRENT_USER); //@pw3
boolean isSecureCurrentUser = true; //@pw3
//if system property or jdbc property is set to false then secure current user code is not used
//null value for system property means not specified...so true by default
if(((secureCurrentUser != null) && (Boolean.valueOf(secureCurrentUser).booleanValue() == false)) || !jdProperties.getBoolean(JDProperties.SECURE_CURRENT_USER)) //@pw3
isSecureCurrentUser = false; //@pw3
if(info == null)
info = new Properties();
String userParm = info.getProperty("user"); //@pw1
String passwordParm = info.getProperty("password"); //@pw1
boolean forcePrompt = false; //@prompt
if ("".equals(userName) && "".equals(userParm)) //@pw1 //@pw2
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1 //@prompt
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
if ("".equals(password) && "".equals(passwordParm)) //@pw1 //@pw2
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1 //@prompt
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
if(userParm != null) //@pw1
{ //@pw1
//check for *current //@pw1
if (userParm.compareToIgnoreCase("*CURRENT") == 0) //@pw1
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
} //@pw1
else //@pw1
{ //@pw1
//since info is null, jdProperty must not be "" or *current, but it can be the default value (ie not set by user)
if(!JDProperties.EMPTY_.equals(userName) ) //@pw1
{ //@pw1
//userName was updated by app
if( userName.equals("") || (userName.compareToIgnoreCase("*CURRENT") == 0)) //@pw1
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
} //@pw1
} //@pw1
if(passwordParm != null) //@pw1
{ //@pw1
if (passwordParm.compareToIgnoreCase("*CURRENT") == 0) //@pw1
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
} //@pw1
else //@pw1
{ //@pw1
//since info is null, jdProperty must not be "" or *current, but it can be the default value (ie not set by user)
if(!JDProperties.EMPTY_.equals(password)) //@pw1
{ //@pw1
//password was updated by app
if( password.equals("") || (password.compareToIgnoreCase("*CURRENT") == 0)) //@pw1
{ //@pw1
if(isSecureCurrentUser)//@pw3
{ //@pw3
if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
//JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
forcePrompt = true; //@prompt
} //@pw3
} //@pw1
} //@pw1
} //@pw1
// Create the AS400 object, so we can create a Connection via loadImpl2.
AS400 as400 = null;
if (secure)
{
if (serverName.length() == 0)
as400 = new SecureAS400 ();
else if (userName.length() == 0)
as400 = new SecureAS400 (serverName);
else if (password.length() == 0)
as400 = new SecureAS400 (serverName, userName);
else
as400 = new SecureAS400 (serverName, userName, password);
}
else
{
if (serverName.length() == 0)
as400 = new AS400 ();
else if (userName.length() == 0)
as400 = new AS400 (serverName);
else if (password.length() == 0)
as400 = new AS400 (serverName, userName);
else
as400 = new AS400 (serverName, userName, password);
}
// Determine when the signon GUI can be presented..
try
{
if (!prompt.equals(JDProperties.NOT_SPECIFIED)) // @B8A
as400.setGuiAvailable(jdProperties.getBoolean(JDProperties.PROMPT)); // @B8C
}
catch (java.beans.PropertyVetoException e)
{
// This will never happen, as there are no listeners.
}
//Determine if threads should be used in communication with the host servers
try{
if(!useThreads)
as400.setThreadUsed(useThreads);
}
catch(java.beans.PropertyVetoException e){
}
if(forcePrompt) //@prompt
as400.forcePrompt(); //@prompt
return as400;
}
//@A0A - This logic was formerly in the AS400JDBCConnection ctor and open() method.
private Connection initializeConnection (JDDataSourceURL dataSourceUrl,
JDProperties jdProperties,
Properties info)
throws SQLException
{
//@B7D Connection connection = null;
AS400 as400 = null;
boolean proxyServerWasSpecifiedInUrl = false;
boolean proxyServerWasSpecifiedInProperties = false;
boolean proxyServerWasSpecified = false;
//@C4A Check for native driver only if driver property is not set to Toolbox
String driverImplementation = jdProperties.getString(JDProperties.DRIVER); //@C4M
if (!driverImplementation.equals(JDProperties.DRIVER_TOOLBOX)) //@C4A
{ //@C4A
// @B2A
// Determine whether the native driver is available.
if (nativeDriver == null) {
try {
nativeDriver = (Driver) Class.forName(
"com.ibm.db2.jdbc.app.DB2Driver").newInstance();
if (JDTrace.isTraceOn()) // @C2A
JDTrace
.logInformation(this,
"Native IBM Developer Kit for Java JDBC driver implementation was loaded"); // @C2A
} catch (Throwable e) {
nativeDriver = null;
}
}
// @B2A
// Decide which JDBC driver implementation to use. If the
// native driver is available AND there is no secondary URL
// available AND the "driver" property was not set to "toolbox",
// then use the native driver implementation.
//@C4M String driverImplementation = jdProperties.getString(JDProperties.DRIVER);
if ((nativeDriver != null)
&& (dataSourceUrl.getSecondaryURL().length() == 0))
//@C4D Already checked above && (!driverImplementation.equals(JDProperties.DRIVER_TOOLBOX)))
{
//@C3M
boolean isLocal = false; // @C2A
String serverName = dataSourceUrl.getServerName(); // @C2A
if (serverName.length() == 0 || serverName.equalsIgnoreCase("localhost")) // @C2A //@locala
isLocal = true; // @C2A
else { // @C2A
try { // @C2A
InetAddress localInet = InetAddress.getLocalHost(); // @C2A
InetAddress[] remoteInet = InetAddress.getAllByName(serverName); // @C2A
for (int i = 0; i < remoteInet.length; ++i) { // @C2A
if (localInet.equals(remoteInet[i])) { // @C2A
isLocal = true; // @C2A
} // @C2A
} // @C2A
} // @C2A
catch (Throwable e) { // @C2A
// Ignore. We will just assume that we are not local. @C2A
} // @C2A
}
if (isLocal) { // @C2A
if (JDTrace.isTraceOn()) // @C2A
JDTrace.logInformation(this, "Connection is local"); // @C2A
String nativeURL = dataSourceUrl.getNativeURL();
if (JDTrace.isTraceOn())
JDTrace.logInformation(this, "Using native IBM Developer Kit for Java JDBC driver implementation");//@native don't print passwd
return nativeDriver.connect(nativeURL, info);
} // @C2A
}
}//@C4A
// @C2D else
// @C2D {
if (JDTrace.isTraceOn())
JDTrace.logInformation (this, "Using IBM Toolbox for Java JDBC driver implementation");
// @C2D }
// @A0A
// See if a proxy server was specified.
//if (jdProperties.getIndex (JDProperties.PROXY_SERVER) != -1) //@A3D
if (jdProperties.getString(JDProperties.PROXY_SERVER).length() != 0) //@A3C
proxyServerWasSpecifiedInUrl = true;
if (SystemProperties.getProperty (SystemProperties.AS400_PROXY_SERVER) != null)
proxyServerWasSpecifiedInProperties = true;
if (proxyServerWasSpecifiedInUrl || proxyServerWasSpecifiedInProperties)
proxyServerWasSpecified = true;
// If no proxy server was specified, and there is a secondary URL,
// simply pass the secondary URL to the DriverManager and ask it for
// an appropriate Connection object.
if (!proxyServerWasSpecified)
{
String secondaryUrl = dataSourceUrl.getSecondaryURL ();
if (secondaryUrl.length() != 0)
{
if (JDTrace.isTraceOn())
JDTrace.logInformation (this,
"Secondary URL [" + secondaryUrl + "]");
return DriverManager.getConnection (secondaryUrl, info);
}
}
as400 = initializeAS400(dataSourceUrl, jdProperties, info); // @B3C
if (proxyServerWasSpecifiedInUrl)
{
// A proxy server was specified in URL,
// so we need to inform the AS400 object.
//boolean proxyServerSecure = jdProperties.getBoolean (JDProperties.PROXY_SERVER_SECURE); // TBD
String proxyServerNameAndPort = jdProperties.getString (JDProperties.PROXY_SERVER);
// Note: The PROXY_SERVER property is of the form:
// hostName[:portNumber]
// where portNumber is optional.
try
{
as400.setProxyServer (proxyServerNameAndPort);
//as400.setProxyServerSecure (proxyServerSecure); // TBD
}
catch (java.beans.PropertyVetoException e)
{
} // Will never happen.
}
//@B6C Moved common code to prepareConnection.
return prepareConnection(as400, dataSourceUrl, info, jdProperties);
}
//@B5A
private Connection initializeConnection (AS400 as400)
throws SQLException
{
JDDataSourceURL dataSourceUrl = new JDDataSourceURL(null);
Properties info = new Properties();
JDProperties jdProperties = new JDProperties(null, info);
//@B6C Moved common code to prepareConnection.
return prepareConnection(as400, dataSourceUrl, info, jdProperties);
}
//@B5A
private Connection initializeConnection (String schema, Properties info, AS400 as400)
throws SQLException
{
boolean proxyServerWasSpecifiedInUrl = false;
String url = null;
if (schema != null) //@B6A
url = "jdbc:as400://" + as400.getSystemName() + "/" + schema;
else //@B6A
url = "jdbc:as400://" + as400.getSystemName(); //@B6A
JDDataSourceURL dataSourceUrl = new JDDataSourceURL(url);
JDProperties jdProperties = new JDProperties(null, info);
if (JDTrace.isTraceOn())
JDTrace.logInformation (this, "Using IBM Toolbox for Java JDBC driver implementation");
// See if a proxy server was specified.
if (jdProperties.getString(JDProperties.PROXY_SERVER).length() != 0)
proxyServerWasSpecifiedInUrl = true;
if (proxyServerWasSpecifiedInUrl)
{
// A proxy server was specified in URL, so we need to inform the AS400 object.
//boolean proxyServerSecure = jdProperties.getBoolean (JDProperties.PROXY_SERVER_SECURE);// TBD
String proxyServerNameAndPort = jdProperties.getString (JDProperties.PROXY_SERVER);
// Note: The PROXY_SERVER property is of the form:
// hostName[:portNumber]
// where portNumber is optional.
try
{
as400.setProxyServer (proxyServerNameAndPort);
//as400.setProxyServerSecure (proxyServerSecure); // TBD
}
catch (java.beans.PropertyVetoException e)
{
} // Will never happen.
}
//@B6C Moved common code to prepareConnection.
return prepareConnection(as400, dataSourceUrl, info, jdProperties);
}
/**
Indicates if the driver is a genuine JDBC compliant driver.
@return Always true.
**/
public boolean jdbcCompliant ()
{
return true;
}
//@B6A -- This logic was formerly in the initializeConnection() method.
private Connection prepareConnection(AS400 as400, JDDataSourceURL dataSourceUrl,
Properties info, JDProperties jdProperties)
throws SQLException
{
// set socket properties
SocketProperties sockProps = null;
//if == "", then take platform defaults...do not set
//only get/set properties is one is updated
if( jdProperties.getString(JDProperties.KEEP_ALIVE).equals("") == false)
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setKeepAlive(jdProperties.getBoolean(JDProperties.KEEP_ALIVE));
}
if( jdProperties.getString(JDProperties.RECEIVE_BUFFER_SIZE).equals("") == false)
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setReceiveBufferSize( jdProperties.getInt(JDProperties.RECEIVE_BUFFER_SIZE));
}
if( jdProperties.getString(JDProperties.SEND_BUFFER_SIZE).equals("") == false)
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setSendBufferSize(jdProperties.getInt(JDProperties.SEND_BUFFER_SIZE));
}
//@timeout2
//First get setting from DriverManager, then override with property updates
if(!as400.arePropertiesFrozen()) //@timeout3 AS400JDBCDriver.connect(clone=false) cannot update props. We don't know if DriverManager.setLoginTimeout() has been updated.
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setLoginTimeout(DriverManager.getLoginTimeout() * 1000); //@STIMEOUT
}
//@timeout
if( jdProperties.getString(JDProperties.LOGIN_TIMEOUT).equals("") == false)
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setLoginTimeout(jdProperties.getInt(JDProperties.LOGIN_TIMEOUT) * 1000); //@STIMEOUT
}
//@STIMEOUT
if( jdProperties.getString(JDProperties.SOCKET_TIMEOUT).equals("") == false)
{
if(sockProps == null)
sockProps = as400.getSocketProperties();
sockProps.setSoTimeout(jdProperties.getInt(JDProperties.SOCKET_TIMEOUT)); //@STIMEOUT already in milliseconds
}
String defaultImpl = "com.ibm.as400.access.AS400JDBCConnectionImpl";
if (jdProperties.getInt(JDProperties.ENABLE_CLIENT_AFFINITIES_LIST) == 1) {
defaultImpl = "com.ibm.as400.access.AS400JDBCConnectionRedirect";
}
if(sockProps != null)
as400.setSocketProperties(sockProps);
// Create the appropriate kind of Connection object.
Connection connection = (Connection) as400.loadImpl2 (
defaultImpl,
"com.ibm.as400.access.JDConnectionProxy");
// Set the properties on the Connection object.
if (connection != null)
{
((AS400JDBCConnection)connection).setSystem(as400);
((AS400JDBCConnection)connection).setProperties(dataSourceUrl, jdProperties, as400, info);
}
return connection;
}
/**
Returns the name of the driver.
@return The driver name.
**/
public String toString ()
{
return DRIVER_NAME_; // @D0C
}
/*ifdef JDBC40
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
endif */
}