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

src.com.ibm.as400.access.AS400JDBCDriver Maven / Gradle / Ivy

The newest version!
///////////////////////////////////////////////////////////////////////////////
//                                                                             
// 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/4.3 driver that accesses DB2 for IBM i databases.

To use this driver, the application or caller must register the driver with the JDBC DriverManager prior to JDBC 4.0. This class also registers itself automatically when it is loaded. When using the JDBC 4.0 or later versions, the driver is automatically registered.

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 otherwise. @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 otherwise. @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 } if( jdProperties.getBoolean(JDProperties.TCP_NO_DELAY) == true) { if(sockProps == null) sockProps = as400.getSocketProperties(); sockProps.setTcpNoDelay(true); if (JDTrace.isTraceOn()) JDTrace.logInformation(this, "Setting sockProps.setTcpNoDelay(true)"); } 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) { // If we get an exception, make sure the connection is closed. // The common case is when an exit program prevents access to the system. // @AB1A try { if (connection instanceof JDConnectionProxy) { ((JDConnectionProxy)connection).setSystem(as400); ((JDConnectionProxy)connection).setProperties(dataSourceUrl, jdProperties, as400); } else { ((AS400JDBCConnection)connection).setSystem(as400); ((AS400JDBCConnection)connection).setProperties(dataSourceUrl, jdProperties, as400, info); } } catch (SQLException sqlex) { try { connection.close(); } catch (Exception e) { // Just ignore } throw sqlex; } } 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 */ }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy