Bump for 3.6-28
[LibreOffice.git] / connectivity / source / commontools / ConnectionWrapper.cxx
blobf66843395682477179319b7124c019a07fee9f87
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "connectivity/ConnectionWrapper.hxx"
30 #include <com/sun/star/sdbc/ColumnValue.hpp>
31 #include <com/sun/star/sdbc/XRow.hpp>
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <comphelper/uno3.hxx>
34 #include <comphelper/sequence.hxx>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <com/sun/star/reflection/XProxyFactory.hpp>
37 #include <rtl/digest.h>
38 #include <algorithm>
40 using namespace connectivity;
41 //------------------------------------------------------------------------------
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::lang;
44 using namespace com::sun::star::beans;
45 using namespace com::sun::star::sdbc;
46 using namespace ::com::sun::star::reflection;
47 // --------------------------------------------------------------------------------
48 OConnectionWrapper::OConnectionWrapper()
52 // -----------------------------------------------------------------------------
53 void OConnectionWrapper::setDelegation(Reference< XAggregation >& _rxProxyConnection,oslInterlockedCount& _rRefCount)
55 OSL_ENSURE(_rxProxyConnection.is(),"OConnectionWrapper: Connection must be valid!");
56 osl_incrementInterlockedCount( &_rRefCount );
57 if (_rxProxyConnection.is())
59 // transfer the (one and only) real ref to the aggregate to our member
60 m_xProxyConnection = _rxProxyConnection;
61 _rxProxyConnection = NULL;
62 ::comphelper::query_aggregation(m_xProxyConnection,m_xConnection);
63 m_xTypeProvider.set(m_xConnection,UNO_QUERY);
64 m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
65 m_xServiceInfo.set(m_xConnection,UNO_QUERY);
67 // set ourself as delegator
68 Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
69 m_xProxyConnection->setDelegator( xIf );
72 osl_decrementInterlockedCount( &_rRefCount );
74 // -----------------------------------------------------------------------------
75 void OConnectionWrapper::setDelegation(const Reference< XConnection >& _xConnection
76 ,const Reference< XMultiServiceFactory>& _xORB
77 ,oslInterlockedCount& _rRefCount)
79 OSL_ENSURE(_xConnection.is(),"OConnectionWrapper: Connection must be valid!");
80 osl_incrementInterlockedCount( &_rRefCount );
82 m_xConnection = _xConnection;
83 m_xTypeProvider.set(m_xConnection,UNO_QUERY);
84 m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
85 m_xServiceInfo.set(m_xConnection,UNO_QUERY);
87 Reference< XProxyFactory > xProxyFactory(_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
88 Reference< XAggregation > xConProxy = xProxyFactory->createProxy(_xConnection);
89 if (xConProxy.is())
91 // transfer the (one and only) real ref to the aggregate to our member
92 m_xProxyConnection = xConProxy;
94 // set ourself as delegator
95 Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
96 m_xProxyConnection->setDelegator( xIf );
99 osl_decrementInterlockedCount( &_rRefCount );
101 // -----------------------------------------------------------------------------
102 void OConnectionWrapper::disposing()
104 m_xConnection.clear();
106 //-----------------------------------------------------------------------------
107 OConnectionWrapper::~OConnectionWrapper()
109 if (m_xProxyConnection.is())
110 m_xProxyConnection->setDelegator(NULL);
113 // XServiceInfo
114 // --------------------------------------------------------------------------------
115 ::rtl::OUString SAL_CALL OConnectionWrapper::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException)
117 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.drivers.OConnectionWrapper" ) );
120 // --------------------------------------------------------------------------------
121 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConnectionWrapper::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException)
123 // first collect the services which are supported by our aggregate
124 Sequence< ::rtl::OUString > aSupported;
125 if ( m_xServiceInfo.is() )
126 aSupported = m_xServiceInfo->getSupportedServiceNames();
128 // append our own service, if necessary
129 ::rtl::OUString sConnectionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) );
130 if ( 0 == ::comphelper::findValue( aSupported, sConnectionService, sal_True ).getLength() )
132 sal_Int32 nLen = aSupported.getLength();
133 aSupported.realloc( nLen + 1 );
134 aSupported[ nLen ] = sConnectionService;
137 // outta here
138 return aSupported;
141 // --------------------------------------------------------------------------------
142 sal_Bool SAL_CALL OConnectionWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)
144 return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName, sal_True ).getLength() != 0;
147 // --------------------------------------------------------------------------------
148 Any SAL_CALL OConnectionWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
150 Any aReturn = OConnection_BASE::queryInterface(_rType);
151 return aReturn.hasValue() ? aReturn : (m_xProxyConnection.is() ? m_xProxyConnection->queryAggregation(_rType) : aReturn);
153 // --------------------------------------------------------------------------------
154 Sequence< Type > SAL_CALL OConnectionWrapper::getTypes( ) throw (::com::sun::star::uno::RuntimeException)
156 return ::comphelper::concatSequences(
157 OConnection_BASE::getTypes(),
158 m_xTypeProvider->getTypes()
161 // -----------------------------------------------------------------------------
162 // com::sun::star::lang::XUnoTunnel
163 sal_Int64 SAL_CALL OConnectionWrapper::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
165 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
166 return reinterpret_cast< sal_Int64 >( this );
168 if(m_xUnoTunnel.is())
169 return m_xUnoTunnel->getSomething(rId);
170 return 0;
173 // -----------------------------------------------------------------------------
174 Sequence< sal_Int8 > OConnectionWrapper::getUnoTunnelImplementationId()
176 static ::cppu::OImplementationId * pId = 0;
177 if (! pId)
179 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
180 if (! pId)
182 static ::cppu::OImplementationId aId;
183 pId = &aId;
186 return pId->getImplementationId();
188 // -----------------------------------------------------------------------------
189 namespace
191 class TPropertyValueLessFunctor : public ::std::binary_function< ::com::sun::star::beans::PropertyValue,::com::sun::star::beans::PropertyValue,bool>
193 public:
194 TPropertyValueLessFunctor()
196 bool operator() (const ::com::sun::star::beans::PropertyValue& lhs, const ::com::sun::star::beans::PropertyValue& rhs) const
198 return !!(lhs.Name.equalsIgnoreAsciiCase( rhs.Name ));
204 // -----------------------------------------------------------------------------
205 // creates a unique id out of the url and sequence of properties
206 void OConnectionWrapper::createUniqueId( const ::rtl::OUString& _rURL
207 ,Sequence< PropertyValue >& _rInfo
208 ,sal_uInt8* _pBuffer
209 ,const ::rtl::OUString& _rUserName
210 ,const ::rtl::OUString& _rPassword)
212 // first we create the digest we want to have
213 rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
214 rtl_digest_update(aDigest,_rURL.getStr(),_rURL.getLength()*sizeof(sal_Unicode));
215 if ( !_rUserName.isEmpty() )
216 rtl_digest_update(aDigest,_rUserName.getStr(),_rUserName.getLength()*sizeof(sal_Unicode));
217 if ( !_rPassword.isEmpty() )
218 rtl_digest_update(aDigest,_rPassword.getStr(),_rPassword.getLength()*sizeof(sal_Unicode));
219 // now we need to sort the properties
220 PropertyValue* pBegin = _rInfo.getArray();
221 PropertyValue* pEnd = pBegin + _rInfo.getLength();
222 ::std::sort(pBegin,pEnd,TPropertyValueLessFunctor());
224 pBegin = _rInfo.getArray();
225 pEnd = pBegin + _rInfo.getLength();
226 for (; pBegin != pEnd; ++pBegin)
228 // we only include strings an integer values
229 ::rtl::OUString sValue;
230 if ( pBegin->Value >>= sValue )
232 else
234 sal_Int32 nValue = 0;
235 if ( pBegin->Value >>= nValue )
236 sValue = ::rtl::OUString::valueOf(nValue);
237 else
239 Sequence< ::rtl::OUString> aSeq;
240 if ( pBegin->Value >>= aSeq )
242 const ::rtl::OUString* pSBegin = aSeq.getConstArray();
243 const ::rtl::OUString* pSEnd = pSBegin + aSeq.getLength();
244 for(;pSBegin != pSEnd;++pSBegin)
245 rtl_digest_update(aDigest,pSBegin->getStr(),pSBegin->getLength()*sizeof(sal_Unicode));
249 if ( !sValue.isEmpty() )
251 // we don't have to convert this into UTF8 because we don't store on a file system
252 rtl_digest_update(aDigest,sValue.getStr(),sValue.getLength()*sizeof(sal_Unicode));
256 rtl_digest_get(aDigest,_pBuffer,RTL_DIGEST_LENGTH_SHA1);
257 // we have to destroy the digest
258 rtl_digest_destroy(aDigest);
260 // -----------------------------------------------------------------------------
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */