LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/connectivity/source/drivers/jdbc - JConnection.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 398 0.0 %
Date: 2013-07-09 Functions: 0 45 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "java/sql/Connection.hxx"
      22             : #include "java/lang/Class.hxx"
      23             : #include "java/tools.hxx"
      24             : #include "java/ContextClassLoader.hxx"
      25             : #include "java/sql/DatabaseMetaData.hxx"
      26             : #include "java/sql/JStatement.hxx"
      27             : #include "java/sql/Driver.hxx"
      28             : #include "java/sql/PreparedStatement.hxx"
      29             : #include "java/sql/CallableStatement.hxx"
      30             : #include "java/sql/SQLWarning.hxx"
      31             : #include <com/sun/star/lang/DisposedException.hpp>
      32             : #include <com/sun/star/sdbc/SQLWarning.hpp>
      33             : #include <com/sun/star/beans/NamedValue.hpp>
      34             : #include "connectivity/sqlparse.hxx"
      35             : #include "connectivity/dbexception.hxx"
      36             : #include "java/util/Property.hxx"
      37             : #include "java/LocalRef.hxx"
      38             : #include "resource/jdbc_log.hrc"
      39             : #include "com/sun/star/uno/XComponentContext.hpp"
      40             : #include "jvmaccess/classpath.hxx"
      41             : #include <comphelper/namedvaluecollection.hxx>
      42             : #include <rtl/ustrbuf.hxx>
      43             : #include <jni.h>
      44             : #include "resource/common_res.hrc"
      45             : #include <unotools/confignode.hxx>
      46             : 
      47             : #include <list>
      48             : #include <memory>
      49             : 
      50             : using namespace connectivity;
      51             : using namespace connectivity::jdbc;
      52             : using namespace ::com::sun::star::uno;
      53             : using namespace ::com::sun::star::beans;
      54             : using namespace ::com::sun::star::sdbc;
      55             : using namespace ::com::sun::star::container;
      56             : using namespace ::com::sun::star::lang;
      57             : 
      58             : namespace {
      59             : 
      60           0 : struct ClassMapEntry {
      61           0 :     ClassMapEntry(
      62             :         OUString const & theClassPath, OUString const & theClassName):
      63             :         classPath(theClassPath), className(theClassName), classLoader(NULL),
      64           0 :         classObject(NULL) {}
      65             : 
      66             :     OUString classPath;
      67             :     OUString className;
      68             :     jweak classLoader;
      69             :     jweak classObject;
      70             : };
      71             : 
      72             : typedef std::list< ClassMapEntry > ClassMap;
      73             : 
      74           0 : struct ClassMapData {
      75             :     osl::Mutex mutex;
      76             : 
      77             :     ClassMap map;
      78             : };
      79             : 
      80             : struct ClassMapDataInit {
      81           0 :     ClassMapData * operator()() {
      82           0 :         static ClassMapData instance;
      83           0 :         return &instance;
      84             :     }
      85             : };
      86             : 
      87             : template < typename T >
      88           0 : bool getLocalFromWeakRef( jweak& _weak, LocalRef< T >& _inout_local )
      89             : {
      90           0 :     _inout_local.set( static_cast< T >( _inout_local.env().NewLocalRef( _weak ) ) );
      91             : 
      92           0 :     if ( !_inout_local.is() )
      93             :     {
      94           0 :         if ( _inout_local.env().ExceptionCheck())
      95             :         {
      96           0 :             return false;
      97             :         }
      98           0 :         else if ( _weak != NULL )
      99             :         {
     100           0 :             _inout_local.env().DeleteWeakGlobalRef( _weak );
     101           0 :             _weak = NULL;
     102             :         }
     103             :     }
     104           0 :     return true;
     105             : }
     106             : 
     107             : // Load a class.  A map from pairs of (classPath, name) to pairs of weak Java
     108             : // references to (ClassLoader, Class) is maintained, so that a class is only
     109             : // loaded once.
     110             : //
     111             : // It may happen that the weak reference to the ClassLoader becomes null while
     112             : // the reference to the Class remains non-null (in case the Class was actually
     113             : // loaded by some parent of the ClassLoader), in which case the ClassLoader is
     114             : // resurrected (which cannot cause any classes to be loaded multiple times, as
     115             : // the ClassLoader is no longer reachable, so no classes it has ever loaded are
     116             : // still reachable).
     117             : //
     118             : // Similarly, it may happen that the weak reference to the Class becomes null
     119             : // while the reference to the ClassLoader remains non-null, in which case the
     120             : // Class is simply re-loaded.
     121             : //
     122             : // This code is close to the implementation of jvmaccess::ClassPath::loadClass
     123             : // in jvmaccess/classpath.hxx, but not close enough to avoid the duplication.
     124             : //
     125             : // If false is returned, a (still pending) JNI exception occurred.
     126           0 : bool loadClass(
     127             :     Reference< XComponentContext > const & context, JNIEnv& environment,
     128             :     OUString const & classPath, OUString const & name,
     129             :     LocalRef< jobject > * classLoaderPtr, LocalRef< jclass > * classPtr)
     130             : {
     131             :     OSL_ASSERT(classLoaderPtr != NULL);
     132             :     // For any jweak entries still present in the map upon destruction,
     133             :     // DeleteWeakGlobalRef is not called (which is a leak):
     134             :     ClassMapData * d =
     135             :         rtl_Instance< ClassMapData, ClassMapDataInit, osl::MutexGuard,
     136             :         osl::GetGlobalMutex >::create(
     137           0 :             ClassMapDataInit(), osl::GetGlobalMutex());
     138           0 :     osl::MutexGuard g(d->mutex);
     139           0 :     ClassMap::iterator i(d->map.begin());
     140           0 :     LocalRef< jobject > cloader(environment);
     141           0 :     LocalRef< jclass > cl(environment);
     142             :     // Prune dangling weak references from the list while searching for a match,
     143             :     // so that the list cannot grow unbounded:
     144           0 :     for (; i != d->map.end();)
     145             :     {
     146           0 :         LocalRef< jobject > classLoader( environment );
     147           0 :         if ( !getLocalFromWeakRef( i->classLoader, classLoader ) )
     148           0 :             return false;
     149             : 
     150           0 :         LocalRef< jclass > classObject( environment );
     151           0 :         if ( !getLocalFromWeakRef( i->classObject, classObject ) )
     152           0 :             return false;
     153             : 
     154           0 :         if ( !classLoader.is() && !classObject.is() )
     155             :         {
     156           0 :             i = d->map.erase(i);
     157             :         }
     158           0 :         else if ( i->classPath == classPath && i->className == name )
     159             :         {
     160           0 :             cloader.set( classLoader.release() );
     161           0 :             cl.set( classObject.release() );
     162           0 :             break;
     163             :         }
     164             :         else
     165             :         {
     166           0 :             ++i;
     167             :         }
     168           0 :     }
     169           0 :     if ( !cloader.is() || !cl.is() )
     170             :     {
     171           0 :         if ( i == d->map.end() )
     172             :         {
     173             :             // Push a new ClassMapEntry (which can potentially fail) before
     174             :             // loading the class, so that it never happens that a class is
     175             :             // loaded but not added to the map (which could have effects on the
     176             :             // JVM that are not easily undone).  If the pushed ClassMapEntry is
     177             :             // not used after all (return false, etc.) it will be pruned on next
     178             :             // call because its classLoader/classObject are null:
     179           0 :             d->map.push_front( ClassMapEntry( classPath, name ) );
     180           0 :             i = d->map.begin();
     181             :         }
     182             : 
     183           0 :         LocalRef< jclass > clClass( environment );
     184           0 :         clClass.set( environment.FindClass( "java/net/URLClassLoader" ) );
     185           0 :         if ( !clClass.is() )
     186           0 :             return false;
     187             : 
     188           0 :         jweak wcloader = NULL;
     189           0 :         if (!cloader.is())
     190             :         {
     191           0 :             jmethodID ctorLoader( environment.GetMethodID( clClass.get(), "<init>", "([Ljava/net/URL;)V" ) );
     192           0 :             if (ctorLoader == NULL)
     193           0 :                 return false;
     194             : 
     195           0 :             LocalRef< jobjectArray > arr( environment );
     196           0 :             arr.set( jvmaccess::ClassPath::translateToUrls( context, &environment, classPath ) );
     197           0 :             if ( !arr.is() )
     198           0 :                 return false;
     199             : 
     200             :             jvalue arg;
     201           0 :             arg.l = arr.get();
     202           0 :             cloader.set( environment.NewObjectA( clClass.get(), ctorLoader, &arg ) );
     203           0 :             if ( !cloader.is() )
     204           0 :                 return false;
     205             : 
     206           0 :             wcloader = environment.NewWeakGlobalRef( cloader.get() );
     207           0 :             if ( wcloader == NULL )
     208           0 :                 return false;
     209             :         }
     210             : 
     211           0 :         jweak wcl = NULL;
     212           0 :         if ( !cl.is() )
     213             :         {
     214           0 :             jmethodID methLoadClass( environment.GetMethodID( clClass.get(), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;" ) );
     215           0 :             if ( methLoadClass == NULL )
     216           0 :                 return false;
     217             : 
     218           0 :             LocalRef< jstring > str( environment );
     219           0 :             str.set( convertwchar_tToJavaString( &environment, name ) );
     220           0 :             if ( !str.is() )
     221           0 :                 return false;
     222             : 
     223             :             jvalue arg;
     224           0 :             arg.l = str.get();
     225           0 :             cl.set( static_cast< jclass >( environment.CallObjectMethodA( cloader.get(), methLoadClass, &arg ) ) );
     226           0 :             if ( !cl.is() )
     227           0 :                 return false;
     228             : 
     229           0 :             wcl = environment.NewWeakGlobalRef( cl.get() );
     230           0 :             if ( wcl == NULL )
     231           0 :                 return false;
     232             :         }
     233             : 
     234           0 :         if ( wcloader != NULL)
     235             :         {
     236           0 :             i->classLoader = wcloader;
     237             :         }
     238           0 :         if ( wcl != NULL )
     239             :         {
     240           0 :             i->classObject = wcl;
     241           0 :         }
     242             :     }
     243             : 
     244           0 :     classLoaderPtr->set( cloader.release() );
     245           0 :     classPtr->set( cl.release() );
     246           0 :     return true;
     247             : }
     248             : 
     249             : }
     250             : 
     251             : //------------------------------------------------------------------------------
     252           0 : IMPLEMENT_SERVICE_INFO(java_sql_Connection,"com.sun.star.sdbcx.JConnection","com.sun.star.sdbc.Connection");
     253             : //------------------------------------------------------------------------------
     254             : //**************************************************************
     255             : //************ Class: java.sql.Connection
     256             : //**************************************************************
     257             : jclass java_sql_Connection::theClass = 0;
     258             : 
     259           0 : java_sql_Connection::java_sql_Connection( const java_sql_Driver& _rDriver )
     260             :     :java_lang_Object()
     261             :     ,OSubComponent<java_sql_Connection, java_sql_Connection_BASE>((::cppu::OWeakObject*)(&_rDriver), this)
     262           0 :     ,m_xContext( _rDriver.getContext() )
     263             :     ,m_pDriver( &_rDriver )
     264             :     ,m_pDriverobject(NULL)
     265             :     ,m_pDriverClassLoader()
     266             :     ,m_Driver_theClass(NULL)
     267           0 :     ,m_aLogger( _rDriver.getLogger() )
     268             :     ,m_bParameterSubstitution(sal_False)
     269             :     ,m_bIgnoreDriverPrivileges(sal_True)
     270           0 :     ,m_bIgnoreCurrency(sal_False)
     271             : {
     272           0 : }
     273             : // -----------------------------------------------------------------------------
     274           0 : java_sql_Connection::~java_sql_Connection()
     275             : {
     276           0 :     ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM();
     277           0 :     if ( xTest.is() )
     278             :     {
     279           0 :         SDBThreadAttach t;
     280           0 :         clearObject(*t.pEnv);
     281             : 
     282             :         {
     283           0 :             if ( m_pDriverobject )
     284           0 :                 t.pEnv->DeleteGlobalRef( m_pDriverobject );
     285           0 :             m_pDriverobject = NULL;
     286           0 :             if ( m_Driver_theClass )
     287           0 :                 t.pEnv->DeleteGlobalRef( m_Driver_theClass );
     288           0 :             m_Driver_theClass = NULL;
     289             :         }
     290           0 :         t.releaseRef();
     291           0 :     }
     292           0 : }
     293             : //-----------------------------------------------------------------------------
     294           0 : void SAL_CALL java_sql_Connection::release() throw()
     295             : {
     296           0 :     relase_ChildImpl();
     297           0 : }
     298             : //------------------------------------------------------------------------------
     299           0 : void java_sql_Connection::disposing()
     300             : {
     301           0 :     ::osl::MutexGuard aGuard(m_aMutex);
     302             : 
     303           0 :     m_aLogger.log( LogLevel::INFO, STR_LOG_SHUTDOWN_CONNECTION );
     304             : 
     305           0 :     dispose_ChildImpl();
     306           0 :     java_sql_Connection_BASE::disposing();
     307             : 
     308           0 :     if ( object )
     309             :     {
     310             :         static jmethodID mID(NULL);
     311           0 :         callVoidMethod("close",mID);
     312           0 :     }
     313           0 : }
     314             : // -------------------------------------------------------------------------
     315           0 : jclass java_sql_Connection::getMyClass() const
     316             : {
     317             :     // the class must be fetched only once, therefore static
     318           0 :     if( !theClass )
     319           0 :         theClass = findMyClass("java/sql/Connection");
     320           0 :     return theClass;
     321             : }
     322             : 
     323             : // -------------------------------------------------------------------------
     324           0 : OUString SAL_CALL java_sql_Connection::getCatalog(  ) throw(SQLException, RuntimeException)
     325             : {
     326           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     327           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     328             : 
     329             :     static jmethodID mID(NULL);
     330           0 :     return callStringMethod("getCatalog",mID);
     331             : }
     332             : // -------------------------------------------------------------------------
     333           0 : Reference< XDatabaseMetaData > SAL_CALL java_sql_Connection::getMetaData(  ) throw(SQLException, RuntimeException)
     334             : {
     335           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     336           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     337             : 
     338             : 
     339           0 :     Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
     340           0 :     if(!xMetaData.is())
     341             :     {
     342           0 :         SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     343             :         static jmethodID mID(NULL);
     344           0 :         jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/DatabaseMetaData;", mID);
     345           0 :         if(out)
     346             :         {
     347           0 :             xMetaData = new java_sql_DatabaseMetaData( t.pEnv, out, *this );
     348           0 :             m_xMetaData = xMetaData;
     349           0 :         }
     350             :     }
     351             : 
     352           0 :     return xMetaData;
     353             : }
     354             : // -------------------------------------------------------------------------
     355           0 : void SAL_CALL java_sql_Connection::close(  ) throw(SQLException, RuntimeException)
     356             : {
     357           0 :     dispose();
     358           0 : }
     359             : // -------------------------------------------------------------------------
     360           0 : void SAL_CALL java_sql_Connection::commit(  ) throw(SQLException, RuntimeException)
     361             : {
     362             :     static jmethodID mID(NULL);
     363           0 :     callVoidMethod("commit",mID);
     364           0 : }
     365             : // -------------------------------------------------------------------------
     366           0 : sal_Bool SAL_CALL java_sql_Connection::isClosed(  ) throw(SQLException, RuntimeException)
     367             : {
     368           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     369             : 
     370             :     static jmethodID mID(NULL);
     371           0 :     return callBooleanMethod( "isClosed", mID ) && java_sql_Connection_BASE::rBHelper.bDisposed;
     372             : }
     373             : // -------------------------------------------------------------------------
     374           0 : sal_Bool SAL_CALL java_sql_Connection::isReadOnly(  ) throw(SQLException, RuntimeException)
     375             : {
     376           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     377           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     378             :     static jmethodID mID(NULL);
     379           0 :     return callBooleanMethod( "isReadOnly", mID );
     380             : }
     381             : // -------------------------------------------------------------------------
     382           0 : void SAL_CALL java_sql_Connection::setCatalog( const OUString& catalog ) throw(SQLException, RuntimeException)
     383             : {
     384             :     static jmethodID mID(NULL);
     385           0 :     callVoidMethodWithStringArg("setCatalog",mID,catalog);
     386           0 : }
     387             : // -------------------------------------------------------------------------
     388           0 : void SAL_CALL java_sql_Connection::rollback(  ) throw(SQLException, RuntimeException)
     389             : {
     390             :     static jmethodID mID(NULL);
     391           0 :     callVoidMethod("rollback",mID);
     392           0 : }
     393             : // -------------------------------------------------------------------------
     394           0 : sal_Bool SAL_CALL java_sql_Connection::getAutoCommit(  ) throw(SQLException, RuntimeException)
     395             : {
     396             :     static jmethodID mID(NULL);
     397           0 :     return callBooleanMethod( "getAutoCommit", mID );
     398             : }
     399             : // -------------------------------------------------------------------------
     400           0 : void SAL_CALL java_sql_Connection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
     401             : {
     402             :     static jmethodID mID(NULL);
     403           0 :     callVoidMethodWithBoolArg("setReadOnly",mID,readOnly);
     404           0 : }
     405             : // -------------------------------------------------------------------------
     406           0 : void SAL_CALL java_sql_Connection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
     407             : {
     408             :     static jmethodID mID(NULL);
     409           0 :     callVoidMethodWithBoolArg("setAutoCommit",mID,autoCommit);
     410           0 : }
     411             : // -------------------------------------------------------------------------
     412           0 : Reference< ::com::sun::star::container::XNameAccess > SAL_CALL java_sql_Connection::getTypeMap(  ) throw(SQLException, RuntimeException)
     413             : {
     414           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     415           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     416             : 
     417           0 :     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     418             :     static jmethodID mID(NULL);
     419           0 :     callObjectMethod(t.pEnv,"getTypeMap","()Ljava/util/Map;", mID);
     420             :     // WARNING: the caller becomes the owner of the returned pointer
     421           0 :     return 0;
     422             : }
     423             : // -------------------------------------------------------------------------
     424           0 : void SAL_CALL java_sql_Connection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
     425             : {
     426           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     427           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     428             : 
     429           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
     430           0 : }
     431             : 
     432             : // -------------------------------------------------------------------------
     433           0 : sal_Int32 SAL_CALL java_sql_Connection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
     434             : {
     435           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     436           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     437             : 
     438             :     static jmethodID mID(NULL);
     439           0 :     return callIntMethod("getTransactionIsolation",mID);
     440             : }
     441             : // -------------------------------------------------------------------------
     442           0 : void SAL_CALL java_sql_Connection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
     443             : {
     444           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     445           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     446             : 
     447             :     static jmethodID mID(NULL);
     448           0 :     callVoidMethodWithIntArg("setTransactionIsolation",mID,level);
     449           0 : }
     450             : // -------------------------------------------------------------------------
     451           0 : Reference< XStatement > SAL_CALL java_sql_Connection::createStatement(  ) throw(SQLException, RuntimeException)
     452             : {
     453           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     454           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     455           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATE_STATEMENT );
     456             : 
     457           0 :     SDBThreadAttach t;
     458           0 :     java_sql_Statement* pStatement = new java_sql_Statement( t.pEnv, *this );
     459           0 :     Reference< XStatement > xStmt = pStatement;
     460           0 :     m_aStatements.push_back( WeakReferenceHelper( xStmt ) );
     461             : 
     462           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATED_STATEMENT_ID, pStatement->getStatementObjectID() );
     463           0 :     return xStmt;
     464             : }
     465             : // -----------------------------------------------------------------------------
     466           0 : OUString java_sql_Connection::transFormPreparedStatement(const OUString& _sSQL)
     467             : {
     468           0 :     OUString sSqlStatement = _sSQL;
     469           0 :     if ( m_bParameterSubstitution )
     470             :     {
     471             :         try
     472             :         {
     473           0 :             OSQLParser aParser( m_pDriver->getContext() );
     474           0 :             OUString sErrorMessage;
     475           0 :             OUString sNewSql;
     476           0 :             OSQLParseNode* pNode = aParser.parseTree(sErrorMessage,_sSQL);
     477           0 :             if(pNode)
     478             :             {   // special handling for parameters
     479           0 :                 OSQLParseNode::substituteParameterNames(pNode);
     480           0 :                 pNode->parseNodeToStr( sNewSql, this );
     481           0 :                 delete pNode;
     482           0 :                 sSqlStatement = sNewSql;
     483           0 :             }
     484             :         }
     485           0 :         catch(const Exception&)
     486             :         {
     487             :         }
     488             :     }
     489           0 :     return sSqlStatement;
     490             : }
     491             : // -------------------------------------------------------------------------
     492           0 : Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareStatement( const OUString& sql ) throw(SQLException, RuntimeException)
     493             : {
     494           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     495           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     496           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_STATEMENT, sql );
     497             : 
     498           0 :     SDBThreadAttach t;
     499           0 :     OUString sSqlStatement = sql;
     500           0 :     sSqlStatement = transFormPreparedStatement( sSqlStatement );
     501             : 
     502           0 :     java_sql_PreparedStatement* pStatement = new java_sql_PreparedStatement( t.pEnv, *this, sSqlStatement );
     503           0 :     Reference< XPreparedStatement > xReturn( pStatement );
     504           0 :     m_aStatements.push_back(WeakReferenceHelper(xReturn));
     505             : 
     506           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_STATEMENT_ID, pStatement->getStatementObjectID() );
     507           0 :     return xReturn;
     508             : }
     509             : // -------------------------------------------------------------------------
     510           0 : Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareCall( const OUString& sql ) throw(SQLException, RuntimeException)
     511             : {
     512           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     513           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     514           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_CALL, sql );
     515             : 
     516           0 :     SDBThreadAttach t;
     517           0 :     OUString sSqlStatement = sql;
     518           0 :     sSqlStatement = transFormPreparedStatement( sSqlStatement );
     519             : 
     520           0 :     java_sql_CallableStatement* pStatement = new java_sql_CallableStatement( t.pEnv, *this, sSqlStatement );
     521           0 :     Reference< XPreparedStatement > xStmt( pStatement );
     522           0 :     m_aStatements.push_back(WeakReferenceHelper(xStmt));
     523             : 
     524           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_CALL_ID, pStatement->getStatementObjectID() );
     525           0 :     return xStmt;
     526             : }
     527             : // -------------------------------------------------------------------------
     528           0 : OUString SAL_CALL java_sql_Connection::nativeSQL( const OUString& sql ) throw(SQLException, RuntimeException)
     529             : {
     530           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     531           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     532             : 
     533           0 :     OUString aStr;
     534           0 :     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     535             :     {
     536             : 
     537             :         // initialize temporary Variable
     538             :         static const char * cSignature = "(Ljava/lang/String;)Ljava/lang/String;";
     539             :         static const char * cMethodName = "nativeSQL";
     540             :         // Java-Call
     541             :         static jmethodID mID(NULL);
     542           0 :         obtainMethodId(t.pEnv, cMethodName,cSignature, mID);
     543             :         // Convert Parameter
     544           0 :         jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,sql));
     545             : 
     546           0 :         jobject out = t.pEnv->CallObjectMethod( object, mID, str.get() );
     547           0 :         aStr = JavaString2String(t.pEnv, (jstring)out );
     548           0 :         ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     549             :     } //t.pEnv
     550             : 
     551           0 :     m_aLogger.log( LogLevel::FINER, STR_LOG_NATIVE_SQL, sql, aStr );
     552             : 
     553           0 :     return aStr;
     554             : }
     555             : // -------------------------------------------------------------------------
     556           0 : void SAL_CALL java_sql_Connection::clearWarnings(  ) throw(SQLException, RuntimeException)
     557             : {
     558             :     static jmethodID mID(NULL);
     559           0 :     callVoidMethod("clearWarnings",mID);
     560           0 : }
     561             : // -------------------------------------------------------------------------
     562           0 : Any SAL_CALL java_sql_Connection::getWarnings(  ) throw(SQLException, RuntimeException)
     563             : {
     564           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     565           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     566             : 
     567           0 :     SDBThreadAttach t;
     568             :     static jmethodID mID(NULL);
     569           0 :     jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
     570             :     // WARNING: the caller becomes the owner of the returned pointer
     571           0 :     if( out )
     572             :     {
     573           0 :         java_sql_SQLWarning_BASE        warn_base(t.pEnv, out);
     574           0 :         SQLException aAsException( static_cast< starsdbc::SQLException >( java_sql_SQLWarning( warn_base, *this ) ) );
     575             : 
     576             :         // translate to warning
     577           0 :         SQLWarning aWarning;
     578           0 :         aWarning.Context = aAsException.Context;
     579           0 :         aWarning.Message = aAsException.Message;
     580           0 :         aWarning.SQLState = aAsException.SQLState;
     581           0 :         aWarning.ErrorCode = aAsException.ErrorCode;
     582           0 :         aWarning.NextException = aAsException.NextException;
     583             : 
     584           0 :         return makeAny( aWarning );
     585             :     }
     586             : 
     587           0 :     return Any();
     588             : }
     589             : 
     590             : // -----------------------------------------------------------------------------
     591             : namespace
     592             : {
     593           0 :     OUString lcl_getDriverLoadErrorMessage( const ::connectivity::SharedResources& _aResource,const OUString& _rDriverClass, const OUString& _rDriverClassPath )
     594             :     {
     595             :         OUString sError1( _aResource.getResourceStringWithSubstitution(
     596             :                 STR_NO_CLASSNAME,
     597             :                 "$classname$", _rDriverClass
     598           0 :              ) );
     599           0 :         if ( !_rDriverClassPath.isEmpty() )
     600             :         {
     601             :             const OUString sError2( _aResource.getResourceStringWithSubstitution(
     602             :                 STR_NO_CLASSNAME_PATH,
     603             :                 "$classpath$", _rDriverClassPath
     604           0 :              ) );
     605           0 :             sError1 += sError2;
     606             :         } // if ( _rDriverClassPath.getLength() )
     607           0 :         return sError1;
     608             :     }
     609             : }
     610             : 
     611             : // -----------------------------------------------------------------------------
     612             : namespace
     613             : {
     614           0 :     bool lcl_setSystemProperties_nothrow( const java::sql::ConnectionLog& _rLogger,
     615             :         JNIEnv& _rEnv, const Sequence< NamedValue >& _rSystemProperties )
     616             :     {
     617           0 :         if ( _rSystemProperties.getLength() == 0 )
     618             :             // nothing to do
     619           0 :             return true;
     620             : 
     621           0 :         LocalRef< jclass > systemClass( _rEnv );
     622           0 :         jmethodID nSetPropertyMethodID = 0;
     623             :         // retrieve the java.lang.System class
     624           0 :         systemClass.set( _rEnv.FindClass( "java/lang/System" ) );
     625           0 :         if ( systemClass.is() )
     626             :         {
     627             :             nSetPropertyMethodID = _rEnv.GetStaticMethodID(
     628           0 :                 systemClass.get(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" );
     629             :         }
     630             : 
     631           0 :         if ( nSetPropertyMethodID == 0 )
     632           0 :             return false;
     633             : 
     634           0 :         for (   const NamedValue* pSystemProp = _rSystemProperties.getConstArray();
     635           0 :                 pSystemProp != _rSystemProperties.getConstArray() + _rSystemProperties.getLength();
     636             :                 ++pSystemProp
     637             :             )
     638             :         {
     639           0 :             OUString sValue;
     640           0 :             OSL_VERIFY( pSystemProp->Value >>= sValue );
     641             : 
     642           0 :             _rLogger.log( LogLevel::FINER, STR_LOG_SETTING_SYSTEM_PROPERTY, pSystemProp->Name, sValue );
     643             : 
     644           0 :             LocalRef< jstring > jName( _rEnv, convertwchar_tToJavaString( &_rEnv, pSystemProp->Name ) );
     645           0 :             LocalRef< jstring > jValue( _rEnv, convertwchar_tToJavaString( &_rEnv, sValue ) );
     646             : 
     647           0 :             _rEnv.CallStaticObjectMethod( systemClass.get(), nSetPropertyMethodID, jName.get(), jValue.get() );
     648           0 :             LocalRef< jthrowable > throwable( _rEnv, _rEnv.ExceptionOccurred() );
     649           0 :             if ( throwable.is() )
     650           0 :                 return false;
     651           0 :         }
     652             : 
     653           0 :         return true;
     654             :     }
     655             : }
     656             : 
     657             : // -----------------------------------------------------------------------------
     658           0 : void java_sql_Connection::loadDriverFromProperties( const OUString& _sDriverClass, const OUString& _sDriverClassPath,
     659             :     const Sequence< NamedValue >& _rSystemProperties )
     660             : {
     661             :     // contains the statement which should be used when query for automatically generated values
     662           0 :     OUString     sGeneratedValueStatement;
     663             :     // set to <TRUE/> when we should allow to query for generated values
     664           0 :     sal_Bool            bAutoRetrievingEnabled = sal_False;
     665             : 
     666             :     // first try if the jdbc driver is already registered at the driver manager
     667           0 :     SDBThreadAttach t;
     668             :     try
     669             :     {
     670           0 :         if ( !object )
     671             :         {
     672           0 :             if ( !lcl_setSystemProperties_nothrow( getLogger(), *t.pEnv, _rSystemProperties ) )
     673           0 :                 ThrowLoggedSQLException( getLogger(), t.pEnv, *this );
     674             : 
     675           0 :             m_pDriverClassLoader.reset();
     676             : 
     677             :             // here I try to find the class for jdbc driver
     678           0 :             java_sql_SQLException_BASE::st_getMyClass();
     679           0 :             java_lang_Throwable::st_getMyClass();
     680             : 
     681           0 :             if ( _sDriverClass.isEmpty() )
     682             :             {
     683           0 :                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_DRIVER_CLASS );
     684             :                 ::dbtools::throwGenericSQLException(
     685           0 :                     lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     686             :                     *this
     687           0 :                 );
     688             :             }
     689             :             else
     690             :             {
     691           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_LOADING_DRIVER, _sDriverClass );
     692             :                 // the driver manager holds the class of the driver for later use
     693           0 :                 ::std::auto_ptr< java_lang_Class > pDrvClass;
     694           0 :                 if ( _sDriverClassPath.isEmpty() )
     695             :                 {
     696             :                     // if forName didn't find the class it will throw an exception
     697           0 :                     pDrvClass = ::std::auto_ptr< java_lang_Class >(java_lang_Class::forName(_sDriverClass));
     698             :                 }
     699             :                 else
     700             :                 {
     701           0 :                     LocalRef< jclass > driverClass(t.env());
     702           0 :                     LocalRef< jobject > driverClassLoader(t.env());
     703             : 
     704             :                     loadClass(
     705           0 :                         m_pDriver->getContext(),
     706           0 :                         t.env(), _sDriverClassPath, _sDriverClass, &driverClassLoader, &driverClass );
     707             : 
     708           0 :                     m_pDriverClassLoader.set( driverClassLoader );
     709           0 :                     pDrvClass.reset( new java_lang_Class( t.pEnv, driverClass.release() ) );
     710             : 
     711           0 :                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     712             :                 }
     713           0 :                 if ( pDrvClass.get() )
     714             :                 {
     715           0 :                     LocalRef< jobject > driverObject( t.env() );
     716           0 :                     driverObject.set( pDrvClass->newInstanceObject() );
     717           0 :                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     718           0 :                     m_pDriverobject = driverObject.release();
     719             : 
     720           0 :                     if( t.pEnv && m_pDriverobject )
     721           0 :                         m_pDriverobject = t.pEnv->NewGlobalRef( m_pDriverobject );
     722             : 
     723             :                     {
     724           0 :                         jclass tempClass = t.pEnv->GetObjectClass(m_pDriverobject);
     725           0 :                         if ( m_pDriverobject )
     726             :                         {
     727           0 :                             m_Driver_theClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
     728           0 :                             t.pEnv->DeleteLocalRef( tempClass );
     729             :                         }
     730           0 :                     }
     731             :                 }
     732           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_CONN_SUCCESS );
     733             :             }
     734             :         }
     735             :     }
     736           0 :     catch( const SQLException& e )
     737             :     {
     738             :         throw SQLException(
     739           0 :             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     740             :             *this,
     741             :             OUString(),
     742             :             1000,
     743             :             makeAny(e)
     744           0 :         );
     745             :     }
     746           0 :     catch( Exception& )
     747             :     {
     748             :         ::dbtools::throwGenericSQLException(
     749           0 :             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     750             :             *this
     751           0 :         );
     752             :     }
     753             : 
     754           0 :     enableAutoRetrievingEnabled( bAutoRetrievingEnabled );
     755           0 :     setAutoRetrievingStatement( sGeneratedValueStatement );
     756           0 : }
     757             : // -----------------------------------------------------------------------------
     758           0 : OUString java_sql_Connection::impl_getJavaDriverClassPath_nothrow(const OUString& _sDriverClass)
     759             : {
     760           0 :     static const OUString s_sNodeName("org.openoffice.Office.DataAccess/JDBC/DriverClassPaths");
     761             :     ::utl::OConfigurationTreeRoot aNamesRoot = ::utl::OConfigurationTreeRoot::createWithComponentContext(
     762           0 :         m_pDriver->getContext(), s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
     763           0 :     OUString sURL;
     764           0 :     if ( aNamesRoot.isValid() && aNamesRoot.hasByName( _sDriverClass ) )
     765             :     {
     766           0 :         ::utl::OConfigurationNode aRegisterObj = aNamesRoot.openNode( _sDriverClass );
     767           0 :         OSL_VERIFY( aRegisterObj.getNodeValue( "Path" ) >>= sURL );
     768             :     }
     769           0 :     return sURL;
     770             : }
     771             : // -----------------------------------------------------------------------------
     772           0 : sal_Bool java_sql_Connection::construct(const OUString& url,
     773             :                                     const Sequence< PropertyValue >& info)
     774             : {
     775             :     { // initialize the java vm
     776           0 :         ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM(m_xContext);
     777           0 :         if ( !xTest.is() )
     778           0 :             throwGenericSQLException(STR_NO_JAVA,*this);
     779             :     }
     780           0 :     SDBThreadAttach t;
     781           0 :     t.addRef();      // will be released in dtor
     782           0 :     if ( !t.pEnv )
     783           0 :         throwGenericSQLException(STR_NO_JAVA,*this);
     784             : 
     785           0 :     OUString     sGeneratedValueStatement; // contains the statement which should be used when query for automatically generated values
     786           0 :     sal_Bool            bAutoRetrievingEnabled = sal_False; // set to <TRUE/> when we should allow to query for generated values
     787           0 :     OUString sDriverClassPath,sDriverClass;
     788           0 :     Sequence< NamedValue > aSystemProperties;
     789             : 
     790           0 :     ::comphelper::NamedValueCollection aSettings( info );
     791           0 :     sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass );
     792           0 :     sDriverClassPath = aSettings.getOrDefault( "JavaDriverClassPath", sDriverClassPath);
     793           0 :     if ( sDriverClassPath.isEmpty() )
     794           0 :         sDriverClassPath = impl_getJavaDriverClassPath_nothrow(sDriverClass);
     795           0 :     bAutoRetrievingEnabled = aSettings.getOrDefault( "IsAutoRetrievingEnabled", bAutoRetrievingEnabled );
     796           0 :     sGeneratedValueStatement = aSettings.getOrDefault( "AutoRetrievingStatement", sGeneratedValueStatement );
     797           0 :     m_bParameterSubstitution = aSettings.getOrDefault( "ParameterNameSubstitution", m_bParameterSubstitution );
     798           0 :     m_bIgnoreDriverPrivileges = aSettings.getOrDefault( "IgnoreDriverPrivileges", m_bIgnoreDriverPrivileges );
     799           0 :     m_bIgnoreCurrency = aSettings.getOrDefault( "IgnoreCurrency", m_bIgnoreCurrency );
     800           0 :     aSystemProperties = aSettings.getOrDefault( "SystemProperties", aSystemProperties );
     801           0 :     m_aCatalogRestriction = aSettings.getOrDefault( "ImplicitCatalogRestriction", Any() );
     802           0 :     m_aSchemaRestriction = aSettings.getOrDefault( "ImplicitSchemaRestriction", Any() );
     803             : 
     804           0 :     loadDriverFromProperties( sDriverClass, sDriverClassPath, aSystemProperties );
     805             : 
     806           0 :     enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
     807           0 :     setAutoRetrievingStatement(sGeneratedValueStatement);
     808             : 
     809           0 :     if ( t.pEnv && m_Driver_theClass && m_pDriverobject )
     810             :     {
     811             :         // initialize temporary Variable
     812             :         static const char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
     813             :         static const char * cMethodName = "connect";
     814             :         // Java-Call
     815           0 :         jmethodID mID = NULL;
     816           0 :         if ( !mID  )
     817           0 :             mID  = t.pEnv->GetMethodID( m_Driver_theClass, cMethodName, cSignature );
     818           0 :         if ( mID )
     819             :         {
     820             :             jvalue args[2];
     821             :             // convert Parameter
     822           0 :             args[0].l = convertwchar_tToJavaString(t.pEnv,url);
     823           0 :             java_util_Properties* pProps = createStringPropertyArray(info);
     824           0 :             args[1].l = pProps->getJavaObject();
     825             : 
     826           0 :             LocalRef< jobject > ensureDelete( t.env(), args[0].l );
     827             : 
     828           0 :             jobject out = NULL;
     829             :             // In some cases (e.g.,
     830             :             // connectivity/source/drivers/hsqldb/HDriver.cxx:1.24
     831             :             // l. 249) the JavaDriverClassPath contains multiple jars,
     832             :             // as creating the JavaDriverClass instance requires
     833             :             // (reflective) access to those other jars.  Now, if the
     834             :             // JavaDriverClass is actually loaded by some parent class
     835             :             // loader (e.g., because its jar is also on the global
     836             :             // class path), it would still not have access to the
     837             :             // additional jars on the JavaDriverClassPath.  Hence, the
     838             :             // JavaDriverClassPath class loader is pushed as context
     839             :             // class loader around the JavaDriverClass instance
     840             :             // creation:
     841             :             // #i82222# / 2007-10-15
     842             :             {
     843           0 :                 ContextClassLoaderScope ccl( t.env(), getDriverClassLoader(), getLogger(), *this );
     844           0 :                 out = t.pEnv->CallObjectMethod( m_pDriverobject, mID, args[0].l,args[1].l );
     845           0 :                 delete pProps, pProps = NULL;
     846           0 :                 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     847             :             }
     848             : 
     849           0 :             if ( !out )
     850           0 :                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_SYSTEM_CONNECTION );
     851             : 
     852           0 :             if ( out )
     853           0 :                 object = t.pEnv->NewGlobalRef( out );
     854             : 
     855           0 :             if ( object )
     856           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_GOT_JDBC_CONNECTION, url );
     857             : 
     858           0 :             m_aConnectionInfo = info;
     859             :         } //mID
     860             :     } //t.pEnv
     861           0 :      return object != NULL;
     862             : }
     863             : // -----------------------------------------------------------------------------
     864             : 
     865             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10