/*


    ========== licence begin GPL
    Copyright (C) 2002-2003 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


*/

package com.sap.dbtech.jdbc;

import java.io.*;
import java.sql.*;
import com.sap.dbtech.util.*;
import com.sap.dbtech.rte.comm.*;
import com.sap.dbtech.jdbc.exceptions.*;

/**
 *
 */
public class DriverSapDB
    implements java.sql.Driver
{
    static DriverSapDB driver = new DriverSapDB ();
    static JdbcCommFactory commFactory;
    static public boolean isJDBC20 = detectJDBC20 ();
    static VersionInfo jdbcDriverVersion;
    static final String protocolName_C = "jdbc:sapdb:";
    static final public String nativeCommunication_dllName_C = "sapdbcbin";
    static final String loadbinProperty_C = "com.sap.dbtech.jdbc.loadbin";
    static final String osNameProperty_C = "os.name";
    static final String osLinuxString_C = "Linux";
    static {
        loadDriver ();
    }
    static final String driverName_C = "SAP DB";
    public static final String sapdbEncodingC = "ISO8859_1";

    /*VM version*/
    public static final int JAVA_1_1 = 1001999;
    public static final int JAVA_1_2 = 1002999;
    public static final int JAVA_1_3 = 1003999;
    public static final int currentVMVersion = getVMVersion();

    static int getVMVersion()
    {
        try {
            String vers = System.getProperty("java.version");
            int startpos=vers.indexOf('1');
            if(startpos==-1) {
                return JAVA_1_3;
            }
            int endpos=vers.indexOf('.', startpos);
            if(endpos==-1) {
                return JAVA_1_3;
            }
            int major=Integer.parseInt(vers.substring(startpos, endpos));
            startpos=endpos+1;
            endpos=vers.indexOf('.', startpos);
            if(endpos==-1) {
                return JAVA_1_3;
            }
            int minor=Integer.parseInt(vers.substring(startpos, endpos));
            return major*1000000+minor*1000;
        } catch(NumberFormatException numberFormatEx) {
            return JAVA_1_3;
        } catch(java.security.AccessControlException ex) {
            return JAVA_1_2;
        }
    }

    // Property names
    static final String userName_C = "user";
    static final String passwordName_C = "password";
    static final String urlName_C = "url";
    static final String sqlmodeName_C = "sqlmode";
    static final String cachelimitName_C = "cachelimit";
    static final String timeoutName_C = "timeout";
    static final String isolationName_C = "isolation";
    static final String autocommitName_C = "autocommit";
    static final String traceName_C = "trace";
    static final String traceSize_C = "tracesize";
    static final String transportName_C = "transport";
    static final String cacheName_C = "cache";
    static final String cacheSizeName_C = "cachesize";
    static final String unicodeName_C = "unicode";
    static final String reconnect_C = "reconnect";
    static final String spaceoption_C = "spaceoption";
    static final String application_C = "application";
    static final String appversion_C = "appversion";
    static final String communicationtimeout_C = "communicationtimeout";
    static final String authentication_C = "authentication";
    static final String encrytption_C = "encryption";
    static final String useDefaultValueForUpdatableRS_C = "useDefaultValueForUpdatableRS";
    static final String connecttype_C = "connecttype";

    // internal information about connection
    static final String dburlName_C = "dburl";
    static final String dbName_C = "dbname";
    static final String sqlmodeOracle_C = "oracle";
    static final String niconnect_C  = "niconnect";

    // tracing and checks
    public static final boolean catchAllNotImplemented_C = false;

    /**
     * acceptsURL method comment.
     */
    public boolean acceptsURL(String url) throws java.sql.SQLException {
        boolean result = url.startsWith (protocolName_C);

        return result;
    }
    /**
     *
     * @return java.lang.String
     * @param host java.lang.String
     * @param dbname java.lang.String
     */
    final public static String buildURL (String host, String dbname) {
        return protocolName_C + "//" + host + "/" + dbname;
    }

    /**
     *
     * @return java.sql.Connection
     * @param user java.lang.String
     * @param pwd java.lang.String
     * @param host java.lang.String
     * @param dbname java.lang.String
     * @exception java.sql.SQLException The exception description.
     */
    final public static java.sql.Connection connect (String user, String pwd, String host, String dbname, String properties)
    throws SQLException
    {
        String url = buildURL (host, dbname);
        if ((properties != null) && (properties.length () > 0)) {
            url = url + "?" + properties;
        }
        java.util.Properties info = new java.util.Properties ();
        info.put(userName_C, user);
        info.put(passwordName_C, pwd);

        return singleton ().connect (url, info);
    }
    /**
     * connect method comment.
     */
    public java.sql.Connection connect(
        String url,
        java.util.Properties info)
    throws java.sql.SQLException
    {
        java.sql.Connection result;
        JdbcCommunication session = null;
        boolean wrapSession;

        if (!this.acceptsURL(url)) {
            return null;
        }
        url = this.parseURLProperties (url, info);
        wrapSession = openTrace (url, info);
        Tracer.print ("new Connection '"+ url+"'", info);
        try {
            session = this.openByURL (url, info);
        }
        catch (RTEException rteExc) {
            //rteExc.printStackTrace(System.out);
            if (wrapSession) {
               Tracer.println ("using "+session);
               Tracer.println ("=> FAILED");
            }
            throw new JDBCDriverException (MessageTranslator.translate(
                    MessageKey.ERROR_CONNECTRTEEXCEPTION,
                    url,
                    rteExc.getMessage()),
                this);
        }
        result = new ConnectionSapDB (session, info);
        if (wrapSession) {
           Tracer.println ("using "+session);
           Tracer.println ("=> " + result);
           result = new com.sap.dbtech.jdbc.trace.Connection (result);
        }
        return result;
    }
    /**
     *
     */
    final static public boolean
        openTrace (
        String url,
        java.util.Properties info)
    {
        boolean result = false;
        String trace = info.getProperty(traceName_C);
        if(trace == null){
          try {
            trace = System.getProperty("sapdbctrace");
          }
          catch (java.security.AccessControlException ignore) {}
        }
        long maxTraceSize;
        try {
          maxTraceSize = Long.parseLong(info.getProperty(traceSize_C));
        }
        catch (NumberFormatException ex) {
          maxTraceSize = Long.MAX_VALUE;
        }

//        if (trace == null) {
//            String context = Thread.currentThread().getContextClassLoader().toString();
//            try {
//                java.security.MessageDigest md5 = java.security.MessageDigest.getInstance("MD5");
//                byte [] data = md5.digest(context.getBytes());
//                context = Tracer.Hex2String(data);
//            } catch (Exception e) {
//            }
//            String osName = System.getProperty ("os.name", "<unknown>").toUpperCase();     
//            if ((osName != null) && osName.startsWith("WINDOWS")) {
//                trace="c://temp/MaxDBJDBCTrace_"+context+".prt";
//            } else{
//              trace="/tmp/MaxDBJDBCTrace_"+context+".prt";
//            }  
//        }
        if (trace != null) {
            result = true;
            try {
                Tracer.forceNewLog(trace, true, maxTraceSize);

            }
            catch (IOException ioExc) {
            }
            Tracer.println ("==================================");
            String java_version = "<unknown>";
            try {
              java_version = System.getProperty ("java.version", "<unknown>");
            }
            catch (java.security.AccessControlException ignore) {}
            Tracer.println (getVersionString () + " on Java " + java_version);
        }
        /*
         * extended trace for specific bugs
         */
        trace = info.getProperty ("extendedTrace");
        if (trace != null) {
            TimeoutException.addExtendedTrace(trace);
        }
        return result;
    }
    /**
     *
     * @return boolean
     * @param property java.lang.String
     */
    private static final String [] trueStrings = {
        "true", "yes", "on"
    };
    final public static boolean getBooleanProperty (
        java.util.Properties properties,
        String name,
        boolean defaultValue)
    {
        boolean result = defaultValue;
        String value;

        value = properties.getProperty(name);
        if (value != null) {
                result = false;
            for (int i = 0; i < trueStrings.length; ++i) {
                if (value.equalsIgnoreCase (trueStrings [i])) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
    /**
     *
     */
    final public static int
    getIntProperty (
        java.util.Properties properties,
        String name,
        int defaultValue)
    {
        int result = defaultValue;
        String value;

        value = properties.getProperty (name);
        if (value != null) {
            try {
                result = Integer.parseInt (value);
            }
            catch (NumberFormatException exc) {
                // ignore
            }
        }
        return result;
    }
    /**
     * getMajorVersion method comment.
     */
    final public int getMajorVersion() {
        return jdbcDriverVersion.getMajorVersion();
    }
    /**
     * getMinorVersion method comment.
     */
    final public int getMinorVersion() {
        return jdbcDriverVersion.getMinorVersion();
    }
    /**
     *
     * @return java.lang.String
     */
    final String getName () {
        return driverName_C;
    }
    /**
     * getPropertyInfo method comment.
     */
    final public DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info) throws SQLException {
        DriverPropertyInfo [] result;
        DriverPropertyInfo userItem = null;
        DriverPropertyInfo passwordItem = null;
        int count = 0;
        int i = 0;

        if (info.getProperty (userName_C) == null) {
            userItem = new DriverPropertyInfo (userName_C, null);
            userItem.required = true;
            ++count;
        }
        if (info.getProperty (passwordName_C) == null) {
            passwordItem = new DriverPropertyInfo (passwordName_C, null);
            passwordItem.required = true;
            ++count;
        }
        result = new DriverPropertyInfo [count];
        if (userItem != null) {
            result [i] = userItem;
            ++i;
        }
        if (passwordItem != null) {
            result [i] = passwordItem;
            ++i;
        }
        return result;
    }
    /**
     *
     * @return java.lang.String
     */
    final public static String getProtocol () {
        return protocolName_C;
    }
    /**
     *
     * @return java.lang.String
     */
    final public static String getVersionString () {
        return getStaticVersion ();
    }
    /**
     *
     */
    static public String
    getStaticVersion ()
    {
        return jdbcDriverVersion.toString();
    }
    /**
     * jdbcCompliant method comment.
     */
    final public boolean jdbcCompliant() {
        return true;
    }
    /**
     *
     */
    public static void load () {
    }
    /**
     *
     * @param args java.lang.String[]
     */
    public static void main(String args[]) {
        if (args.length > 0) {
          if ((args[0].equals ("-V")) || (args[0].equals ("--version"))) {
            System.out.println (getStaticVersion ());
          } else {
            java.util.Properties info = new java.util.Properties ();
            boolean hasUser = false;
            boolean hasDb = false;
            info.put("host","");
            info.put("options","");
            info.put("cmd","Select 'successfully connected' as \"connect test\" from dual");
            for (int i = 0; i < args.length; ++i) {
                String currentArg = args [i];
                if (currentArg.charAt (0) != '-') {
                    break;
                }
                char currentOpt = currentArg.charAt (1);
                switch (currentOpt) {
                case 'u':
                    ++i;
                    currentArg = args [i];
                    int pos = currentArg.indexOf (',');
                    info.put(userName_C, currentArg.substring (0, pos));
                    info.put(passwordName_C, currentArg.substring (pos + 1));
                    hasUser = true;
                    break;
                case 'd':
                    ++i;
                    info.put(dbName_C , args [i]);
                    hasDb = true;
                    break;
                case 'n':
                    ++i;
                    info.put("host" , args [i]);
                    break;
                case 'o':
                    ++i;
                    info.put("options", "?"+args [i]);
                    break;
                case 'c':
                    ++i;
                    info.put("cmd", args [i]);
                    break;
                default:
                    System.err.println ("invalid option " + currentOpt);
                    break;
                }
             }
             if (hasDb && hasUser){
               try {
                 Connection connection = new DriverSapDB().connect (DriverSapDB.buildURL((String)info.get("host"), (String)info.get(dbName_C))+info.get("options") , info);
                 Statement stmt = connection.createStatement ();
                 if (stmt.execute ((String)info.get("cmd"))){
                   ResultSet rs = stmt.getResultSet();
                   if (!rs.next ())
                     System.out.println ("row not found");
                   else{
                    ResultSetMetaData rsmd = rs.getMetaData();
                    StringBuffer res = new StringBuffer(50);
                    res.append("| ");
                    for (int i=1; i<=rsmd.getColumnCount(); i++){
                      String val = rsmd.getColumnName(i);
                      int    len = rsmd.getPrecision(i);
                      if (val.length()>len){
                        res.append(val.substring(0,len));
                      } else {
                        res.append(val);
                        for (int j=0; j < len-val.length();j++) res.append(" ");
                      }
                      res.append(" | ");
                    }
                    System.out.println(res.toString());
                    for (int j=1; j < res.length();j++) System.out.print("-");;
                    System.out.println("");
                    do{
                      res = new StringBuffer(res.capacity());
                      res.append("| ");
                      for (int i=1; i<=rsmd.getColumnCount(); i++){
                      String val = rs.getString(i);
                      int    len = rsmd.getPrecision(i);
                      if (val.length()>len){
                        res.append(val.substring(0,len));
                      } else {
                        res.append(val);
                        for (int j=0; j < len-val.length();j++) res.append(" ");
                      }
                      res.append(" | ");
                    }
                    System.out.println(res.toString());
                    }while(rs.next());
                   }
                 }else{
                   System.out.println (stmt.getUpdateCount() +" row(s) affected");
                 }
               }
               catch (Exception ex) {
                 ex.printStackTrace();
               }
            }
          } //else
        }
    }
    /**
     *
     * @return java.lang.String
     */
    static String mapIsolation (String isolationProperty)
    throws JDBCDriverException
    {
        int isolevel = -1;
        String result;

        try {
            isolevel = Integer.parseInt(isolationProperty);
        }
        catch (NumberFormatException exc1) {
            final String sapdbtechPrefix = "ADABAS";
            final String jdbcPrefix = "TRANSACTION_";
            if (isolationProperty.startsWith (sapdbtechPrefix)) {
                try {
                    isolevel = Integer.parseInt(
                        isolationProperty.substring (sapdbtechPrefix.length()));
                }
                catch (NumberFormatException exc2) {
                    // isolevel kept at invalid
                }
            }
            else if (isolationProperty.startsWith (jdbcPrefix)) {
                String rest = isolationProperty.substring (jdbcPrefix.length());
                if (rest.equals ("READ_UNCOMMITTED")) {
                    isolevel = Connection.TRANSACTION_READ_UNCOMMITTED;
                }
                else if (rest.equals ("READ_COMMITTED")) {
                    isolevel = Connection.TRANSACTION_READ_COMMITTED;
                }
                else if (rest.equals ("REPEATABLE_READ")) {
                    isolevel = Connection.TRANSACTION_REPEATABLE_READ;
                }
                else if (rest.equals ("SERIALIZABLE")) {
                    isolevel = Connection.TRANSACTION_SERIALIZABLE;
                }
            }
        }
        switch (isolevel) {
            case Connection.TRANSACTION_READ_UNCOMMITTED:
                result = "0";
                break;
            case Connection.TRANSACTION_READ_COMMITTED:
                result = "1";
                break;
            case Connection.TRANSACTION_REPEATABLE_READ:
                result = "2";
                break;
            case Connection.TRANSACTION_SERIALIZABLE:
                result = "3";
                break;
            default:
                throw new JDBCDriverException(MessageTranslator.translate(
                    MessageKey.ERROR_INVALIDTRANSACTIONISOLATION,
                    isolationProperty));
        }
        return result;
    }
    /**
     *
     */
    static int
    isolevelString2Jdbc (
        String isolationProperty)
    {
        int isolevel = -1;
        try {
            isolevel = Integer.parseInt(isolationProperty);
        }
        catch (NumberFormatException exc1) {
            final String sapdbtechPrefix = "ADABAS";
            final String jdbcPrefix = "TRANSACTION_";
            if (isolationProperty.startsWith (sapdbtechPrefix)) {
                try {
                    isolevel = Integer.parseInt(
                        isolationProperty.substring (sapdbtechPrefix.length()));
                }
                catch (NumberFormatException exc2) {
                    // isolevel kept at invalid
                }
            }
            else if (isolationProperty.startsWith (jdbcPrefix)) {
                String rest = isolationProperty.substring (jdbcPrefix.length());
                if (rest.equals ("READ_UNCOMMITTED")) {
                    isolevel = Connection.TRANSACTION_READ_UNCOMMITTED;
                }
                else if (rest.equals ("READ_COMMITTED")) {
                    isolevel = Connection.TRANSACTION_READ_COMMITTED;
                }
                else if (rest.equals ("REPEATABLE_READ")) {
                    isolevel = Connection.TRANSACTION_REPEATABLE_READ;
                }
                else if (rest.equals ("SERIALIZABLE")) {
                    isolevel = Connection.TRANSACTION_SERIALIZABLE;
                }
            }
        }
        return isolevel;
    }
    /**
     *
     */
    static String
    isolevelJdbc2native (
        int isolevel)
    throws SQLException
    {
        String result;
        switch (isolevel) {
            case Connection.TRANSACTION_NONE:
            case Connection.TRANSACTION_READ_UNCOMMITTED:
                result = "0";
                break;
            case Connection.TRANSACTION_READ_COMMITTED:
                result = "1";
                break;
            case Connection.TRANSACTION_REPEATABLE_READ:
                result = "2";
                break;
            case Connection.TRANSACTION_SERIALIZABLE:
                result = "3";
                break;
            default:
                throw new JDBCDriverException(MessageTranslator.translate(
                    MessageKey.ERROR_INVALIDTRANSACTIONISOLATION,
                    Integer.toString(isolevel)));
        }
        return result;
    }
    /**
     *
     * @return com.sap.dbtech.rte.comm.JdbcCommunication
     * @param url java.lang.String
     * @exception com.sap.dbtech.rte.comm.RTEException The exception description.
     */
    final private JdbcCommunication openByURL (
        String url,
        java.util.Properties info)
    throws RTEException, SQLException
    {
        int slashPos;
        int closingSlashPos;
        String host;
        String dbname;
        String dburl;
        int urlLength = url.length ();

        slashPos = protocolName_C.length ();
        if ((urlLength >= slashPos + 3)
            && url.substring (slashPos, slashPos + 2).equals ("//")) {
            String strippedUrl = url.substring (slashPos + 2);
            if (strippedUrl.startsWith("sapni:")){
                int endPattern = strippedUrl.indexOf(":inpas", 6);
                if (-1 == endPattern){
                  throw new ConnectionException( new SQLExceptionSapDB (MessageTranslator.translate(MessageKey.ERROR_WRONG_CONNECT_URL, "closing token \":inpas\" not found for SAP routerstring"),"0800",-709));
                }
                host = strippedUrl.substring(6, endPattern);
                dbname = strippedUrl.substring(endPattern + 7, strippedUrl.length());
                info.put(niconnect_C, "true");
                if (commFactory == SocketComm.factory) {
                    commFactory = NiCommunication.factory;
                }
            } else {
	            closingSlashPos = strippedUrl.indexOf ('/');
	            host = strippedUrl.substring (0, closingSlashPos);
	            dbname = strippedUrl.substring(closingSlashPos + 1, strippedUrl.length());
            }
        }
        else {
            host = "";
            dbname = url.substring (slashPos, urlLength).trim();
        }
        dbname = dbname.toUpperCase();
        dburl = buildURL (host, dbname);
        info.put (dburlName_C, dburl);
        info.put (dbName_C, dbname);
        return this.openConnection (host, dbname, info);
    }
    /**
     *
     */
    final private String
    parseURLProperties (
        String url,
        java.util.Properties info)
    {
        int questionPos;

        questionPos = url.indexOf ('?');
        if (questionPos >= 0) {
            this.parsePropertiesString (url.substring (questionPos + 1), info);
            url = url.substring (0, questionPos);
        }
        return url;
    }
    /**
     *
     * @return com.sap.dbtech.rte.comm.JdbcCommunication
     * @param host java.lang.String
     * @param dbname java.lang.String
     * @exception com.sap.dbtech.rte.comm.RTEException The exception description.
     */
    final public JdbcCommunication openConnection (
        String host,
        String dbname,
        java.util.Properties info)
    throws RTEException
    {
        JdbcCommFactory factory;
        JdbcCommunication result;
        String transport;
        if (getBooleanProperty(info, encrytption_C, false)){
          transport = "secure";
        } else {
          transport = info.getProperty (transportName_C, "socket");
        }

        if (transport.equals ("native")) {
            try {
              if (loadNativeCommunication() == nativeCommunication_enabled){
                  factory = NativeComm.factory;
              } else {
                  transport = "socket";                  
              }
            }  catch (Error linkErr) {
                throw new RTEException(MessageTranslator.translate
                    (MessageKey.ERROR_LIBRARYNOTLOADED, nativeCommunication_dllName_C, linkErr.toString()), -10899);
            }
            factory = NativeComm.factory;
        } else if (transport.equals ("socket")) {
            if (getBooleanProperty(info, niconnect_C, false)){
                factory = NiCommunication.factory;
            } else {
                factory = SocketComm.factory;
            }
        }
        else if(transport.equals ("secure")) {
            factory = SecureCommunication.factory;
        }
        else {
            throw new RTEException(MessageTranslator.translate
                (MessageKey.ERROR_INVALIDTRANSPORT, transport),
                                   -10899);
        }
        try {
            result = factory.open (host, dbname, info);
        }  catch (UnsatisfiedLinkError linkErr) {
            throw new RTEException(MessageTranslator.translate
                (MessageKey.ERROR_LIBRARYNOTLOADED, nativeCommunication_dllName_C, linkErr.toString()), -10899);
        }
        return result;
    }

    /**
     *
     * @return boolean
     * @param property java.lang.String
     */
    public static boolean parseBooleanProperty (String property) {
        boolean result = false;

        if (property.equalsIgnoreCase ("true")) {
            result = true;
        }
        return result;
    }
    /**
     *
     * @param urlArgs java.lang.String
     * @param info java.util.Properties
     */
    private void
    parsePropertiesString (
        String urlArgs,
        java.util.Properties info)
    {
        String [] args = StringUtil.split (urlArgs, "&");
        String arg;
        int assignPos;

        for (int i = 0; i < args.length; ++i) {
            arg = args [i];
            assignPos = arg.indexOf ('=');
            if (assignPos > 0) {
                info.put(arg.substring (0, assignPos), arg.substring (assignPos + 1));
            }
        }
    }
    /**
     *
     */
    public static DriverSapDB singleton () {
        return driver;
    }
    /**
     *
     */
    private static void switchTraces (String verbosity, String filename) {
        if (verbosity != null) {
            try {
                Tracer.setVerbosity (Integer.parseInt(verbosity));
            }
            catch (NumberFormatException exc) {
                // ignore
            }
        }
        if (filename != null) {
            try {
                Tracer.openLog (filename);
            }
            catch (IOException exc) {
                System.err.println ("SAP DBTech JDBC: Cannot open log " + filename);
            }
        }
    }
    /**
     *
     */
    private static void switchTracesByProperties (java.util.Properties info) {
        switchTraces (
            info.getProperty ("traceVerbosity"),
            info.getProperty ("traceFile"));
    }
    /**
     *
     */
    private static void
    loadDriver ()
    {
        //getDriverVersion
        jdbcDriverVersion = new com.sap.dbtech.util.VersionInfo(
           "com.sap.dbtech.jdbc", "package com.sap.dbtech.jdbc, SAP DB JDBC Driver, SAP AG, ");
        try {
            DriverManager.registerDriver (driver);
        }
        catch (SQLException sqlExc) {
            // ignore
        }
    }
    
    final static public int nativeCommunication_notInit = 1;
    final static public int nativeCommunication_enabled  = 2;
    final static public int nativeCommunication_disabled = 3;
    
    static private int nativeCommunication = nativeCommunication_notInit;
    
    static public int loadNativeCommunication() {
        if (nativeCommunication != nativeCommunication_notInit){
          return nativeCommunication;  
        }
        try {
            System.loadLibrary(nativeCommunication_dllName_C);
            nativeCommunication = nativeCommunication_enabled;
        } catch (java.security.AccessControlException exc) {
            nativeCommunication = nativeCommunication_disabled;
        } catch (java.lang.UnsatisfiedLinkError err) {
            try {
                System.loadLibrary(nativeCommunication_dllName_C + "32");
                nativeCommunication = nativeCommunication_enabled;
            } catch (java.lang.UnsatisfiedLinkError erro) {
                nativeCommunication = nativeCommunication_disabled;
            } catch (Error e) {
                nativeCommunication = nativeCommunication_disabled;
                throw e;
            }
        } catch (Error e) {
            nativeCommunication = nativeCommunication_disabled;
            throw e;  
        }
        return nativeCommunication;
    }
    /**
     *
     */
    private static boolean
    detectJDBC20 ()
    {
        boolean result;

        try {
            Class.forName ("java.sql.Clob");
            result = true;
        }
        catch (ClassNotFoundException exc) {
            result = false;
        }
        return result;
    }

    /**
     *
     */
    static public JdbcCommFactory
    getCommunicationFactory ()
    {
        return commFactory;
    }
}
