1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "connectivity/ConnectionWrapper.hxx"
21 #include <com/sun/star/sdbc/ColumnValue.hpp>
22 #include <com/sun/star/sdbc/XRow.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <comphelper/uno3.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <cppuhelper/typeprovider.hxx>
27 #include <com/sun/star/reflection/ProxyFactory.hpp>
28 #include <rtl/digest.h>
32 using namespace connectivity
;
33 //------------------------------------------------------------------------------
34 using namespace com::sun::star::uno
;
35 using namespace com::sun::star::lang
;
36 using namespace com::sun::star::beans
;
37 using namespace com::sun::star::sdbc
;
38 using namespace ::com::sun::star::reflection
;
39 // --------------------------------------------------------------------------------
40 OConnectionWrapper::OConnectionWrapper()
44 // -----------------------------------------------------------------------------
45 void OConnectionWrapper::setDelegation(Reference
< XAggregation
>& _rxProxyConnection
,oslInterlockedCount
& _rRefCount
)
47 OSL_ENSURE(_rxProxyConnection
.is(),"OConnectionWrapper: Connection must be valid!");
48 osl_atomic_increment( &_rRefCount
);
49 if (_rxProxyConnection
.is())
51 // transfer the (one and only) real ref to the aggregate to our member
52 m_xProxyConnection
= _rxProxyConnection
;
53 _rxProxyConnection
= NULL
;
54 ::comphelper::query_aggregation(m_xProxyConnection
,m_xConnection
);
55 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
56 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
57 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
59 // set ourself as delegator
60 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
61 m_xProxyConnection
->setDelegator( xIf
);
64 osl_atomic_decrement( &_rRefCount
);
66 // -----------------------------------------------------------------------------
67 void OConnectionWrapper::setDelegation(const Reference
< XConnection
>& _xConnection
68 ,const Reference
< XComponentContext
>& _rxContext
69 ,oslInterlockedCount
& _rRefCount
)
71 OSL_ENSURE(_xConnection
.is(),"OConnectionWrapper: Connection must be valid!");
72 osl_atomic_increment( &_rRefCount
);
74 m_xConnection
= _xConnection
;
75 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
76 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
77 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
79 Reference
< XProxyFactory
> xProxyFactory
= ProxyFactory::create( _rxContext
);
80 Reference
< XAggregation
> xConProxy
= xProxyFactory
->createProxy(_xConnection
);
83 // transfer the (one and only) real ref to the aggregate to our member
84 m_xProxyConnection
= xConProxy
;
86 // set ourself as delegator
87 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
88 m_xProxyConnection
->setDelegator( xIf
);
91 osl_atomic_decrement( &_rRefCount
);
93 // -----------------------------------------------------------------------------
94 void OConnectionWrapper::disposing()
96 m_xConnection
.clear();
98 //-----------------------------------------------------------------------------
99 OConnectionWrapper::~OConnectionWrapper()
101 if (m_xProxyConnection
.is())
102 m_xProxyConnection
->setDelegator(NULL
);
106 // --------------------------------------------------------------------------------
107 OUString SAL_CALL
OConnectionWrapper::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException
)
109 return OUString( "com.sun.star.sdbc.drivers.OConnectionWrapper" );
112 // --------------------------------------------------------------------------------
113 ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
OConnectionWrapper::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException
)
115 // first collect the services which are supported by our aggregate
116 Sequence
< OUString
> aSupported
;
117 if ( m_xServiceInfo
.is() )
118 aSupported
= m_xServiceInfo
->getSupportedServiceNames();
120 // append our own service, if necessary
121 OUString
sConnectionService( "com.sun.star.sdbc.Connection" );
122 if ( 0 == ::comphelper::findValue( aSupported
, sConnectionService
, sal_True
).getLength() )
124 sal_Int32 nLen
= aSupported
.getLength();
125 aSupported
.realloc( nLen
+ 1 );
126 aSupported
[ nLen
] = sConnectionService
;
133 // --------------------------------------------------------------------------------
134 sal_Bool SAL_CALL
OConnectionWrapper::supportsService( const OUString
& _rServiceName
) throw(::com::sun::star::uno::RuntimeException
)
136 return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName
, sal_True
).getLength() != 0;
139 // --------------------------------------------------------------------------------
140 Any SAL_CALL
OConnectionWrapper::queryInterface( const Type
& _rType
) throw (RuntimeException
)
142 Any aReturn
= OConnection_BASE::queryInterface(_rType
);
143 return aReturn
.hasValue() ? aReturn
: (m_xProxyConnection
.is() ? m_xProxyConnection
->queryAggregation(_rType
) : aReturn
);
145 // --------------------------------------------------------------------------------
146 Sequence
< Type
> SAL_CALL
OConnectionWrapper::getTypes( ) throw (::com::sun::star::uno::RuntimeException
)
148 return ::comphelper::concatSequences(
149 OConnection_BASE::getTypes(),
150 m_xTypeProvider
->getTypes()
153 // -----------------------------------------------------------------------------
154 // com::sun::star::lang::XUnoTunnel
155 sal_Int64 SAL_CALL
OConnectionWrapper::getSomething( const Sequence
< sal_Int8
>& rId
) throw(RuntimeException
)
157 if (rId
.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId
.getConstArray(), 16 ) )
158 return reinterpret_cast< sal_Int64
>( this );
160 if(m_xUnoTunnel
.is())
161 return m_xUnoTunnel
->getSomething(rId
);
165 // -----------------------------------------------------------------------------
166 Sequence
< sal_Int8
> OConnectionWrapper::getUnoTunnelImplementationId()
168 static ::cppu::OImplementationId
* pId
= 0;
171 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
174 static ::cppu::OImplementationId aId
;
178 return pId
->getImplementationId();
180 // -----------------------------------------------------------------------------
183 class TPropertyValueLessFunctor
: public ::std::binary_function
< ::com::sun::star::beans::PropertyValue
,::com::sun::star::beans::PropertyValue
,bool>
186 TPropertyValueLessFunctor()
188 bool operator() (const ::com::sun::star::beans::PropertyValue
& lhs
, const ::com::sun::star::beans::PropertyValue
& rhs
) const
190 return lhs
.Name
.compareToIgnoreAsciiCase(rhs
.Name
) < 0;
196 // -----------------------------------------------------------------------------
197 // creates a unique id out of the url and sequence of properties
198 void OConnectionWrapper::createUniqueId( const OUString
& _rURL
199 ,Sequence
< PropertyValue
>& _rInfo
201 ,const OUString
& _rUserName
202 ,const OUString
& _rPassword
)
204 // first we create the digest we want to have
205 rtlDigest aDigest
= rtl_digest_create( rtl_Digest_AlgorithmSHA1
);
206 rtl_digest_update(aDigest
,_rURL
.getStr(),_rURL
.getLength()*sizeof(sal_Unicode
));
207 if ( !_rUserName
.isEmpty() )
208 rtl_digest_update(aDigest
,_rUserName
.getStr(),_rUserName
.getLength()*sizeof(sal_Unicode
));
209 if ( !_rPassword
.isEmpty() )
210 rtl_digest_update(aDigest
,_rPassword
.getStr(),_rPassword
.getLength()*sizeof(sal_Unicode
));
211 // now we need to sort the properties
212 PropertyValue
* pBegin
= _rInfo
.getArray();
213 PropertyValue
* pEnd
= pBegin
+ _rInfo
.getLength();
214 ::std::sort(pBegin
,pEnd
,TPropertyValueLessFunctor());
216 pBegin
= _rInfo
.getArray();
217 pEnd
= pBegin
+ _rInfo
.getLength();
218 for (; pBegin
!= pEnd
; ++pBegin
)
220 // we only include strings an integer values
222 if ( pBegin
->Value
>>= sValue
)
226 sal_Int32 nValue
= 0;
227 if ( pBegin
->Value
>>= nValue
)
228 sValue
= OUString::valueOf(nValue
);
231 Sequence
< OUString
> aSeq
;
232 if ( pBegin
->Value
>>= aSeq
)
234 const OUString
* pSBegin
= aSeq
.getConstArray();
235 const OUString
* pSEnd
= pSBegin
+ aSeq
.getLength();
236 for(;pSBegin
!= pSEnd
;++pSBegin
)
237 rtl_digest_update(aDigest
,pSBegin
->getStr(),pSBegin
->getLength()*sizeof(sal_Unicode
));
241 if ( !sValue
.isEmpty() )
243 // we don't have to convert this into UTF8 because we don't store on a file system
244 rtl_digest_update(aDigest
,sValue
.getStr(),sValue
.getLength()*sizeof(sal_Unicode
));
248 rtl_digest_get(aDigest
,_pBuffer
,RTL_DIGEST_LENGTH_SHA1
);
249 // we have to destroy the digest
250 rtl_digest_destroy(aDigest
);
252 // -----------------------------------------------------------------------------
255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */