001: /*
002: Copyright (C) 2002-2007 MySQL AB
003:
004: This program is free software; you can redistribute it and/or modify
005: it under the terms of version 2 of the GNU General Public License as
006: published by the Free Software Foundation.
007:
008: There are special exceptions to the terms and conditions of the GPL
009: as it is applied to this software. View the full text of the
010: exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
011: software distribution.
012:
013: This program is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: GNU General Public License for more details.
017:
018: You should have received a copy of the GNU General Public License
019: along with this program; if not, write to the Free Software
020: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021:
022:
023:
024: */
025: package com.mysql.jdbc;
026:
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.io.UnsupportedEncodingException;
030: import java.net.URLDecoder;
031: import java.sql.DriverPropertyInfo;
032: import java.sql.SQLException;
033:
034: import java.util.ArrayList;
035: import java.util.Iterator;
036: import java.util.List;
037: import java.util.Properties;
038: import java.util.StringTokenizer;
039:
040: /**
041: * The Java SQL framework allows for multiple database drivers. Each driver
042: * should supply a class that implements the Driver interface
043: *
044: * <p>
045: * The DriverManager will try to load as many drivers as it can find and then
046: * for any given connection request, it will ask each driver in turn to try to
047: * connect to the target URL.
048: * </p>
049: *
050: * <p>
051: * It is strongly recommended that each Driver class should be small and
052: * standalone so that the Driver class can be loaded and queried without
053: * bringing in vast quantities of supporting code.
054: * </p>
055: *
056: * <p>
057: * When a Driver class is loaded, it should create an instance of itself and
058: * register it with the DriverManager. This means that a user can load and
059: * register a driver by doing Class.forName("foo.bah.Driver")
060: * </p>
061: *
062: * @author Mark Matthews
063: * @version $Id: NonRegisteringDriver.java,v 1.1.2.1 2005/05/13 18:58:38
064: * mmatthews Exp $
065: *
066: * @see org.gjt.mm.mysql.Connection
067: * @see java.sql.Driver
068: */
069: public class NonRegisteringDriver implements java.sql.Driver {
070: private static final String REPLICATION_URL_PREFIX = "jdbc:mysql:replication://";
071:
072: private static final String URL_PREFIX = "jdbc:mysql://";
073:
074: private static final String MXJ_URL_PREFIX = "jdbc:mysql:mxj://";
075:
076: private static final String LOADBALANCE_URL_PREFIX = "jdbc:mysql:loadbalance://";
077:
078: /**
079: * Key used to retreive the database value from the properties instance
080: * passed to the driver.
081: */
082: public static final String DBNAME_PROPERTY_KEY = "DBNAME";
083:
084: /** Should the driver generate debugging output? */
085: public static final boolean DEBUG = false;
086:
087: /** Index for hostname coming out of parseHostPortPair(). */
088: public final static int HOST_NAME_INDEX = 0;
089:
090: /**
091: * Key used to retreive the hostname value from the properties instance
092: * passed to the driver.
093: */
094: public static final String HOST_PROPERTY_KEY = "HOST";
095:
096: /**
097: * Key used to retreive the password value from the properties instance
098: * passed to the driver.
099: */
100: public static final String PASSWORD_PROPERTY_KEY = "password";
101:
102: /** Index for port # coming out of parseHostPortPair(). */
103: public final static int PORT_NUMBER_INDEX = 1;
104:
105: /**
106: * Key used to retreive the port number value from the properties instance
107: * passed to the driver.
108: */
109: public static final String PORT_PROPERTY_KEY = "PORT";
110:
111: public static final String PROPERTIES_TRANSFORM_KEY = "propertiesTransform";
112:
113: /** Should the driver generate method-call traces? */
114: public static final boolean TRACE = false;
115:
116: public static final String USE_CONFIG_PROPERTY_KEY = "useConfigs";
117:
118: /**
119: * Key used to retreive the username value from the properties instance
120: * passed to the driver.
121: */
122: public static final String USER_PROPERTY_KEY = "user";
123:
124: /**
125: * Gets the drivers major version number
126: *
127: * @return the drivers major version number
128: */
129: static int getMajorVersionInternal() {
130: return safeIntParse("@MYSQL_CJ_MAJOR_VERSION@"); //$NON-NLS-1$
131: }
132:
133: /**
134: * Get the drivers minor version number
135: *
136: * @return the drivers minor version number
137: */
138: static int getMinorVersionInternal() {
139: return safeIntParse("@MYSQL_CJ_MINOR_VERSION@"); //$NON-NLS-1$
140: }
141:
142: /**
143: * Parses hostPortPair in the form of [host][:port] into an array, with the
144: * element of index HOST_NAME_INDEX being the host (or null if not
145: * specified), and the element of index PORT_NUMBER_INDEX being the port (or
146: * null if not specified).
147: *
148: * @param hostPortPair
149: * host and port in form of of [host][:port]
150: *
151: * @return array containing host and port as Strings
152: *
153: * @throws SQLException
154: * if a parse error occurs
155: */
156: protected static String[] parseHostPortPair(String hostPortPair)
157: throws SQLException {
158: int portIndex = hostPortPair.indexOf(":"); //$NON-NLS-1$
159:
160: String[] splitValues = new String[2];
161:
162: String hostname = null;
163:
164: if (portIndex != -1) {
165: if ((portIndex + 1) < hostPortPair.length()) {
166: String portAsString = hostPortPair
167: .substring(portIndex + 1);
168: hostname = hostPortPair.substring(0, portIndex);
169:
170: splitValues[HOST_NAME_INDEX] = hostname;
171:
172: splitValues[PORT_NUMBER_INDEX] = portAsString;
173: } else {
174: throw SQLError
175: .createSQLException(
176: Messages
177: .getString("NonRegisteringDriver.37"), //$NON-NLS-1$
178: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
179: }
180: } else {
181: splitValues[HOST_NAME_INDEX] = hostPortPair;
182: splitValues[PORT_NUMBER_INDEX] = null;
183: }
184:
185: return splitValues;
186: }
187:
188: private static int safeIntParse(String intAsString) {
189: try {
190: return Integer.parseInt(intAsString);
191: } catch (NumberFormatException nfe) {
192: return 0;
193: }
194: }
195:
196: /**
197: * Construct a new driver and register it with DriverManager
198: *
199: * @throws SQLException
200: * if a database error occurs.
201: */
202: public NonRegisteringDriver() throws SQLException {
203: // Required for Class.forName().newInstance()
204: }
205:
206: /**
207: * Typically, drivers will return true if they understand the subprotocol
208: * specified in the URL and false if they don't. This driver's protocols
209: * start with jdbc:mysql:
210: *
211: * @param url
212: * the URL of the driver
213: *
214: * @return true if this driver accepts the given URL
215: *
216: * @exception SQLException
217: * if a database-access error occurs
218: *
219: * @see java.sql.Driver#acceptsURL
220: */
221: public boolean acceptsURL(String url) throws SQLException {
222: return (parseURL(url, null) != null);
223: }
224:
225: //
226: // return the database name property
227: //
228:
229: /**
230: * Try to make a database connection to the given URL. The driver should
231: * return "null" if it realizes it is the wrong kind of driver to connect to
232: * the given URL. This will be common, as when the JDBC driverManager is
233: * asked to connect to a given URL, it passes the URL to each loaded driver
234: * in turn.
235: *
236: * <p>
237: * The driver should raise an SQLException if it is the right driver to
238: * connect to the given URL, but has trouble connecting to the database.
239: * </p>
240: *
241: * <p>
242: * The java.util.Properties argument can be used to pass arbitrary string
243: * tag/value pairs as connection arguments.
244: * </p>
245: *
246: * <p>
247: * My protocol takes the form:
248: *
249: * <PRE>
250: *
251: * jdbc:mysql://host:port/database
252: *
253: * </PRE>
254: *
255: * </p>
256: *
257: * @param url
258: * the URL of the database to connect to
259: * @param info
260: * a list of arbitrary tag/value pairs as connection arguments
261: *
262: * @return a connection to the URL or null if it isnt us
263: *
264: * @exception SQLException
265: * if a database access error occurs
266: *
267: * @see java.sql.Driver#connect
268: */
269: public java.sql.Connection connect(String url, Properties info)
270: throws SQLException {
271: if (url != null) {
272: if (StringUtils.startsWithIgnoreCase(url,
273: LOADBALANCE_URL_PREFIX)) {
274: return connectLoadBalanced(url, info);
275: } else if (StringUtils.startsWithIgnoreCase(url,
276: REPLICATION_URL_PREFIX)) {
277: return connectReplicationConnection(url, info);
278: }
279: }
280:
281: Properties props = null;
282:
283: if ((props = parseURL(url, info)) == null) {
284: return null;
285: }
286:
287: try {
288: Connection newConn = com.mysql.jdbc.ConnectionImpl
289: .getInstance(host(props), port(props), props,
290: database(props), url);
291:
292: return newConn;
293: } catch (SQLException sqlEx) {
294: // Don't wrap SQLExceptions, throw
295: // them un-changed.
296: throw sqlEx;
297: } catch (Exception ex) {
298: throw SQLError.createSQLException(Messages
299: .getString("NonRegisteringDriver.17") //$NON-NLS-1$
300: + ex.toString()
301: + Messages.getString("NonRegisteringDriver.18"), //$NON-NLS-1$
302: SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
303: }
304: }
305:
306: private java.sql.Connection connectLoadBalanced(String url,
307: Properties info) throws SQLException {
308: Properties parsedProps = parseURL(url, info);
309:
310: if (parsedProps == null) {
311: return null;
312: }
313:
314: String hostValues = parsedProps.getProperty(HOST_PROPERTY_KEY);
315:
316: List hostList = null;
317:
318: if (hostValues != null) {
319: hostList = StringUtils.split(hostValues, ",", true);
320: }
321:
322: if (hostList == null) {
323: hostList = new ArrayList();
324: hostList.add("localhost:3306");
325: }
326:
327: LoadBalancingConnectionProxy proxyBal = new LoadBalancingConnectionProxy(
328: hostList, parsedProps);
329:
330: return (java.sql.Connection) java.lang.reflect.Proxy
331: .newProxyInstance(this .getClass().getClassLoader(),
332: new Class[] { java.sql.Connection.class },
333: proxyBal);
334: }
335:
336: private java.sql.Connection connectReplicationConnection(
337: String url, Properties info) throws SQLException {
338: Properties parsedProps = parseURL(url, info);
339:
340: if (parsedProps == null) {
341: return null;
342: }
343:
344: Properties masterProps = (Properties) parsedProps.clone();
345: Properties slavesProps = (Properties) parsedProps.clone();
346:
347: // Marker used for further testing later on, also when
348: // debugging
349: slavesProps.setProperty(
350: "com.mysql.jdbc.ReplicationConnection.isSlave", "true");
351:
352: String hostValues = parsedProps.getProperty(HOST_PROPERTY_KEY);
353:
354: if (hostValues != null) {
355: StringTokenizer st = new StringTokenizer(hostValues, ",");
356:
357: StringBuffer masterHost = new StringBuffer();
358: StringBuffer slaveHosts = new StringBuffer();
359:
360: if (st.hasMoreTokens()) {
361: String[] hostPortPair = parseHostPortPair(st
362: .nextToken());
363:
364: if (hostPortPair[HOST_NAME_INDEX] != null) {
365: masterHost.append(hostPortPair[HOST_NAME_INDEX]);
366: }
367:
368: if (hostPortPair[PORT_NUMBER_INDEX] != null) {
369: masterHost.append(":");
370: masterHost.append(hostPortPair[PORT_NUMBER_INDEX]);
371: }
372: }
373:
374: boolean firstSlaveHost = true;
375:
376: while (st.hasMoreTokens()) {
377: String[] hostPortPair = parseHostPortPair(st
378: .nextToken());
379:
380: if (!firstSlaveHost) {
381: slaveHosts.append(",");
382: } else {
383: firstSlaveHost = false;
384: }
385:
386: if (hostPortPair[HOST_NAME_INDEX] != null) {
387: slaveHosts.append(hostPortPair[HOST_NAME_INDEX]);
388: }
389:
390: if (hostPortPair[PORT_NUMBER_INDEX] != null) {
391: slaveHosts.append(":");
392: slaveHosts.append(hostPortPair[PORT_NUMBER_INDEX]);
393: }
394: }
395:
396: if (slaveHosts.length() == 0) {
397: throw SQLError
398: .createSQLException(
399: "Must specify at least one slave host to connect to for master/slave replication load-balancing functionality",
400: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
401: }
402:
403: masterProps.setProperty(HOST_PROPERTY_KEY, masterHost
404: .toString());
405: slavesProps.setProperty(HOST_PROPERTY_KEY, slaveHosts
406: .toString());
407: }
408:
409: return new ReplicationConnection(masterProps, slavesProps);
410: }
411:
412: /**
413: * Returns the database property from <code>props</code>
414: *
415: * @param props
416: * the Properties to look for the database property.
417: *
418: * @return the database name.
419: */
420: public String database(Properties props) {
421: return props.getProperty(DBNAME_PROPERTY_KEY); //$NON-NLS-1$
422: }
423:
424: /**
425: * Gets the drivers major version number
426: *
427: * @return the drivers major version number
428: */
429: public int getMajorVersion() {
430: return getMajorVersionInternal();
431: }
432:
433: /**
434: * Get the drivers minor version number
435: *
436: * @return the drivers minor version number
437: */
438: public int getMinorVersion() {
439: return getMinorVersionInternal();
440: }
441:
442: /**
443: * The getPropertyInfo method is intended to allow a generic GUI tool to
444: * discover what properties it should prompt a human for in order to get
445: * enough information to connect to a database.
446: *
447: * <p>
448: * Note that depending on the values the human has supplied so far,
449: * additional values may become necessary, so it may be necessary to iterate
450: * through several calls to getPropertyInfo
451: * </p>
452: *
453: * @param url
454: * the Url of the database to connect to
455: * @param info
456: * a proposed list of tag/value pairs that will be sent on
457: * connect open.
458: *
459: * @return An array of DriverPropertyInfo objects describing possible
460: * properties. This array may be an empty array if no properties are
461: * required
462: *
463: * @exception SQLException
464: * if a database-access error occurs
465: *
466: * @see java.sql.Driver#getPropertyInfo
467: */
468: public DriverPropertyInfo[] getPropertyInfo(String url,
469: Properties info) throws SQLException {
470: if (info == null) {
471: info = new Properties();
472: }
473:
474: if ((url != null) && url.startsWith(URL_PREFIX)) { //$NON-NLS-1$
475: info = parseURL(url, info);
476: }
477:
478: DriverPropertyInfo hostProp = new DriverPropertyInfo(
479: HOST_PROPERTY_KEY, //$NON-NLS-1$
480: info.getProperty(HOST_PROPERTY_KEY)); //$NON-NLS-1$
481: hostProp.required = true;
482: hostProp.description = Messages
483: .getString("NonRegisteringDriver.3"); //$NON-NLS-1$
484:
485: DriverPropertyInfo portProp = new DriverPropertyInfo(
486: PORT_PROPERTY_KEY, //$NON-NLS-1$
487: info.getProperty(PORT_PROPERTY_KEY, "3306")); //$NON-NLS-1$ //$NON-NLS-2$
488: portProp.required = false;
489: portProp.description = Messages
490: .getString("NonRegisteringDriver.7"); //$NON-NLS-1$
491:
492: DriverPropertyInfo dbProp = new DriverPropertyInfo(
493: DBNAME_PROPERTY_KEY, //$NON-NLS-1$
494: info.getProperty(DBNAME_PROPERTY_KEY)); //$NON-NLS-1$
495: dbProp.required = false;
496: dbProp.description = "Database name"; //$NON-NLS-1$
497:
498: DriverPropertyInfo userProp = new DriverPropertyInfo(
499: USER_PROPERTY_KEY, //$NON-NLS-1$
500: info.getProperty(USER_PROPERTY_KEY)); //$NON-NLS-1$
501: userProp.required = true;
502: userProp.description = Messages
503: .getString("NonRegisteringDriver.13"); //$NON-NLS-1$
504:
505: DriverPropertyInfo passwordProp = new DriverPropertyInfo(
506: PASSWORD_PROPERTY_KEY, //$NON-NLS-1$
507: info.getProperty(PASSWORD_PROPERTY_KEY)); //$NON-NLS-1$
508: passwordProp.required = true;
509: passwordProp.description = Messages
510: .getString("NonRegisteringDriver.16"); //$NON-NLS-1$
511:
512: DriverPropertyInfo[] dpi = ConnectionPropertiesImpl
513: .exposeAsDriverPropertyInfo(info, 5);
514:
515: dpi[0] = hostProp;
516: dpi[1] = portProp;
517: dpi[2] = dbProp;
518: dpi[3] = userProp;
519: dpi[4] = passwordProp;
520:
521: return dpi;
522: }
523:
524: //
525: // return the value of any property this driver knows about
526: //
527:
528: /**
529: * Returns the hostname property
530: *
531: * @param props
532: * the java.util.Properties instance to retrieve the hostname
533: * from.
534: *
535: * @return the hostname
536: */
537: public String host(Properties props) {
538: return props.getProperty(HOST_PROPERTY_KEY, "localhost"); //$NON-NLS-1$ //$NON-NLS-2$
539: }
540:
541: /**
542: * Report whether the driver is a genuine JDBC compliant driver. A driver
543: * may only report "true" here if it passes the JDBC compliance tests,
544: * otherwise it is required to return false. JDBC compliance requires full
545: * support for the JDBC API and full support for SQL 92 Entry Level.
546: *
547: * <p>
548: * MySQL is not SQL92 compliant
549: * </p>
550: *
551: * @return is this driver JDBC compliant?
552: */
553: public boolean jdbcCompliant() {
554: return false;
555: }
556:
557: public Properties parseURL(String url, Properties defaults)
558: throws java.sql.SQLException {
559: Properties urlProps = (defaults != null) ? new Properties(
560: defaults) : new Properties();
561:
562: if (url == null) {
563: return null;
564: }
565:
566: if (!StringUtils.startsWithIgnoreCase(url, URL_PREFIX)
567: && !StringUtils.startsWithIgnoreCase(url,
568: MXJ_URL_PREFIX)
569: && !StringUtils.startsWithIgnoreCase(url,
570: LOADBALANCE_URL_PREFIX)
571: && !StringUtils.startsWithIgnoreCase(url,
572: REPLICATION_URL_PREFIX)) { //$NON-NLS-1$
573:
574: return null;
575: }
576:
577: int beginningOfSlashes = url.indexOf("//");
578:
579: if (StringUtils.startsWithIgnoreCase(url, MXJ_URL_PREFIX)) {
580:
581: urlProps
582: .setProperty("socketFactory",
583: "com.mysql.management.driverlaunched.ServerLauncherSocketFactory");
584: }
585:
586: /*
587: * Parse parameters after the ? in the URL and remove them from the
588: * original URL.
589: */
590: int index = url.indexOf("?"); //$NON-NLS-1$
591:
592: if (index != -1) {
593: String paramString = url.substring(index + 1, url.length());
594: url = url.substring(0, index);
595:
596: StringTokenizer queryParams = new StringTokenizer(
597: paramString, "&"); //$NON-NLS-1$
598:
599: while (queryParams.hasMoreTokens()) {
600: String parameterValuePair = queryParams.nextToken();
601:
602: int indexOfEquals = StringUtils.indexOfIgnoreCase(0,
603: parameterValuePair, "=");
604:
605: String parameter = null;
606: String value = null;
607:
608: if (indexOfEquals != -1) {
609: parameter = parameterValuePair.substring(0,
610: indexOfEquals);
611:
612: if (indexOfEquals + 1 < parameterValuePair.length()) {
613: value = parameterValuePair
614: .substring(indexOfEquals + 1);
615: }
616: }
617:
618: if ((value != null && value.length() > 0)
619: && (parameter != null && parameter.length() > 0)) {
620: try {
621: urlProps.put(parameter, URLDecoder.decode(
622: value, "UTF-8"));
623: } catch (UnsupportedEncodingException badEncoding) {
624: // punt
625: urlProps.put(parameter, URLDecoder
626: .decode(value));
627: } catch (NoSuchMethodError nsme) {
628: // punt again
629: urlProps.put(parameter, URLDecoder
630: .decode(value));
631: }
632: }
633: }
634: }
635:
636: url = url.substring(beginningOfSlashes + 2);
637:
638: String hostStuff = null;
639:
640: int slashIndex = url.indexOf("/"); //$NON-NLS-1$
641:
642: if (slashIndex != -1) {
643: hostStuff = url.substring(0, slashIndex);
644:
645: if ((slashIndex + 1) < url.length()) {
646: urlProps.put(DBNAME_PROPERTY_KEY, //$NON-NLS-1$
647: url.substring((slashIndex + 1), url.length()));
648: }
649: } else {
650: hostStuff = url;
651: }
652:
653: if ((hostStuff != null) && (hostStuff.length() > 0)) {
654: urlProps.put(HOST_PROPERTY_KEY, hostStuff); //$NON-NLS-1$
655: }
656:
657: String propertiesTransformClassName = urlProps
658: .getProperty(PROPERTIES_TRANSFORM_KEY);
659:
660: if (propertiesTransformClassName != null) {
661: try {
662: ConnectionPropertiesTransform propTransformer = (ConnectionPropertiesTransform) Class
663: .forName(propertiesTransformClassName)
664: .newInstance();
665:
666: urlProps = propTransformer
667: .transformProperties(urlProps);
668: } catch (InstantiationException e) {
669: throw SQLError
670: .createSQLException(
671: "Unable to create properties transform instance '"
672: + propertiesTransformClassName
673: + "' due to underlying exception: "
674: + e.toString(),
675: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
676: } catch (IllegalAccessException e) {
677: throw SQLError
678: .createSQLException(
679: "Unable to create properties transform instance '"
680: + propertiesTransformClassName
681: + "' due to underlying exception: "
682: + e.toString(),
683: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
684: } catch (ClassNotFoundException e) {
685: throw SQLError
686: .createSQLException(
687: "Unable to create properties transform instance '"
688: + propertiesTransformClassName
689: + "' due to underlying exception: "
690: + e.toString(),
691: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
692: }
693: }
694:
695: if (Util.isColdFusion()
696: && urlProps.getProperty("autoConfigureForColdFusion",
697: "true").equalsIgnoreCase("true")) {
698: String configs = urlProps
699: .getProperty(USE_CONFIG_PROPERTY_KEY);
700:
701: StringBuffer newConfigs = new StringBuffer();
702:
703: if (configs != null) {
704: newConfigs.append(configs);
705: newConfigs.append(",");
706: }
707:
708: newConfigs.append("coldFusion");
709:
710: urlProps.setProperty(USE_CONFIG_PROPERTY_KEY, newConfigs
711: .toString());
712: }
713:
714: // If we use a config, it actually should get overridden by anything in
715: // the URL or passed-in properties
716:
717: String configNames = null;
718:
719: if (defaults != null) {
720: configNames = defaults.getProperty(USE_CONFIG_PROPERTY_KEY);
721: }
722:
723: if (configNames == null) {
724: configNames = urlProps.getProperty(USE_CONFIG_PROPERTY_KEY);
725: }
726:
727: if (configNames != null) {
728: List splitNames = StringUtils.split(configNames, ",", true);
729:
730: Properties configProps = new Properties();
731:
732: Iterator namesIter = splitNames.iterator();
733:
734: while (namesIter.hasNext()) {
735: String configName = (String) namesIter.next();
736:
737: try {
738: InputStream configAsStream = getClass()
739: .getResourceAsStream(
740: "configs/" + configName
741: + ".properties");
742:
743: if (configAsStream == null) {
744: throw SQLError
745: .createSQLException(
746: "Can't find configuration template named '"
747: + configName + "'",
748: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
749: }
750: configProps.load(configAsStream);
751: } catch (IOException ioEx) {
752: throw SQLError
753: .createSQLException(
754: "Unable to load configuration template '"
755: + configName
756: + "' due to underlying IOException: "
757: + ioEx,
758: SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
759: }
760: }
761:
762: Iterator propsIter = urlProps.keySet().iterator();
763:
764: while (propsIter.hasNext()) {
765: String key = propsIter.next().toString();
766: String property = urlProps.getProperty(key);
767: configProps.setProperty(key, property);
768: }
769:
770: urlProps = configProps;
771: }
772:
773: // Properties passed in should override ones in URL
774:
775: if (defaults != null) {
776: Iterator propsIter = defaults.keySet().iterator();
777:
778: while (propsIter.hasNext()) {
779: String key = propsIter.next().toString();
780: String property = defaults.getProperty(key);
781: urlProps.setProperty(key, property);
782: }
783: }
784:
785: return urlProps;
786: }
787:
788: /**
789: * Returns the port number property
790: *
791: * @param props
792: * the properties to get the port number from
793: *
794: * @return the port number
795: */
796: public int port(Properties props) {
797: return Integer.parseInt(props.getProperty(PORT_PROPERTY_KEY,
798: "3306")); //$NON-NLS-1$ //$NON-NLS-2$
799: }
800:
801: /**
802: * Returns the given property from <code>props</code>
803: *
804: * @param name
805: * the property name
806: * @param props
807: * the property instance to look in
808: *
809: * @return the property value, or null if not found.
810: */
811: public String property(String name, Properties props) {
812: return props.getProperty(name);
813: }
814: }
|