1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 package com.sun.star.comp.sdbc; 22 23 import com.sun.star.comp.sdbc.classloading.ClassMap; 24 import java.util.Iterator; 25 import java.util.Properties; 26 27 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.CompHelper; 28 import org.apache.openoffice.comp.sdbc.dbtools.util.AutoRetrievingBase; 29 import org.apache.openoffice.comp.sdbc.dbtools.util.Resources; 30 import org.apache.openoffice.comp.sdbc.dbtools.util.SharedResources; 31 import org.apache.openoffice.comp.sdbc.dbtools.util.StandardSQLState; 32 33 import com.sun.star.beans.NamedValue; 34 import com.sun.star.beans.PropertyValue; 35 import com.sun.star.comp.sdbc.classloading.ClassLoaderAndClass; 36 import com.sun.star.comp.sdbc.ConnectionLog.ObjectType; 37 import com.sun.star.container.XNameAccess; 38 import com.sun.star.lang.IllegalArgumentException; 39 import com.sun.star.lang.XMultiServiceFactory; 40 import com.sun.star.lang.XServiceInfo; 41 import com.sun.star.lib.uno.helper.ComponentBase; 42 import com.sun.star.lib.util.WeakMap; 43 import com.sun.star.logging.LogLevel; 44 import com.sun.star.sdbc.SQLException; 45 import com.sun.star.sdbc.SQLWarning; 46 import com.sun.star.sdbc.XConnection; 47 import com.sun.star.sdbc.XDatabaseMetaData; 48 import com.sun.star.sdbc.XPreparedStatement; 49 import com.sun.star.sdbc.XStatement; 50 import com.sun.star.sdbc.XWarningsSupplier; 51 import com.sun.star.uno.Any; 52 import com.sun.star.uno.AnyConverter; 53 import com.sun.star.uno.UnoRuntime; 54 import com.sun.star.uno.XComponentContext; 55 import com.sun.star.util.XStringSubstitution; 56 57 public class JavaSQLConnection extends ComponentBase 58 implements XConnection, XWarningsSupplier, XServiceInfo { 59 60 private static final String[] services = { 61 "com.sun.star.sdbc.Connection" 62 }; 63 private static final ClassMap classMap = new ClassMap(); 64 65 private final AutoRetrievingBase autoRetrievingBase = new AutoRetrievingBase(); 66 private String url; 67 private final JDBCDriver driver; 68 private final ConnectionLog logger; 69 private boolean useParameterSubstitution; 70 private boolean ignoreDriverPrivileges; 71 private boolean ignoreCurrency; 72 private Object catalogRestriction; 73 private Object schemaRestriction; 74 private ClassLoader driverClassLoader; 75 private java.sql.Driver driverObject; 76 private java.sql.Connection connection; 77 private PropertyValue[] connectionInfo; 78 private final WeakMap statements = new WeakMap(); 79 JavaSQLConnection(JDBCDriver driver)80 public JavaSQLConnection(JDBCDriver driver) { 81 this.driver = driver; 82 this.logger = new ConnectionLog(driver.getLogger(), ObjectType.CONNECTION); 83 } 84 85 // XComponent 86 87 @Override postDisposing()88 protected synchronized void postDisposing() { 89 logger.log(LogLevel.INFO, Resources.STR_LOG_SHUTDOWN_CONNECTION); 90 try { 91 for (Iterator<?> it = statements.keySet().iterator(); it.hasNext();) { 92 JavaSQLStatementBase statement = (JavaSQLStatementBase) it.next(); 93 it.remove(); 94 CompHelper.disposeComponent(statement); 95 } 96 if (connection != null) { 97 connection.close(); 98 } 99 } catch (java.sql.SQLException sqlException) { 100 logger.log(LogLevel.WARNING, sqlException); 101 } 102 } 103 104 // XCloseable 105 106 @Override close()107 public void close() throws SQLException { 108 dispose(); 109 } 110 111 // XServiceInfo 112 113 @Override getImplementationName()114 public String getImplementationName() { 115 return "com.sun.star.sdbcx.JConnection"; 116 } 117 118 @Override getSupportedServiceNames()119 public String[] getSupportedServiceNames() { 120 return services.clone(); 121 } 122 123 @Override supportsService(String serviceName)124 public boolean supportsService(String serviceName) { 125 for (String service : services) { 126 if (service.equals(serviceName)) { 127 return true; 128 } 129 } 130 return false; 131 } 132 133 // XWarningsSupplier 134 135 @Override clearWarnings()136 public synchronized void clearWarnings() throws SQLException { 137 checkDisposed(); 138 try { 139 connection.clearWarnings(); 140 } catch (java.sql.SQLException sqlException) { 141 throw Tools.toUnoException(this, sqlException); 142 } 143 } 144 145 @Override getWarnings()146 public synchronized Object getWarnings() throws SQLException { 147 checkDisposed(); 148 try { 149 java.sql.SQLWarning javaWarning = connection.getWarnings(); 150 if (javaWarning != null) { 151 java.lang.Throwable nextException = javaWarning.getCause(); 152 SQLWarning warning = new SQLWarning(javaWarning.getMessage()); 153 warning.Context = this; 154 warning.SQLState = javaWarning.getSQLState(); 155 warning.ErrorCode = javaWarning.getErrorCode(); 156 warning.NextException = nextException != null ? Tools.toUnoException(this, nextException) : Any.VOID; 157 return warning; 158 } 159 return Any.VOID; 160 } catch (java.sql.SQLException sqlException) { 161 throw Tools.toUnoException(this, sqlException); 162 } 163 } 164 165 // XConnection 166 167 @Override commit()168 public void commit() throws SQLException { 169 try { 170 connection.commit(); 171 } catch (java.sql.SQLException sqlException) { 172 throw Tools.toUnoException(this, sqlException); 173 } 174 } 175 176 @Override createStatement()177 public synchronized XStatement createStatement() throws SQLException { 178 checkDisposed(); 179 logger.log(LogLevel.FINE, Resources.STR_LOG_CREATE_STATEMENT); 180 JavaSQLStatement statement = new JavaSQLStatement(this); 181 statements.put(statement, statement); 182 logger.log(LogLevel.FINE, Resources.STR_LOG_CREATED_STATEMENT_ID, statement.getStatementObjectId()); 183 return statement; 184 } 185 186 @Override getAutoCommit()187 public boolean getAutoCommit() throws SQLException { 188 try { 189 return connection.getAutoCommit(); 190 } catch (java.sql.SQLException sqlException) { 191 throw Tools.toUnoException(this, sqlException); 192 } 193 } 194 195 @Override getCatalog()196 public synchronized String getCatalog() throws SQLException { 197 checkDisposed(); 198 try { 199 String catalog = connection.getCatalog(); 200 if (catalog != null) { 201 return catalog; 202 } else { 203 return ""; 204 } 205 } catch (java.sql.SQLException sqlException) { 206 throw Tools.toUnoException(this, sqlException); 207 } 208 } 209 210 @Override getMetaData()211 public synchronized XDatabaseMetaData getMetaData() throws SQLException { 212 checkDisposed(); 213 try { 214 return new JavaSQLDatabaseMetaData(connection.getMetaData(), this); 215 } catch (java.sql.SQLException sqlException) { 216 throw Tools.toUnoException(this, sqlException); 217 } 218 } 219 220 @Override getTransactionIsolation()221 public synchronized int getTransactionIsolation() throws SQLException { 222 checkDisposed(); 223 try { 224 return connection.getTransactionIsolation(); 225 } catch (java.sql.SQLException sqlException) { 226 throw Tools.toUnoException(this, sqlException); 227 } 228 } 229 230 @Override getTypeMap()231 public synchronized XNameAccess getTypeMap() throws SQLException { 232 checkDisposed(); 233 return null; 234 } 235 236 @Override isClosed()237 public synchronized boolean isClosed() throws SQLException { 238 try { 239 return connection.isClosed() && bDisposed; 240 } catch (java.sql.SQLException sqlException) { 241 throw Tools.toUnoException(this, sqlException); 242 } 243 } 244 245 @Override isReadOnly()246 public synchronized boolean isReadOnly() throws SQLException { 247 checkDisposed(); 248 try { 249 return connection.isReadOnly(); 250 } catch (java.sql.SQLException sqlException) { 251 throw Tools.toUnoException(this, sqlException); 252 } 253 } 254 255 @Override nativeSQL(String sql)256 public synchronized String nativeSQL(String sql) throws SQLException { 257 checkDisposed(); 258 try { 259 String ret = connection.nativeSQL(sql); 260 if (ret == null) { 261 // UNO hates null strings 262 ret = ""; 263 } 264 logger.log(LogLevel.FINER, Resources.STR_LOG_NATIVE_SQL, sql, ret); 265 return ret; 266 } catch (java.sql.SQLException sqlException) { 267 throw Tools.toUnoExceptionLogged(this, logger, sqlException); 268 } 269 } 270 271 @Override prepareCall(String sql)272 public synchronized XPreparedStatement prepareCall(String sql) throws SQLException { 273 checkDisposed(); 274 logger.log(LogLevel.FINE, Resources.STR_LOG_PREPARE_CALL, sql); 275 String sqlStatement = transformPreparedStatement(sql); 276 JavaSQLCallableStatement statement = new JavaSQLCallableStatement(this, sqlStatement); 277 statements.put(statement, statement); 278 logger.log(LogLevel.FINE, Resources.STR_LOG_PREPARED_CALL_ID, statement.getStatementObjectId()); 279 return statement; 280 } 281 282 @Override prepareStatement(String sql)283 public synchronized XPreparedStatement prepareStatement(String sql) throws SQLException { 284 checkDisposed(); 285 logger.log(LogLevel.FINE, Resources.STR_LOG_PREPARE_STATEMENT, sql); 286 String sqlStatement = transformPreparedStatement(sql); 287 JavaSQLPreparedStatement statement = new JavaSQLPreparedStatement(this, sqlStatement); 288 statements.put(statement, statement); 289 logger.log(LogLevel.FINE, Resources.STR_LOG_PREPARED_STATEMENT_ID, statement.getStatementObjectId()); 290 return statement; 291 } 292 293 @Override rollback()294 public void rollback() throws SQLException { 295 try { 296 connection.rollback(); 297 } catch (java.sql.SQLException sqlException) { 298 throw Tools.toUnoException(this, sqlException); 299 } 300 } 301 302 @Override setAutoCommit(boolean autoCommit)303 public void setAutoCommit(boolean autoCommit) throws SQLException { 304 try { 305 connection.setAutoCommit(autoCommit); 306 } catch (java.sql.SQLException sqlException) { 307 throw Tools.toUnoException(this, sqlException); 308 } 309 } 310 311 @Override setCatalog(String catalog)312 public void setCatalog(String catalog) throws SQLException { 313 try { 314 connection.setCatalog(catalog); 315 } catch (java.sql.SQLException sqlException) { 316 throw Tools.toUnoException(this, sqlException); 317 } 318 } 319 320 @Override setReadOnly(boolean readOnly)321 public void setReadOnly(boolean readOnly) throws SQLException { 322 try { 323 connection.setReadOnly(readOnly); 324 } catch (java.sql.SQLException sqlException) { 325 throw Tools.toUnoException(this, sqlException); 326 } 327 } 328 329 @Override setTransactionIsolation(int level)330 public synchronized void setTransactionIsolation(int level) throws SQLException { 331 checkDisposed(); 332 try { 333 connection.setTransactionIsolation(level); 334 } catch (java.sql.SQLException sqlException) { 335 throw Tools.toUnoException(this, sqlException); 336 } 337 } 338 339 @Override setTypeMap(XNameAccess arg0)340 public synchronized void setTypeMap(XNameAccess arg0) throws SQLException { 341 checkDisposed(); 342 String error = SharedResources.getInstance().getResourceStringWithSubstitution( 343 Resources.STR_UNSUPPORTED_FEATURE, "$featurename$", "XConnection::setTypeMap"); 344 throw new SQLException(error, this, 345 StandardSQLState.SQL_FEATURE_NOT_IMPLEMENTED.text(), 346 0, Any.VOID); 347 } 348 349 // others: 350 construct(String url, PropertyValue[] info)351 public boolean construct(String url, PropertyValue[] info) throws SQLException { 352 this.url = url; 353 String generatedValueStatement = ""; // contains the statement which should be used when query for automatically generated values 354 boolean autoRetrievingEnabled = false; // set to <TRUE/> when we should allow to query for generated values 355 String driverClassPath = ""; 356 String driverClass = ""; 357 NamedValue[] systemProperties = new NamedValue[0]; 358 359 try { 360 driverClass = Tools.getOrDefault(info, "JavaDriverClass", driverClass); 361 driverClassPath = Tools.getOrDefault(info, "JavaDriverClassPath", driverClassPath); 362 if (driverClassPath.isEmpty()) { 363 driverClassPath = getJavaDriverClassPath(driverClass); 364 } 365 autoRetrievingEnabled = Tools.getOrDefault(info, "IsAutoRetrievingEnabled", autoRetrievingEnabled); 366 generatedValueStatement = Tools.getOrDefault(info, "AutoRetrievingStatement", generatedValueStatement); 367 useParameterSubstitution = Tools.getOrDefault(info, "ParameterNameSubstitution", useParameterSubstitution); 368 ignoreDriverPrivileges = Tools.getOrDefault(info, "IgnoreDriverPrivileges", ignoreDriverPrivileges); 369 ignoreCurrency = Tools.getOrDefault(info, "IgnoreCurrency", ignoreCurrency); 370 systemProperties = Tools.getOrDefault(info, "SystemProperties", systemProperties); 371 catalogRestriction = Tools.getOrDefault(info, "ImplicitCatalogRestriction", Any.VOID); 372 schemaRestriction = Tools.getOrDefault(info, "ImplicitSchemaRestriction", Any.VOID); 373 374 loadDriverFromProperties(driverClass, driverClassPath, systemProperties); 375 376 autoRetrievingBase.setAutoRetrievingEnabled(autoRetrievingEnabled); 377 autoRetrievingBase.setAutoRetrievingStatement(generatedValueStatement); 378 379 Properties properties = createStringPropertyArray(info); 380 try (ContextClassLoaderScope ccl = new ContextClassLoaderScope(driverClassLoader)) { 381 connection = driverObject.connect(url, properties); 382 } 383 logger.log(LogLevel.INFO, Resources.STR_LOG_GOT_JDBC_CONNECTION, url); 384 connectionInfo = info; 385 return true; 386 } catch (IllegalArgumentException illegalArgumentException) { 387 logger.log(LogLevel.SEVERE, illegalArgumentException); 388 throw new SQLException("Driver property error", this, 389 StandardSQLState.SQL_GENERAL_ERROR.text(), 0, illegalArgumentException); 390 } catch (java.sql.SQLException sqlException) { 391 throw Tools.toUnoExceptionLogged(this, logger, sqlException); 392 } 393 } 394 getJavaDriverClassPath(String driverClass)395 private String getJavaDriverClassPath(String driverClass) { 396 String url = ""; 397 try { 398 XMultiServiceFactory configurationProvider = UnoRuntime.queryInterface(XMultiServiceFactory.class, 399 driver.getContext().getServiceManager().createInstanceWithContext( 400 "com.sun.star.configuration.ConfigurationProvider", driver.getContext())); 401 402 PropertyValue[] arguments = new PropertyValue[1]; 403 arguments[0] = new PropertyValue(); 404 arguments[0].Name = "nodepath"; 405 arguments[0].Value = "/org.openoffice.Office.DataAccess/JDBC/DriverClassPaths"; 406 407 Object configurationAccess = configurationProvider.createInstanceWithArguments( 408 "com.sun.star.configuration.ConfigurationAccess", arguments); 409 XNameAccess myNode = UnoRuntime.queryInterface(XNameAccess.class, configurationAccess); 410 if (myNode.hasByName(driverClass)) { 411 XNameAccess driverNode = UnoRuntime.queryInterface(XNameAccess.class, myNode.getByName(driverClass)); 412 if (driverNode.hasByName("Path")) { 413 url = AnyConverter.toString(driverNode.getByName("Path")); 414 } 415 } 416 } catch (com.sun.star.uno.Exception exception) { 417 logger.log(LogLevel.WARNING, exception); 418 } 419 return url; 420 } 421 loadDriverFromProperties(String driverClassName, String driverClassPath, NamedValue[] properties)422 private void loadDriverFromProperties(String driverClassName, String driverClassPath, NamedValue[] properties) throws SQLException { 423 if (connection != null) { 424 return; 425 } 426 try { 427 setSystemProperties(properties); 428 driverClassLoader = null; 429 430 if (driverClassName.isEmpty()) { 431 logger.log(LogLevel.SEVERE, Resources.STR_LOG_NO_DRIVER_CLASS); 432 throw new SQLException(getDriverLoadErrorMessage(SharedResources.getInstance(), driverClassName, driverClassPath), 433 this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, Any.VOID); 434 } 435 logger.log(LogLevel.INFO, Resources.STR_LOG_LOADING_DRIVER, driverClassName); 436 // the driver manager holds the class of the driver for later use 437 Class<?> driverClass; 438 if (driverClassPath.isEmpty()) { 439 driverClass = Class.forName(driverClassName); 440 } else { 441 ClassLoaderAndClass classLoaderAndClass = classMap.loadClass(driver.getContext(), driverClassPath, driverClassName); 442 driverClassLoader = classLoaderAndClass.getClassLoader(); 443 driverClass = classLoaderAndClass.getClassObject(); 444 } 445 driverObject = (java.sql.Driver) driverClass.newInstance(); 446 driverClass = driverObject.getClass(); 447 logger.log(LogLevel.INFO, Resources.STR_LOG_CONN_SUCCESS); 448 } catch (SQLException sqlException) { 449 throw new SQLException( 450 getDriverLoadErrorMessage(SharedResources.getInstance(), driverClassName, driverClassPath), 451 this, "", 1000, sqlException); 452 } catch (Exception exception) { 453 throw new SQLException( 454 getDriverLoadErrorMessage(SharedResources.getInstance(), driverClassName, driverClassPath), 455 this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, 456 Tools.toUnoExceptionLogged(this, logger, exception)); 457 } 458 } 459 setSystemProperties(NamedValue[] properties)460 private void setSystemProperties(NamedValue[] properties) { 461 for (NamedValue namedValue : properties) { 462 String value = ""; 463 try { 464 value = AnyConverter.toString(namedValue.Value); 465 } catch (IllegalArgumentException illegalArgumentException) { 466 logger.log(LogLevel.WARNING, illegalArgumentException); 467 } 468 logger.log(LogLevel.FINER, Resources.STR_LOG_SETTING_SYSTEM_PROPERTY, namedValue.Name, value); 469 System.setProperty(namedValue.Name, value); 470 } 471 } 472 getDriverLoadErrorMessage(SharedResources sharedResouces, String driverClass, String driverClassPath)473 private static String getDriverLoadErrorMessage(SharedResources sharedResouces, String driverClass, String driverClassPath) { 474 String error1 = sharedResouces.getResourceStringWithSubstitution( 475 Resources.STR_NO_CLASSNAME, "$classname$", driverClass); 476 if (!driverClassPath.isEmpty()) { 477 String error2 = sharedResouces.getResourceStringWithSubstitution( 478 Resources.STR_NO_CLASSNAME_PATH, "$classpath$", driverClassPath); 479 error1 += error2; 480 } 481 return error1; 482 } 483 createStringPropertyArray(PropertyValue[] info)484 private Properties createStringPropertyArray(PropertyValue[] info) throws IllegalArgumentException { 485 Properties properties = new Properties(); 486 for (PropertyValue propertyValue : info) { 487 if (!propertyValue.Name.equals("JavaDriverClass") && 488 !propertyValue.Name.equals("JavaDriverClassPath") && 489 !propertyValue.Name.equals("SystemProperties") && 490 !propertyValue.Name.equals("CharSet") && 491 !propertyValue.Name.equals("AppendTableAliasName") && 492 !propertyValue.Name.equals("AddIndexAppendix") && 493 !propertyValue.Name.equals("FormsCheckRequiredFields") && 494 !propertyValue.Name.equals("GenerateASBeforeCorrelationName") && 495 !propertyValue.Name.equals("EscapeDateTime") && 496 !propertyValue.Name.equals("ParameterNameSubstitution") && 497 !propertyValue.Name.equals("IsPasswordRequired") && 498 !propertyValue.Name.equals("IsAutoRetrievingEnabled") && 499 !propertyValue.Name.equals("AutoRetrievingStatement") && 500 !propertyValue.Name.equals("UseCatalogInSelect") && 501 !propertyValue.Name.equals("UseSchemaInSelect") && 502 !propertyValue.Name.equals("AutoIncrementCreation") && 503 !propertyValue.Name.equals("Extension") && 504 !propertyValue.Name.equals("NoNameLengthLimit") && 505 !propertyValue.Name.equals("EnableSQL92Check") && 506 !propertyValue.Name.equals("EnableOuterJoinEscape") && 507 !propertyValue.Name.equals("BooleanComparisonMode") && 508 !propertyValue.Name.equals("IgnoreCurrency") && 509 !propertyValue.Name.equals("TypeInfoSettings") && 510 !propertyValue.Name.equals("IgnoreDriverPrivileges") && 511 !propertyValue.Name.equals("ImplicitCatalogRestriction") && 512 !propertyValue.Name.equals("ImplicitSchemaRestriction") && 513 !propertyValue.Name.equals("SupportsTableCreation") && 514 !propertyValue.Name.equals("UseJava") && 515 !propertyValue.Name.equals("Authentication") && 516 !propertyValue.Name.equals("PreferDosLikeLineEnds") && 517 !propertyValue.Name.equals("PrimaryKeySupport") && 518 !propertyValue.Name.equals("RespectDriverResultSetType")) { 519 properties.setProperty(propertyValue.Name, AnyConverter.toString(propertyValue.Value)); 520 } 521 } 522 return properties; 523 } 524 transformPreparedStatement(String sql)525 private String transformPreparedStatement(String sql) throws SQLException { 526 PropertyValue[] properties = new PropertyValue[1]; 527 properties[0] = new PropertyValue(); 528 properties[0].Name = "ActiveConnection"; 529 properties[0].Value = this; 530 XComponentContext context = driver.getContext(); 531 try { 532 Object parameterSubstitution = context.getServiceManager().createInstanceWithArgumentsAndContext( 533 "com.sun.star.sdb.ParameterSubstitution", properties, context); 534 XStringSubstitution stringSubstitution = UnoRuntime.queryInterface(XStringSubstitution.class, parameterSubstitution); 535 return stringSubstitution.substituteVariables(sql, true); 536 } catch (com.sun.star.uno.Exception exception) { 537 throw Tools.toUnoExceptionLogged(this, logger, exception); 538 } 539 } 540 541 /** returns the instance used for logging events related to this connection 542 */ getLogger()543 public ConnectionLog getLogger() { 544 return logger; 545 } 546 getJDBCConnection()547 public java.sql.Connection getJDBCConnection() { 548 return connection; 549 } 550 isAutoRetrievingEnabled()551 public boolean isAutoRetrievingEnabled() { 552 return autoRetrievingBase.isAutoRetrievingEnabled(); 553 } 554 isIgnoreCurrencyEnabled()555 public boolean isIgnoreCurrencyEnabled() { 556 return ignoreCurrency; 557 } 558 getTransformedGeneratedStatement(String sql)559 public String getTransformedGeneratedStatement(String sql) { 560 return autoRetrievingBase.getTransformedGeneratedStatement(sql); 561 } 562 getDriverClassLoader()563 public ClassLoader getDriverClassLoader() { 564 return driverClassLoader; 565 } 566 getCatalogRestriction()567 public Object getCatalogRestriction() { 568 return catalogRestriction; 569 } 570 getSchemaRestriction()571 public Object getSchemaRestriction() { 572 return schemaRestriction; 573 } 574 isIgnoreDriverPrivilegesEnabled()575 public boolean isIgnoreDriverPrivilegesEnabled() { 576 return ignoreDriverPrivileges; 577 } 578 getURL()579 public String getURL() { 580 return url; 581 } 582 getConnectionInfo()583 public PropertyValue[] getConnectionInfo() { 584 return connectionInfo; 585 } 586 } 587