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/beans/PropertyValue.hpp>
22 #include <com/sun/star/sdbc/XConnection.hpp>
23 #include <comphelper/uno3.hxx>
24 #include <comphelper/sequence.hxx>
25 #include <comphelper/servicehelper.hxx>
26 #include <comphelper/hash.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <com/sun/star/reflection/ProxyFactory.hpp>
31 using namespace connectivity
;
33 using namespace com::sun::star::uno
;
34 using namespace com::sun::star::lang
;
35 using namespace com::sun::star::beans
;
36 using namespace com::sun::star::sdbc
;
37 using namespace ::com::sun::star::reflection
;
39 OConnectionWrapper::OConnectionWrapper()
40 : OConnection_BASE(m_aMutex
)
45 void OConnectionWrapper::setDelegation(Reference
< XAggregation
>& _rxProxyConnection
)
47 // So far only called from constructors
48 OSL_ENSURE(_rxProxyConnection
.is(),"OConnectionWrapper: Connection must be valid!");
49 osl_atomic_increment(&m_refCount
);
50 if (_rxProxyConnection
.is())
52 // transfer the (one and only) real ref to the aggregate to our member
53 m_xProxyConnection
= _rxProxyConnection
;
54 _rxProxyConnection
= nullptr;
55 ::comphelper::query_aggregation(m_xProxyConnection
,m_xConnection
);
56 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
57 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
58 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
60 // set ourself as delegator
61 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
62 m_xProxyConnection
->setDelegator( xIf
);
65 osl_atomic_decrement(&m_refCount
);
68 void OConnectionWrapper::setDelegation(const Reference
< XConnection
>& _xConnection
69 ,const Reference
< XComponentContext
>& _rxContext
)
71 // So far only called from constructors
72 OSL_ENSURE(_xConnection
.is(),"OConnectionWrapper: Connection must be valid!");
73 osl_atomic_increment(&m_refCount
);
75 m_xConnection
= _xConnection
;
76 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
77 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
78 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
80 Reference
< XProxyFactory
> xProxyFactory
= ProxyFactory::create( _rxContext
);
81 Reference
< XAggregation
> xConProxy
= xProxyFactory
->createProxy(_xConnection
);
84 // transfer the (one and only) real ref to the aggregate to our member
85 m_xProxyConnection
= std::move(xConProxy
);
87 // set ourself as delegator
88 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
89 m_xProxyConnection
->setDelegator( xIf
);
92 osl_atomic_decrement(&m_refCount
);
95 void OConnectionWrapper::disposing()
97 osl::MutexGuard
aGuard(m_aMutex
);
98 OConnection_BASE::disposing();
99 m_xConnection
.clear();
102 OConnectionWrapper::~OConnectionWrapper()
104 if (m_xProxyConnection
.is())
105 m_xProxyConnection
->setDelegator(nullptr);
110 OUString SAL_CALL
OConnectionWrapper::getImplementationName( )
112 return u
"com.sun.star.sdbc.drivers.OConnectionWrapper"_ustr
;
116 css::uno::Sequence
< OUString
> SAL_CALL
OConnectionWrapper::getSupportedServiceNames( )
118 osl::MutexGuard
aGuard(m_aMutex
);
119 // first collect the services which are supported by our aggregate
120 Sequence
< OUString
> aSupported
;
121 if ( m_xServiceInfo
.is() )
122 aSupported
= m_xServiceInfo
->getSupportedServiceNames();
124 // append our own service, if necessary
125 OUString
sConnectionService( u
"com.sun.star.sdbc.Connection"_ustr
);
126 if ( ::comphelper::findValue( aSupported
, sConnectionService
) == -1 )
128 sal_Int32 nLen
= aSupported
.getLength();
129 aSupported
.realloc( nLen
+ 1 );
130 aSupported
.getArray()[ nLen
] = sConnectionService
;
138 sal_Bool SAL_CALL
OConnectionWrapper::supportsService( const OUString
& _rServiceName
)
140 return cppu::supportsService(this, _rServiceName
);
144 Any SAL_CALL
OConnectionWrapper::queryInterface( const Type
& _rType
)
146 osl::MutexGuard
aGuard(m_aMutex
);
147 Any aReturn
= OConnection_BASE::queryInterface(_rType
);
148 return aReturn
.hasValue() ? aReturn
: (m_xProxyConnection
.is() ? m_xProxyConnection
->queryAggregation(_rType
) : aReturn
);
151 Sequence
< Type
> SAL_CALL
OConnectionWrapper::getTypes( )
153 osl::MutexGuard
aGuard(m_aMutex
);
154 return ::comphelper::concatSequences(
155 OConnection_BASE::getTypes(),
156 m_xTypeProvider
->getTypes()
160 // css::lang::XUnoTunnel
161 sal_Int64 SAL_CALL
OConnectionWrapper::getSomething( const Sequence
< sal_Int8
>& rId
)
163 if (comphelper::isUnoTunnelId
<OConnectionWrapper
>(rId
))
164 return comphelper::getSomething_cast(this);
166 osl::MutexGuard
aGuard(m_aMutex
);
167 if(m_xUnoTunnel
.is())
168 return m_xUnoTunnel
->getSomething(rId
);
173 const Sequence
< sal_Int8
> & OConnectionWrapper::getUnoTunnelId()
175 static const comphelper::UnoIdInit implId
;
176 return implId
.getSeq();
181 class TPropertyValueLessFunctor
184 TPropertyValueLessFunctor()
186 bool operator() (const css::beans::PropertyValue
& lhs
, const css::beans::PropertyValue
& rhs
) const
188 return lhs
.Name
.compareToIgnoreAsciiCase(rhs
.Name
) < 0;
195 // creates a unique id out of the url and sequence of properties
196 void OConnectionWrapper::createUniqueId( const OUString
& _rURL
197 ,Sequence
< PropertyValue
>& _rInfo
199 ,const OUString
& _rUserName
200 ,const OUString
& _rPassword
)
202 // first we create the digest we want to have
203 ::comphelper::Hash
sha1(::comphelper::HashType::SHA1
);
204 sha1
.update(reinterpret_cast<unsigned char const*>(_rURL
.getStr()), _rURL
.getLength() * sizeof(sal_Unicode
));
205 if ( !_rUserName
.isEmpty() )
206 sha1
.update(reinterpret_cast<unsigned char const*>(_rUserName
.getStr()), _rUserName
.getLength() * sizeof(sal_Unicode
));
207 if ( !_rPassword
.isEmpty() )
208 sha1
.update(reinterpret_cast<unsigned char const*>(_rPassword
.getStr()), _rPassword
.getLength() * sizeof(sal_Unicode
));
209 // now we need to sort the properties
210 auto [begin
, end
] = asNonConstRange(_rInfo
);
211 std::sort(begin
,end
,TPropertyValueLessFunctor());
213 for (PropertyValue
const& prop
: _rInfo
)
215 // we only include strings an integer values
217 if ( prop
.Value
>>= sValue
)
221 sal_Int32 nValue
= 0;
222 if ( prop
.Value
>>= nValue
)
223 sValue
= OUString::number(nValue
);
226 Sequence
< OUString
> aSeq
;
227 if ( prop
.Value
>>= aSeq
)
229 for (OUString
const& s
: aSeq
)
230 sha1
.update(reinterpret_cast<unsigned char const*>(s
.getStr()), s
.getLength() * sizeof(sal_Unicode
));
234 if ( !sValue
.isEmpty() )
236 // we don't have to convert this into UTF8 because we don't store on a file system
237 sha1
.update(reinterpret_cast<unsigned char const*>(sValue
.getStr()), sValue
.getLength() * sizeof(sal_Unicode
));
241 std::vector
<unsigned char> result(sha1
.finalize());
242 std::copy(result
.begin(), result
.end(), _pBuffer
);
246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */