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/ColumnValue.hpp>
23 #include <com/sun/star/sdbc/XRow.hpp>
24 #include <com/sun/star/sdbc/XConnection.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <comphelper/uno3.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <comphelper/hash.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <cppuhelper/typeprovider.hxx>
31 #include <com/sun/star/reflection/ProxyFactory.hpp>
35 using namespace connectivity
;
37 using namespace com::sun::star::uno
;
38 using namespace com::sun::star::lang
;
39 using namespace com::sun::star::beans
;
40 using namespace com::sun::star::sdbc
;
41 using namespace ::com::sun::star::reflection
;
43 OConnectionWrapper::OConnectionWrapper()
48 void OConnectionWrapper::setDelegation(Reference
< XAggregation
>& _rxProxyConnection
,oslInterlockedCount
& _rRefCount
)
50 OSL_ENSURE(_rxProxyConnection
.is(),"OConnectionWrapper: Connection must be valid!");
51 osl_atomic_increment( &_rRefCount
);
52 if (_rxProxyConnection
.is())
54 // transfer the (one and only) real ref to the aggregate to our member
55 m_xProxyConnection
= _rxProxyConnection
;
56 _rxProxyConnection
= nullptr;
57 ::comphelper::query_aggregation(m_xProxyConnection
,m_xConnection
);
58 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
59 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
60 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
62 // set ourself as delegator
63 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
64 m_xProxyConnection
->setDelegator( xIf
);
67 osl_atomic_decrement( &_rRefCount
);
70 void OConnectionWrapper::setDelegation(const Reference
< XConnection
>& _xConnection
71 ,const Reference
< XComponentContext
>& _rxContext
72 ,oslInterlockedCount
& _rRefCount
)
74 OSL_ENSURE(_xConnection
.is(),"OConnectionWrapper: Connection must be valid!");
75 osl_atomic_increment( &_rRefCount
);
77 m_xConnection
= _xConnection
;
78 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
79 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
80 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
82 Reference
< XProxyFactory
> xProxyFactory
= ProxyFactory::create( _rxContext
);
83 Reference
< XAggregation
> xConProxy
= xProxyFactory
->createProxy(_xConnection
);
86 // transfer the (one and only) real ref to the aggregate to our member
87 m_xProxyConnection
= xConProxy
;
89 // set ourself as delegator
90 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
91 m_xProxyConnection
->setDelegator( xIf
);
94 osl_atomic_decrement( &_rRefCount
);
97 void OConnectionWrapper::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 OUString( "com.sun.star.sdbc.drivers.OConnectionWrapper" );
116 css::uno::Sequence
< OUString
> SAL_CALL
OConnectionWrapper::getSupportedServiceNames( )
118 // first collect the services which are supported by our aggregate
119 Sequence
< OUString
> aSupported
;
120 if ( m_xServiceInfo
.is() )
121 aSupported
= m_xServiceInfo
->getSupportedServiceNames();
123 // append our own service, if necessary
124 OUString
sConnectionService( "com.sun.star.sdbc.Connection" );
125 if ( ::comphelper::findValue( aSupported
, sConnectionService
) == -1 )
127 sal_Int32 nLen
= aSupported
.getLength();
128 aSupported
.realloc( nLen
+ 1 );
129 aSupported
[ nLen
] = sConnectionService
;
137 sal_Bool SAL_CALL
OConnectionWrapper::supportsService( const OUString
& _rServiceName
)
139 return cppu::supportsService(this, _rServiceName
);
143 Any SAL_CALL
OConnectionWrapper::queryInterface( const Type
& _rType
)
145 Any aReturn
= OConnection_BASE::queryInterface(_rType
);
146 return aReturn
.hasValue() ? aReturn
: (m_xProxyConnection
.is() ? m_xProxyConnection
->queryAggregation(_rType
) : aReturn
);
149 Sequence
< Type
> SAL_CALL
OConnectionWrapper::getTypes( )
151 return ::comphelper::concatSequences(
152 OConnection_BASE::getTypes(),
153 m_xTypeProvider
->getTypes()
157 // css::lang::XUnoTunnel
158 sal_Int64 SAL_CALL
OConnectionWrapper::getSomething( const Sequence
< sal_Int8
>& rId
)
160 if (rId
.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId
.getConstArray(), 16 ) )
161 return reinterpret_cast< sal_Int64
>( this );
163 if(m_xUnoTunnel
.is())
164 return m_xUnoTunnel
->getSomething(rId
);
169 Sequence
< sal_Int8
> OConnectionWrapper::getUnoTunnelImplementationId()
171 static ::cppu::OImplementationId implId
;
173 return implId
.getImplementationId();
178 class TPropertyValueLessFunctor
181 TPropertyValueLessFunctor()
183 bool operator() (const css::beans::PropertyValue
& lhs
, const css::beans::PropertyValue
& rhs
) const
185 return lhs
.Name
.compareToIgnoreAsciiCase(rhs
.Name
) < 0;
192 // creates a unique id out of the url and sequence of properties
193 void OConnectionWrapper::createUniqueId( const OUString
& _rURL
194 ,Sequence
< PropertyValue
>& _rInfo
196 ,const OUString
& _rUserName
197 ,const OUString
& _rPassword
)
199 // first we create the digest we want to have
200 ::comphelper::Hash
sha1(::comphelper::HashType::SHA1
);
201 sha1
.update(reinterpret_cast<unsigned char const*>(_rURL
.getStr()), _rURL
.getLength() * sizeof(sal_Unicode
));
202 if ( !_rUserName
.isEmpty() )
203 sha1
.update(reinterpret_cast<unsigned char const*>(_rUserName
.getStr()), _rUserName
.getLength() * sizeof(sal_Unicode
));
204 if ( !_rPassword
.isEmpty() )
205 sha1
.update(reinterpret_cast<unsigned char const*>(_rPassword
.getStr()), _rPassword
.getLength() * sizeof(sal_Unicode
));
206 // now we need to sort the properties
207 std::sort(_rInfo
.begin(),_rInfo
.end(),TPropertyValueLessFunctor());
209 for (PropertyValue
const & prop
: _rInfo
)
211 // we only include strings an integer values
213 if ( prop
.Value
>>= sValue
)
217 sal_Int32 nValue
= 0;
218 if ( prop
.Value
>>= nValue
)
219 sValue
= OUString::number(nValue
);
222 Sequence
< OUString
> aSeq
;
223 if ( prop
.Value
>>= aSeq
)
225 for(OUString
const & s
: aSeq
)
226 sha1
.update(reinterpret_cast<unsigned char const*>(s
.getStr()), s
.getLength() * sizeof(sal_Unicode
));
230 if ( !sValue
.isEmpty() )
232 // we don't have to convert this into UTF8 because we don't store on a file system
233 sha1
.update(reinterpret_cast<unsigned char const*>(sValue
.getStr()), sValue
.getLength() * sizeof(sal_Unicode
));
237 std::vector
<unsigned char> result(sha1
.finalize());
238 std::copy(result
.begin(), result
.end(), _pBuffer
);
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */