1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 30*cdf0e10cSrcweir #ifndef _CONNECTIVITY_CONNECTIONWRAPPER_HXX_ 31*cdf0e10cSrcweir #include "connectivity/ConnectionWrapper.hxx" 32*cdf0e10cSrcweir #endif 33*cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 36*cdf0e10cSrcweir #include <comphelper/uno3.hxx> 37*cdf0e10cSrcweir #include <comphelper/sequence.hxx> 38*cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx> 39*cdf0e10cSrcweir #include <com/sun/star/reflection/XProxyFactory.hpp> 40*cdf0e10cSrcweir #include <rtl/digest.h> 41*cdf0e10cSrcweir #include <algorithm> 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir #include <algorithm> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir using namespace connectivity; 46*cdf0e10cSrcweir //------------------------------------------------------------------------------ 47*cdf0e10cSrcweir using namespace com::sun::star::uno; 48*cdf0e10cSrcweir using namespace com::sun::star::lang; 49*cdf0e10cSrcweir using namespace com::sun::star::beans; 50*cdf0e10cSrcweir using namespace com::sun::star::sdbc; 51*cdf0e10cSrcweir using namespace ::com::sun::star::reflection; 52*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 53*cdf0e10cSrcweir OConnectionWrapper::OConnectionWrapper() 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir } 57*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 58*cdf0e10cSrcweir void OConnectionWrapper::setDelegation(Reference< XAggregation >& _rxProxyConnection,oslInterlockedCount& _rRefCount) 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir OSL_ENSURE(_rxProxyConnection.is(),"OConnectionWrapper: Connection must be valid!"); 61*cdf0e10cSrcweir osl_incrementInterlockedCount( &_rRefCount ); 62*cdf0e10cSrcweir if (_rxProxyConnection.is()) 63*cdf0e10cSrcweir { 64*cdf0e10cSrcweir // transfer the (one and only) real ref to the aggregate to our member 65*cdf0e10cSrcweir m_xProxyConnection = _rxProxyConnection; 66*cdf0e10cSrcweir _rxProxyConnection = NULL; 67*cdf0e10cSrcweir ::comphelper::query_aggregation(m_xProxyConnection,m_xConnection); 68*cdf0e10cSrcweir m_xTypeProvider.set(m_xConnection,UNO_QUERY); 69*cdf0e10cSrcweir m_xUnoTunnel.set(m_xConnection,UNO_QUERY); 70*cdf0e10cSrcweir m_xServiceInfo.set(m_xConnection,UNO_QUERY); 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir // set ourself as delegator 73*cdf0e10cSrcweir Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this ); 74*cdf0e10cSrcweir m_xProxyConnection->setDelegator( xIf ); 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir osl_decrementInterlockedCount( &_rRefCount ); 78*cdf0e10cSrcweir } 79*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 80*cdf0e10cSrcweir void OConnectionWrapper::setDelegation(const Reference< XConnection >& _xConnection 81*cdf0e10cSrcweir ,const Reference< XMultiServiceFactory>& _xORB 82*cdf0e10cSrcweir ,oslInterlockedCount& _rRefCount) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir OSL_ENSURE(_xConnection.is(),"OConnectionWrapper: Connection must be valid!"); 85*cdf0e10cSrcweir osl_incrementInterlockedCount( &_rRefCount ); 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir m_xConnection = _xConnection; 88*cdf0e10cSrcweir m_xTypeProvider.set(m_xConnection,UNO_QUERY); 89*cdf0e10cSrcweir m_xUnoTunnel.set(m_xConnection,UNO_QUERY); 90*cdf0e10cSrcweir m_xServiceInfo.set(m_xConnection,UNO_QUERY); 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir Reference< XProxyFactory > xProxyFactory(_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY); 93*cdf0e10cSrcweir Reference< XAggregation > xConProxy = xProxyFactory->createProxy(_xConnection); 94*cdf0e10cSrcweir if (xConProxy.is()) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir // transfer the (one and only) real ref to the aggregate to our member 97*cdf0e10cSrcweir m_xProxyConnection = xConProxy; 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir // set ourself as delegator 100*cdf0e10cSrcweir Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this ); 101*cdf0e10cSrcweir m_xProxyConnection->setDelegator( xIf ); 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir osl_decrementInterlockedCount( &_rRefCount ); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 107*cdf0e10cSrcweir void OConnectionWrapper::disposing() 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir m_xConnection.clear(); 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir //----------------------------------------------------------------------------- 112*cdf0e10cSrcweir OConnectionWrapper::~OConnectionWrapper() 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir if (m_xProxyConnection.is()) 115*cdf0e10cSrcweir m_xProxyConnection->setDelegator(NULL); 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir // XServiceInfo 119*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 120*cdf0e10cSrcweir ::rtl::OUString SAL_CALL OConnectionWrapper::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException) 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.drivers.OConnectionWrapper" ) ); 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 126*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConnectionWrapper::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir // first collect the services which are supported by our aggregate 129*cdf0e10cSrcweir Sequence< ::rtl::OUString > aSupported; 130*cdf0e10cSrcweir if ( m_xServiceInfo.is() ) 131*cdf0e10cSrcweir aSupported = m_xServiceInfo->getSupportedServiceNames(); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir // append our own service, if necessary 134*cdf0e10cSrcweir ::rtl::OUString sConnectionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) ); 135*cdf0e10cSrcweir if ( 0 == ::comphelper::findValue( aSupported, sConnectionService, sal_True ).getLength() ) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir sal_Int32 nLen = aSupported.getLength(); 138*cdf0e10cSrcweir aSupported.realloc( nLen + 1 ); 139*cdf0e10cSrcweir aSupported[ nLen ] = sConnectionService; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir // outta here 143*cdf0e10cSrcweir return aSupported; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 147*cdf0e10cSrcweir sal_Bool SAL_CALL OConnectionWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName, sal_True ).getLength() != 0; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 153*cdf0e10cSrcweir Any SAL_CALL OConnectionWrapper::queryInterface( const Type& _rType ) throw (RuntimeException) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir Any aReturn = OConnection_BASE::queryInterface(_rType); 156*cdf0e10cSrcweir return aReturn.hasValue() ? aReturn : (m_xProxyConnection.is() ? m_xProxyConnection->queryAggregation(_rType) : aReturn); 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 159*cdf0e10cSrcweir Sequence< Type > SAL_CALL OConnectionWrapper::getTypes( ) throw (::com::sun::star::uno::RuntimeException) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir return ::comphelper::concatSequences( 162*cdf0e10cSrcweir OConnection_BASE::getTypes(), 163*cdf0e10cSrcweir m_xTypeProvider->getTypes() 164*cdf0e10cSrcweir ); 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 167*cdf0e10cSrcweir // com::sun::star::lang::XUnoTunnel 168*cdf0e10cSrcweir sal_Int64 SAL_CALL OConnectionWrapper::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 171*cdf0e10cSrcweir return reinterpret_cast< sal_Int64 >( this ); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir if(m_xUnoTunnel.is()) 174*cdf0e10cSrcweir return m_xUnoTunnel->getSomething(rId); 175*cdf0e10cSrcweir return 0; 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 179*cdf0e10cSrcweir Sequence< sal_Int8 > OConnectionWrapper::getUnoTunnelImplementationId() 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir static ::cppu::OImplementationId * pId = 0; 182*cdf0e10cSrcweir if (! pId) 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 185*cdf0e10cSrcweir if (! pId) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir static ::cppu::OImplementationId aId; 188*cdf0e10cSrcweir pId = &aId; 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir return pId->getImplementationId(); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 194*cdf0e10cSrcweir namespace 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir class TPropertyValueLessFunctor : public ::std::binary_function< ::com::sun::star::beans::PropertyValue,::com::sun::star::beans::PropertyValue,bool> 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir public: 199*cdf0e10cSrcweir TPropertyValueLessFunctor() 200*cdf0e10cSrcweir {} 201*cdf0e10cSrcweir bool operator() (const ::com::sun::star::beans::PropertyValue& lhs, const ::com::sun::star::beans::PropertyValue& rhs) const 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir return !!(lhs.Name.equalsIgnoreAsciiCase( rhs.Name )); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir }; 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 210*cdf0e10cSrcweir // creates a unique id out of the url and sequence of properties 211*cdf0e10cSrcweir void OConnectionWrapper::createUniqueId( const ::rtl::OUString& _rURL 212*cdf0e10cSrcweir ,Sequence< PropertyValue >& _rInfo 213*cdf0e10cSrcweir ,sal_uInt8* _pBuffer 214*cdf0e10cSrcweir ,const ::rtl::OUString& _rUserName 215*cdf0e10cSrcweir ,const ::rtl::OUString& _rPassword) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir // first we create the digest we want to have 218*cdf0e10cSrcweir rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 219*cdf0e10cSrcweir rtlDigestError aError = rtl_digest_update(aDigest,_rURL.getStr(),_rURL.getLength()*sizeof(sal_Unicode)); 220*cdf0e10cSrcweir if ( _rUserName.getLength() ) 221*cdf0e10cSrcweir aError = rtl_digest_update(aDigest,_rUserName.getStr(),_rUserName.getLength()*sizeof(sal_Unicode)); 222*cdf0e10cSrcweir if ( _rPassword.getLength() ) 223*cdf0e10cSrcweir aError = rtl_digest_update(aDigest,_rPassword.getStr(),_rPassword.getLength()*sizeof(sal_Unicode)); 224*cdf0e10cSrcweir // now we need to sort the properties 225*cdf0e10cSrcweir PropertyValue* pBegin = _rInfo.getArray(); 226*cdf0e10cSrcweir PropertyValue* pEnd = pBegin + _rInfo.getLength(); 227*cdf0e10cSrcweir ::std::sort(pBegin,pEnd,TPropertyValueLessFunctor()); 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir pBegin = _rInfo.getArray(); 230*cdf0e10cSrcweir pEnd = pBegin + _rInfo.getLength(); 231*cdf0e10cSrcweir for (; pBegin != pEnd; ++pBegin) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir // we only include strings an integer values 234*cdf0e10cSrcweir ::rtl::OUString sValue; 235*cdf0e10cSrcweir if ( pBegin->Value >>= sValue ) 236*cdf0e10cSrcweir ; 237*cdf0e10cSrcweir else 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir sal_Int32 nValue = 0; 240*cdf0e10cSrcweir if ( pBegin->Value >>= nValue ) 241*cdf0e10cSrcweir sValue = ::rtl::OUString::valueOf(nValue); 242*cdf0e10cSrcweir else 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir Sequence< ::rtl::OUString> aSeq; 245*cdf0e10cSrcweir if ( pBegin->Value >>= aSeq ) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir const ::rtl::OUString* pSBegin = aSeq.getConstArray(); 248*cdf0e10cSrcweir const ::rtl::OUString* pSEnd = pSBegin + aSeq.getLength(); 249*cdf0e10cSrcweir for(;pSBegin != pSEnd;++pSBegin) 250*cdf0e10cSrcweir aError = rtl_digest_update(aDigest,pSBegin->getStr(),pSBegin->getLength()*sizeof(sal_Unicode)); 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir if ( sValue.getLength() > 0 ) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir // we don't have to convert this into UTF8 because we don't store on a file system 257*cdf0e10cSrcweir aError = rtl_digest_update(aDigest,sValue.getStr(),sValue.getLength()*sizeof(sal_Unicode)); 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir aError = rtl_digest_get(aDigest,_pBuffer,RTL_DIGEST_LENGTH_SHA1); 262*cdf0e10cSrcweir // we have to destroy the digest 263*cdf0e10cSrcweir rtl_digest_destroy(aDigest); 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir 268