00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 package org.objectweb.cjdbc.driver;
00027
00028 import java.io.IOException;
00029 import java.net.Socket;
00030 import java.sql.DriverPropertyInfo;
00031 import java.sql.SQLException;
00032 import java.util.ArrayList;
00033 import java.util.Enumeration;
00034 import java.util.HashMap;
00035 import java.util.Hashtable;
00036 import java.util.Properties;
00037 import java.util.Random;
00038 import java.util.StringTokenizer;
00039
00040 import javax.net.SocketFactory;
00041
00042 import org.objectweb.cjdbc.common.net.SSLConfiguration;
00043 import org.objectweb.cjdbc.common.net.SocketFactoryFactory;
00044 import org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter;
00045 import org.objectweb.cjdbc.common.stream.CJDBCInputStream;
00046 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream;
00047 import org.objectweb.cjdbc.common.util.Constants;
00048 import org.objectweb.cjdbc.controller.core.ControllerConstants;
00049 import org.objectweb.cjdbc.driver.protocol.Commands;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 public class Driver implements java.sql.Driver
00106 {
00107
00108 public static final int MAJOR_VERSION = Constants
00109 .getMajorVersion();
00110
00111
00112 public static final int MINOR_VERSION = Constants
00113 .getMinorVersion();
00114
00115
00116 private static final String HOST_PROPERTY = "HOST";
00117 private static final String PORT_PROPERTY = "PORT";
00118 private static final String CONTROLLER_PROPERTY = "CONTROLLER";
00119 protected static final String DATABASE_PROPERTY = "DATABASE";
00120 protected static final String USER_PROPERTY = "user";
00121 protected static final String PASSWORD_PROPERTY = "password";
00122 protected static final String PARAMETER_PROPERTY = "parameter";
00123 protected static final String BOOLEAN_TRUE_PROPERTY = "booleanTrue";
00124 protected static final String BOOLEAN_FALSE_PROPERTY = "booleanFalse";
00125 protected static final String ESCAPE_BACKSLASH_PROPERTY = "escapeBackslash";
00126 protected static final String ESCAPE_SINGLE_QUOTE_PROPERTY = "escapeSingleQuote";
00127 protected static final String ESCAPE_CHARACTER_PROPERTY = "escapeCharacter";
00128 protected static final String DRIVER_PROCESSED_PROPERTY = "driverProcessed";
00129
00130
00131 private static final String HOST_PROPERTY_DESCRIPTION = "Hostname of C-JDBC controller";
00132 private static final String PORT_PROPERTY_DESCRIPTION = "Port number of C-JDBC controller";
00133 private static final String DATABASE_PROPERTY_DESCRIPTION = "Database name";
00134 private static final String USER_PROPERTY_DESCRIPTION = "Username to authenticate as";
00135 private static final String PASSWORD_PROPERTY_DESCRIPTION = "Password to use for authentication";
00136 private static final String BOOLEAN_TRUE_PROPERTY_DESCRIPTION = "Use this value for the 'true' value when using PreparedStatement.setBoolean method";
00137 private static final String BOOLEAN_FALSE_PROPERTY_DESCRIPTION = "Use this value for the 'false' value when using PreparedStatement.setBoolean method";
00138 private static final String ESCAPE_BACKSLASH_PROPERTY_DESCRIPTION = "Set this to true to escape backslashes when performing escape processing of PreparedStatements";
00139 private static final String ESCAPE_SINGLE_QUOTE_PROPERTY_DESCRIPTION = "Set this to true to escape single quotes (') when performing escape processing of PreparedStatements";
00140 private static final String ESCAPE_CHARACTER_PROPERTY_DESCRIPTION = "Use this character to prepend and append to the values when performing escape processing of PreparedStatements";
00141 private static final String DRIVER_PROCESSED_PROPERTY_DESCRIPTION = "Set this to false to let queries be passed and prepared for each individual backend";
00142
00143
00144 private static final String CJDBC_URL_HEADER = "jdbc:cjdbc://";
00145
00146
00147 private static final int CJDBC_URL_HEADER_LENGTH = CJDBC_URL_HEADER
00148 .length();
00149
00150
00151
00152
00153
00154 private HashMap controllerCache = new HashMap();
00155
00156
00157 private HashMap dbNameCache = new HashMap();
00158
00159
00160 protected ArrayList pendingConnectionClosing = new ArrayList();
00161 protected boolean connectionClosingThreadisAlive = false;
00162
00163
00164 private String currentControllerURL = null;
00165 private ArrayList controllerConfig = null;
00166 private ControllerInfo currentControllerConfig = null;
00167 private String currentDatabase = null;
00168 private Random random;
00169 private int controllerConfigArraySize;
00170 private int connectionRequestSinceControllerFailure = 0;
00171
00172
00173 private static final int RETRY_CONTROLLER_AFTER_FAILURE = 10;
00174
00175
00176
00177 static
00178 {
00179
00180
00181 try
00182 {
00183 java.sql.DriverManager.registerDriver(new Driver());
00184 }
00185 catch (SQLException e)
00186 {
00187 throw new RuntimeException("Unable to register C-JDBC driver");
00188 }
00189 }
00190
00191
00192
00193
00194
00195 public Driver()
00196 {
00197
00198 random = new Random(System.currentTimeMillis());
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 public java.sql.Connection connect(String url, Properties info)
00216 throws SQLException
00217 {
00218 if (url == null)
00219 throw new SQLException("Invalid null URL in connect");
00220
00221
00222
00223
00224
00225
00226 if (!url.toLowerCase().startsWith(CJDBC_URL_HEADER))
00227 return null;
00228
00229 String user = null;
00230 if (info != null)
00231 user = info.getProperty(USER_PROPERTY);
00232 else
00233 {
00234 info = new Properties();
00235 }
00236
00237
00238 Hashtable props = this.parseUrlParams(url);
00239 if (props != null)
00240 info.putAll(props);
00241
00242 if (user == null || user.equals(""))
00243 {
00244 if ((user = info.getProperty(USER_PROPERTY)) == null)
00245 throw new SQLException("Invalid null user name in connect");
00246 }
00247
00248 String password = info.getProperty(PASSWORD_PROPERTY);
00249 if (password == null)
00250 {
00251 password = "";
00252 }
00253
00254
00255 SSLConfiguration ssl = null;
00256 if ("true".equals(System.getProperty("cjdbc.ssl.enabled")))
00257 {
00258 ssl = SSLConfiguration.getDefaultConfig();
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 try
00273 {
00274 Connection c;
00275 synchronized (pendingConnectionClosing)
00276 {
00277
00278 c = (Connection) pendingConnectionClosing
00279 .remove(pendingConnectionClosing.size() - 1);
00280 }
00281 if (url.equals(c.getURL()) && user.equals(c.getUserName())
00282 && password.equals(c.getPassword()))
00283 {
00284 c.isClosed = false;
00285 return setParametersOnConnection(info, c);
00286 }
00287 else
00288
00289 synchronized (pendingConnectionClosing)
00290 {
00291 pendingConnectionClosing.add(c);
00292 }
00293 }
00294 catch (IndexOutOfBoundsException ignore)
00295 {
00296
00297 }
00298
00299 int retry = 2;
00300 int picked;
00301 while (retry > 0)
00302 {
00303
00304
00305 synchronized (this)
00306 {
00307 if (!url.equals(currentControllerURL)
00308 || (connectionRequestSinceControllerFailure >= RETRY_CONTROLLER_AFTER_FAILURE)
00309 || ((controllerConfig != null) && (controllerConfig.size() == 0)))
00310 {
00311 ControllerInfo[] controllerConfigArray = (ControllerInfo[]) controllerCache
00312 .get(url);
00313 if (controllerConfigArray == null)
00314 {
00315 parseURL(url);
00316 controllerConfigArray = (ControllerInfo[]) controllerCache.get(url);
00317 }
00318 controllerConfig = new ArrayList();
00319 controllerConfigArraySize = controllerConfigArray.length;
00320 for (int i = 0; i < controllerConfigArraySize; i++)
00321 controllerConfig.add(controllerConfigArray[i]);
00322
00323 currentControllerURL = url;
00324 currentDatabase = (String) dbNameCache.get(url);
00325 if (currentDatabase == null)
00326 throw new SQLException("Database name cache failure");
00327
00328
00329 retry = controllerConfig.size();
00330 connectionRequestSinceControllerFailure = 0;
00331 }
00332 }
00333
00334 int size = controllerConfig.size();
00335 if (size < controllerConfigArraySize)
00336 connectionRequestSinceControllerFailure++;
00337
00338
00339
00340 picked = random.nextInt(size);
00341 currentControllerConfig = (ControllerInfo) controllerConfig.get(picked);
00342
00343 boolean sentVdbName = false;
00344 boolean sentUserInfo = false;
00345 try
00346 {
00347
00348 Socket socket = null;
00349 if (ssl == null)
00350 {
00351
00352 socket = new Socket(currentControllerConfig.getHostname(),
00353 currentControllerConfig.getPort());
00354 }
00355 else
00356 {
00357 SocketFactory sslFact = SocketFactoryFactory.createFactory(ssl);
00358 socket = sslFact.createSocket(currentControllerConfig.getHostname(),
00359 currentControllerConfig.getPort());
00360 }
00361
00362
00363
00364 socket.setTcpNoDelay(true);
00365
00366 CJDBCOutputStream out = new CJDBCOutputStream(socket);
00367
00368 out.writeInt(Commands.ProtocolVersion);
00369 out.writeUTF(currentDatabase);
00370 out.flush();
00371 sentVdbName = true;
00372
00373
00374 out.writeUTF(user);
00375 out.writeUTF(password);
00376 out.flush();
00377 sentUserInfo = true;
00378
00379 CJDBCInputStream in;
00380 boolean needSkeleton;
00381 AbstractBlobFilter filter = null;
00382 try
00383 {
00384
00385 in = new CJDBCInputStream(socket);
00386
00387 Object response = in.readObject();
00388 if (response instanceof Boolean)
00389 {
00390 needSkeleton = ((Boolean) response).booleanValue();
00391 String sfilter = in.readUTF();
00392 filter = AbstractBlobFilter.getBlobFilterInstance(sfilter);
00393 }
00394 else if (response instanceof SQLException)
00395 throw (SQLException) response;
00396 else
00397 throw new SQLException("Error during connection (received "
00398 + response + ")");
00399 }
00400 catch (IOException e)
00401 {
00402 currentControllerURL = null;
00403 throw new SQLException("Authentication failed");
00404 }
00405 return setParametersOnConnection(info, new Connection(this, socket, in,
00406 out, url, user, password, needSkeleton, filter));
00407 }
00408 catch (Exception re)
00409 {
00410 controllerConfig.remove(picked);
00411 retry--;
00412 if (retry == 0)
00413 {
00414 if (!sentVdbName)
00415 throw new SQLException("Unable to connect to controller on "
00416 + currentControllerConfig.getHostname() + ":"
00417 + currentControllerConfig.getPort() + " (" + re + ")");
00418 else if (!sentUserInfo)
00419 throw new SQLException(
00420 "Unable to connect to the virtual database (virtual database name is probably not correct)");
00421 else
00422 throw new SQLException(
00423 "Unable to connect to the virtual database (" + re + ")");
00424 }
00425 else
00426 {
00427 if (controllerConfig.isEmpty())
00428 currentControllerURL = null;
00429 }
00430 }
00431 }
00432 throw new SQLException(
00433 "Unable to connect to the virtual database - Unexpected error.");
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 public synchronized boolean acceptsURL(String url) throws SQLException
00447 {
00448 try
00449 {
00450 parseURL(url);
00451 return true;
00452 }
00453 catch (SQLException e)
00454 {
00455 return false;
00456 }
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466 synchronized Hashtable parseURL(String url) throws SQLException
00467 {
00468
00469 if (url == null)
00470 {
00471 throw new IllegalArgumentException(
00472 "Illegal null URL in parseURL(String) method");
00473 }
00474
00475 if (!url.toLowerCase().startsWith(CJDBC_URL_HEADER))
00476 throw new SQLException("Malformed header from URL '" + url
00477 + "' (expected '" + CJDBC_URL_HEADER + "')");
00478 else
00479 {
00480
00481 Hashtable result = new Hashtable();
00482
00483
00484 int nextSlash = url.indexOf('/', CJDBC_URL_HEADER_LENGTH);
00485 if (nextSlash == -1)
00486
00487 throw new SQLException("Malformed URL '" + url + "' (expected '"
00488 + CJDBC_URL_HEADER + "<hostname>/<database>')");
00489
00490
00491 int questionMark = url.indexOf('?', nextSlash);
00492 questionMark = (questionMark == -1)
00493 ? url.indexOf(';', nextSlash)
00494 : questionMark;
00495
00496 String controllerURLs = url.substring(CJDBC_URL_HEADER_LENGTH, nextSlash);
00497
00498 StringTokenizer controllers = new StringTokenizer(controllerURLs, ",",
00499 true);
00500 int tokenNumber = controllers.countTokens();
00501 ArrayList list = new ArrayList();
00502
00503 int i = 0;
00504 String s;
00505 boolean lastTokenWasComma = false;
00506 while (controllers.hasMoreTokens())
00507 {
00508 s = controllers.nextToken().trim();
00509 if (s.equals(","))
00510 {
00511 if (lastTokenWasComma || (i == 0) || (i == tokenNumber - 1))
00512
00513
00514 throw new SQLException("Syntax error in controller list '"
00515 + controllerURLs + "' from URL '" + url + "'");
00516 else
00517 {
00518 lastTokenWasComma = true;
00519 continue;
00520 }
00521 }
00522 lastTokenWasComma = false;
00523 list.add(parseController(s));
00524 i++;
00525 }
00526
00527 ControllerInfo[] controllerList = new ControllerInfo[i];
00528 for (int j = 0; j < i; j++)
00529 {
00530 controllerList[j] = (ControllerInfo) (list.get(j));
00531 }
00532
00533 result.put(CONTROLLER_PROPERTY, controllerList);
00534
00535
00536 String databaseName = (questionMark == -1) ? url.substring(nextSlash + 1,
00537 url.length()) : url.substring(nextSlash + 1, questionMark);
00538 Character c = validDatabaseName(databaseName);
00539 if (c != null)
00540 throw new SQLException(
00541 "Unable to validate database name (unacceptable character '" + c
00542 + "' in database '" + databaseName + "' from URL '" + url
00543 + "')");
00544
00545
00546 result.put(DATABASE_PROPERTY, databaseName);
00547
00548
00549 controllerCache.put(url, controllerList);
00550 dbNameCache.put(url, databaseName);
00551
00552
00553 Hashtable params = parseUrlParams(url);
00554 if (params != null)
00555 result.put(PARAMETER_PROPERTY, params);
00556 return result;
00557 }
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 private java.sql.Connection setParametersOnConnection(Properties props,
00575 org.objectweb.cjdbc.driver.Connection connection)
00576 {
00577 String booleanTrue = props.getProperty(BOOLEAN_TRUE_PROPERTY);
00578 if (booleanTrue != null)
00579 connection.setPreparedStatementBooleanTrue(booleanTrue);
00580 String booleanFalse = props.getProperty(BOOLEAN_FALSE_PROPERTY);
00581 if (booleanFalse != null)
00582 connection.setPreparedStatementBooleanFalse(booleanFalse);
00583 String escapeBaskslash = props.getProperty(ESCAPE_BACKSLASH_PROPERTY);
00584 if (escapeBaskslash != null)
00585 connection
00586 .setEscapeBackslash(new Boolean(escapeBaskslash).booleanValue());
00587 String escapeQuote = props.getProperty(ESCAPE_SINGLE_QUOTE_PROPERTY);
00588 if (escapeQuote != null)
00589 connection.setEscapeSingleQuote(new Boolean(escapeQuote).booleanValue());
00590
00591 String escapeChar = props.getProperty(ESCAPE_CHARACTER_PROPERTY);
00592 if (escapeChar != null)
00593 connection.setEscapeChar(escapeChar);
00594
00595 String driverProcessed = props.getProperty(DRIVER_PROCESSED_PROPERTY);
00596 if (driverProcessed != null)
00597 connection.setDriverProcessed(Boolean.valueOf(driverProcessed)
00598 .booleanValue());
00599
00600 return connection;
00601 }
00602
00603
00604
00605
00606
00607
00608
00609 protected ArrayList getControllerConfig()
00610 {
00611 return controllerConfig;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620 protected String getUrlFromProperties(Hashtable props)
00621 {
00622 StringBuffer sb = new StringBuffer();
00623 sb.append(CJDBC_URL_HEADER);
00624 ControllerInfo[] controllerList = (ControllerInfo[]) props
00625 .get(CONTROLLER_PROPERTY);
00626 for (int i = 0; i < controllerList.length; i++)
00627 {
00628 if (i == 0)
00629 sb.append(controllerList[i].toString());
00630 else
00631 sb.append("," + controllerList[i].toString());
00632 }
00633 sb.append("/" + props.get(DATABASE_PROPERTY));
00634 Hashtable params = (Hashtable) props.get(PARAMETER_PROPERTY);
00635 if (params != null)
00636 {
00637 Enumeration paramsKeys = params.keys();
00638 String element = null;
00639 while (paramsKeys.hasMoreElements())
00640 {
00641 if (element == null)
00642 sb.append("?");
00643 else
00644 sb.append("&");
00645 element = (String) paramsKeys.nextElement();
00646 sb.append(element + "=" + params.get(paramsKeys));
00647 }
00648 }
00649 return sb.toString();
00650 }
00651
00652 private Hashtable parseUrlParams(String url) throws SQLException
00653 {
00654 Hashtable props;
00655 props = parseUrlParams(url, '?', "&", "=");
00656 if (props == null)
00657 {
00658 props = parseUrlParams(url, ';', ";", "=");
00659 }
00660 return props;
00661 }
00662
00663 private Hashtable parseUrlParams(String url, char mark, String link,
00664 String equal) throws SQLException
00665 {
00666 int questionMark = url.indexOf(mark, url.lastIndexOf('/'));
00667 if (questionMark == -1)
00668 return null;
00669 else
00670 {
00671 Hashtable props = new Hashtable();
00672 String parameters = url.substring(questionMark + 1);
00673 StringTokenizer st1 = new StringTokenizer(parameters, link);
00674 while (st1.hasMoreTokens())
00675 {
00676 String param = st1.nextToken();
00677 StringTokenizer st2 = new StringTokenizer(param, equal);
00678 if (st2.hasMoreTokens())
00679 {
00680 try
00681 {
00682 String paramName = st2.nextToken();
00683 String paramValue = (st2.hasMoreTokens()) ? st2.nextToken() : "";
00684 props.put(paramName, paramValue);
00685 }
00686 catch (Exception e)
00687 {
00688 throw new SQLException("Invalid parameter in URL");
00689 }
00690 }
00691 }
00692 return props;
00693 }
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 private ControllerInfo parseController(String controller) throws SQLException
00705 {
00706 ControllerInfo controllerInfo = new ControllerInfo();
00707
00708
00709 StringTokenizer controllerURL = new StringTokenizer(controller, ":", true);
00710
00711
00712 controllerInfo.setHostname(controllerURL.nextToken());
00713 Character c = validHostname(controllerInfo.getHostname());
00714 if (c != null)
00715 throw new SQLException(
00716 "Unable to validate hostname (unacceptable character '" + c
00717 + "' in hostname '" + controllerInfo.getHostname()
00718 + "' from the URL part '" + controller + "')");
00719
00720 if (!controllerURL.hasMoreTokens())
00721 controllerInfo.setPort(ControllerConstants.DEFAULT_PORT);
00722 else
00723 {
00724 controllerURL.nextToken();
00725 if (!controllerURL.hasMoreTokens())
00726 controllerInfo.setPort(ControllerConstants.DEFAULT_PORT);
00727 else
00728 {
00729 String port = controllerURL.nextToken();
00730 if (controllerURL.hasMoreTokens())
00731 throw new SQLException(
00732 "Invalid controller definition with more than one semicolon in URL part '"
00733 + controller + "'");
00734
00735
00736 try
00737 {
00738 controllerInfo.setPort(Integer.parseInt(port));
00739 }
00740 catch (NumberFormatException ne)
00741 {
00742 throw new SQLException(
00743 "Unable to validate port number (unacceptable port number '"
00744 + port + "' in this URL part '" + controller + "')");
00745 }
00746 }
00747 }
00748 return controllerInfo;
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
00779 throws SQLException
00780 {
00781 DriverPropertyInfo hostProp = new DriverPropertyInfo(HOST_PROPERTY, info
00782 .getProperty(HOST_PROPERTY));
00783 hostProp.required = true;
00784 hostProp.description = HOST_PROPERTY_DESCRIPTION;
00785
00786 DriverPropertyInfo portProp = new DriverPropertyInfo(PORT_PROPERTY, info
00787 .getProperty(PORT_PROPERTY, Integer
00788 .toString(ControllerConstants.DEFAULT_PORT)));
00789 portProp.required = false;
00790 portProp.description = PORT_PROPERTY_DESCRIPTION;
00791
00792 DriverPropertyInfo databaseProp = new DriverPropertyInfo(DATABASE_PROPERTY,
00793 info.getProperty(DATABASE_PROPERTY));
00794 databaseProp.required = true;
00795 databaseProp.description = DATABASE_PROPERTY_DESCRIPTION;
00796
00797 DriverPropertyInfo userProp = new DriverPropertyInfo(USER_PROPERTY, info
00798 .getProperty(USER_PROPERTY));
00799 userProp.required = true;
00800 userProp.description = USER_PROPERTY_DESCRIPTION;
00801
00802 DriverPropertyInfo passwordProp = new DriverPropertyInfo(PASSWORD_PROPERTY,
00803 info.getProperty(PASSWORD_PROPERTY));
00804 passwordProp.required = true;
00805 passwordProp.description = PASSWORD_PROPERTY_DESCRIPTION;
00806
00807 DriverPropertyInfo escapeCharProp = new DriverPropertyInfo(
00808 ESCAPE_CHARACTER_PROPERTY, info.getProperty(ESCAPE_CHARACTER_PROPERTY));
00809 escapeCharProp.required = false;
00810 escapeCharProp.description = ESCAPE_CHARACTER_PROPERTY_DESCRIPTION;
00811
00812 DriverPropertyInfo escapeBackProp = new DriverPropertyInfo(
00813 ESCAPE_BACKSLASH_PROPERTY, info.getProperty(ESCAPE_BACKSLASH_PROPERTY));
00814 escapeBackProp.required = false;
00815 escapeBackProp.description = ESCAPE_BACKSLASH_PROPERTY_DESCRIPTION;
00816
00817 DriverPropertyInfo escapeSingleProp = new DriverPropertyInfo(
00818 ESCAPE_SINGLE_QUOTE_PROPERTY, info
00819 .getProperty(ESCAPE_SINGLE_QUOTE_PROPERTY));
00820 escapeSingleProp.required = false;
00821 escapeSingleProp.description = ESCAPE_SINGLE_QUOTE_PROPERTY_DESCRIPTION;
00822
00823 DriverPropertyInfo booleanFalseProp = new DriverPropertyInfo(
00824 BOOLEAN_FALSE_PROPERTY, info.getProperty(BOOLEAN_FALSE_PROPERTY));
00825 booleanFalseProp.required = false;
00826 booleanFalseProp.description = BOOLEAN_FALSE_PROPERTY_DESCRIPTION;
00827
00828 DriverPropertyInfo booleanTrueProp = new DriverPropertyInfo(
00829 BOOLEAN_TRUE_PROPERTY, info.getProperty(BOOLEAN_TRUE_PROPERTY));
00830 booleanTrueProp.required = false;
00831 booleanTrueProp.description = BOOLEAN_TRUE_PROPERTY_DESCRIPTION;
00832
00833 DriverPropertyInfo parseQueryProp = new DriverPropertyInfo(
00834 DRIVER_PROCESSED_PROPERTY, info.getProperty(DRIVER_PROCESSED_PROPERTY));
00835 escapeSingleProp.required = false;
00836 escapeSingleProp.description = DRIVER_PROCESSED_PROPERTY_DESCRIPTION;
00837
00838 return new DriverPropertyInfo[]{hostProp, portProp, databaseProp, userProp,
00839 passwordProp, escapeCharProp, escapeBackProp, escapeSingleProp,
00840 booleanFalseProp, booleanTrueProp, parseQueryProp};
00841 }
00842
00843
00844
00845
00846
00847
00848 public int getMajorVersion()
00849 {
00850 return MAJOR_VERSION;
00851 }
00852
00853
00854
00855
00856
00857
00858 public int getMinorVersion()
00859 {
00860 return MINOR_VERSION;
00861 }
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 public boolean jdbcCompliant()
00874 {
00875 return false;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 private static Character validHostname(String hostname)
00888 {
00889 char[] name = hostname.toCharArray();
00890 int size = hostname.length();
00891 char c;
00892
00893 char lastChar = ' ';
00894
00895 for (int i = 0; i < size; i++)
00896 {
00897 c = name[i];
00898
00899 if (c == '.' || c == '-')
00900 {
00901 if (lastChar == '.' || lastChar == '-' || (i == size - 1) || (i == 0))
00902 {
00903
00904
00905 return new Character(c);
00906 }
00907 }
00908 else
00909 {
00910 if (((c < '0') || (c > 'z') || ((c > '9') && (c < 'A')) || ((c > 'Z') && (c < 'a'))))
00911 {
00912 return new Character(c);
00913 }
00914 }
00915 lastChar = c;
00916 }
00917 return null;
00918 }
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 private static Character validDatabaseName(String databaseName)
00930 {
00931 char[] name = databaseName.toCharArray();
00932 int size = databaseName.length();
00933 char c;
00934
00935 for (int i = 0; i < size; i++)
00936 {
00937 c = name[i];
00938 if ((c < '0') || (c > 'z') || ((c > '9') && (c < 'A'))
00939 || ((c > 'Z') && (c < 'a')))
00940 return new Character(c);
00941 }
00942 return null;
00943 }
00944
00945
00946
00947
00948
00949
00950
00951
00952 public class ControllerInfo
00953 {
00954 String hostname;
00955 int port;
00956
00957
00958
00959
00960 public ControllerInfo()
00961 {
00962 }
00963
00964
00965
00966
00967
00968
00969 public String getHostname()
00970 {
00971 return hostname;
00972 }
00973
00974
00975
00976
00977
00978
00979 public int getPort()
00980 {
00981 return port;
00982 }
00983
00984
00985
00986
00987
00988
00989 public void setHostname(String string)
00990 {
00991 hostname = string;
00992 }
00993
00994
00995
00996
00997
00998
00999 public void setPort(int port)
01000 {
01001 this.port = port;
01002 }
01003
01004
01005
01006
01007 public String toString()
01008 {
01009 return hostname + ":" + port;
01010 }
01011 }
01012
01013 }