Source Code Cross Referenced for Driver.java in  » Database-JDBC-Connection-Pool » sequoia-2.10.9 » org » continuent » sequoia » driver » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » sequoia 2.10.9 » org.continuent.sequoia.driver 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * Sequoia: Database clustering technology.
0003:         * Copyright (C) 2002-2004 French National Institute For Research In Computer
0004:         * Science And Control (INRIA).
0005:         * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
0006:         * Copyright (C) 2005-2006 Continuent, Inc.
0007:         * Contact: sequoia@continuent.org
0008:         * 
0009:         * Licensed under the Apache License, Version 2.0 (the "License");
0010:         * you may not use this file except in compliance with the License.
0011:         * You may obtain a copy of the License at
0012:         * 
0013:         * http://www.apache.org/licenses/LICENSE-2.0
0014:         * 
0015:         * Unless required by applicable law or agreed to in writing, software
0016:         * distributed under the License is distributed on an "AS IS" BASIS,
0017:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0018:         * See the License for the specific language governing permissions and
0019:         * limitations under the License. 
0020:         *
0021:         * Initial developer(s): Emmanuel Cecchet.
0022:         * Contributor(s): Julie Marguerite, Mathieu Peltier, Marek Prochazka, Sara
0023:         * Bouchenak, Jaco Swart.
0024:         */package org.continuent.sequoia.driver;
0025:
0026:        import java.io.IOException;
0027:        import java.net.Socket;
0028:        import java.security.GeneralSecurityException;
0029:        import java.sql.DriverPropertyInfo;
0030:        import java.sql.SQLException;
0031:        import java.util.ArrayList;
0032:        import java.util.HashMap;
0033:        import java.util.Iterator;
0034:        import java.util.Properties;
0035:
0036:        import javax.net.SocketFactory;
0037:
0038:        import org.continuent.sequoia.common.exceptions.AuthenticationException;
0039:        import org.continuent.sequoia.common.exceptions.NoMoreControllerException;
0040:        import org.continuent.sequoia.common.exceptions.driver.DriverSQLException;
0041:        import org.continuent.sequoia.common.exceptions.driver.VirtualDatabaseUnavailableException;
0042:        import org.continuent.sequoia.common.net.SSLConfiguration;
0043:        import org.continuent.sequoia.common.net.SocketFactoryFactory;
0044:        import org.continuent.sequoia.common.protocol.Commands;
0045:        import org.continuent.sequoia.common.protocol.Field;
0046:        import org.continuent.sequoia.common.protocol.SQLDataSerialization;
0047:        import org.continuent.sequoia.common.protocol.TypeTag;
0048:        import org.continuent.sequoia.common.stream.DriverBufferedInputStream;
0049:        import org.continuent.sequoia.common.stream.DriverBufferedOutputStream;
0050:        import org.continuent.sequoia.common.util.Constants;
0051:        import org.continuent.sequoia.driver.connectpolicy.AbstractControllerConnectPolicy;
0052:
0053:        /**
0054:         * Sequoia Driver for client side. This driver is a generic driver that is
0055:         * designed to replace any specific JDBC driver that could be used by a client.
0056:         * The client only has to know the node where the Sequoia controller is running
0057:         * and the database he wants to access (the RDBMS could be PostgreSQL, Oracle,
0058:         * DB2, Sybase, MySQL or whatever, we only need the name of the database and the
0059:         * Sequoia controller will be responsible for finding the RDBMs hosting this
0060:         * database).
0061:         * <p>
0062:         * The Sequoia driver can be loaded from the client with:
0063:         * <code>Class.forName("org.continuent.sequoia.driver.Driver");</code>
0064:         * <p>
0065:         * The URL expected for the use with Sequoia is:
0066:         * <code>jdbc:sequoia://host1:port1,host2:port2/database</code>.
0067:         * <p>
0068:         * At least one host must be specified. If several hosts are given, one is
0069:         * picked up randomly from the list. If the currently selected controller fails,
0070:         * another one is automatically picked up from the list.
0071:         * <p>
0072:         * Default port number is 25322 if omitted.
0073:         * <p>
0074:         * Those 2 examples are equivalent:
0075:         * 
0076:         * <pre>
0077:         * DriverManager.getConnection(&quot;jdbc:sequoia://localhost:/tpcw&quot;);
0078:         * DriverManager.getConnection(&quot;jdbc:sequoia://localhost:25322/tpcw&quot;);
0079:         * </pre>
0080:         * 
0081:         * <p>
0082:         * Examples using 2 controllers for fault tolerance:
0083:         * 
0084:         * <pre>
0085:         * DriverManager
0086:         *     .getConnection(&quot;jdbc:sequoia://cluster1.continuent.org:25322,cluster2.continuent.org:25322/tpcw&quot;);
0087:         * DriverManager
0088:         *     .getConnection(&quot;jdbc:sequoia://localhost:25322,remote.continuent.org:25322/tpcw&quot;);
0089:         * DriverManager
0090:         *     .getConnection(&quot;jdbc:sequoia://smpnode.com:25322,smpnode.com:1098/tpcw&quot;);
0091:         * </pre>
0092:         * 
0093:         * <p>
0094:         * The driver accepts a number of options that starts after a ? sign and are
0095:         * separated by an & sign. Each option is a name=value pair. Example:
0096:         * jdbc:sequoia://host/db?option1=value1;option2=value2.
0097:         * <p>
0098:         * Currently supported options are:
0099:         * 
0100:         * <pre>
0101:         * user: user login
0102:         * password: user password
0103:         * escapeBackslash: set this to true to escape backslashes when performing escape processing of PreparedStatements
0104:         * escapeSingleQuote: set this to true to escape single quotes (') when performing escape processing of PreparedStatements
0105:         * escapeCharacter: use this character to prepend and append to the values when performing escape processing of PreparedStatements
0106:         * connectionPooling: set this to false if you do not want the driver to perform transparent connection pooling
0107:         * preferredController: defines the strategy to use to choose a preferred controller to connect to
0108:         *  - jdbc:sequoia://node1,node2,node3/myDB?preferredController=ordered 
0109:         *      Always connect to node1, and if not available then try to node2 and
0110:         *      finally if none are available try node3.
0111:         *  - jdbc:sequoia://node1,node2,node3/myDB?preferredController=random
0112:         *      Pickup a controller node randomly (default strategy)
0113:         *  - jdbc:sequoia://node1,node2:25343,node3/myDB?preferredController=node2:25343,node3 
0114:         *      Round-robin between node2 and node3, fallback to node1 if none of node2
0115:         *      and node3 is available.
0116:         *  - jdbc:sequoia://node1,node2,node3/myDB?preferredController=roundRobin
0117:         *      Round robin starting with first node in URL.
0118:         * pingDelayInMs Interval in milliseconds between two pings of a controller. The
0119:         * default is 1000 (1 second).
0120:         * controllerTimeoutInMs timeout in milliseconds after which a controller is
0121:         * considered as dead if it did not respond to pings. Default is 25000 (25
0122:         * seconds).
0123:         * persistentConnection: defines if a connection should remain persistent on 
0124:         *   cluster backends between connection opening and closing (bypasses any 
0125:         *   connection pooling and preserve all information relative to the connection
0126:         *   context. Default is false.
0127:         * retrieveSQLWarnings: set this to true if you want the controller to retrieve
0128:         * SQL warnings. Default is false, which means that (Connection|Statement|ResultSet).getWarnings()
0129:         * will always return null.
0130:         * allowCommitWithAutoCommit: When set to true, trying to call commit/rollback
0131:         *   on a connection in autoCommit will not throw an exception. If set to false
0132:         *   (default) an SQLException will be thrown when commit is called on a 
0133:         *   connection in autoCommit mode.
0134:         * alwaysGetGeneratedKeys: when set to true, always fetch generated keys even if 
0135:         *   not requested with Statement.RETURN_GENERATED_KEYS.
0136:         * </pre>
0137:         * 
0138:         * <p>
0139:         * This original code has been inspired from the PostgreSQL JDBC driver by Peter
0140:         * T. Mount <peter@retep.org.uk>and the MM MySQL JDBC Drivers from Mark Matthews
0141:         * <mmatthew@worldserver.com>.
0142:         * 
0143:         * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
0144:         * @author <a href="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
0145:         * @author <a href="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
0146:         * @author <a href="mailto:Marek.Prochazka@inrialpes.fr">Marek Prochazka </a>
0147:         * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
0148:         * @author <a href="mailto:jaco.swart@iblocks.co.uk">Jaco Swart </a>
0149:         * @author <a href="mailto:Gilles.Rayrat@continuent.com">Gilles Rayrat </a>
0150:         * @version 1.0
0151:         */
0152:
0153:        public class Driver implements  java.sql.Driver {
0154:            /** Sequoia URL header. */
0155:            protected String sequoiaUrlHeader = "jdbc:sequoia://";
0156:
0157:            /** Sequoia URL header length. */
0158:            protected int sequoiaUrlHeaderLength = sequoiaUrlHeader.length();
0159:            /**
0160:             * Default interval in milliseconds between two pings of a controller. The
0161:             * default is 1000 (1 second)
0162:             */
0163:            public static final int DEFAULT_PING_DELAY_IN_MS = 1000;
0164:            /**
0165:             * Default timeout in milliseconds after which a controller is considered as
0166:             * dead if it did not respond to pings. Default is 25000 (25 seconds).
0167:             */
0168:            public static final int DEFAULT_CONTROLLER_TIMEOUT_IN_MS = 25000;
0169:
0170:            /**
0171:             * List of driver properties initialized in the static class initializer
0172:             * <p>
0173:             * !!! Static intializer needs to be udpated when new properties are added !!!
0174:             */
0175:            protected static ArrayList driverPropertiesNames;
0176:
0177:            /** Sequoia driver property name (if you add one, read driverProperties above). */
0178:            protected static final String HOST_PROPERTY = "HOST";
0179:            protected static final String PORT_PROPERTY = "PORT";
0180:            protected static final String DATABASE_PROPERTY = "DATABASE";
0181:            protected static final String USER_PROPERTY = "user";
0182:            protected static final String PASSWORD_PROPERTY = "password";
0183:
0184:            protected static final String ESCAPE_BACKSLASH_PROPERTY = "escapeBackslash";
0185:            protected static final String ESCAPE_SINGLE_QUOTE_PROPERTY = "escapeSingleQuote";
0186:            protected static final String ESCAPE_CHARACTER_PROPERTY = "escapeCharacter";
0187:            protected static final String CONNECTION_POOLING_PROPERTY = "connectionPooling";
0188:            protected static final String PREFERRED_CONTROLLER_PROPERTY = "preferredController";
0189:            protected static final String PING_DELAY_IN_MS_PROPERTY = "pingDelayInMs";
0190:            protected static final String CONTROLLER_TIMEOUT_IN_MS_PROPERTY = "controllerTimeoutInMs";
0191:            protected static final String DEBUG_PROPERTY = "debugLevel";
0192:            protected static final String PERSISTENT_CONNECTION_PROPERTY = "persistentConnection";
0193:            protected static final String RETRIEVE_SQL_WARNINGS_PROPERTY = "retrieveSQLWarnings";
0194:            protected static final String ALLOW_COMMIT_WITH_AUTOCOMMIT_PROPERTY = "allowCommitWithAutoCommit";
0195:            protected static final String ALWAYS_RETRIEVE_GENERATED_KEYS_PROPERTY = "alwaysGetGeneratedKeys";
0196:
0197:            /** Sequoia driver property description. */
0198:            private static final String HOST_PROPERTY_DESCRIPTION = "Hostname of Sequoia controller";
0199:            private static final String PORT_PROPERTY_DESCRIPTION = "Port number of Sequoia controller";
0200:            private static final String DATABASE_PROPERTY_DESCRIPTION = "Database name";
0201:            private static final String USER_PROPERTY_DESCRIPTION = "Username to authenticate as";
0202:            private static final String PASSWORD_PROPERTY_DESCRIPTION = "Password to use for authentication";
0203:            private static final String ESCAPE_BACKSLASH_PROPERTY_DESCRIPTION = "Set this to true to escape backslashes when performing escape processing of PreparedStatements";
0204:            private static final String ESCAPE_SINGLE_QUOTE_PROPERTY_DESCRIPTION = "Set this to true to escape single quotes (') when performing escape processing of PreparedStatements";
0205:            private static final String ESCAPE_CHARACTER_PROPERTY_DESCRIPTION = "Use this character to prepend and append to the values when performing escape processing of PreparedStatements";
0206:            protected static final String CONNECTION_POOLING_PROPERTY_DESCRIPTION = "Set this to false if you do not want the driver to perform transparent connection pooling";
0207:            protected static final String PREFERRED_CONTROLLER_PROPERTY_DESCRIPTION = "Defines the strategy to use to choose a preferred controller to connect to";
0208:            protected static final String PING_DELAY_IN_MS_DESCRIPTION = "Interval in milliseconds between two pings of a controller";
0209:            protected static final String CONTROLLER_TIMEOUT_IN_MS_DESCRIPTION = "Timeout in milliseconds after which a controller is considered as dead if it did not respond to pings";
0210:            protected static final String DEBUG_PROPERTY_DESCRIPTION = "Debug level that can be set to 'debug', 'info' or 'off'";
0211:            protected static final String PERSISTENT_CONNECTION_PROPERTY_DESCRIPTION = "Defines if a connection in autoCommit mode should remain persistent on cluster backends";
0212:            protected static final String RETRIEVE_SQL_WARNINGS_PROPERTY_DESCRIPTION = "Set this to true to allow retrieval of SQL warnings. A value set to false will make *.getWarnings() always return null";
0213:            protected static final String ALLOW_COMMIT_WITH_AUTOCOMMIT_PROPERTY_DESCRIPTION = "Indicates whether or not commit can be called while autocommit is enabled";
0214:            protected static final String ALWAYS_RETRIEVE_GENERATED_KEYS_DESCRIPTION = "Indicates whether or not every INSERT should make generated keys available, if any";
0215:
0216:            /** Driver major version. */
0217:            public static final int MAJOR_VERSION = Constants.getMajorVersion();
0218:
0219:            /** Driver minor version. */
0220:            public static final int MINOR_VERSION = Constants.getMinorVersion();
0221:            /** Get the sequoia.ssl.enabled system property to check if SSL is enabled */
0222:            protected static final boolean SSL_ENABLED_PROPERTY = "true"
0223:                    .equalsIgnoreCase(System.getProperty("sequoia.ssl.enabled"));
0224:
0225:            /**
0226:             * Cache of parsed URLs used to connect to the controller. It always grows and
0227:             * is never purged: we don't yet handle the unlikely case of a long-lived
0228:             * driver using zillions of different URLs. Warning: this caches urls BOTH
0229:             * with AND without properties.
0230:             * <p>
0231:             * Hashmap is URL=> <code>SequoiaUrl</code>
0232:             */
0233:            private HashMap parsedUrlsCache = new HashMap();
0234:
0235:            /** List of connections that are ready to be closed. */
0236:            protected ArrayList pendingConnectionClosing = new ArrayList();
0237:            protected boolean connectionClosingThreadisAlive = false;
0238:
0239:            private JDBCRegExp jdbcRegExp = new SequoiaJDBCRegExp();
0240:
0241:            // optimization: non-lazy class loading
0242:            private static Class c1 = Field.class;
0243:            private static Class c2 = SQLDataSerialization.class;
0244:            private static Class c3 = TypeTag.class;
0245:            private static Class c4 = DriverResultSet.class;
0246:
0247:            // The static initializer registers ourselves with the DriverManager
0248:            // and try to bind the Sequoia Controller
0249:            static {
0250:                // Register with the DriverManager (see JDBC API Tutorial and Reference,
0251:                // Second Edition p. 941)
0252:                try {
0253:                    java.sql.DriverManager.registerDriver(new Driver());
0254:                } catch (SQLException e) {
0255:                    throw new RuntimeException(
0256:                            "Unable to register Sequoia driver");
0257:                }
0258:
0259:                // Build the static list of driver properties
0260:                driverPropertiesNames = new ArrayList();
0261:                driverPropertiesNames.add(Driver.HOST_PROPERTY);
0262:                driverPropertiesNames.add(Driver.PORT_PROPERTY);
0263:                driverPropertiesNames.add(Driver.DATABASE_PROPERTY);
0264:                driverPropertiesNames.add(Driver.USER_PROPERTY);
0265:                driverPropertiesNames.add(Driver.PASSWORD_PROPERTY);
0266:
0267:                driverPropertiesNames.add(Driver.ESCAPE_BACKSLASH_PROPERTY);
0268:                driverPropertiesNames.add(Driver.ESCAPE_SINGLE_QUOTE_PROPERTY);
0269:                driverPropertiesNames.add(Driver.ESCAPE_CHARACTER_PROPERTY);
0270:                driverPropertiesNames.add(Driver.CONNECTION_POOLING_PROPERTY);
0271:                driverPropertiesNames.add(Driver.PREFERRED_CONTROLLER_PROPERTY);
0272:                driverPropertiesNames.add(Driver.PING_DELAY_IN_MS_PROPERTY);
0273:                driverPropertiesNames
0274:                        .add(Driver.CONTROLLER_TIMEOUT_IN_MS_PROPERTY);
0275:                driverPropertiesNames.add(Driver.DEBUG_PROPERTY);
0276:                driverPropertiesNames
0277:                        .add(Driver.PERSISTENT_CONNECTION_PROPERTY);
0278:                driverPropertiesNames
0279:                        .add(Driver.ALLOW_COMMIT_WITH_AUTOCOMMIT_PROPERTY);
0280:                driverPropertiesNames
0281:                        .add(Driver.ALWAYS_RETRIEVE_GENERATED_KEYS_PROPERTY);
0282:            }
0283:
0284:            /**
0285:             * Creates a new <code>Driver</code>. Only an actual instance can be
0286:             * registered to the DriverManager, see call to
0287:             * {@link java.sql.DriverManager#registerDriver(java.sql.Driver)} in static
0288:             * initializer block just above.
0289:             */
0290:            public Driver() {
0291:                // see javadoc above
0292:            }
0293:
0294:            /**
0295:             * Asks the Sequoia controller if the requested database can be accessed with
0296:             * the provided user name and password. If the Sequoia controller can't access
0297:             * the requested database, an <code>SQLException</code> is thrown, else a
0298:             * "fake" <code>Connection</code> is returned to the user so that he or she
0299:             * can create <code>Statements</code>.
0300:             * 
0301:             * @param url the URL of the Sequoia controller to which to connect.
0302:             * @param clientProperties a list of arbitrary string tag/value pairs as
0303:             *          connection arguments (usually at least a "user" and "password").
0304:             *          In case of conflict, this list overrides settings from the url;
0305:             *          see SEQUOIA-105
0306:             * @return a <code>Connection</code> object that represents a connection to
0307:             *         the database through the Sequoia Controller.
0308:             * @exception SQLException if an error occurs.
0309:             */
0310:            public java.sql.Connection connect(String url,
0311:                    Properties clientProperties) throws SQLException,
0312:                    VirtualDatabaseUnavailableException,
0313:                    NoMoreControllerException {
0314:                if (url == null)
0315:                    throw new SQLException("Invalid null URL in connect");
0316:
0317:                /**
0318:                 * If the URL is for another driver we must return null according to the
0319:                 * javadoc of the implemented interface. This is likely to happen as the
0320:                 * DriverManager tries every driver until one succeeds.
0321:                 */
0322:                if (!url.startsWith(sequoiaUrlHeader))
0323:                    return null;
0324:
0325:                Properties filteredProperties = filterProperties(clientProperties);
0326:
0327:                String urlCacheKey = url + filteredProperties.toString();
0328:
0329:                // In the common case, we do not synchronize
0330:                SequoiaUrl sequoiaUrl = (SequoiaUrl) parsedUrlsCache
0331:                        .get(urlCacheKey);
0332:                if (sequoiaUrl == null) // Not in the cache
0333:                {
0334:                    synchronized (this ) {
0335:                        // Recheck here in case someone updated before we entered the
0336:                        // synchronized block
0337:                        sequoiaUrl = (SequoiaUrl) parsedUrlsCache
0338:                                .get(urlCacheKey);
0339:                        if (sequoiaUrl == null) {
0340:                            sequoiaUrl = new SequoiaUrl(this , url,
0341:                                    filteredProperties);
0342:                            parsedUrlsCache.put(urlCacheKey, sequoiaUrl);
0343:                        }
0344:                    }
0345:                }
0346:
0347:                ControllerInfo controller = null;
0348:                try {
0349:                    Connection newConn = getConnectionToNewController(sequoiaUrl);
0350:                    if (newConn != null)
0351:                        controller = newConn.getControllerInfo();
0352:                    return newConn;
0353:                }
0354:                // Exceptions thrown directly to client:
0355:                // VirtualDatabaseUnavailableException
0356:                // NoMoreControllerException
0357:                catch (AuthenticationException e) {
0358:                    throw (SQLException) new SQLException(e.getMessage())
0359:                            .initCause(e);
0360:                } catch (GeneralSecurityException e) {
0361:                    e.printStackTrace();
0362:                    throw (SQLException) new SQLException(
0363:                            "Fatal General Security Exception received while trying to connect")
0364:                            .initCause(e);
0365:                } catch (RuntimeException e) {
0366:                    e.printStackTrace();
0367:                    throw (SQLException) new SQLException(
0368:                            "Fatal Runtime Exception received while trying to connect to"
0369:                                    + e + ")").initCause(e);
0370:                }
0371:            }
0372:
0373:            /**
0374:             * This function should be used to establish a new connection to another
0375:             * controller in the list. It monitors "virtualdatabase not available"
0376:             * failures by calling {@link #connectToNextController(SequoiaUrl)} only a
0377:             * limited number of times (number = number of available controllers).
0378:             * 
0379:             * @param sequoiaUrl Sequoia URL object including parameters
0380:             * @return connection to the next available controller
0381:             * @throws AuthenticationException if the authentication has failed
0382:             * @throws NoMoreControllerException if all controllers in the list are down
0383:             * @throws DriverSQLException if the connection cannot be established with the
0384:             *           controller
0385:             * @throws VirtualDatabaseUnavailableException if none of the remaining
0386:             *           controllers has the desired vdb
0387:             */
0388:            protected Connection getConnectionToNewController(
0389:                    SequoiaUrl sequoiaUrl) throws AuthenticationException,
0390:                    NoMoreControllerException,
0391:                    VirtualDatabaseUnavailableException,
0392:                    GeneralSecurityException {
0393:                // This will count the number of controllers left to connect to upon
0394:                // VDB not available exceptions
0395:                // No need to synchronize with getController(): at worth, we will not try
0396:                // one controller that just reappeared, or we will try two time the same
0397:                // controller. This is harmless, we just want to prevent endless retry loops
0398:                int numberOfCtrlsLeft = sequoiaUrl.getControllerConnectPolicy()
0399:                        .numberOfAliveControllers();
0400:                while (numberOfCtrlsLeft > 0) {
0401:                    try {
0402:                        return connectToNextController(sequoiaUrl);
0403:                    } catch (VirtualDatabaseUnavailableException vdbue) {
0404:                        numberOfCtrlsLeft--;
0405:                    }
0406:                }
0407:                // at this point, we have tried all controllers
0408:                throw new VirtualDatabaseUnavailableException(
0409:                        "Virtual database " + sequoiaUrl.getDatabaseName()
0410:                                + " not found on any of the controllers");
0411:            }
0412:
0413:            /**
0414:             * Connects with the specified parameters to the next controller (next
0415:             * according to the current connection policy).<br>
0416:             * Retrieves a new controller by asking the connect policy, creates and
0417:             * connects a socket to this new controller, and registers the new socket to
0418:             * the policy. Then, tries to authenticate to the controller. Finally, creates
0419:             * the connection with the given parameters.<br>
0420:             * Upon IOException during connection, this function will mark the new
0421:             * controller as failing (by calling
0422:             * {@link AbstractControllerConnectPolicy#forceControllerDown(ControllerInfo)}
0423:             * and try the next controller until NoMoreControllerException (which will be
0424:             * forwarded to caller)<br>
0425:             * If a VirtualDatabaseUnavailableException is thrown, the controller's vdb
0426:             * will be considered as down by calling
0427:             * {@link AbstractControllerConnectPolicy#setVdbDownOnController(ControllerInfo)}
0428:             * and the exception will be forwarded to caller Note that newly connected
0429:             * controller can be retrieved by calling
0430:             * {@link Connection#getControllerInfo()}
0431:             * 
0432:             * @param sequoiaUrl Sequoia URL object including parameters
0433:             * @return connection to the next available controller
0434:             * @throws VirtualDatabaseUnavailableException if the given vdb is not
0435:             *           available on the new controller we are trying to connect to
0436:             * @throws AuthenticationException if the authentication has failed or the
0437:             *           database name is wrong
0438:             * @throws NoMoreControllerException if all controllers in the list are down
0439:             */
0440:            private Connection connectToNextController(SequoiaUrl sequoiaUrl)
0441:                    throws AuthenticationException, NoMoreControllerException,
0442:                    VirtualDatabaseUnavailableException,
0443:                    GeneralSecurityException {
0444:                // TODO: methods should be extracted to reduce the size of this one
0445:
0446:                ControllerInfo newController = null;
0447:
0448:                // Check the user
0449:                String user = (String) sequoiaUrl.getParameters().get(
0450:                        USER_PROPERTY);
0451:                if (user == null || user.equals(""))
0452:                    throw new AuthenticationException(
0453:                            "Invalid user name in connect");
0454:                // Check the password
0455:                String password = (String) sequoiaUrl.getParameters().get(
0456:                        PASSWORD_PROPERTY);
0457:                if (password == null)
0458:                    password = "";
0459:
0460:                // Let's go for a new connection
0461:
0462:                // This is actually a connection constructor,
0463:                // we should try to move most of it below.
0464:                AbstractControllerConnectPolicy policy = sequoiaUrl
0465:                        .getControllerConnectPolicy();
0466:                try {
0467:                    Socket socket = null;
0468:                    // This synchronized block prevents other connections from doing a
0469:                    // forceControllerDown between our getController and registerSocket
0470:                    synchronized (policy) {
0471:                        // Choose a controller according to the policy
0472:                        newController = policy.getController();
0473:
0474:                        // Try to retrieve a reusable connection
0475:                        if (!"false".equals(sequoiaUrl.getParameters().get(
0476:                                CONNECTION_POOLING_PROPERTY))) { // Connection pooling is activated
0477:                            Connection c = retrievePendingClosingConnection(
0478:                                    sequoiaUrl, newController, user, password);
0479:                            if (c != null) {
0480:                                if (sequoiaUrl.isDebugEnabled())
0481:                                    System.out
0482:                                            .println("Reusing connection from pool");
0483:                                return c; // Re-use this one
0484:                            }
0485:                        }
0486:
0487:                        // Create the socket
0488:                        // SSL enabled ?
0489:                        if (SSL_ENABLED_PROPERTY) {
0490:                            SocketFactory sslFact = SocketFactoryFactory
0491:                                    .createFactory(SSLConfiguration
0492:                                            .getDefaultConfig());
0493:                            socket = sslFact.createSocket();
0494:                        } else {
0495:                            // no ssl - we use ordinary socket
0496:                            socket = new Socket();
0497:                        }
0498:                        // Register asap the socket to the policy callback so it can kill it
0499:                        // (even when connecting)
0500:                        // synchronized is reentrant => we can call a policy synchronized method
0501:                        // inside this synchronized(policy) block
0502:                        policy.registerSocket(newController, socket);
0503:
0504:                        socket.connect(newController);
0505:                    }
0506:
0507:                    // Disable Nagle algorithm else small messages are not sent
0508:                    // (at least under Linux) even if we flush the output stream.
0509:                    socket.setTcpNoDelay(true);
0510:
0511:                    if (sequoiaUrl.isInfoEnabled())
0512:                        System.out.println("Authenticating with controller "
0513:                                + newController);
0514:
0515:                    DriverBufferedOutputStream out = new DriverBufferedOutputStream(
0516:                            socket, sequoiaUrl.getDebugLevel());
0517:                    // Send protocol version and database name
0518:                    out.writeInt(Commands.ProtocolVersion);
0519:                    out.writeLongUTF(sequoiaUrl.getDatabaseName());
0520:                    out.flush();
0521:
0522:                    // Send user information
0523:                    out.writeLongUTF(user);
0524:                    out.writeLongUTF(password);
0525:                    out.flush();
0526:
0527:                    // Create input stream only here else it will block
0528:                    DriverBufferedInputStream in = new DriverBufferedInputStream(
0529:                            socket, sequoiaUrl.getDebugLevel());
0530:
0531:                    return new Connection(this , socket, in, out, sequoiaUrl,
0532:                            newController, user, password);
0533:                } // try connect to the controller/connection constructor
0534:                catch (IOException ioe) {
0535:                    policy.forceControllerDown(newController);
0536:                    return connectToNextController(sequoiaUrl);
0537:                } catch (VirtualDatabaseUnavailableException vdbue) {
0538:                    // mark vdb as down. Caller will retry if appropriate
0539:                    policy.setVdbDownOnController(newController);
0540:                    throw vdbue;
0541:                }
0542:                // Other exceptions are forwarded to caller
0543:            }
0544:
0545:            /**
0546:             * This extracts from the (too complex) client Properties a leaner and cleaner
0547:             * HashMap with is: - maybe empty but never null, - holding only the keys we
0548:             * are interested in, - its values are guaranteed to be strings, - no complex
0549:             * and hidden layered "defaults". See SEQUOIA-105 and SEQUOIA-440
0550:             * 
0551:             * @param props to filter
0552:             * @return filtered properties
0553:             * @throws SQLException
0554:             */
0555:            protected Properties filterProperties(Properties props) {
0556:                Properties filtered = new Properties();
0557:
0558:                if (props == null)
0559:                    return filtered;
0560:
0561:                // extract only the keys we know
0562:                Iterator iter = driverPropertiesNames.iterator();
0563:                while (iter.hasNext()) {
0564:                    String name = (String) iter.next();
0565:                    String val = props.getProperty(name);
0566:                    if (val == null)
0567:                        continue;
0568:                    filtered.setProperty(name, val);
0569:                }
0570:
0571:                return filtered;
0572:            }
0573:
0574:            /**
0575:             * This method is used to implement the transparent connection pooling and try
0576:             * to retrieve a connection that was recently closed to the given controller
0577:             * with the provided login/password information.
0578:             * 
0579:             * @param url Sequoia URL object including parameters
0580:             * @param controllerInfo the controller to connect to
0581:             * @param user user name used for connection
0582:             * @param password password used for connection
0583:             * @return a connection that could be reuse or null if none
0584:             */
0585:            private Connection retrievePendingClosingConnection(SequoiaUrl url,
0586:                    ControllerInfo controllerInfo, String user, String password) {
0587:                // Check if there is a connection that is about to be closed that could
0588:                // be reused. We take the bet that if a connection has been released by
0589:                // a client, in the general case, it will reuse the same connection.
0590:                // As we need to keep the work in the synchronized block as minimal as
0591:                // possible, we have to extract the string comparison
0592:                // (url,name,password,controller)from the sync block. This way, we cannot
0593:                // just read/compare/take the connection without synchronizing the whole
0594:                // thing. A solution is to systematically extract the first available
0595:                // connection in the sync block, and do the checkings outside the block. If
0596:                // we fail, we re-sync to put the connection back but in practice it is
0597:                // almost always a success and we don't really care to pay this extra cost
0598:                // once in a while.
0599:                try {
0600:                    Connection c;
0601:                    synchronized (pendingConnectionClosing) {
0602:                        // Take the last one to prevent shifting all elements
0603:                        c = (Connection) pendingConnectionClosing
0604:                                .remove(pendingConnectionClosing.size() - 1);
0605:                    }
0606:                    if (url.equals(c.getSequoiaUrl()) // This compares all the Connection
0607:                            // properties
0608:                            && controllerInfo.equals(c.getControllerInfo())
0609:                            && user.equals(c.getUserName())
0610:                            && password.equals(c.getPassword())) { // Great! Take this one.
0611:                        c.isClosed = false;
0612:                        return c;
0613:                    } else {
0614:                        // Put this connection back, it is not good for us
0615:                        synchronized (pendingConnectionClosing) {
0616:                            pendingConnectionClosing.add(c);
0617:                            // Now scan the list for a suitable connection
0618:                            for (Iterator iter = pendingConnectionClosing
0619:                                    .iterator(); iter.hasNext();) {
0620:                                Connection conn = (Connection) iter.next();
0621:                                if (url.equals(conn.getSequoiaUrl()) // This compares all the
0622:                                        // Connection
0623:                                        // properties
0624:                                        && controllerInfo.equals(conn
0625:                                                .getControllerInfo())
0626:                                        && user.equals(conn.getUserName())
0627:                                        && password.equals(conn.getPassword())) { // Great! Take this one.
0628:                                    iter.remove();
0629:                                    conn.isClosed = false;
0630:                                    return conn;
0631:                                }
0632:                            }
0633:                        }
0634:                    }
0635:                } catch (IndexOutOfBoundsException ignore) {
0636:                    // No connection available
0637:                }
0638:                return null;
0639:            }
0640:
0641:            /**
0642:             * Tests if the URL is understood by the driver. Simply tries to construct a
0643:             * parsed URLs and catch the failure.
0644:             * 
0645:             * @param url the JDBC URL.
0646:             * @return <code>true</code> if the URL is correct, otherwise an exception
0647:             *         with extensive error message is thrown.
0648:             * @exception SQLException if the URL is incorrect an explicit error message
0649:             *              is given.
0650:             */
0651:            public synchronized boolean acceptsURL(String url)
0652:                    throws SQLException {
0653:                if (url == null)
0654:                    return false;
0655:
0656:                try {
0657:                    SequoiaUrl sequoiaUrl = (SequoiaUrl) parsedUrlsCache
0658:                            .get(url);
0659:                    if (sequoiaUrl == null) // Not in the cache
0660:                    {
0661:                        synchronized (this ) {
0662:                            // Recheck here in case someone updated before we entered the
0663:                            // synchronized block
0664:                            sequoiaUrl = (SequoiaUrl) parsedUrlsCache.get(url);
0665:                            if (sequoiaUrl == null) {
0666:                                // URL parsed here.
0667:                                sequoiaUrl = new SequoiaUrl(this , url,
0668:                                        new Properties());
0669:                                // Update the cache anyway that can be useful later on
0670:                                parsedUrlsCache.put(url, sequoiaUrl);
0671:                            }
0672:                        }
0673:                    }
0674:                    return true;
0675:                } catch (SQLException e) {
0676:                    return false;
0677:                }
0678:            }
0679:
0680:            /**
0681:             * Change the database name in the provided URL.
0682:             * 
0683:             * @param url URL to parse
0684:             * @param newDbName new database name to insert
0685:             * @return the updated URL
0686:             * @throws SQLException if an error occurs while parsing the url
0687:             */
0688:            public String changeDatabaseName(String url, String newDbName)
0689:                    throws SQLException {
0690:                StringBuffer sb = new StringBuffer();
0691:                sb.append(sequoiaUrlHeader);
0692:
0693:                SequoiaUrl sequoiaUrl = (SequoiaUrl) parsedUrlsCache.get(url);
0694:                if (sequoiaUrl == null) {
0695:                    acceptsURL(url); // parse and put in cache
0696:                    sequoiaUrl = (SequoiaUrl) parsedUrlsCache.get(url);
0697:                }
0698:
0699:                // append controller list
0700:                ControllerInfo[] controllerList = sequoiaUrl
0701:                        .getControllerList();
0702:                for (int i = 0; i < controllerList.length; i++) {
0703:                    if (i == 0)
0704:                        sb.append(controllerList[i].toString());
0705:                    else
0706:                        sb.append("," + controllerList[i].toString());
0707:                }
0708:                sb.append("/" + newDbName);
0709:
0710:                // append parameters parsed above
0711:                HashMap params = sequoiaUrl.getParameters();
0712:                if (params != null) {
0713:                    Iterator paramsKeys = params.keySet().iterator();
0714:                    String element = null;
0715:                    while (paramsKeys.hasNext()) {
0716:                        if (element == null)
0717:                            sb.append("?");
0718:                        else
0719:                            sb.append("&");
0720:                        element = (String) paramsKeys.next();
0721:                        sb.append(element + "=" + params.get(paramsKeys));
0722:                    }
0723:                }
0724:                return sb.toString();
0725:            }
0726:
0727:            /**
0728:             * Get the default transaction isolation level to use for this driver.
0729:             * 
0730:             * @return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED
0731:             */
0732:            protected int getDefaultTransactionIsolationLevel() {
0733:                return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
0734:            }
0735:
0736:            /**
0737:             * Returns the SequoiaJDBCRegExp value.
0738:             * 
0739:             * @return Returns the SequoiaJDBCRegExp.
0740:             */
0741:            public JDBCRegExp getJDBCRegExp() {
0742:                return jdbcRegExp;
0743:            }
0744:
0745:            /**
0746:             * This method is intended to allow a generic GUI tool to discover what
0747:             * properties it should prompt a human for in order to get enough information
0748:             * to connect to a database.
0749:             * <p>
0750:             * The only properties supported by Sequoia are:
0751:             * <ul>
0752:             * <li>HOST_PROPERTY</li>
0753:             * <li>PORT_PROPERTY</li>
0754:             * <li>DATABASE_PROPERTY</li>
0755:             * <li>USER_PROPERTY</li>
0756:             * <li>PASSWORD_PROPERTY</li>
0757:             * <li>ESCAPE_BACKSLASH_PROPERTY</li>
0758:             * <li>ESCAPE_SINGLE_QUOTE_PROPERTY</li>
0759:             * <li>ESCAPE_CHARACTER_PROPERTY</li>
0760:             * <li>CONNECTION_POOLING_PROPERTY</li>
0761:             * <li>PREFERRED_CONTROLLER_PROPERTY</li>
0762:             * <li>PING_DELAY_IN_MS_PROPERTY</li>
0763:             * <li>CONTROLLER_TIMEOUT_IN_MS_PROPERTY</li>
0764:             * <li>DEBUG_PROPERTY</li>
0765:             * <li>PERSISTENT_CONNECTION_PROPERTY</li>
0766:             * <li>RETRIEVE_SQL_WARNINGS_PROPERTY</li>
0767:             * <li>ALLOW_COMMIT_WITH_AUTOCOMMIT_PROPERTY</li>
0768:             * </ul>
0769:             * 
0770:             * @param url the URL of the database to connect to
0771:             * @param info a proposed list of tag/value pairs that will be sent on connect
0772:             *          open.
0773:             * @return an array of <code>DriverPropertyInfo</code> objects describing
0774:             *         possible properties. This array may be an empty array if no
0775:             *         properties are required (note that this override any setting that
0776:             *         might be set in the URL).
0777:             * @exception SQLException if the url is not valid
0778:             * @see java.sql.Driver#getPropertyInfo
0779:             */
0780:            public DriverPropertyInfo[] getPropertyInfo(String url,
0781:                    Properties info) throws SQLException {
0782:                if (!acceptsURL(url))
0783:                    throw new SQLException("Invalid url " + url);
0784:
0785:                SequoiaUrl sequoiaUrl;
0786:                synchronized (this ) {
0787:                    sequoiaUrl = (SequoiaUrl) parsedUrlsCache.get(url);
0788:                    if (sequoiaUrl == null)
0789:                        throw new SQLException(
0790:                                "Error while retrieving URL information");
0791:                }
0792:                HashMap params = sequoiaUrl.getParameters();
0793:
0794:                String host = info.getProperty(HOST_PROPERTY);
0795:                if (host == null) {
0796:                    ControllerInfo[] controllerList = sequoiaUrl
0797:                            .getControllerList();
0798:                    for (int i = 0; i < controllerList.length; i++) {
0799:                        ControllerInfo controller = controllerList[i];
0800:                        if (i == 0)
0801:                            host = controller.toString();
0802:                        else
0803:                            host += "," + controller.toString();
0804:                    }
0805:                }
0806:                DriverPropertyInfo hostProp = new DriverPropertyInfo(
0807:                        HOST_PROPERTY, host);
0808:                hostProp.required = true;
0809:                hostProp.description = HOST_PROPERTY_DESCRIPTION;
0810:
0811:                DriverPropertyInfo portProp = new DriverPropertyInfo(
0812:                        PORT_PROPERTY, info.getProperty(PORT_PROPERTY, Integer
0813:                                .toString(SequoiaUrl.DEFAULT_CONTROLLER_PORT)));
0814:                portProp.required = false;
0815:                portProp.description = PORT_PROPERTY_DESCRIPTION;
0816:
0817:                String database = info.getProperty(DATABASE_PROPERTY);
0818:                if (database == null)
0819:                    database = sequoiaUrl.getDatabaseName();
0820:                DriverPropertyInfo databaseProp = new DriverPropertyInfo(
0821:                        DATABASE_PROPERTY, database);
0822:                databaseProp.required = true;
0823:                databaseProp.description = DATABASE_PROPERTY_DESCRIPTION;
0824:
0825:                String user = info.getProperty(USER_PROPERTY);
0826:                if (user == null)
0827:                    user = (String) params.get(USER_PROPERTY);
0828:                DriverPropertyInfo userProp = new DriverPropertyInfo(
0829:                        USER_PROPERTY, user);
0830:                userProp.required = true;
0831:                userProp.description = USER_PROPERTY_DESCRIPTION;
0832:
0833:                String password = info.getProperty(PASSWORD_PROPERTY);
0834:                if (password == null)
0835:                    password = (String) params.get(PASSWORD_PROPERTY);
0836:                DriverPropertyInfo passwordProp = new DriverPropertyInfo(
0837:                        PASSWORD_PROPERTY, password);
0838:                passwordProp.required = true;
0839:                passwordProp.description = PASSWORD_PROPERTY_DESCRIPTION;
0840:
0841:                String escapeChar = info.getProperty(ESCAPE_CHARACTER_PROPERTY);
0842:                if (escapeChar == null)
0843:                    escapeChar = (String) params.get(ESCAPE_CHARACTER_PROPERTY);
0844:                DriverPropertyInfo escapeCharProp = new DriverPropertyInfo(
0845:                        ESCAPE_CHARACTER_PROPERTY, escapeChar);
0846:                escapeCharProp.required = false;
0847:                escapeCharProp.description = ESCAPE_CHARACTER_PROPERTY_DESCRIPTION;
0848:
0849:                String escapeBackslash = info
0850:                        .getProperty(ESCAPE_BACKSLASH_PROPERTY);
0851:                if (escapeBackslash == null)
0852:                    escapeBackslash = (String) params
0853:                            .get(ESCAPE_BACKSLASH_PROPERTY);
0854:                DriverPropertyInfo escapeBackProp = new DriverPropertyInfo(
0855:                        ESCAPE_BACKSLASH_PROPERTY, escapeBackslash);
0856:                escapeBackProp.required = false;
0857:                escapeBackProp.description = ESCAPE_BACKSLASH_PROPERTY_DESCRIPTION;
0858:
0859:                String escapeSingleQuote = info
0860:                        .getProperty(ESCAPE_SINGLE_QUOTE_PROPERTY);
0861:                if (escapeSingleQuote == null)
0862:                    escapeSingleQuote = (String) params
0863:                            .get(ESCAPE_SINGLE_QUOTE_PROPERTY);
0864:                DriverPropertyInfo escapeSingleProp = new DriverPropertyInfo(
0865:                        ESCAPE_SINGLE_QUOTE_PROPERTY, escapeSingleQuote);
0866:                escapeSingleProp.required = false;
0867:                escapeSingleProp.description = ESCAPE_SINGLE_QUOTE_PROPERTY_DESCRIPTION;
0868:
0869:                String connectionPooling = info
0870:                        .getProperty(CONNECTION_POOLING_PROPERTY);
0871:                if (connectionPooling == null)
0872:                    connectionPooling = (String) params
0873:                            .get(CONNECTION_POOLING_PROPERTY);
0874:                DriverPropertyInfo connectionPoolingProp = new DriverPropertyInfo(
0875:                        CONNECTION_POOLING_PROPERTY, connectionPooling);
0876:                connectionPoolingProp.required = false;
0877:                connectionPoolingProp.description = CONNECTION_POOLING_PROPERTY_DESCRIPTION;
0878:
0879:                String preferredController = info
0880:                        .getProperty(PREFERRED_CONTROLLER_PROPERTY);
0881:                if (preferredController == null)
0882:                    preferredController = (String) params
0883:                            .get(PREFERRED_CONTROLLER_PROPERTY);
0884:                DriverPropertyInfo preferredControllerProp = new DriverPropertyInfo(
0885:                        PREFERRED_CONTROLLER_PROPERTY, preferredController);
0886:                preferredControllerProp.required = false;
0887:                preferredControllerProp.description = PREFERRED_CONTROLLER_PROPERTY_DESCRIPTION;
0888:
0889:                String pingDelayInMs = info
0890:                        .getProperty(PING_DELAY_IN_MS_PROPERTY);
0891:                if (pingDelayInMs == null)
0892:                    pingDelayInMs = (String) params
0893:                            .get(PING_DELAY_IN_MS_PROPERTY);
0894:                DriverPropertyInfo pingDelayInMsProp = new DriverPropertyInfo(
0895:                        PING_DELAY_IN_MS_PROPERTY, pingDelayInMs);
0896:                pingDelayInMsProp.required = false;
0897:                pingDelayInMsProp.description = PING_DELAY_IN_MS_DESCRIPTION;
0898:
0899:                String controllerTimeoutInMs = info
0900:                        .getProperty(CONTROLLER_TIMEOUT_IN_MS_PROPERTY);
0901:                if (controllerTimeoutInMs == null)
0902:                    controllerTimeoutInMs = (String) params
0903:                            .get(CONTROLLER_TIMEOUT_IN_MS_PROPERTY);
0904:                DriverPropertyInfo controllerTimeoutInMsProp = new DriverPropertyInfo(
0905:                        CONTROLLER_TIMEOUT_IN_MS_PROPERTY,
0906:                        controllerTimeoutInMs);
0907:                controllerTimeoutInMsProp.required = false;
0908:                controllerTimeoutInMsProp.description = CONTROLLER_TIMEOUT_IN_MS_DESCRIPTION;
0909:
0910:                String persistentConnection = info
0911:                        .getProperty(PERSISTENT_CONNECTION_PROPERTY);
0912:                if (persistentConnection == null)
0913:                    persistentConnection = (String) params
0914:                            .get(PERSISTENT_CONNECTION_PROPERTY);
0915:                DriverPropertyInfo persistentConnectionProp = new DriverPropertyInfo(
0916:                        PERSISTENT_CONNECTION_PROPERTY, persistentConnection);
0917:                persistentConnectionProp.required = false;
0918:                persistentConnectionProp.description = PERSISTENT_CONNECTION_PROPERTY_DESCRIPTION;
0919:
0920:                String retrieveSQLWarnings = info
0921:                        .getProperty(RETRIEVE_SQL_WARNINGS_PROPERTY);
0922:                if (retrieveSQLWarnings == null)
0923:                    retrieveSQLWarnings = (String) params
0924:                            .get(RETRIEVE_SQL_WARNINGS_PROPERTY);
0925:                DriverPropertyInfo retrieveSQLWarningsProp = new DriverPropertyInfo(
0926:                        RETRIEVE_SQL_WARNINGS_PROPERTY, retrieveSQLWarnings);
0927:                retrieveSQLWarningsProp.required = false;
0928:                retrieveSQLWarningsProp.description = RETRIEVE_SQL_WARNINGS_PROPERTY_DESCRIPTION;
0929:
0930:                String getGeneratedKeys = info
0931:                        .getProperty(ALWAYS_RETRIEVE_GENERATED_KEYS_PROPERTY);
0932:                if (getGeneratedKeys == null)
0933:                    getGeneratedKeys = (String) params
0934:                            .get(ALWAYS_RETRIEVE_GENERATED_KEYS_PROPERTY);
0935:                DriverPropertyInfo getGeneratedKeysProp = new DriverPropertyInfo(
0936:                        ALWAYS_RETRIEVE_GENERATED_KEYS_PROPERTY,
0937:                        getGeneratedKeys);
0938:                getGeneratedKeysProp.required = false;
0939:                getGeneratedKeysProp.description = ALWAYS_RETRIEVE_GENERATED_KEYS_DESCRIPTION;
0940:
0941:                return new DriverPropertyInfo[] { hostProp, portProp,
0942:                        databaseProp, userProp, passwordProp, escapeCharProp,
0943:                        escapeBackProp, escapeSingleProp,
0944:                        connectionPoolingProp, preferredControllerProp,
0945:                        persistentConnectionProp, retrieveSQLWarningsProp,
0946:                        getGeneratedKeysProp };
0947:            }
0948:
0949:            /**
0950:             * Gets the driver's major version number
0951:             * 
0952:             * @return the driver's major version number
0953:             */
0954:            public int getMajorVersion() {
0955:                return MAJOR_VERSION;
0956:            }
0957:
0958:            /**
0959:             * Gets the driver's minor version number
0960:             * 
0961:             * @return the driver's minor version number
0962:             */
0963:            public int getMinorVersion() {
0964:                return MINOR_VERSION;
0965:            }
0966:
0967:            /**
0968:             * Reports whether the driver is a genuine JDBC compliant driver. A driver may
0969:             * only report <code>true</code> here if it passes the JDBC compliance
0970:             * tests, otherwise it is required to return <code>false</code>. JDBC
0971:             * compliance requires full support for the JDBC API and full support for SQL
0972:             * 92 Entry Level. We cannot ensure that the underlying JDBC drivers will be
0973:             * JDBC compliant, so it is safer to return <code>false</code>.
0974:             * 
0975:             * @return always <code>false</code>
0976:             */
0977:            public boolean jdbcCompliant() {
0978:                return false;
0979:            }
0980:
0981:            /**
0982:             * @return True, escape processing of backslash is ON by default
0983:             */
0984:            public boolean getEscapeBackslash() {
0985:                return true;
0986:            }
0987:
0988:            /**
0989:             * @return the default escape character
0990:             */
0991:            public String getEscapeChar() {
0992:                return "\'";
0993:            }
0994:
0995:            /**
0996:             * @return True, escape processing of single quote is ON by default
0997:             */
0998:            public boolean getEscapeSingleQuote() {
0999:                return true;
1000:            }
1001:
1002:            /**
1003:             * @return True, as connection pooling is activated by default
1004:             */
1005:            public boolean getConnectionPooling() {
1006:                return true;
1007:            }
1008:
1009:            /**
1010:             * @return False, as connection are not persistent by default.
1011:             */
1012:            public boolean getPersistentConnection() {
1013:                return false;
1014:            }
1015:
1016:            /**
1017:             * @return False, as retrieval of SQL warnings is disabled by default.
1018:             */
1019:            public boolean getRetrieveSQLWarnings() {
1020:                return false;
1021:            }
1022:
1023:            /**
1024:             * @return False, as retrieval of generated keys is not forced by default.
1025:             */
1026:            public boolean getRetrieveGeneratedKeys() {
1027:                return false;
1028:            }
1029:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.