LibreOffice Module connectivity (master) 1
ConnectionWrapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <com/sun/star/beans/PropertyValue.hpp>
22#include <com/sun/star/sdbc/XConnection.hpp>
23#include <comphelper/uno3.hxx>
26#include <comphelper/hash.hxx>
28#include <com/sun/star/reflection/ProxyFactory.hpp>
29#include <algorithm>
30
31using namespace connectivity;
32
33using namespace com::sun::star::uno;
34using namespace com::sun::star::lang;
35using namespace com::sun::star::beans;
36using namespace com::sun::star::sdbc;
37using namespace ::com::sun::star::reflection;
38
39OConnectionWrapper::OConnectionWrapper()
40{
41
42}
43
44void OConnectionWrapper::setDelegation(Reference< XAggregation >& _rxProxyConnection,oslInterlockedCount& _rRefCount)
45{
46 OSL_ENSURE(_rxProxyConnection.is(),"OConnectionWrapper: Connection must be valid!");
47 osl_atomic_increment( &_rRefCount );
48 if (_rxProxyConnection.is())
49 {
50 // transfer the (one and only) real ref to the aggregate to our member
51 m_xProxyConnection = _rxProxyConnection;
52 _rxProxyConnection = nullptr;
53 ::comphelper::query_aggregation(m_xProxyConnection,m_xConnection);
54 m_xTypeProvider.set(m_xConnection,UNO_QUERY);
55 m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
56 m_xServiceInfo.set(m_xConnection,UNO_QUERY);
57
58 // set ourself as delegator
59 Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
60 m_xProxyConnection->setDelegator( xIf );
61
62 }
63 osl_atomic_decrement( &_rRefCount );
64}
65
67 ,const Reference< XComponentContext>& _rxContext
68 ,oslInterlockedCount& _rRefCount)
69{
70 OSL_ENSURE(_xConnection.is(),"OConnectionWrapper: Connection must be valid!");
71 osl_atomic_increment( &_rRefCount );
72
73 m_xConnection = _xConnection;
74 m_xTypeProvider.set(m_xConnection,UNO_QUERY);
75 m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
76 m_xServiceInfo.set(m_xConnection,UNO_QUERY);
77
78 Reference< XProxyFactory > xProxyFactory = ProxyFactory::create( _rxContext );
79 Reference< XAggregation > xConProxy = xProxyFactory->createProxy(_xConnection);
80 if (xConProxy.is())
81 {
82 // transfer the (one and only) real ref to the aggregate to our member
83 m_xProxyConnection = xConProxy;
84
85 // set ourself as delegator
86 Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
87 m_xProxyConnection->setDelegator( xIf );
88
89 }
90 osl_atomic_decrement( &_rRefCount );
91}
92
94{
95m_xConnection.clear();
96}
97
99{
100 if (m_xProxyConnection.is())
101 m_xProxyConnection->setDelegator(nullptr);
102}
103
104// XServiceInfo
105
106OUString SAL_CALL OConnectionWrapper::getImplementationName( )
107{
108 return "com.sun.star.sdbc.drivers.OConnectionWrapper";
109}
110
111
112css::uno::Sequence< OUString > SAL_CALL OConnectionWrapper::getSupportedServiceNames( )
113{
114 // first collect the services which are supported by our aggregate
115 Sequence< OUString > aSupported;
116 if ( m_xServiceInfo.is() )
117 aSupported = m_xServiceInfo->getSupportedServiceNames();
118
119 // append our own service, if necessary
120 OUString sConnectionService( "com.sun.star.sdbc.Connection" );
121 if ( ::comphelper::findValue( aSupported, sConnectionService ) == -1 )
122 {
123 sal_Int32 nLen = aSupported.getLength();
124 aSupported.realloc( nLen + 1 );
125 aSupported.getArray()[ nLen ] = sConnectionService;
126 }
127
128 // outta here
129 return aSupported;
130}
131
132
133sal_Bool SAL_CALL OConnectionWrapper::supportsService( const OUString& _rServiceName )
134{
135 return cppu::supportsService(this, _rServiceName);
136}
137
138
140{
141 Any aReturn = OConnection_BASE::queryInterface(_rType);
142 return aReturn.hasValue() ? aReturn : (m_xProxyConnection.is() ? m_xProxyConnection->queryAggregation(_rType) : aReturn);
143}
144
146{
147 return ::comphelper::concatSequences(
149 m_xTypeProvider->getTypes()
150 );
151}
152
153// css::lang::XUnoTunnel
155{
156 if (comphelper::isUnoTunnelId<OConnectionWrapper>(rId))
158
159 if(m_xUnoTunnel.is())
160 return m_xUnoTunnel->getSomething(rId);
161 return 0;
162}
163
164
166{
167 static const comphelper::UnoIdInit implId;
168 return implId.getSeq();
169}
170
171namespace
172{
173 class TPropertyValueLessFunctor
174 {
175 public:
176 TPropertyValueLessFunctor()
177 {}
178 bool operator() (const css::beans::PropertyValue& lhs, const css::beans::PropertyValue& rhs) const
179 {
180 return lhs.Name.compareToIgnoreAsciiCase(rhs.Name) < 0;
181 }
182 };
183
184}
185
186
187// creates a unique id out of the url and sequence of properties
188void OConnectionWrapper::createUniqueId( const OUString& _rURL
190 ,sal_uInt8* _pBuffer
191 ,const OUString& _rUserName
192 ,const OUString& _rPassword)
193{
194 // first we create the digest we want to have
195 ::comphelper::Hash sha1(::comphelper::HashType::SHA1);
196 sha1.update(reinterpret_cast<unsigned char const*>(_rURL.getStr()), _rURL.getLength() * sizeof(sal_Unicode));
197 if ( !_rUserName.isEmpty() )
198 sha1.update(reinterpret_cast<unsigned char const*>(_rUserName.getStr()), _rUserName.getLength() * sizeof(sal_Unicode));
199 if ( !_rPassword.isEmpty() )
200 sha1.update(reinterpret_cast<unsigned char const*>(_rPassword.getStr()), _rPassword.getLength() * sizeof(sal_Unicode));
201 // now we need to sort the properties
202 auto [begin, end] = asNonConstRange(_rInfo);
203 std::sort(begin,end,TPropertyValueLessFunctor());
204
205 for (PropertyValue const & prop : std::as_const(_rInfo))
206 {
207 // we only include strings an integer values
208 OUString sValue;
209 if ( prop.Value >>= sValue )
210 ;
211 else
212 {
213 sal_Int32 nValue = 0;
214 if ( prop.Value >>= nValue )
215 sValue = OUString::number(nValue);
216 else
217 {
219 if ( prop.Value >>= aSeq )
220 {
221 for(OUString const & s : std::as_const(aSeq))
222 sha1.update(reinterpret_cast<unsigned char const*>(s.getStr()), s.getLength() * sizeof(sal_Unicode));
223 }
224 }
225 }
226 if ( !sValue.isEmpty() )
227 {
228 // we don't have to convert this into UTF8 because we don't store on a file system
229 sha1.update(reinterpret_cast<unsigned char const*>(sValue.getStr()), sValue.getLength() * sizeof(sal_Unicode));
230 }
231 }
232
233 std::vector<unsigned char> result(sha1.finalize());
234 std::copy(result.begin(), result.end(), _pBuffer);
235}
236
237
238/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< unsigned char > finalize()
void update(const unsigned char *pInput, size_t length)
const css::uno::Sequence< sal_Int8 > & getSeq() const
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &_rType) override
css::uno::Reference< css::lang::XUnoTunnel > m_xUnoTunnel
void setDelegation(css::uno::Reference< css::uno::XAggregation > &_rxProxyConnection, oslInterlockedCount &_rRefCount)
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
static void createUniqueId(const OUString &_rURL, css::uno::Sequence< css::beans::PropertyValue > &_rInfo, sal_uInt8 *_pBuffer, const OUString &_rUserName=OUString(), const OUString &_rPassword=OUString())
method to create unique ids
css::uno::Reference< css::lang::XTypeProvider > m_xTypeProvider
css::uno::Reference< css::lang::XServiceInfo > m_xServiceInfo
css::uno::Reference< css::uno::XAggregation > m_xProxyConnection
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
css::uno::Reference< css::sdbc::XConnection > m_xConnection
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
sal_Int16 nValue
Sequence< sal_Int8 > aSeq
sal_Int64 getSomething_cast(void *p)
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
enumrange< T >::Iterator begin(enumrange< T >)
end
unsigned char sal_uInt8
unsigned char sal_Bool
sal_uInt16 sal_Unicode
Any result