Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

DriverCompliance.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2004 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Emmanuel Cecchet. 
00022  * Contributor(s): ______________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.backend;
00026 
00027 import java.net.ConnectException;
00028 import java.sql.Connection;
00029 import java.sql.DatabaseMetaData;
00030 import java.sql.ResultSet;
00031 import java.sql.Statement;
00032 
00033 import org.objectweb.cjdbc.common.i18n.Translate;
00034 import org.objectweb.cjdbc.common.log.Trace;
00035 import org.objectweb.cjdbc.controller.connection.DriverManager;
00036 
00037 /**
00038  * This class checks if a given driver provides the mandatory features necessary
00039  * for C-JDBC.
00040  * 
00041  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00042  * @version 1.0
00043  */
00044 public class DriverCompliance
00045 {
00046   private boolean             isCompliant                 = false;
00047   private boolean             hasBeenTested               = false;
00048   private boolean             supportSetQueryTimeout      = false;
00049   private boolean             supportGetGeneratedKeys     = false;
00050   private boolean             supportGetColumnCount       = false;
00051   private boolean             supportGetColumnClassName   = false;
00052   private boolean             supportGetColumnTypeName    = false;
00053   private boolean             supportGetColumnType        = false;
00054   private boolean             supportGetColumnDisplaySize = false;
00055   private boolean             supportGetTableName         = false;
00056   private boolean             supportSetCursorName        = false;
00057   private boolean             supportSetFetchSize         = false;
00058   private boolean             supportSetMaxRows           = false;
00059 
00060   private Trace               logger;
00061 
00062   private static final int    TIMEOUT_VALUE               = 1000;
00063   private static final String DEFAULT_TEST_STATEMENT      = "select 1";
00064   private String              databaseProductName         = "C-JDBC";
00065 
00066   /**
00067    * Builds a new DriverCompliance object.
00068    * 
00069    * @param logger the logger to use
00070    */
00071   public DriverCompliance(Trace logger)
00072   {
00073     this.logger = logger;
00074   }
00075 
00076   /**
00077    * Check the driver compliance.
00078    * 
00079    * @param backendUrl the JDBC URL to connect to
00080    * @param login the user login
00081    * @param password the user password
00082    * @param driverPath path for driver
00083    * @param driverClassName class name for driver
00084    * @param connectionTestStatement SQL statement used to check if a connection
00085    *                    is still valid
00086    * @return true if the driver is C-JDBC compliant
00087    * @throws ConnectException if it is not possible to connect to the backend
00088    */
00089   public boolean complianceTest(String backendUrl, String login,
00090       String password, String driverPath, String driverClassName,
00091       String connectionTestStatement) throws ConnectException
00092   {
00093     if (hasBeenTested)
00094       return isCompliant;
00095 
00096     isCompliant = false;
00097 
00098     Connection c = null;
00099     try
00100     {
00101       c = DriverManager.getConnection(backendUrl, login, password, driverPath,
00102           driverClassName);
00103     }
00104     catch (Exception e)
00105     {
00106       logger.error(Translate.get("backend.driver.test.connection.failed", e));
00107       throw new ConnectException(e.getMessage());
00108     }
00109     if (logger.isDebugEnabled())
00110       logger.debug(Translate.get("backend.driver.test.connection.ok"));
00111 
00112     DatabaseMetaData connectionMetaData;
00113     try
00114     {
00115       connectionMetaData = c.getMetaData();
00116     }
00117     catch (Exception e)
00118     {
00119       logger.error(Translate.get("backend.driver.test.metadata.failed", e));
00120       return isCompliant;
00121     }
00122     if (logger.isDebugEnabled())
00123       logger.debug(Translate.get("backend.driver.test.metadata.ok"));
00124 
00125     try
00126     {
00127       this.databaseProductName = connectionMetaData.getDatabaseProductName();
00128       logger.info(Translate
00129           .get("backend.detected.as", this.databaseProductName));
00130     }
00131     catch (Exception e)
00132     {
00133       logger.warn(Translate.get(
00134           "backend.driver.test.database.productname.failed", e));
00135     }
00136 
00137     Statement s;
00138     try
00139     {
00140       s = c.createStatement();
00141     }
00142     catch (Exception e)
00143     {
00144       logger.error(Translate.get("backend.driver.test.statement.failed", e));
00145       return isCompliant;
00146     }
00147 
00148     try
00149     {
00150       if (connectionTestStatement == null)
00151       {
00152         if (logger.isDebugEnabled())
00153           logger.debug(Translate.get("backend.driver.using.default.statement",
00154               DEFAULT_TEST_STATEMENT));
00155         connectionTestStatement = DEFAULT_TEST_STATEMENT;
00156       }
00157       s.execute(connectionTestStatement);
00158     }
00159     catch (Exception e)
00160     {
00161       logger.error(Translate.get("backend.driver.test.statement.invalid",
00162           connectionTestStatement));
00163       return isCompliant;
00164     }
00165     if (logger.isDebugEnabled())
00166       logger.debug(Translate.get("backend.driver.test.statement.ok"));
00167 
00168     try
00169     {
00170       s.setCursorName("testcursor");
00171       supportSetCursorName = true;
00172       if (logger.isDebugEnabled())
00173         logger
00174             .debug(Translate.get("backend.driver.statement.setCursorName.ok"));
00175     }
00176     catch (Exception e1)
00177     {
00178       logger.warn(Translate
00179           .get("backend.driver.statement.setCursorName.failed"));
00180       supportSetMaxRows = false;
00181     }
00182 
00183     try
00184     {
00185       s.setFetchSize(25);
00186       supportSetFetchSize = true;
00187       if (logger.isDebugEnabled())
00188         logger.debug(Translate.get("backend.driver.statement.setFetchSize.ok"));
00189     }
00190     catch (Exception e1)
00191     {
00192       logger
00193           .warn(Translate.get("backend.driver.statement.setFetchSize.failed"));
00194       supportSetMaxRows = false;
00195     }
00196 
00197     try
00198     {
00199       s.setMaxRows(5);
00200       supportSetMaxRows = true;
00201       if (logger.isDebugEnabled())
00202         logger.debug(Translate.get("backend.driver.statement.setMaxRows.ok"));
00203     }
00204     catch (Exception e1)
00205     {
00206       logger.warn(Translate.get("backend.driver.statement.setMaxRows.failed"));
00207       supportSetMaxRows = false;
00208     }
00209 
00210     try
00211     {
00212       s.getGeneratedKeys();
00213       supportGetGeneratedKeys = true;
00214       if (logger.isDebugEnabled())
00215         logger.debug(Translate
00216             .get("backend.driver.statement.getGeneratedKeys.ok"));
00217     }
00218     catch (Exception e1)
00219     {
00220       logger.warn(Translate
00221           .get("backend.driver.statement.getGeneratedKeys.failed"));
00222       supportGetGeneratedKeys = false;
00223     }
00224     catch (AbstractMethodError e1)
00225     {
00226       logger.warn(Translate
00227           .get("backend.driver.statement.getGeneratedKeys.failed"));
00228       supportGetGeneratedKeys = false;
00229     }
00230     catch (java.lang.NoSuchMethodError e1)
00231     {
00232       logger.warn(Translate
00233           .get("backend.driver.statement.getGeneratedKeys.failed"));
00234       supportGetGeneratedKeys = false;
00235     }
00236 
00237     // Commented out:
00238     // A prepared statement can be sent to the DBMS right away to be compiled
00239     // Should fine a work around for this test.
00240 
00241     //    PreparedStatement ps;
00242     //    try
00243     //    {
00244     //      ps = c.prepareStatement("INSERT INTO versions VALUES (?,?)");
00245     //      ps.setInt(1, 10);
00246     //      ps.setString(2, "just a test");
00247     //    }
00248     //    catch (Exception e)
00249     //    {
00250     //      logger.warn(Translate.get("backend.driver.prepared.statement.failed"),
00251     // e);
00252     //    }
00253     //    if (logger.isDebugEnabled())
00254     //      logger.debug(Translate.get("backend.driver.prepared.statement.ok"));
00255 
00256     try
00257     {
00258       s.setQueryTimeout(TIMEOUT_VALUE);
00259       supportSetQueryTimeout = true;
00260     }
00261     catch (Exception e)
00262     {
00263       logger.warn(Translate.get("backend.driver.setQueryTimeout.failed", e));
00264     }
00265     if (supportSetQueryTimeout && logger.isDebugEnabled())
00266       logger.debug(Translate.get("backend.driver.setQueryTimeout.ok"));
00267 
00268     ResultSet rs;
00269     try
00270     {
00271       String[] types = {"TABLE", "VIEW"};
00272       rs = connectionMetaData.getTables(null, null, "%", types);
00273     }
00274     catch (Exception e)
00275     {
00276       logger
00277           .error(Translate.get("backend.driver.metadata.getTables.failed", e));
00278       return isCompliant;
00279     }
00280     if (logger.isDebugEnabled())
00281       logger.debug(Translate.get("backend.driver.metadata.getTables.ok"));
00282 
00283     java.sql.ResultSetMetaData rsMetaData;
00284     try
00285     {
00286       rsMetaData = rs.getMetaData();
00287     }
00288     catch (Exception e)
00289     {
00290       logger.error(Translate.get("backend.driver.resultset.getMetaData.failed",
00291           e));
00292       return isCompliant;
00293     }
00294     if (logger.isDebugEnabled())
00295       logger.debug(Translate.get("backend.driver.resultset.getMetaData.ok"));
00296 
00297     try
00298     {
00299       if (rs.next())
00300       {
00301         rs.getObject(1);
00302       }
00303       else
00304         logger.warn(Translate.get("backend.driver.resultset.getObject.unable"));
00305     }
00306     catch (Exception e)
00307     {
00308       logger.error(Translate
00309           .get("backend.driver.resultset.getObject.failed", e));
00310       return isCompliant;
00311     }
00312     if (logger.isDebugEnabled())
00313       logger.debug(Translate.get("backend.driver.resultset.getObject.ok"));
00314 
00315     try
00316     {
00317       rsMetaData.getColumnCount();
00318       supportGetColumnCount = true;
00319     }
00320     catch (Exception e)
00321     {
00322       logger.error(Translate
00323           .get("backend.driver.metadata.getColumnCount.failed"));
00324       return isCompliant;
00325     }
00326     if (supportGetColumnCount && logger.isDebugEnabled())
00327       logger.debug(Translate.get("backend.driver.metadata.getColumnCount.ok"));
00328 
00329     try
00330     {
00331       rsMetaData.getColumnName(1);
00332     }
00333     catch (Exception e)
00334     {
00335       logger.error(Translate
00336           .get("backend.driver.metadata.getColumnName.failed"));
00337       return isCompliant;
00338     }
00339     if (logger.isDebugEnabled())
00340       logger.debug(Translate.get("backend.driver.metadata.getColumnName.ok"));
00341 
00342     try
00343     {
00344       rsMetaData.getTableName(1);
00345       supportGetTableName = true;
00346     }
00347     catch (Exception e)
00348     {
00349       logger.warn(Translate.get("backend.driver.metadata.getTableName.failed",
00350           e));
00351     }
00352 
00353     if (supportGetTableName && logger.isDebugEnabled())
00354       logger.debug(Translate.get("backend.driver.metadata.getTableName.ok"));
00355 
00356     try
00357     {
00358       rsMetaData.getColumnDisplaySize(1);
00359       supportGetColumnDisplaySize = true;
00360     }
00361     catch (Exception e)
00362     {
00363       logger.warn(Translate.get(
00364           "backend.driver.metadata.getColumnDisplaySize.failed", e));
00365     }
00366     if (supportGetColumnDisplaySize && logger.isDebugEnabled())
00367       logger.debug(Translate
00368           .get("backend.driver.metadata.getColumnDisplaySize.ok"));
00369 
00370     try
00371     {
00372       rsMetaData.getColumnType(1);
00373       supportGetColumnType = true;
00374     }
00375     catch (Exception e)
00376     {
00377       logger.warn(Translate.get("backend.driver.metadata.getColumnType.failed",
00378           e));
00379     }
00380     if (supportGetColumnType && logger.isDebugEnabled())
00381       logger.debug(Translate.get("backend.driver.metadata.getColumnType.ok"));
00382 
00383     try
00384     {
00385       rsMetaData.getColumnTypeName(1);
00386       supportGetColumnTypeName = true;
00387     }
00388     catch (Exception e)
00389     {
00390       logger.warn(Translate.get(
00391           "backend.driver.metadata.getColumnTypeName.failed", e));
00392     }
00393     if (supportGetColumnTypeName && logger.isDebugEnabled())
00394       logger.debug(Translate
00395           .get("backend.driver.metadata.getColumnTypeName.ok"));
00396 
00397     try
00398     {
00399       rsMetaData.getColumnClassName(1);
00400       supportGetColumnClassName = true;
00401     }
00402     catch (Exception e)
00403     {
00404       logger.warn(Translate.get(
00405           "backend.driver.metadata.getColumnClassName.failed", e));
00406     }
00407     if (supportGetColumnClassName && logger.isDebugEnabled())
00408       logger.debug(Translate
00409           .get("backend.driver.metadata.getColumnClassName.ok"));
00410 
00411     isCompliant = true;
00412     hasBeenTested = true;
00413     return isCompliant;
00414   }
00415 
00416   /**
00417    * @return true if the driver is compliant to the C-JDBC requirements
00418    */
00419   public boolean isCompliant()
00420   {
00421     return isCompliant;
00422   }
00423 
00424   /**
00425    * @return true if the driver supports getGeneratedKeys
00426    */
00427   public boolean supportGetGeneratedKeys()
00428   {
00429     return supportGetGeneratedKeys;
00430   }
00431 
00432   /**
00433    * @return true if the driver supports getColumnClassName
00434    */
00435   public boolean supportGetColumnClassName()
00436   {
00437     return supportGetColumnClassName;
00438   }
00439 
00440   /**
00441    * @return true if the driver supports getColumnCount
00442    */
00443   public boolean supportGetColumnCount()
00444   {
00445     return supportGetColumnCount;
00446   }
00447 
00448   /**
00449    * @return true if the driver supports getColumnDisplaySize
00450    */
00451   public boolean supportGetColumnDisplaySize()
00452   {
00453     return supportGetColumnDisplaySize;
00454   }
00455 
00456   /**
00457    * @return true if the driver supports getColumnType
00458    */
00459   public boolean supportGetColumnType()
00460   {
00461     return supportGetColumnType;
00462   }
00463 
00464   /**
00465    * @return true if the driver supports getColumnTypeName
00466    */
00467   public boolean supportGetColumnTypeName()
00468   {
00469     return supportGetColumnTypeName;
00470   }
00471 
00472   /**
00473    * @return true if the driver supports getTableName
00474    */
00475   public boolean supportGetTableName()
00476   {
00477     return supportGetTableName;
00478   }
00479 
00480   /**
00481    * @return true if the driver supports setQueryTimeout
00482    */
00483   public boolean supportSetQueryTimeout()
00484   {
00485     return supportSetQueryTimeout;
00486   }
00487 
00488   /**
00489    * @return true if the driver supports Statement.setMaxRows
00490    */
00491   public boolean supportSetMaxRows()
00492   {
00493     return supportSetMaxRows;
00494   }
00495 
00496   /**
00497    * Returns the supportSetCursorName value.
00498    * 
00499    * @return Returns the supportSetCursorName.
00500    */
00501   public boolean supportSetCursorName()
00502   {
00503     return supportSetCursorName;
00504   }
00505 
00506   /**
00507    * Returns the supportSetFetchSize value.
00508    * 
00509    * @return Returns the supportSetFetchSize.
00510    */
00511   public boolean supportSetFetchSize()
00512   {
00513     return supportSetFetchSize;
00514   }
00515 
00516   /**
00517    * Returns the databaseProductName value.
00518    * 
00519    * @return Returns the databaseProductName.
00520    */
00521   public String getDatabaseProductName()
00522   {
00523     return this.databaseProductName;
00524   }
00525 }

Generated on Mon Apr 11 22:01:31 2005 for C-JDBC by  doxygen 1.3.9.1