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

Generated by: LCOV version 1.10