1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ConnectionWrapper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #ifndef _CONNECTIVITY_CONNECTIONWRAPPER_HXX_
34 #include "connectivity/ConnectionWrapper.hxx"
36 #include <com/sun/star/sdbc/ColumnValue.hpp>
37 #include <com/sun/star/sdbc/XRow.hpp>
38 #include <com/sun/star/lang/DisposedException.hpp>
39 #include <comphelper/uno3.hxx>
40 #include <comphelper/sequence.hxx>
41 #include <cppuhelper/typeprovider.hxx>
42 #include <com/sun/star/reflection/XProxyFactory.hpp>
43 #include <rtl/digest.h>
48 using namespace connectivity
;
49 //------------------------------------------------------------------------------
50 using namespace com::sun::star::uno
;
51 using namespace com::sun::star::lang
;
52 using namespace com::sun::star::beans
;
53 using namespace com::sun::star::sdbc
;
54 using namespace ::com::sun::star::reflection
;
55 // --------------------------------------------------------------------------------
56 OConnectionWrapper::OConnectionWrapper()
60 // -----------------------------------------------------------------------------
61 void OConnectionWrapper::setDelegation(Reference
< XAggregation
>& _rxProxyConnection
,oslInterlockedCount
& _rRefCount
)
63 OSL_ENSURE(_rxProxyConnection
.is(),"OConnectionWrapper: Connection must be valid!");
64 osl_incrementInterlockedCount( &_rRefCount
);
65 if (_rxProxyConnection
.is())
67 // transfer the (one and only) real ref to the aggregate to our member
68 m_xProxyConnection
= _rxProxyConnection
;
69 _rxProxyConnection
= NULL
;
70 ::comphelper::query_aggregation(m_xProxyConnection
,m_xConnection
);
71 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
72 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
73 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
75 // set ourself as delegator
76 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
77 m_xProxyConnection
->setDelegator( xIf
);
80 osl_decrementInterlockedCount( &_rRefCount
);
82 // -----------------------------------------------------------------------------
83 void OConnectionWrapper::setDelegation(const Reference
< XConnection
>& _xConnection
84 ,const Reference
< XMultiServiceFactory
>& _xORB
85 ,oslInterlockedCount
& _rRefCount
)
87 OSL_ENSURE(_xConnection
.is(),"OConnectionWrapper: Connection must be valid!");
88 osl_incrementInterlockedCount( &_rRefCount
);
90 m_xConnection
= _xConnection
;
91 m_xTypeProvider
.set(m_xConnection
,UNO_QUERY
);
92 m_xUnoTunnel
.set(m_xConnection
,UNO_QUERY
);
93 m_xServiceInfo
.set(m_xConnection
,UNO_QUERY
);
95 Reference
< XProxyFactory
> xProxyFactory(_xORB
->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY
);
96 Reference
< XAggregation
> xConProxy
= xProxyFactory
->createProxy(_xConnection
);
99 // transfer the (one and only) real ref to the aggregate to our member
100 m_xProxyConnection
= xConProxy
;
102 // set ourself as delegator
103 Reference
<XInterface
> xIf
= static_cast< XUnoTunnel
* >( this );
104 m_xProxyConnection
->setDelegator( xIf
);
107 osl_decrementInterlockedCount( &_rRefCount
);
109 // -----------------------------------------------------------------------------
110 void OConnectionWrapper::disposing()
112 m_xConnection
.clear();
114 //-----------------------------------------------------------------------------
115 OConnectionWrapper::~OConnectionWrapper()
117 if (m_xProxyConnection
.is())
118 m_xProxyConnection
->setDelegator(NULL
);
122 // --------------------------------------------------------------------------------
123 ::rtl::OUString SAL_CALL
OConnectionWrapper::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException
)
125 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.drivers.OConnectionWrapper" ) );
128 // --------------------------------------------------------------------------------
129 ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
OConnectionWrapper::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException
)
131 // first collect the services which are supported by our aggregate
132 Sequence
< ::rtl::OUString
> aSupported
;
133 if ( m_xServiceInfo
.is() )
134 aSupported
= m_xServiceInfo
->getSupportedServiceNames();
136 // append our own service, if necessary
137 ::rtl::OUString
sConnectionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) );
138 if ( 0 == ::comphelper::findValue( aSupported
, sConnectionService
, sal_True
).getLength() )
140 sal_Int32 nLen
= aSupported
.getLength();
141 aSupported
.realloc( nLen
+ 1 );
142 aSupported
[ nLen
] = sConnectionService
;
149 // --------------------------------------------------------------------------------
150 sal_Bool SAL_CALL
OConnectionWrapper::supportsService( const ::rtl::OUString
& _rServiceName
) throw(::com::sun::star::uno::RuntimeException
)
152 return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName
, sal_True
).getLength() != 0;
155 // --------------------------------------------------------------------------------
156 Any SAL_CALL
OConnectionWrapper::queryInterface( const Type
& _rType
) throw (RuntimeException
)
158 Any aReturn
= OConnection_BASE::queryInterface(_rType
);
159 return aReturn
.hasValue() ? aReturn
: (m_xProxyConnection
.is() ? m_xProxyConnection
->queryAggregation(_rType
) : aReturn
);
161 // --------------------------------------------------------------------------------
162 Sequence
< Type
> SAL_CALL
OConnectionWrapper::getTypes( ) throw (::com::sun::star::uno::RuntimeException
)
164 return ::comphelper::concatSequences(
165 OConnection_BASE::getTypes(),
166 m_xTypeProvider
->getTypes()
169 // -----------------------------------------------------------------------------
170 // com::sun::star::lang::XUnoTunnel
171 sal_Int64 SAL_CALL
OConnectionWrapper::getSomething( const Sequence
< sal_Int8
>& rId
) throw(RuntimeException
)
173 if (rId
.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId
.getConstArray(), 16 ) )
174 return reinterpret_cast< sal_Int64
>( this );
176 if(m_xUnoTunnel
.is())
177 return m_xUnoTunnel
->getSomething(rId
);
181 // -----------------------------------------------------------------------------
182 Sequence
< sal_Int8
> OConnectionWrapper::getUnoTunnelImplementationId()
184 static ::cppu::OImplementationId
* pId
= 0;
187 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
190 static ::cppu::OImplementationId aId
;
194 return pId
->getImplementationId();
196 // -----------------------------------------------------------------------------
199 class TPropertyValueLessFunctor
: public ::std::binary_function
< ::com::sun::star::beans::PropertyValue
,::com::sun::star::beans::PropertyValue
,bool>
202 TPropertyValueLessFunctor()
204 bool operator() (const ::com::sun::star::beans::PropertyValue
& lhs
, const ::com::sun::star::beans::PropertyValue
& rhs
) const
206 return !!(lhs
.Name
.equalsIgnoreAsciiCase( rhs
.Name
));
212 // -----------------------------------------------------------------------------
213 // creates a unique id out of the url and sequence of properties
214 void OConnectionWrapper::createUniqueId( const ::rtl::OUString
& _rURL
215 ,Sequence
< PropertyValue
>& _rInfo
217 ,const ::rtl::OUString
& _rUserName
218 ,const ::rtl::OUString
& _rPassword
)
220 // first we create the digest we want to have
221 rtlDigest aDigest
= rtl_digest_create( rtl_Digest_AlgorithmSHA1
);
222 rtlDigestError aError
= rtl_digest_update(aDigest
,_rURL
.getStr(),_rURL
.getLength()*sizeof(sal_Unicode
));
223 if ( _rUserName
.getLength() )
224 aError
= rtl_digest_update(aDigest
,_rUserName
.getStr(),_rUserName
.getLength()*sizeof(sal_Unicode
));
225 if ( _rPassword
.getLength() )
226 aError
= rtl_digest_update(aDigest
,_rPassword
.getStr(),_rPassword
.getLength()*sizeof(sal_Unicode
));
227 // now we need to sort the properties
228 PropertyValue
* pBegin
= _rInfo
.getArray();
229 PropertyValue
* pEnd
= pBegin
+ _rInfo
.getLength();
230 ::std::sort(pBegin
,pEnd
,TPropertyValueLessFunctor());
232 pBegin
= _rInfo
.getArray();
233 pEnd
= pBegin
+ _rInfo
.getLength();
234 for (; pBegin
!= pEnd
; ++pBegin
)
236 // we only include strings an integer values
237 ::rtl::OUString sValue
;
238 if ( pBegin
->Value
>>= sValue
)
242 sal_Int32 nValue
= 0;
243 if ( pBegin
->Value
>>= nValue
)
244 sValue
= ::rtl::OUString::valueOf(nValue
);
247 Sequence
< ::rtl::OUString
> aSeq
;
248 if ( pBegin
->Value
>>= aSeq
)
250 const ::rtl::OUString
* pSBegin
= aSeq
.getConstArray();
251 const ::rtl::OUString
* pSEnd
= pSBegin
+ aSeq
.getLength();
252 for(;pSBegin
!= pSEnd
;++pSBegin
)
253 aError
= rtl_digest_update(aDigest
,pSBegin
->getStr(),pSBegin
->getLength()*sizeof(sal_Unicode
));
257 if ( sValue
.getLength() > 0 )
259 // we don't have to convert this into UTF8 because we don't store on a file system
260 aError
= rtl_digest_update(aDigest
,sValue
.getStr(),sValue
.getLength()*sizeof(sal_Unicode
));
264 aError
= rtl_digest_get(aDigest
,_pBuffer
,RTL_DIGEST_LENGTH_SHA1
);
265 // we have to destroy the digest
266 rtl_digest_destroy(aDigest
);
268 // -----------------------------------------------------------------------------