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