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>
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
);
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
);
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
;
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
);
173 // -----------------------------------------------------------------------------
174 Sequence
< sal_Int8
> OConnectionWrapper::getUnoTunnelImplementationId()
176 static ::cppu::OImplementationId
* pId
= 0;
179 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
182 static ::cppu::OImplementationId aId
;
186 return pId
->getImplementationId();
188 // -----------------------------------------------------------------------------
191 class TPropertyValueLessFunctor
: public ::std::binary_function
< ::com::sun::star::beans::PropertyValue
,::com::sun::star::beans::PropertyValue
,bool>
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
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
)
234 sal_Int32 nValue
= 0;
235 if ( pBegin
->Value
>>= nValue
)
236 sValue
= ::rtl::OUString::valueOf(nValue
);
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: */