LCOV - code coverage report
Current view: top level - libreoffice/connectivity/source/drivers/jdbc - JConnection.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 397 0.0 %
Date: 2012-12-17 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             :         rtl::OUString const & theClassPath, rtl::OUString const & theClassName):
      63             :         classPath(theClassPath), className(theClassName), classLoader(NULL),
      64           0 :         classObject(NULL) {}
      65             : 
      66             :     rtl::OUString classPath;
      67             :     rtl::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             :     rtl::OUString const & classPath, rtl::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             :             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           0 :     :java_lang_Object( _rDriver.getContext().getLegacyServiceFactory() )
     261             :     ,OSubComponent<java_sql_Connection, java_sql_Connection_BASE>((::cppu::OWeakObject*)(&_rDriver), this)
     262             :     ,m_pDriver( &_rDriver )
     263             :     ,m_pDriverobject(NULL)
     264             :     ,m_pDriverClassLoader()
     265             :     ,m_Driver_theClass(NULL)
     266           0 :     ,m_aLogger( _rDriver.getLogger() )
     267             :     ,m_bParameterSubstitution(sal_False)
     268             :     ,m_bIgnoreDriverPrivileges(sal_True)
     269           0 :     ,m_bIgnoreCurrency(sal_False)
     270             : {
     271           0 : }
     272             : // -----------------------------------------------------------------------------
     273           0 : java_sql_Connection::~java_sql_Connection()
     274             : {
     275           0 :     ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM();
     276           0 :     if ( xTest.is() )
     277             :     {
     278           0 :         SDBThreadAttach t;
     279           0 :         clearObject(*t.pEnv);
     280             : 
     281             :         {
     282           0 :             if ( m_pDriverobject )
     283           0 :                 t.pEnv->DeleteGlobalRef( m_pDriverobject );
     284           0 :             m_pDriverobject = NULL;
     285           0 :             if ( m_Driver_theClass )
     286           0 :                 t.pEnv->DeleteGlobalRef( m_Driver_theClass );
     287           0 :             m_Driver_theClass = NULL;
     288             :         }
     289           0 :         t.releaseRef();
     290           0 :     }
     291           0 : }
     292             : //-----------------------------------------------------------------------------
     293           0 : void SAL_CALL java_sql_Connection::release() throw()
     294             : {
     295           0 :     relase_ChildImpl();
     296           0 : }
     297             : //------------------------------------------------------------------------------
     298           0 : void java_sql_Connection::disposing()
     299             : {
     300           0 :     ::osl::MutexGuard aGuard(m_aMutex);
     301             : 
     302           0 :     m_aLogger.log( LogLevel::INFO, STR_LOG_SHUTDOWN_CONNECTION );
     303             : 
     304           0 :     dispose_ChildImpl();
     305           0 :     java_sql_Connection_BASE::disposing();
     306             : 
     307           0 :     if ( object )
     308             :     {
     309             :         static jmethodID mID(NULL);
     310           0 :         callVoidMethod("close",mID);
     311           0 :     }
     312           0 : }
     313             : // -------------------------------------------------------------------------
     314           0 : jclass java_sql_Connection::getMyClass() const
     315             : {
     316             :     // the class must be fetched only once, therefore static
     317           0 :     if( !theClass )
     318           0 :         theClass = findMyClass("java/sql/Connection");
     319           0 :     return theClass;
     320             : }
     321             : 
     322             : // -------------------------------------------------------------------------
     323           0 : ::rtl::OUString SAL_CALL java_sql_Connection::getCatalog(  ) throw(SQLException, RuntimeException)
     324             : {
     325           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     326           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     327             : 
     328             :     static jmethodID mID(NULL);
     329           0 :     return callStringMethod("getCatalog",mID);
     330             : }
     331             : // -------------------------------------------------------------------------
     332           0 : Reference< XDatabaseMetaData > SAL_CALL java_sql_Connection::getMetaData(  ) throw(SQLException, RuntimeException)
     333             : {
     334           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     335           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     336             : 
     337             : 
     338           0 :     Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
     339           0 :     if(!xMetaData.is())
     340             :     {
     341           0 :         SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     342             :         static jmethodID mID(NULL);
     343           0 :         jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/DatabaseMetaData;", mID);
     344           0 :         if(out)
     345             :         {
     346           0 :             xMetaData = new java_sql_DatabaseMetaData( t.pEnv, out, *this );
     347           0 :             m_xMetaData = xMetaData;
     348           0 :         }
     349             :     }
     350             : 
     351           0 :     return xMetaData;
     352             : }
     353             : // -------------------------------------------------------------------------
     354           0 : void SAL_CALL java_sql_Connection::close(  ) throw(SQLException, RuntimeException)
     355             : {
     356           0 :     dispose();
     357           0 : }
     358             : // -------------------------------------------------------------------------
     359           0 : void SAL_CALL java_sql_Connection::commit(  ) throw(SQLException, RuntimeException)
     360             : {
     361             :     static jmethodID mID(NULL);
     362           0 :     callVoidMethod("commit",mID);
     363           0 : }
     364             : // -------------------------------------------------------------------------
     365           0 : sal_Bool SAL_CALL java_sql_Connection::isClosed(  ) throw(SQLException, RuntimeException)
     366             : {
     367           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     368             : 
     369             :     static jmethodID mID(NULL);
     370           0 :     return callBooleanMethod( "isClosed", mID ) && java_sql_Connection_BASE::rBHelper.bDisposed;
     371             : }
     372             : // -------------------------------------------------------------------------
     373           0 : sal_Bool SAL_CALL java_sql_Connection::isReadOnly(  ) throw(SQLException, RuntimeException)
     374             : {
     375           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     376           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     377             :     static jmethodID mID(NULL);
     378           0 :     return callBooleanMethod( "isReadOnly", mID );
     379             : }
     380             : // -------------------------------------------------------------------------
     381           0 : void SAL_CALL java_sql_Connection::setCatalog( const ::rtl::OUString& catalog ) throw(SQLException, RuntimeException)
     382             : {
     383             :     static jmethodID mID(NULL);
     384           0 :     callVoidMethodWithStringArg("setCatalog",mID,catalog);
     385           0 : }
     386             : // -------------------------------------------------------------------------
     387           0 : void SAL_CALL java_sql_Connection::rollback(  ) throw(SQLException, RuntimeException)
     388             : {
     389             :     static jmethodID mID(NULL);
     390           0 :     callVoidMethod("rollback",mID);
     391           0 : }
     392             : // -------------------------------------------------------------------------
     393           0 : sal_Bool SAL_CALL java_sql_Connection::getAutoCommit(  ) throw(SQLException, RuntimeException)
     394             : {
     395             :     static jmethodID mID(NULL);
     396           0 :     return callBooleanMethod( "getAutoCommit", mID );
     397             : }
     398             : // -------------------------------------------------------------------------
     399           0 : void SAL_CALL java_sql_Connection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
     400             : {
     401             :     static jmethodID mID(NULL);
     402           0 :     callVoidMethodWithBoolArg("setReadOnly",mID,readOnly);
     403           0 : }
     404             : // -------------------------------------------------------------------------
     405           0 : void SAL_CALL java_sql_Connection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
     406             : {
     407             :     static jmethodID mID(NULL);
     408           0 :     callVoidMethodWithBoolArg("setAutoCommit",mID,autoCommit);
     409           0 : }
     410             : // -------------------------------------------------------------------------
     411           0 : Reference< ::com::sun::star::container::XNameAccess > SAL_CALL java_sql_Connection::getTypeMap(  ) throw(SQLException, RuntimeException)
     412             : {
     413           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     414           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     415             : 
     416           0 :     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     417             :     static jmethodID mID(NULL);
     418           0 :     callObjectMethod(t.pEnv,"getTypeMap","()Ljava/util/Map;", mID);
     419             :     // WARNING: the caller becomes the owner of the returned pointer
     420           0 :     return 0;
     421             : }
     422             : // -------------------------------------------------------------------------
     423           0 : void SAL_CALL java_sql_Connection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
     424             : {
     425           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     426           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     427             : 
     428           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
     429           0 : }
     430             : 
     431             : // -------------------------------------------------------------------------
     432           0 : sal_Int32 SAL_CALL java_sql_Connection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
     433             : {
     434           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     435           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     436             : 
     437             :     static jmethodID mID(NULL);
     438           0 :     return callIntMethod("getTransactionIsolation",mID);
     439             : }
     440             : // -------------------------------------------------------------------------
     441           0 : void SAL_CALL java_sql_Connection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
     442             : {
     443           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     444           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     445             : 
     446             :     static jmethodID mID(NULL);
     447           0 :     callVoidMethodWithIntArg("setTransactionIsolation",mID,level);
     448           0 : }
     449             : // -------------------------------------------------------------------------
     450           0 : Reference< XStatement > SAL_CALL java_sql_Connection::createStatement(  ) throw(SQLException, RuntimeException)
     451             : {
     452           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     453           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     454           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATE_STATEMENT );
     455             : 
     456           0 :     SDBThreadAttach t;
     457           0 :     java_sql_Statement* pStatement = new java_sql_Statement( t.pEnv, *this );
     458           0 :     Reference< XStatement > xStmt = pStatement;
     459           0 :     m_aStatements.push_back( WeakReferenceHelper( xStmt ) );
     460             : 
     461           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATED_STATEMENT_ID, pStatement->getStatementObjectID() );
     462           0 :     return xStmt;
     463             : }
     464             : // -----------------------------------------------------------------------------
     465           0 : ::rtl::OUString java_sql_Connection::transFormPreparedStatement(const ::rtl::OUString& _sSQL)
     466             : {
     467           0 :     ::rtl::OUString sSqlStatement = _sSQL;
     468           0 :     if ( m_bParameterSubstitution )
     469             :     {
     470             :         try
     471             :         {
     472           0 :             OSQLParser aParser( m_pDriver->getContext().getUNOContext() );
     473           0 :             ::rtl::OUString sErrorMessage;
     474           0 :             ::rtl::OUString sNewSql;
     475           0 :             OSQLParseNode* pNode = aParser.parseTree(sErrorMessage,_sSQL);
     476           0 :             if(pNode)
     477             :             {   // special handling for parameters
     478           0 :                 OSQLParseNode::substituteParameterNames(pNode);
     479           0 :                 pNode->parseNodeToStr( sNewSql, this );
     480           0 :                 delete pNode;
     481           0 :                 sSqlStatement = sNewSql;
     482           0 :             }
     483             :         }
     484           0 :         catch(const Exception&)
     485             :         {
     486             :         }
     487             :     }
     488           0 :     return sSqlStatement;
     489             : }
     490             : // -------------------------------------------------------------------------
     491           0 : Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
     492             : {
     493           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     494           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     495           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_STATEMENT, sql );
     496             : 
     497           0 :     SDBThreadAttach t;
     498           0 :     ::rtl::OUString sSqlStatement = sql;
     499           0 :     sSqlStatement = transFormPreparedStatement( sSqlStatement );
     500             : 
     501           0 :     java_sql_PreparedStatement* pStatement = new java_sql_PreparedStatement( t.pEnv, *this, sSqlStatement );
     502           0 :     Reference< XPreparedStatement > xReturn( pStatement );
     503           0 :     m_aStatements.push_back(WeakReferenceHelper(xReturn));
     504             : 
     505           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_STATEMENT_ID, pStatement->getStatementObjectID() );
     506           0 :     return xReturn;
     507             : }
     508             : // -------------------------------------------------------------------------
     509           0 : Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
     510             : {
     511           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     512           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     513           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_CALL, sql );
     514             : 
     515           0 :     SDBThreadAttach t;
     516           0 :     ::rtl::OUString sSqlStatement = sql;
     517           0 :     sSqlStatement = transFormPreparedStatement( sSqlStatement );
     518             : 
     519           0 :     java_sql_CallableStatement* pStatement = new java_sql_CallableStatement( t.pEnv, *this, sSqlStatement );
     520           0 :     Reference< XPreparedStatement > xStmt( pStatement );
     521           0 :     m_aStatements.push_back(WeakReferenceHelper(xStmt));
     522             : 
     523           0 :     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_CALL_ID, pStatement->getStatementObjectID() );
     524           0 :     return xStmt;
     525             : }
     526             : // -------------------------------------------------------------------------
     527           0 : ::rtl::OUString SAL_CALL java_sql_Connection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
     528             : {
     529           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     530           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     531             : 
     532           0 :     ::rtl::OUString aStr;
     533           0 :     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
     534             :     {
     535             : 
     536             :         // initialize temporary Variable
     537             :         static const char * cSignature = "(Ljava/lang/String;)Ljava/lang/String;";
     538             :         static const char * cMethodName = "nativeSQL";
     539             :         // Java-Call
     540             :         static jmethodID mID(NULL);
     541           0 :         obtainMethodId(t.pEnv, cMethodName,cSignature, mID);
     542             :         // Convert Parameter
     543           0 :         jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,sql));
     544             : 
     545           0 :         jobject out = t.pEnv->CallObjectMethod( object, mID, str.get() );
     546           0 :         aStr = JavaString2String(t.pEnv, (jstring)out );
     547           0 :         ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     548             :     } //t.pEnv
     549             : 
     550           0 :     m_aLogger.log( LogLevel::FINER, STR_LOG_NATIVE_SQL, sql, aStr );
     551             : 
     552           0 :     return aStr;
     553             : }
     554             : // -------------------------------------------------------------------------
     555           0 : void SAL_CALL java_sql_Connection::clearWarnings(  ) throw(SQLException, RuntimeException)
     556             : {
     557             :     static jmethodID mID(NULL);
     558           0 :     callVoidMethod("clearWarnings",mID);
     559           0 : }
     560             : // -------------------------------------------------------------------------
     561           0 : Any SAL_CALL java_sql_Connection::getWarnings(  ) throw(SQLException, RuntimeException)
     562             : {
     563           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     564           0 :     checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
     565             : 
     566           0 :     SDBThreadAttach t;
     567             :     static jmethodID mID(NULL);
     568           0 :     jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
     569             :     // WARNING: the caller becomes the owner of the returned pointer
     570           0 :     if( out )
     571             :     {
     572           0 :         java_sql_SQLWarning_BASE        warn_base(t.pEnv, out);
     573           0 :         SQLException aAsException( static_cast< starsdbc::SQLException >( java_sql_SQLWarning( warn_base, *this ) ) );
     574             : 
     575             :         // translate to warning
     576           0 :         SQLWarning aWarning;
     577           0 :         aWarning.Context = aAsException.Context;
     578           0 :         aWarning.Message = aAsException.Message;
     579           0 :         aWarning.SQLState = aAsException.SQLState;
     580           0 :         aWarning.ErrorCode = aAsException.ErrorCode;
     581           0 :         aWarning.NextException = aAsException.NextException;
     582             : 
     583           0 :         return makeAny( aWarning );
     584             :     }
     585             : 
     586           0 :     return Any();
     587             : }
     588             : 
     589             : // -----------------------------------------------------------------------------
     590             : namespace
     591             : {
     592           0 :     ::rtl::OUString lcl_getDriverLoadErrorMessage( const ::connectivity::SharedResources& _aResource,const ::rtl::OUString& _rDriverClass, const ::rtl::OUString& _rDriverClassPath )
     593             :     {
     594             :         ::rtl::OUString sError1( _aResource.getResourceStringWithSubstitution(
     595             :                 STR_NO_CLASSNAME,
     596             :                 "$classname$", _rDriverClass
     597           0 :              ) );
     598           0 :         if ( !_rDriverClassPath.isEmpty() )
     599             :         {
     600             :             const ::rtl::OUString sError2( _aResource.getResourceStringWithSubstitution(
     601             :                 STR_NO_CLASSNAME_PATH,
     602             :                 "$classpath$", _rDriverClassPath
     603           0 :              ) );
     604           0 :             sError1 += sError2;
     605             :         } // if ( _rDriverClassPath.getLength() )
     606           0 :         return sError1;
     607             :     }
     608             : }
     609             : 
     610             : // -----------------------------------------------------------------------------
     611             : namespace
     612             : {
     613           0 :     bool lcl_setSystemProperties_nothrow( const java::sql::ConnectionLog& _rLogger,
     614             :         JNIEnv& _rEnv, const Sequence< NamedValue >& _rSystemProperties )
     615             :     {
     616           0 :         if ( _rSystemProperties.getLength() == 0 )
     617             :             // nothing to do
     618           0 :             return true;
     619             : 
     620           0 :         LocalRef< jclass > systemClass( _rEnv );
     621           0 :         jmethodID nSetPropertyMethodID = 0;
     622             :         // retrieve the java.lang.System class
     623           0 :         systemClass.set( _rEnv.FindClass( "java/lang/System" ) );
     624           0 :         if ( systemClass.is() )
     625             :         {
     626             :             nSetPropertyMethodID = _rEnv.GetStaticMethodID(
     627           0 :                 systemClass.get(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" );
     628             :         }
     629             : 
     630           0 :         if ( nSetPropertyMethodID == 0 )
     631           0 :             return false;
     632             : 
     633           0 :         for (   const NamedValue* pSystemProp = _rSystemProperties.getConstArray();
     634           0 :                 pSystemProp != _rSystemProperties.getConstArray() + _rSystemProperties.getLength();
     635             :                 ++pSystemProp
     636             :             )
     637             :         {
     638           0 :             ::rtl::OUString sValue;
     639           0 :             OSL_VERIFY( pSystemProp->Value >>= sValue );
     640             : 
     641           0 :             _rLogger.log( LogLevel::FINER, STR_LOG_SETTING_SYSTEM_PROPERTY, pSystemProp->Name, sValue );
     642             : 
     643           0 :             LocalRef< jstring > jName( _rEnv, convertwchar_tToJavaString( &_rEnv, pSystemProp->Name ) );
     644           0 :             LocalRef< jstring > jValue( _rEnv, convertwchar_tToJavaString( &_rEnv, sValue ) );
     645             : 
     646           0 :             _rEnv.CallStaticObjectMethod( systemClass.get(), nSetPropertyMethodID, jName.get(), jValue.get() );
     647           0 :             LocalRef< jthrowable > throwable( _rEnv, _rEnv.ExceptionOccurred() );
     648           0 :             if ( throwable.is() )
     649           0 :                 return false;
     650           0 :         }
     651             : 
     652           0 :         return true;
     653             :     }
     654             : }
     655             : 
     656             : // -----------------------------------------------------------------------------
     657           0 : void java_sql_Connection::loadDriverFromProperties( const ::rtl::OUString& _sDriverClass, const ::rtl::OUString& _sDriverClassPath,
     658             :     const Sequence< NamedValue >& _rSystemProperties )
     659             : {
     660             :     // contains the statement which should be used when query for automatically generated values
     661           0 :     ::rtl::OUString     sGeneratedValueStatement;
     662             :     // set to <TRUE/> when we should allow to query for generated values
     663           0 :     sal_Bool            bAutoRetrievingEnabled = sal_False;
     664             : 
     665             :     // first try if the jdbc driver is alraedy registered at the driver manager
     666           0 :     SDBThreadAttach t;
     667             :     try
     668             :     {
     669           0 :         if ( !object )
     670             :         {
     671           0 :             if ( !lcl_setSystemProperties_nothrow( getLogger(), *t.pEnv, _rSystemProperties ) )
     672           0 :                 ThrowLoggedSQLException( getLogger(), t.pEnv, *this );
     673             : 
     674           0 :             m_pDriverClassLoader.reset();
     675             : 
     676             :             // here I try to find the class for jdbc driver
     677           0 :             java_sql_SQLException_BASE::st_getMyClass();
     678           0 :             java_lang_Throwable::st_getMyClass();
     679             : 
     680           0 :             if ( _sDriverClass.isEmpty() )
     681             :             {
     682           0 :                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_DRIVER_CLASS );
     683             :                 ::dbtools::throwGenericSQLException(
     684           0 :                     lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     685             :                     *this
     686           0 :                 );
     687             :             }
     688             :             else
     689             :             {
     690           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_LOADING_DRIVER, _sDriverClass );
     691             :                 // the driver manager holds the class of the driver for later use
     692           0 :                 ::std::auto_ptr< java_lang_Class > pDrvClass;
     693           0 :                 if ( _sDriverClassPath.isEmpty() )
     694             :                 {
     695             :                     // if forName didn't find the class it will throw an exception
     696           0 :                     pDrvClass = ::std::auto_ptr< java_lang_Class >(java_lang_Class::forName(_sDriverClass));
     697             :                 }
     698             :                 else
     699             :                 {
     700           0 :                     LocalRef< jclass > driverClass(t.env());
     701           0 :                     LocalRef< jobject > driverClassLoader(t.env());
     702             : 
     703             :                     loadClass(
     704           0 :                         m_pDriver->getContext().getUNOContext(),
     705           0 :                         t.env(), _sDriverClassPath, _sDriverClass, &driverClassLoader, &driverClass );
     706             : 
     707           0 :                     m_pDriverClassLoader.set( driverClassLoader );
     708           0 :                     pDrvClass.reset( new java_lang_Class( t.pEnv, driverClass.release() ) );
     709             : 
     710           0 :                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     711             :                 }
     712           0 :                 if ( pDrvClass.get() )
     713             :                 {
     714           0 :                     LocalRef< jobject > driverObject( t.env() );
     715           0 :                     driverObject.set( pDrvClass->newInstanceObject() );
     716           0 :                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     717           0 :                     m_pDriverobject = driverObject.release();
     718             : 
     719           0 :                     if( t.pEnv && m_pDriverobject )
     720           0 :                         m_pDriverobject = t.pEnv->NewGlobalRef( m_pDriverobject );
     721             : 
     722             :                     {
     723           0 :                         jclass tempClass = t.pEnv->GetObjectClass(m_pDriverobject);
     724           0 :                         if ( m_pDriverobject )
     725             :                         {
     726           0 :                             m_Driver_theClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
     727           0 :                             t.pEnv->DeleteLocalRef( tempClass );
     728             :                         }
     729           0 :                     }
     730             :                 }
     731           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_CONN_SUCCESS );
     732             :             }
     733             :         }
     734             :     }
     735           0 :     catch( const SQLException& e )
     736             :     {
     737             :         throw SQLException(
     738           0 :             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     739             :             *this,
     740             :             ::rtl::OUString(),
     741             :             1000,
     742             :             makeAny(e)
     743           0 :         );
     744             :     }
     745           0 :     catch( Exception& )
     746             :     {
     747             :         ::dbtools::throwGenericSQLException(
     748           0 :             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
     749             :             *this
     750           0 :         );
     751             :     }
     752             : 
     753           0 :     enableAutoRetrievingEnabled( bAutoRetrievingEnabled );
     754           0 :     setAutoRetrievingStatement( sGeneratedValueStatement );
     755           0 : }
     756             : // -----------------------------------------------------------------------------
     757           0 : ::rtl::OUString java_sql_Connection::impl_getJavaDriverClassPath_nothrow(const ::rtl::OUString& _sDriverClass)
     758             : {
     759           0 :     static const ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/JDBC/DriverClassPaths"));
     760             :     ::utl::OConfigurationTreeRoot aNamesRoot = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
     761           0 :         m_pDriver->getContext().getLegacyServiceFactory(), s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
     762           0 :     ::rtl::OUString sURL;
     763           0 :     if ( aNamesRoot.isValid() && aNamesRoot.hasByName( _sDriverClass ) )
     764             :     {
     765           0 :         ::utl::OConfigurationNode aRegisterObj = aNamesRoot.openNode( _sDriverClass );
     766           0 :         OSL_VERIFY( aRegisterObj.getNodeValue( "Path" ) >>= sURL );
     767             :     }
     768           0 :     return sURL;
     769             : }
     770             : // -----------------------------------------------------------------------------
     771           0 : sal_Bool java_sql_Connection::construct(const ::rtl::OUString& url,
     772             :                                     const Sequence< PropertyValue >& info)
     773             : {
     774             :     { // initialize the java vm
     775           0 :         ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM(getORB());
     776           0 :         if ( !xTest.is() )
     777           0 :             throwGenericSQLException(STR_NO_JAVA,*this);
     778             :     }
     779           0 :     SDBThreadAttach t;
     780           0 :     t.addRef();      // will be released in dtor
     781           0 :     if ( !t.pEnv )
     782           0 :         throwGenericSQLException(STR_NO_JAVA,*this);
     783             : 
     784           0 :     ::rtl::OUString     sGeneratedValueStatement; // contains the statement which should be used when query for automatically generated values
     785           0 :     sal_Bool            bAutoRetrievingEnabled = sal_False; // set to <TRUE/> when we should allow to query for generated values
     786           0 :     ::rtl::OUString sDriverClassPath,sDriverClass;
     787           0 :     Sequence< NamedValue > aSystemProperties;
     788             : 
     789           0 :     ::comphelper::NamedValueCollection aSettings( info );
     790           0 :     sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass );
     791           0 :     sDriverClassPath = aSettings.getOrDefault( "JavaDriverClassPath", sDriverClassPath);
     792           0 :     if ( sDriverClassPath.isEmpty() )
     793           0 :         sDriverClassPath = impl_getJavaDriverClassPath_nothrow(sDriverClass);
     794           0 :     bAutoRetrievingEnabled = aSettings.getOrDefault( "IsAutoRetrievingEnabled", bAutoRetrievingEnabled );
     795           0 :     sGeneratedValueStatement = aSettings.getOrDefault( "AutoRetrievingStatement", sGeneratedValueStatement );
     796           0 :     m_bParameterSubstitution = aSettings.getOrDefault( "ParameterNameSubstitution", m_bParameterSubstitution );
     797           0 :     m_bIgnoreDriverPrivileges = aSettings.getOrDefault( "IgnoreDriverPrivileges", m_bIgnoreDriverPrivileges );
     798           0 :     m_bIgnoreCurrency = aSettings.getOrDefault( "IgnoreCurrency", m_bIgnoreCurrency );
     799           0 :     aSystemProperties = aSettings.getOrDefault( "SystemProperties", aSystemProperties );
     800           0 :     m_aCatalogRestriction = aSettings.getOrDefault( "ImplicitCatalogRestriction", Any() );
     801           0 :     m_aSchemaRestriction = aSettings.getOrDefault( "ImplicitSchemaRestriction", Any() );
     802             : 
     803           0 :     loadDriverFromProperties( sDriverClass, sDriverClassPath, aSystemProperties );
     804             : 
     805           0 :     enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
     806           0 :     setAutoRetrievingStatement(sGeneratedValueStatement);
     807             : 
     808           0 :     if ( t.pEnv && m_Driver_theClass && m_pDriverobject )
     809             :     {
     810             :         // initialize temporary Variable
     811             :         static const char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
     812             :         static const char * cMethodName = "connect";
     813             :         // Java-Call
     814           0 :         jmethodID mID = NULL;
     815           0 :         if ( !mID  )
     816           0 :             mID  = t.pEnv->GetMethodID( m_Driver_theClass, cMethodName, cSignature );
     817           0 :         if ( mID )
     818             :         {
     819             :             jvalue args[2];
     820             :             // convert Parameter
     821           0 :             args[0].l = convertwchar_tToJavaString(t.pEnv,url);
     822           0 :             java_util_Properties* pProps = createStringPropertyArray(info);
     823           0 :             args[1].l = pProps->getJavaObject();
     824             : 
     825           0 :             LocalRef< jobject > ensureDelete( t.env(), args[0].l );
     826             : 
     827           0 :             jobject out = NULL;
     828             :             // In some cases (e.g.,
     829             :             // connectivity/source/drivers/hsqldb/HDriver.cxx:1.24
     830             :             // l. 249) the JavaDriverClassPath contains multiple jars,
     831             :             // as creating the JavaDriverClass instance requires
     832             :             // (reflective) access to those other jars.  Now, if the
     833             :             // JavaDriverClass is actually loaded by some parent class
     834             :             // loader (e.g., because its jar is also on the global
     835             :             // class path), it would still not have access to the
     836             :             // additional jars on the JavaDriverClassPath.  Hence, the
     837             :             // JavaDriverClassPath class loader is pushed as context
     838             :             // class loader around the JavaDriverClass instance
     839             :             // creation:
     840             :             // #i82222# / 2007-10-15
     841             :             {
     842           0 :                 ContextClassLoaderScope ccl( t.env(), getDriverClassLoader(), getLogger(), *this );
     843           0 :                 out = t.pEnv->CallObjectMethod( m_pDriverobject, mID, args[0].l,args[1].l );
     844           0 :                 delete pProps, pProps = NULL;
     845           0 :                 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
     846             :             }
     847             : 
     848           0 :             if ( !out )
     849           0 :                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_SYSTEM_CONNECTION );
     850             : 
     851           0 :             if ( out )
     852           0 :                 object = t.pEnv->NewGlobalRef( out );
     853             : 
     854           0 :             if ( object )
     855           0 :                 m_aLogger.log( LogLevel::INFO, STR_LOG_GOT_JDBC_CONNECTION, url );
     856             : 
     857           0 :             m_aConnectionInfo = info;
     858             :         } //mID
     859             :     } //t.pEnv
     860           0 :      return object != NULL;
     861             : }
     862             : // -----------------------------------------------------------------------------
     863             : 
     864             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10