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 <cppuhelper/typeprovider.hxx>
29 #include <com/sun/star/reflection/ProxyFactory.hpp>
32 using namespace connectivity
;
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
;
40 OConnectionWrapper::OConnectionWrapper()
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
= nullptr;
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
);
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
);
94 void OConnectionWrapper::disposing()
96 m_xConnection
.clear();
99 OConnectionWrapper::~OConnectionWrapper()
101 if (m_xProxyConnection
.is())
102 m_xProxyConnection
->setDelegator(nullptr);
107 OUString SAL_CALL
OConnectionWrapper::getImplementationName( )
109 return "com.sun.star.sdbc.drivers.OConnectionWrapper";
113 css::uno::Sequence
< OUString
> SAL_CALL
OConnectionWrapper::getSupportedServiceNames( )
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 ( ::comphelper::findValue( aSupported
, sConnectionService
) == -1 )
124 sal_Int32 nLen
= aSupported
.getLength();
125 aSupported
.realloc( nLen
+ 1 );
126 aSupported
[ nLen
] = sConnectionService
;
134 sal_Bool SAL_CALL
OConnectionWrapper::supportsService( const OUString
& _rServiceName
)
136 return cppu::supportsService(this, _rServiceName
);
140 Any SAL_CALL
OConnectionWrapper::queryInterface( const Type
& _rType
)
142 Any aReturn
= OConnection_BASE::queryInterface(_rType
);
143 return aReturn
.hasValue() ? aReturn
: (m_xProxyConnection
.is() ? m_xProxyConnection
->queryAggregation(_rType
) : aReturn
);
146 Sequence
< Type
> SAL_CALL
OConnectionWrapper::getTypes( )
148 return ::comphelper::concatSequences(
149 OConnection_BASE::getTypes(),
150 m_xTypeProvider
->getTypes()
154 // css::lang::XUnoTunnel
155 sal_Int64 SAL_CALL
OConnectionWrapper::getSomething( const Sequence
< sal_Int8
>& rId
)
157 if (isUnoTunnelId
<OConnectionWrapper
>(rId
))
158 return reinterpret_cast< sal_Int64
>( this );
160 if(m_xUnoTunnel
.is())
161 return m_xUnoTunnel
->getSomething(rId
);
166 Sequence
< sal_Int8
> OConnectionWrapper::getUnoTunnelId()
168 static ::cppu::OImplementationId implId
;
170 return implId
.getImplementationId();
175 class TPropertyValueLessFunctor
178 TPropertyValueLessFunctor()
180 bool operator() (const css::beans::PropertyValue
& lhs
, const css::beans::PropertyValue
& rhs
) const
182 return lhs
.Name
.compareToIgnoreAsciiCase(rhs
.Name
) < 0;
189 // creates a unique id out of the url and sequence of properties
190 void OConnectionWrapper::createUniqueId( const OUString
& _rURL
191 ,Sequence
< PropertyValue
>& _rInfo
193 ,const OUString
& _rUserName
194 ,const OUString
& _rPassword
)
196 // first we create the digest we want to have
197 ::comphelper::Hash
sha1(::comphelper::HashType::SHA1
);
198 sha1
.update(reinterpret_cast<unsigned char const*>(_rURL
.getStr()), _rURL
.getLength() * sizeof(sal_Unicode
));
199 if ( !_rUserName
.isEmpty() )
200 sha1
.update(reinterpret_cast<unsigned char const*>(_rUserName
.getStr()), _rUserName
.getLength() * sizeof(sal_Unicode
));
201 if ( !_rPassword
.isEmpty() )
202 sha1
.update(reinterpret_cast<unsigned char const*>(_rPassword
.getStr()), _rPassword
.getLength() * sizeof(sal_Unicode
));
203 // now we need to sort the properties
204 std::sort(_rInfo
.begin(),_rInfo
.end(),TPropertyValueLessFunctor());
206 for (PropertyValue
const & prop
: std::as_const(_rInfo
))
208 // we only include strings an integer values
210 if ( prop
.Value
>>= sValue
)
214 sal_Int32 nValue
= 0;
215 if ( prop
.Value
>>= nValue
)
216 sValue
= OUString::number(nValue
);
219 Sequence
< OUString
> aSeq
;
220 if ( prop
.Value
>>= aSeq
)
222 for(OUString
const & s
: std::as_const(aSeq
))
223 sha1
.update(reinterpret_cast<unsigned char const*>(s
.getStr()), s
.getLength() * sizeof(sal_Unicode
));
227 if ( !sValue
.isEmpty() )
229 // we don't have to convert this into UTF8 because we don't store on a file system
230 sha1
.update(reinterpret_cast<unsigned char const*>(sValue
.getStr()), sValue
.getLength() * sizeof(sal_Unicode
));
234 std::vector
<unsigned char> result(sha1
.finalize());
235 std::copy(result
.begin(), result
.end(), _pBuffer
);
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */