PageRenderTime 67ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/jtopen-7.8/src/com/ibm/as400/access/AS400JDBCDriver.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1169 lines | 670 code | 88 blank | 411 comment | 270 complexity | ef5ea463c34b5711ba0390bba6b930fb MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // JTOpen (IBM Toolbox for Java - OSS version)
  4. //
  5. // Filename: AS400JDBCDriver.java
  6. //
  7. // The source code contained herein is licensed under the IBM Public License
  8. // Version 1.0, which has been approved by the Open Source Initiative.
  9. // Copyright (C) 1997-2010 International Business Machines Corporation and
  10. // others. All rights reserved.
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. package com.ibm.as400.access;
  14. import java.beans.PropertyVetoException; // @B9A
  15. import java.net.InetAddress; // @C2A
  16. import java.sql.Connection;
  17. import java.sql.Driver;
  18. import java.sql.DriverManager;
  19. import java.sql.DriverPropertyInfo;
  20. import java.sql.SQLException;
  21. /* ifdef JDBC40 */
  22. import java.sql.SQLFeatureNotSupportedException;
  23. import java.util.logging.Logger;
  24. /* endif */
  25. import java.util.Properties;
  26. import java.util.MissingResourceException;
  27. import java.util.ResourceBundle;
  28. /**
  29. A JDBC 3.0/4.0 driver that accesses DB2 for IBM i databases.
  30. <p>To use this driver, the application or caller must register
  31. the driver with the JDBC DriverManager. This class also registers
  32. itself automatically when it is loaded.
  33. <p>After registering the driver, applications make connection
  34. requests to the DriverManager, which dispatches them to the
  35. appropriate driver. This driver accepts connection requests
  36. for databases specified by the URLs that match the following syntax:
  37. <pre>
  38. jdbc:as400://<em>system-name</em>/<em>default-schema</em>;<em>properties</em>
  39. </pre>
  40. <p>The driver uses the specified system name to connect
  41. to a corresponding IBM i system. If a system name is not
  42. specified, then the user will be prompted.
  43. <p>The default SQL schema is optional and the driver uses it to resolve
  44. unqualified names in SQL statements. If no default SQL schema is set, then
  45. the driver resolves unqualified names based on the naming convention
  46. for the connection. If SQL naming is being used, and no default SQL schema
  47. is set, then the driver resolves unqualified names using the schema with
  48. the same name as the user. If system naming is being used, and no
  49. default SQL schema is set, then the driver resolves unqualified names using
  50. the server job's library list. See
  51. <a href="doc-files/JDBCProperties.html" target="_blank">JDBC properties</a>
  52. for more details on how to set the naming convention
  53. and library list.
  54. <p>Several properties can optionally be set within the URL. They are
  55. separated by semicolons and are in the form:
  56. <pre>
  57. <em>name1</em>=<em>value1</em>;<em>name2</em>=<em>value2</em>;<em>...</em>
  58. </pre>
  59. See
  60. <a href="doc-files/JDBCProperties.html" target="_blank">JDBC properties</a>
  61. for a complete list of properties supported by this driver.
  62. <p>The following example URL specifies a connection to the
  63. database on system <em>mysystem.helloworld.com</em> with
  64. <em>mylibrary</em> as the default SQL schema. The connection will
  65. use the system naming convention and return full error messages:
  66. <pre>
  67. jdbc:as400://mysystem.helloworld.com/mylibrary;naming=system;errors=full
  68. </pre>
  69. **/
  70. //
  71. // Implementation note:
  72. //
  73. // 1. A goal stated in the JDBC specification is to keep
  74. // the Driver class as small and standalone as possible,
  75. // so that it can be quickly loaded when choosing a
  76. // driver for a particular database.
  77. //
  78. // 2. It was proposed that we also accept URLs with the
  79. // "db2" subprotocol. This would make us consistent with
  80. // other IBM drivers. In addition, it would also allow
  81. // developers to hardcode URLs in programs and they would
  82. // run as-is with both this driver and the "native" driver.
  83. //
  84. // We realized, though, that if running on a client with
  85. // both this driver and another DB2 client for that platform,
  86. // how do the drivers differentiate themselves? Therefore
  87. // we are chosing NOT to recognized the "db2" subprotocol.
  88. // Instead, suggest to developers to externalize the URL
  89. // to users, rather than hardcoding it.
  90. //
  91. //
  92. // Note: Change log is now in Copyright.java
  93. //
  94. public class AS400JDBCDriver
  95. implements java.sql.Driver
  96. {
  97. // Constants.
  98. static final int MAJOR_VERSION_ = Copyright.MAJOR_VERSION;
  99. static final int MINOR_VERSION_ = Copyright.MINOR_VERSION;
  100. static final String DATABASE_PRODUCT_NAME_ = "DB2 UDB for AS/400"; // @D0A
  101. static final String DRIVER_NAME_ = "AS/400 Toolbox for Java JDBC Driver"; // @D0C @C5C @C6C
  102. static final String DRIVER_LEVEL_ = Copyright.DRIVER_LEVEL;
  103. /* ifdef JDBC40 */
  104. public static final int JDBC_MAJOR_VERSION_ = 4; // JDBC spec version: 4.0
  105. /* endif */
  106. /* ifndef JDBC40
  107. public static final int JDBC_MAJOR_VERSION_ = 3; // JDBC spec version: 3.0
  108. endif */
  109. public static final int JDBC_MINOR_VERSION_ = 0;
  110. // This string "9999:9999" is returned when resource
  111. // bundle errors occur. No significance to this string,
  112. // except that Client Access used to use it. It would
  113. // probably be more helpful to return some other string.
  114. //
  115. private static final String MRI_NOT_FOUND_ = "9999:9999";
  116. // Private data.
  117. // Toolbox resources needed in proxy jar file. @A1C
  118. private static ResourceBundle resources_;
  119. // Toolbox resources NOT needed in proxy jar file. @A1A
  120. private static ResourceBundle resources2_;
  121. private static final String CLASSNAME = "com.ibm.as400.access.AS400JDBCDriver";
  122. /**
  123. Static initializer. Registers the JDBC driver with the JDBC
  124. driver manager and loads the appropriate resource bundle for
  125. the current locale.
  126. **/
  127. static {
  128. try
  129. {
  130. // Log where the toolbox is loaded from @B1A
  131. if (Trace.traceOn_) Trace.logLoadPath(CLASSNAME);
  132. DriverManager.registerDriver (new AS400JDBCDriver ());
  133. resources_ = ResourceBundle.getBundle ("com.ibm.as400.access.JDMRI");
  134. resources2_ = ResourceBundle.getBundle ("com.ibm.as400.access.JDMRI2");
  135. // Note: When using the proxy jar file, we do not expect to find JDMRI2.
  136. }
  137. catch (MissingResourceException e)
  138. {
  139. // Catch the exception. This is because exceptions
  140. // thrown from static initializers are hard to debug.
  141. // Instead, we will handle the error when the
  142. // driver needs to get at particular methods.
  143. // See getResource().
  144. }
  145. catch (SQLException e)
  146. {
  147. // Ignore.
  148. }
  149. }
  150. /**
  151. Indicates if the driver understands how to connect
  152. to the database named by the URL.
  153. @param url The URL for the database.
  154. @return true if the driver understands how
  155. to connect to the database; false
  156. otherwise.
  157. @exception SQLException If an error occurs.
  158. **/
  159. public boolean acceptsURL (String url)
  160. throws SQLException
  161. {
  162. JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
  163. return dataSourceUrl.isValid ();
  164. }
  165. /**
  166. Connects to the database named by the specified URL.
  167. There are many optional properties that can be specified.
  168. Properties can be specified either as part of the URL or in
  169. a java.util.Properties object. See
  170. <a href="doc-files/JDBCProperties.html" target="_blank">JDBC properties</a>
  171. for a complete list of properties
  172. supported by this driver.
  173. @param url The URL for the database.
  174. @param info The connection properties.
  175. @return The connection to the database or null if
  176. the driver does not understand how to connect
  177. to the database.
  178. @exception SQLException If the driver is unable to make the connection.
  179. **/
  180. public java.sql.Connection connect (String url,
  181. Properties info)
  182. throws SQLException
  183. {
  184. // Check first thing to see if the trace property is
  185. // turned on. This way we can trace everything, including
  186. // the important stuff like loading the properties.
  187. JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
  188. Properties urlProperties = dataSourceUrl.getProperties ();
  189. // If trace property was set to true, turn on tracing. If trace property was set to false,
  190. // turn off tracing. If trace property was not set, do not change.
  191. if (JDProperties.isTraceSet (urlProperties, info) == JDProperties.TRACE_SET_ON)
  192. { //@B5C
  193. if (! JDTrace.isTraceOn ())
  194. JDTrace.setTraceOn (true);
  195. }
  196. else if (JDProperties.isTraceSet (urlProperties, info) == JDProperties.TRACE_SET_OFF) //@B5A
  197. {
  198. //@B5A
  199. if (JDTrace.isTraceOn ()) //@B5A
  200. JDTrace.setTraceOn (false); //@B5A
  201. } //@B5A
  202. //@B4D Deleted lines because trace should not be set off just because property
  203. //@B4D not specified.
  204. //@B4D else
  205. //@B4D JDTrace.setTraceOn (false);
  206. // If toolbox trace is set to datastream. Turn on datastream tracing.
  207. if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
  208. {
  209. //@K1A
  210. if (! Trace.isTraceOn())
  211. {
  212. Trace.setTraceOn(true);
  213. }
  214. Trace.setTraceDatastreamOn(true);
  215. }
  216. // If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
  217. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
  218. {
  219. //@K1A
  220. if (! Trace.isTraceOn())
  221. {
  222. Trace.setTraceOn(true);
  223. }
  224. Trace.setTraceDiagnosticOn(true);
  225. }
  226. // If toolbox trace is set to error. Turn on error tracing.
  227. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_ERROR)
  228. {
  229. //@K1A
  230. if (! Trace.isTraceOn())
  231. {
  232. Trace.setTraceOn(true);
  233. }
  234. Trace.setTraceErrorOn(true);
  235. }
  236. // If toolbox trace is set to information. Turn on information tracing.
  237. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
  238. {
  239. //@K1A
  240. if (! Trace.isTraceOn())
  241. {
  242. Trace.setTraceOn(true);
  243. }
  244. Trace.setTraceInformationOn(true);
  245. }
  246. // If toolbox trace is set to warning. Turn on warning tracing.
  247. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_WARNING)
  248. {
  249. //@K1A
  250. if (! Trace.isTraceOn())
  251. {
  252. Trace.setTraceOn(true);
  253. }
  254. Trace.setTraceWarningOn(true);
  255. }
  256. // If toolbox trace is set to conversion. Turn on conversion tracing.
  257. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
  258. {
  259. //@K1A
  260. if (! Trace.isTraceOn())
  261. {
  262. Trace.setTraceOn(true);
  263. }
  264. Trace.setTraceConversionOn(true);
  265. }
  266. // If toolbox trace is set to proxy. Turn on proxy tracing.
  267. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_PROXY)
  268. {
  269. //@K1A
  270. if (! Trace.isTraceOn())
  271. {
  272. Trace.setTraceOn(true);
  273. }
  274. Trace.setTraceProxyOn(true);
  275. }
  276. // If toolbox trace is set to pcml. Turn on pcml tracing.
  277. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_PCML)
  278. {
  279. //@K1A
  280. if (! Trace.isTraceOn())
  281. {
  282. Trace.setTraceOn(true);
  283. }
  284. Trace.setTracePCMLOn(true);
  285. }
  286. // If toolbox trace is set to jdbc. Turn on jdbc tracing.
  287. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_JDBC)
  288. {
  289. //@K1A
  290. if (! Trace.isTraceOn())
  291. {
  292. Trace.setTraceOn(true);
  293. }
  294. Trace.setTraceJDBCOn(true);
  295. }
  296. // If toolbox trace is set to all. Turn on tracing for all categories.
  297. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_ALL)
  298. {
  299. //@K1A
  300. if (! Trace.isTraceOn())
  301. {
  302. Trace.setTraceOn(true);
  303. }
  304. Trace.setTraceAllOn(true);
  305. }
  306. // If toolbox trace is set to thread. Turn on thread tracing.
  307. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_THREAD)
  308. {
  309. //@K1A
  310. if (! Trace.isTraceOn())
  311. {
  312. Trace.setTraceOn(true);
  313. }
  314. Trace.setTraceThreadOn(true);
  315. }
  316. // If toolbox trace is set to none. Turn off tracing.
  317. else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TRACE_TOOLBOX_NONE)
  318. {
  319. //@K1A
  320. if (Trace.isTraceOn())
  321. {
  322. Trace.setTraceOn(false);
  323. }
  324. }
  325. JDProperties jdProperties = new JDProperties (urlProperties, info);
  326. // Initialize the connection if the URL is valid.
  327. Connection connection = null; //@A0C
  328. if (dataSourceUrl.isValid ())
  329. connection = initializeConnection (dataSourceUrl, jdProperties,
  330. info); //@A0C
  331. return connection;
  332. }
  333. //@B5A
  334. /**
  335. Connects to the database on the specified system.
  336. <p>Note: Since this method is not defined in the JDBC Driver interface,
  337. you typically need to create a Driver object in order
  338. to call this method:
  339. <blockquote><pre>
  340. AS400JDBCDriver d = new AS400JDBCDriver();
  341. AS400 o = new AS400(myAS400, myUserId, myPwd);
  342. Connection c = d.connect (o);
  343. </pre></blockquote>
  344. @param system The IBM i system to connect.
  345. @return The connection to the database or null if
  346. the driver does not understand how to connect
  347. to the database.
  348. @exception SQLException If the driver is unable to make the connection.
  349. **/
  350. public java.sql.Connection connect (AS400 system)
  351. throws SQLException
  352. {
  353. if (system == null)
  354. throw new NullPointerException("system");
  355. if (system instanceof SecureAS400)
  356. return initializeConnection(new SecureAS400(system));
  357. else
  358. return initializeConnection(new AS400(system));
  359. // Initialize the connection.
  360. //@B7D Connection connection = null;
  361. //@B7D connection = initializeConnection (o);
  362. //@B7D return connection;
  363. }
  364. //@KKB
  365. /**
  366. Connects to the database on the specified system.
  367. <p>Note: Since this method is not defined in the JDBC Driver interface,
  368. you typically need to create a Driver object in order
  369. to call this method:
  370. <blockquote><pre>
  371. AS400JDBCDriver d = new AS400JDBCDriver();
  372. AS400 o = new AS400(myAS400, myUserId, myPwd);
  373. Connection c = d.connect (o, false);
  374. </pre></blockquote>
  375. @param system The IBM i system to connect.
  376. @param clone True if the AS400 object should be cloned, false otherwises
  377. @return The connection to the database or null if
  378. the driver does not understand how to connect
  379. to the database.
  380. @exception SQLException If the driver is unable to make the connection.
  381. **/
  382. public java.sql.Connection connect (AS400 system, boolean clone)
  383. throws SQLException
  384. {
  385. if (system == null)
  386. throw new NullPointerException("system");
  387. if(!clone) //Do not clone the AS400 object, use the one passed in
  388. return initializeConnection(system);
  389. else //clone the AS400 object
  390. return connect(system);
  391. }
  392. //@D4A
  393. /**
  394. Connects to the database on the specified system.
  395. <p>Note: Since this method is not defined in the JDBC Driver interface,
  396. you typically need to create a Driver object in order
  397. to call this method:
  398. <blockquote><pre>
  399. AS400JDBCDriver d = new AS400JDBCDriver();
  400. AS400 o = new AS400(myAS400, myUserId, myPwd);
  401. String mySchema = "defaultSchema";
  402. Properties prop = new Properties();
  403. Connection c = d.connect (o, prop, mySchema, false);
  404. </pre></blockquote>
  405. @param system The IBM i system to connect.
  406. @param info The connection properties.
  407. @param schema The default SQL schema or null meaning no default SQL schema specified.
  408. @param clone True if the AS400 object should be cloned, false otherwises
  409. @return The connection to the database or null if
  410. the driver does not understand how to connect
  411. to the database.
  412. @exception SQLException If the driver is unable to make the connection.
  413. **/
  414. public java.sql.Connection connect (AS400 system, Properties info, String schema, boolean clone)
  415. throws SQLException
  416. {
  417. if (system == null)
  418. throw new NullPointerException("system");
  419. if (info == null)
  420. throw new NullPointerException("properties");
  421. //@PDD not needed, just pass in null to isXTraceSet(null, info) below
  422. //Properties urlProperties = new Properties();
  423. // Check first thing to see if the trace property is
  424. // turned on. This way we can trace everything, including
  425. // the important stuff like loading the properties.
  426. // If trace property was set to true, turn on tracing. If trace property was set to false,
  427. // turn off tracing. If trace property was not set, do not change.
  428. if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_ON)
  429. {
  430. if (! JDTrace.isTraceOn ())
  431. JDTrace.setTraceOn (true);
  432. }
  433. else if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_OFF)
  434. {
  435. if (JDTrace.isTraceOn ())
  436. JDTrace.setTraceOn (false);
  437. }
  438. // If toolbox trace is set to datastream. Turn on datastream tracing.
  439. if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
  440. {
  441. if (! Trace.isTraceOn())
  442. {
  443. Trace.setTraceOn(true);
  444. }
  445. Trace.setTraceDatastreamOn(true);
  446. }
  447. // If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
  448. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
  449. {
  450. if (! Trace.isTraceOn())
  451. {
  452. Trace.setTraceOn(true);
  453. }
  454. Trace.setTraceDiagnosticOn(true);
  455. }
  456. // If toolbox trace is set to error. Turn on error tracing.
  457. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ERROR)
  458. {
  459. if (! Trace.isTraceOn())
  460. {
  461. Trace.setTraceOn(true);
  462. }
  463. Trace.setTraceErrorOn(true);
  464. }
  465. // If toolbox trace is set to information. Turn on information tracing.
  466. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
  467. {
  468. if (! Trace.isTraceOn())
  469. {
  470. Trace.setTraceOn(true);
  471. }
  472. Trace.setTraceInformationOn(true);
  473. }
  474. // If toolbox trace is set to warning. Turn on warning tracing.
  475. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_WARNING)
  476. {
  477. if (! Trace.isTraceOn())
  478. {
  479. Trace.setTraceOn(true);
  480. }
  481. Trace.setTraceWarningOn(true);
  482. }
  483. // If toolbox trace is set to conversion. Turn on conversion tracing.
  484. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
  485. {
  486. if (! Trace.isTraceOn())
  487. {
  488. Trace.setTraceOn(true);
  489. }
  490. Trace.setTraceConversionOn(true);
  491. }
  492. // If toolbox trace is set to proxy. Turn on proxy tracing.
  493. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PROXY)
  494. {
  495. if (! Trace.isTraceOn())
  496. {
  497. Trace.setTraceOn(true);
  498. }
  499. Trace.setTraceProxyOn(true);
  500. }
  501. // If toolbox trace is set to pcml. Turn on pcml tracing.
  502. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PCML)
  503. {
  504. if (! Trace.isTraceOn())
  505. {
  506. Trace.setTraceOn(true);
  507. }
  508. Trace.setTracePCMLOn(true);
  509. }
  510. // If toolbox trace is set to jdbc. Turn on jdbc tracing.
  511. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_JDBC)
  512. {
  513. if (! Trace.isTraceOn())
  514. {
  515. Trace.setTraceOn(true);
  516. }
  517. Trace.setTraceJDBCOn(true);
  518. }
  519. // If toolbox trace is set to all. Turn on tracing for all categories.
  520. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ALL)
  521. {
  522. if (! Trace.isTraceOn())
  523. {
  524. Trace.setTraceOn(true);
  525. }
  526. Trace.setTraceAllOn(true);
  527. }
  528. // If toolbox trace is set to thread. Turn on thread tracing.
  529. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_THREAD)
  530. {
  531. if (! Trace.isTraceOn())
  532. {
  533. Trace.setTraceOn(true);
  534. }
  535. Trace.setTraceThreadOn(true);
  536. }
  537. // If toolbox trace is set to none. Turn off tracing.
  538. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_NONE)
  539. {
  540. if (Trace.isTraceOn())
  541. {
  542. Trace.setTraceOn(false);
  543. }
  544. }
  545. if(!clone) //Do not clone the AS400 object, use the one passed in
  546. return initializeConnection(schema, info, system);
  547. else //clone the AS400 object
  548. {
  549. if(system instanceof SecureAS400)
  550. return initializeConnection(schema, info, new SecureAS400(system));
  551. else
  552. return initializeConnection(schema, info, new AS400(system));
  553. }
  554. }
  555. //@B5A
  556. /**
  557. Connects to the database on the specified system.
  558. There are many optional properties that can be specified.
  559. Properties can be specified in
  560. a java.util.Properties object. See
  561. <a href="doc-files/JDBCProperties.html" target="_blank">JDBC properties</a>
  562. for a complete list of properties
  563. supported by this driver.
  564. <p>Note: Since this method is not defined in the JDBC Driver interface,
  565. you typically need to create a Driver object in order
  566. to call this method:
  567. <blockquote><pre>
  568. AS400JDBCDriver d = new AS400JDBCDriver();
  569. String mySchema = "defaultSchema";
  570. Properties p = new Properties();
  571. AS400 o = new AS400(myAS400, myUserId, myPwd);
  572. Connection c = d.connect (o, p, mySchema);
  573. </pre></blockquote>
  574. @param system The IBM i system to connect.
  575. @param info The connection properties.
  576. @param schema The default SQL schema or null meaning no default SQL schema specified.
  577. @return The connection to the database or null if
  578. the driver does not understand how to connect
  579. to the database.
  580. @exception SQLException If the driver is unable to make the connection.
  581. **/
  582. public java.sql.Connection connect (AS400 system, Properties info, String schema)
  583. throws SQLException
  584. {
  585. if (system == null)
  586. throw new NullPointerException("system");
  587. if (info == null)
  588. throw new NullPointerException("properties");
  589. //@B7D AS400 o = new AS400(system);
  590. //@PDD not needed, just pass in null to isXTraceSet(null, info) below
  591. //Properties urlProperties = new Properties();
  592. // Check first thing to see if the trace property is
  593. // turned on. This way we can trace everything, including
  594. // the important stuff like loading the properties.
  595. // If trace property was set to true, turn on tracing. If trace property was set to false,
  596. // turn off tracing. If trace property was not set, do not change.
  597. if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_ON)
  598. {
  599. if (! JDTrace.isTraceOn ())
  600. JDTrace.setTraceOn (true);
  601. }
  602. else if (JDProperties.isTraceSet (null, info) == JDProperties.TRACE_SET_OFF)
  603. {
  604. if (JDTrace.isTraceOn ())
  605. JDTrace.setTraceOn (false);
  606. }
  607. // If toolbox trace is set to datastream. Turn on datastream tracing.
  608. if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DATASTREAM)
  609. {
  610. //@K1A
  611. if (! Trace.isTraceOn())
  612. {
  613. Trace.setTraceOn(true);
  614. }
  615. Trace.setTraceDatastreamOn(true);
  616. }
  617. // If toolbox trace is set to diagnostic. Turn on diagnostic tracing.
  618. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_DIAGNOSTIC)
  619. {
  620. //@K1A
  621. if (! Trace.isTraceOn())
  622. {
  623. Trace.setTraceOn(true);
  624. }
  625. Trace.setTraceDiagnosticOn(true);
  626. }
  627. // If toolbox trace is set to error. Turn on error tracing.
  628. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ERROR)
  629. {
  630. //@K1A
  631. if (! Trace.isTraceOn())
  632. {
  633. Trace.setTraceOn(true);
  634. }
  635. Trace.setTraceErrorOn(true);
  636. }
  637. // If toolbox trace is set to information. Turn on information tracing.
  638. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_INFORMATION)
  639. {
  640. //@K1A
  641. if (! Trace.isTraceOn())
  642. {
  643. Trace.setTraceOn(true);
  644. }
  645. Trace.setTraceInformationOn(true);
  646. }
  647. // If toolbox trace is set to warning. Turn on warning tracing.
  648. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_WARNING)
  649. {
  650. //@K1A
  651. if (! Trace.isTraceOn())
  652. {
  653. Trace.setTraceOn(true);
  654. }
  655. Trace.setTraceWarningOn(true);
  656. }
  657. // If toolbox trace is set to conversion. Turn on conversion tracing.
  658. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_CONVERSION)
  659. {
  660. //@K1A
  661. if (! Trace.isTraceOn())
  662. {
  663. Trace.setTraceOn(true);
  664. }
  665. Trace.setTraceConversionOn(true);
  666. }
  667. // If toolbox trace is set to proxy. Turn on proxy tracing.
  668. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PROXY)
  669. {
  670. //@K1A
  671. if (! Trace.isTraceOn())
  672. {
  673. Trace.setTraceOn(true);
  674. }
  675. Trace.setTraceProxyOn(true);
  676. }
  677. // If toolbox trace is set to pcml. Turn on pcml tracing.
  678. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_PCML)
  679. {
  680. //@K1A
  681. if (! Trace.isTraceOn())
  682. {
  683. Trace.setTraceOn(true);
  684. }
  685. Trace.setTracePCMLOn(true);
  686. }
  687. // If toolbox trace is set to jdbc. Turn on jdbc tracing.
  688. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_JDBC)
  689. {
  690. //@K1A
  691. if (! Trace.isTraceOn())
  692. {
  693. Trace.setTraceOn(true);
  694. }
  695. Trace.setTraceJDBCOn(true);
  696. }
  697. // If toolbox trace is set to all. Turn on tracing for all categories.
  698. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_ALL)
  699. {
  700. //@K1A
  701. if (! Trace.isTraceOn())
  702. {
  703. Trace.setTraceOn(true);
  704. }
  705. Trace.setTraceAllOn(true);
  706. }
  707. // If toolbox trace is set to thread. Turn on thread tracing.
  708. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_THREAD)
  709. {
  710. //@K1A
  711. if (! Trace.isTraceOn())
  712. {
  713. Trace.setTraceOn(true);
  714. }
  715. Trace.setTraceThreadOn(true);
  716. }
  717. // If toolbox trace is set to none. Turn off tracing.
  718. else if (JDProperties.isToolboxTraceSet (null, info) == JDProperties.TRACE_TOOLBOX_NONE)
  719. {
  720. //@K1A
  721. if (Trace.isTraceOn())
  722. {
  723. Trace.setTraceOn(false);
  724. }
  725. }
  726. //@PDD not used JDProperties jdProperties = new JDProperties (null, info);
  727. if (system instanceof SecureAS400)
  728. return initializeConnection(schema, info, new SecureAS400(system));
  729. else
  730. return initializeConnection(schema, info, new AS400(system));
  731. // Initialize the connection if the URL is valid.
  732. //@B7D Connection connection = null;
  733. //@B7D connection = initializeConnection (schema, info, o);
  734. //@B7D return connection;
  735. }
  736. /**
  737. Returns the driver's major version number.
  738. @return The major version number.
  739. **/
  740. public int getMajorVersion ()
  741. {
  742. return MAJOR_VERSION_;
  743. }
  744. /**
  745. Returns the driver's minor version number.
  746. @return The minor version number.
  747. **/
  748. public int getMinorVersion ()
  749. {
  750. return MINOR_VERSION_;
  751. }
  752. /**
  753. Returns an array of DriverPropertyInfo objects that
  754. describe the properties that are supported by this
  755. driver.
  756. @param url The URL for the database.
  757. @param info The connection properties.
  758. @return The descriptions of all possible properties or null if
  759. the driver does not understand how to connect to the
  760. database.
  761. @exception SQLException If an error occurs.
  762. **/
  763. public DriverPropertyInfo[] getPropertyInfo (String url,
  764. Properties info)
  765. throws SQLException
  766. {
  767. JDDataSourceURL dataSourceUrl = new JDDataSourceURL (url);
  768. DriverPropertyInfo[] dpi = null;
  769. if (dataSourceUrl.isValid ())
  770. {
  771. JDProperties properties = new JDProperties (dataSourceUrl.getProperties(), info);
  772. dpi = properties.getInfo ();
  773. }
  774. return dpi;
  775. }
  776. /**
  777. Returns a resource from the resource bundle.
  778. @param key The resource key.
  779. @return The resource String.
  780. **/
  781. static String getResource (String key)
  782. {
  783. // If the resource bundle or resource is not found,
  784. // do not thrown an exception. Instead, return a
  785. // default string. This is because some JVMs will
  786. // not recover quite right from such errors, and
  787. // claim a security exception (e.g. Netscape starts
  788. // looking in the client class path, which is
  789. // not allowed.)
  790. //
  791. String resource;
  792. if (resources_ == null)
  793. resource = MRI_NOT_FOUND_;
  794. else
  795. {
  796. try
  797. {
  798. resource = resources_.getString (key);
  799. }
  800. catch (MissingResourceException e)
  801. {
  802. if (resources2_ == null) //@A1A
  803. resource = MRI_NOT_FOUND_; //@A1A
  804. else
  805. { //@A1A
  806. try
  807. { //@A1A
  808. resource = resources2_.getString (key); //@A1A
  809. } //@A1A
  810. catch (MissingResourceException e1)
  811. { //@A1A
  812. JDTrace.logInformation (AS400JDBCDriver.class,
  813. "Missing resource [" + key + "]"); //@A1A
  814. resource = MRI_NOT_FOUND_;
  815. }
  816. }
  817. }
  818. }
  819. return resource;
  820. }
  821. //@B3A - This logic was formerly in the initializeConnection() method.
  822. static AS400 initializeAS400(JDDataSourceURL dataSourceUrl,
  823. JDProperties jdProperties,
  824. Properties info)
  825. throws SQLException //@pw1
  826. {
  827. // We must handle the different combinations of input
  828. // user names and passwords.
  829. String serverName = dataSourceUrl.getServerName();
  830. String userName = jdProperties.getString (JDProperties.USER);
  831. String password = jdProperties.getString (JDProperties.PASSWORD);
  832. String prompt = jdProperties.getString (JDProperties.PROMPT); // @B8C
  833. boolean secure = jdProperties.getBoolean (JDProperties.SECURE);
  834. String keyRingName = jdProperties.getString (JDProperties.KEY_RING_NAME); //@B9A
  835. String keyRingPassword = jdProperties.getString (JDProperties.KEY_RING_PASSWORD); //@B9A
  836. boolean useThreads = jdProperties.getBoolean(JDProperties.THREAD_USED);
  837. //@pw1 Decided to leave connections via AS400() as-is and just implement to mimic Native JDBC
  838. //@pw1 info contains args from DriverMangager.getConnection(args)
  839. //@pw1 jdProperties does not represent null values. Both null and "" have a value of "".
  840. //@pw1 if info contains id/pass of "" then they must not be "" in jdProperties (allowing jdProperties to override)
  841. //@pw1 throw exception if info id/pass == "" and change info id/pass to "" if they are null
  842. //@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)
  843. //check if "".
  844. String secureCurrentUser = SystemProperties.getProperty (SystemProperties.JDBC_SECURE_CURRENT_USER); //@pw3
  845. boolean isSecureCurrentUser = true; //@pw3
  846. //if system property or jdbc property is set to false then secure current user code is not used
  847. //null value for system property means not specified...so true by default
  848. if(((secureCurrentUser != null) && (Boolean.valueOf(secureCurrentUser).booleanValue() == false)) || !jdProperties.getBoolean(JDProperties.SECURE_CURRENT_USER)) //@pw3
  849. isSecureCurrentUser = false; //@pw3
  850. if(info == null)
  851. info = new Properties();
  852. String userParm = info.getProperty("user"); //@pw1
  853. String passwordParm = info.getProperty("password"); //@pw1
  854. boolean forcePrompt = false; //@prompt
  855. if ("".equals(userName) && "".equals(userParm)) //@pw1 //@pw2
  856. { //@pw1
  857. if(isSecureCurrentUser)//@pw3
  858. { //@pw3
  859. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  860. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  861. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1 //@prompt
  862. forcePrompt = true; //@prompt
  863. } //@pw3
  864. } //@pw1
  865. if ("".equals(password) && "".equals(passwordParm)) //@pw1 //@pw2
  866. { //@pw1
  867. if(isSecureCurrentUser)//@pw3
  868. { //@pw3
  869. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  870. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  871. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1 //@prompt
  872. forcePrompt = true; //@prompt
  873. } //@pw3
  874. } //@pw1
  875. if(userParm != null) //@pw1
  876. { //@pw1
  877. //check for *current //@pw1
  878. if (userParm.compareToIgnoreCase("*CURRENT") == 0) //@pw1
  879. { //@pw1
  880. if(isSecureCurrentUser)//@pw3
  881. { //@pw3
  882. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  883. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  884. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
  885. forcePrompt = true; //@prompt
  886. } //@pw3
  887. } //@pw1
  888. } //@pw1
  889. else //@pw1
  890. { //@pw1
  891. //since info is null, jdProperty must not be "" or *current, but it can be the default value (ie not set by user)
  892. if(userName != JDProperties.EMPTY_) //@pw1
  893. { //@pw1
  894. //userName was updated by app
  895. if( userName.equals("") || (userName.compareToIgnoreCase("*CURRENT") == 0)) //@pw1
  896. { //@pw1
  897. if(isSecureCurrentUser)//@pw3
  898. { //@pw3
  899. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  900. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  901. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
  902. forcePrompt = true; //@prompt
  903. } //@pw3
  904. } //@pw1
  905. } //@pw1
  906. } //@pw1
  907. if(passwordParm != null) //@pw1
  908. { //@pw1
  909. if (passwordParm.compareToIgnoreCase("*CURRENT") == 0) //@pw1
  910. { //@pw1
  911. if(isSecureCurrentUser)//@pw3
  912. { //@pw3
  913. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  914. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  915. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
  916. forcePrompt = true; //@prompt
  917. } //@pw3
  918. } //@pw1
  919. } //@pw1
  920. else //@pw1
  921. { //@pw1
  922. //since info is null, jdProperty must not be "" or *current, but it can be the default value (ie not set by user)
  923. if(password != JDProperties.EMPTY_) //@pw1
  924. { //@pw1
  925. //password was updated by app
  926. if( password.equals("") || (password.compareToIgnoreCase("*CURRENT") == 0)) //@pw1
  927. { //@pw1
  928. if(isSecureCurrentUser)//@pw3
  929. { //@pw3
  930. if (JDTrace.isTraceOn()) //jdbc category trace //@pw1
  931. JDTrace.logInformation (AS400JDBCDriver.class, "Userid/password cannot be \"\" or *CURRENT due to security constraints. Use null instead"); //@pw1
  932. //JDError.throwSQLException(JDError.EXC_CONNECTION_REJECTED); //@pw1
  933. forcePrompt = true; //@prompt
  934. } //@pw3
  935. } //@pw1
  936. } //@pw1
  937. } //@pw1
  938. // Create the AS400 object, so we can create a Connection via loadImpl2.
  939. AS400 as400 = null;
  940. if (secure)
  941. {
  942. if (serverName.length() == 0)
  943. as400 = new SecureAS400 ();
  944. else if (userName.length() == 0)
  945. as400 = new SecureAS400 (serverName);
  946. else if (password.length() == 0)
  947. as400 = new SecureAS400 (serverName, userName);
  948. else
  949. as400 = new SecureAS400 (serverName, userName, password);
  950. if (keyRingName != null && keyRingPassword != null && !keyRingName.equals("")) //@B9A @C1C
  951. {
  952. try
  953. { //@B9A
  954. ((SecureAS400)as400).setKeyRingName(keyRingName, keyRingPassword); //@B9A
  955. } //@B9A
  956. catch (PropertyVetoException pve) //@B9A
  957. { /*Will never happen*/
  958. } //@B9A
  959. } //@B9A
  960. }
  961. else
  962. {
  963. if (serverName.length() == 0)
  964. as400 = new AS400 ();
  965. else if (userName.length() == 0)
  966. as400 = new AS400 (serverName);
  967. else if (password.length() == 0)
  968. as400 = new AS400 (serverName, userName);
  969. else
  970. as400 = new AS400 (serverName, userName, password);
  971. }
  972. // Determine when the signon GUI can be presented..
  973. try
  974. {
  975. if (!prompt.equals(JDProperties.NOT_SPECIFIED)) // @B8A
  976. as400.setGuiAvailable(jdProperties.getBoolean(JDProperties.PROMPT)); // @B8C
  977. }
  978. catch (java.beans.PropertyVetoException e)
  979. {
  980. // This will never happen, as there are no listeners.
  981. }
  982. //Determine if threads should be used in communication with the host servers
  983. try{
  984. if(!useThreads)
  985. as400.setThreadUsed(useThreads);
  986. }
  987. catch(java.beans.PropertyVetoException e){
  988. }
  989. if(forcePrompt) //@prompt
  990. as400.forcePrompt(); //@prompt
  991. return as400;
  992. }
  993. //@A0A - This logic was formerly in the AS400JDBCConnection ctor and open() method.
  994. private Connection initializeConnection (JDDataSourceURL dataSourceUrl,
  995. JDProperties jdProperties,
  996. Properties info)
  997. throws SQLException
  998. {
  999. //@B7D Connection connection = null;
  1000. AS400 as400 = null;
  1001. boolean proxyServerWasSpecifiedInUrl = false;
  1002. boolean proxyServerWasSpecifiedInProperties = false;
  1003. boolean proxyServerWasSpecified = false;
  1004. //@C4A Check for native driver only if driver property is not set to Toolbox
  1005. String driverImplementation = jdProperties.getString(JDProperties.DRIVER); //@C4M
  1006. if (!driverImplementation.equals(JDProperties.DRIVER_TOOLBOX)) //@C4A
  1007. { //@C4A
  1008. // @B2A
  1009. // Determine whether the native driver is available.
  1010. Driver nativeDriver;
  1011. try
  1012. {
  1013. nativeDriver = (Driver)Class.forName("com.ibm.db2.jdbc.app.DB2Driver").newInstance();
  1014. if (JDTrace.isTraceOn()) // @C2A
  1015. JDTrace.logInformation(this, "Native IBM Developer Kit for Java JDBC driver implementation was loaded"); // @C2A
  1016. }
  1017. catch (Throwable e)
  1018. {
  1019. nativeDriver = null;
  1020. }
  1021. // @B2A
  1022. // Decide which JDBC driver implementation to use. If the
  1023. // native driver is available AND there is no secondary URL
  1024. // available AND the "driver" property was not set to "toolbox",
  1025. // then use the native driver implementation.
  1026. //@C4M String driverImplementation = jdProperties.getString(JDProperties.DRIVER);
  1027. if ((nativeDriver != null)
  1028. && (dataSourceUrl.getSecondaryURL().length() == 0))
  1029. //@C4D Already checked above && (!driverImplementation.equals(JDProperties.DRIVER_TOOLBOX)))
  1030. {
  1031. //@C3M
  1032. boolean isLocal = false; // @C2A
  1033. String serverName = dataSourceUrl.getServerName(); // @C2A
  1034. if (serverName.length() == 0 || serverName.equalsIgnoreCase("localhost")) // @C2A //@locala
  1035. isLocal = true; // @C2A
  1036. else { // @C2A
  1037. try { // @C2A
  1038. InetAddress localInet = InetAddress.getLocalHost(); // @C2A
  1039. InetAddress[] remoteInet = InetAddress.getAllByName(serverName); // @C2A
  1040. for (int i = 0; i < remoteInet.length; ++i) { // @C2A
  1041. if (localInet.equals(remoteInet[i])) { // @C2A
  1042. isLocal = true; // @C2A
  1043. } // @C2A
  1044. } // @C2A
  1045. } // @C2A
  1046. catch (Throwable e) { // @C2A
  1047. // Ignore. We will just assume that we are not local. @C2A
  1048. } // @C2A
  1049. }
  1050. if (isLocal) { // @C2A
  1051. if (JDTrace.isTraceOn()) // @C2A
  1052. JDTrace.logInformation(this, "Connection is local"); // @C2A
  1053. String nativeURL = dataSourceU