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 .
21 #include <dynamicresultsetwrapper.hxx>
22 #include <ucbhelper/macros.hxx>
23 #include <osl/diagnose.h>
24 #include <rtl/ustring.hxx>
25 #include <com/sun/star/ucb/ListActionType.hpp>
26 #include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
27 #include <com/sun/star/ucb/CachedDynamicResultSetStubFactory.hpp>
29 using namespace com::sun::star::lang
;
30 using namespace com::sun::star::sdbc
;
31 using namespace com::sun::star::ucb
;
32 using namespace com::sun::star::uno
;
38 // class DynamicResultSetWrapper
42 DynamicResultSetWrapper::DynamicResultSetWrapper(
43 Reference
< XDynamicResultSet
> xOrigin
44 , const Reference
< XComponentContext
> & rxContext
)
46 : m_bDisposed( false )
47 , m_bInDispose( false )
48 , m_pDisposeEventListeners( NULL
)
49 , m_xContext( rxContext
)
51 , m_bGotWelcome( false )
52 , m_xSource( xOrigin
)
53 , m_xSourceResultOne( NULL
)
54 , m_xSourceResultTwo( NULL
)
55 // , m_xSourceResultCurrent( NULL )
56 // , m_bUseOne( NULL )
57 , m_xMyResultOne( NULL
)
58 , m_xMyResultTwo( NULL
)
61 m_pMyListenerImpl
= new DynamicResultSetWrapperListener( this );
62 m_xMyListenerImpl
= Reference
< XDynamicResultSetListener
>( m_pMyListenerImpl
);
63 //call impl_init() at the end of constructor of derived class
66 void SAL_CALL
DynamicResultSetWrapper::impl_init()
68 //call this at the end of constructor of derived class
71 Reference
< XDynamicResultSet
> xSource
= NULL
;
73 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
81 DynamicResultSetWrapper::~DynamicResultSetWrapper()
83 //call impl_deinit() at start of destructor of derived class
85 delete m_pDisposeEventListeners
;
88 void SAL_CALL
DynamicResultSetWrapper::impl_deinit()
90 //call this at start of destructor of derived class
92 m_pMyListenerImpl
->impl_OwnerDies();
95 void SAL_CALL DynamicResultSetWrapper
96 ::impl_EnsureNotDisposed()
97 throw( DisposedException
, RuntimeException
)
99 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
101 throw DisposedException();
105 void SAL_CALL DynamicResultSetWrapper
106 ::impl_InitResultSetOne( const Reference
< XResultSet
>& xResultSet
)
108 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
109 OSL_ENSURE( !m_xSourceResultOne
.is(), "Source ResultSet One is set already" );
110 m_xSourceResultOne
= xResultSet
;
111 m_xMyResultOne
= xResultSet
;
115 void SAL_CALL DynamicResultSetWrapper
116 ::impl_InitResultSetTwo( const Reference
< XResultSet
>& xResultSet
)
118 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
119 OSL_ENSURE( !m_xSourceResultTwo
.is(), "Source ResultSet Two is set already" );
120 m_xSourceResultTwo
= xResultSet
;
121 m_xMyResultTwo
= xResultSet
;
124 // XInterface methods.
125 css::uno::Any SAL_CALL
DynamicResultSetWrapper::queryInterface( const css::uno::Type
& rType
)
126 throw( css::uno::RuntimeException
, std::exception
)
128 //list all interfaces inclusive baseclasses of interfaces
129 css::uno::Any aRet
= cppu::queryInterface( rType
,
130 (static_cast< XComponent
* >(this)), //base of XDynamicResultSet
131 (static_cast< XDynamicResultSet
* >(this)),
132 (static_cast< XSourceInitialization
* >(this))
134 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
137 // XComponent methods.
140 void SAL_CALL DynamicResultSetWrapper
141 ::dispose() throw( RuntimeException
, std::exception
)
143 impl_EnsureNotDisposed();
145 Reference
< XComponent
> xSourceComponent
;
147 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
148 if( m_bInDispose
|| m_bDisposed
)
152 xSourceComponent
= Reference
< XComponent
>(m_xSource
, UNO_QUERY
);
154 if( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
157 aEvt
.Source
= static_cast< XComponent
* >( this );
160 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
164 /* //@todo ?? ( only if java collection needs to long )
165 if( xSourceComponent.is() )
166 xSourceComponent->dispose();
169 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
171 m_bInDispose
= false;
176 void SAL_CALL DynamicResultSetWrapper
177 ::addEventListener( const Reference
< XEventListener
>& Listener
)
178 throw( RuntimeException
, std::exception
)
180 impl_EnsureNotDisposed();
181 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
183 if ( !m_pDisposeEventListeners
)
184 m_pDisposeEventListeners
=
185 new OInterfaceContainerHelper( m_aContainerMutex
);
187 m_pDisposeEventListeners
->addInterface( Listener
);
192 void SAL_CALL DynamicResultSetWrapper
193 ::removeEventListener( const Reference
< XEventListener
>& Listener
)
194 throw( RuntimeException
, std::exception
)
196 impl_EnsureNotDisposed();
197 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
199 if ( m_pDisposeEventListeners
)
200 m_pDisposeEventListeners
->removeInterface( Listener
);
208 void SAL_CALL DynamicResultSetWrapper
209 ::impl_disposing( const EventObject
& )
210 throw( RuntimeException
)
212 impl_EnsureNotDisposed();
214 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
216 if( !m_xSource
.is() )
219 //release all references to the broadcaster:
221 m_xSourceResultOne
.clear();//?? or only when not static??
222 m_xSourceResultTwo
.clear();//??
223 //@todo m_xMyResultOne.clear(); ???
224 //@todo m_xMyResultTwo.clear(); ???
228 void SAL_CALL DynamicResultSetWrapper
229 ::impl_notify( const ListEvent
& Changes
)
230 throw( RuntimeException
)
232 impl_EnsureNotDisposed();
235 <p>The Listener is allowed to blockade this call, until he really want to go
236 to the new version. The only situation, where the listener has to return the
237 update call at once is, while he disposes his broadcaster or while he is
238 removing himsef as listener (otherwise you deadlock)!!!
240 // handle the actions in the list
243 aNewEvent
.Source
= static_cast< XDynamicResultSet
* >( this );
244 aNewEvent
.Changes
= Changes
.Changes
;
247 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
248 for( long i
=0; !m_bGotWelcome
&& i
<Changes
.Changes
.getLength(); i
++ )
250 ListAction
& rAction
= aNewEvent
.Changes
[i
];
251 switch( rAction
.ListActionType
)
253 case ListActionType::WELCOME
:
255 WelcomeDynamicResultSetStruct aWelcome
;
256 if( rAction
.ActionInfo
>>= aWelcome
)
258 impl_InitResultSetOne( aWelcome
.Old
);
259 impl_InitResultSetTwo( aWelcome
.New
);
260 m_bGotWelcome
= true;
262 aWelcome
.Old
= m_xMyResultOne
;
263 aWelcome
.New
= m_xMyResultTwo
;
265 rAction
.ActionInfo
<<= aWelcome
;
269 OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
270 //throw RuntimeException();
276 OSL_ENSURE( m_bGotWelcome
, "first notification was without WELCOME" );
279 if( !m_xListener
.is() )
280 m_aListenerSet
.wait();
281 m_xListener
->notify( aNewEvent
);
284 m_bUseOne = !m_bUseOne;
286 m_xSourceResultCurrent = m_xSourceResultOne;
288 m_xSourceResultCurrent = m_xSourceResultTwo;
293 // XSourceInitialization
296 void SAL_CALL DynamicResultSetWrapper
297 ::setSource( const Reference
< XInterface
> & Source
)
298 throw( AlreadyInitializedException
, RuntimeException
, std::exception
)
300 impl_EnsureNotDisposed();
302 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
305 throw AlreadyInitializedException();
309 Reference
< XDynamicResultSet
> xSourceDynamic( Source
, UNO_QUERY
);
310 OSL_ENSURE( xSourceDynamic
.is(),
311 "the given source is not of required type XDynamicResultSet" );
313 Reference
< XDynamicResultSetListener
> xListener
= NULL
;
314 Reference
< XDynamicResultSetListener
> xMyListenerImpl
= NULL
;
316 bool bStatic
= false;
318 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
319 m_xSource
= xSourceDynamic
;
320 xListener
= m_xListener
;
322 xMyListenerImpl
= m_xMyListenerImpl
;
325 xSourceDynamic
->setListener( m_xMyListenerImpl
);
328 Reference
< XComponent
> xSourceComponent( Source
, UNO_QUERY
);
329 xSourceComponent
->addEventListener( Reference
< XEventListener
> ::query( xMyListenerImpl
) );
338 Reference
< XResultSet
> SAL_CALL DynamicResultSetWrapper
339 ::getStaticResultSet()
340 throw( ListenerAlreadySetException
, RuntimeException
, std::exception
)
342 impl_EnsureNotDisposed();
344 Reference
< XDynamicResultSet
> xSource
= NULL
;
345 Reference
< XEventListener
> xMyListenerImpl
= NULL
;
347 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
348 if( m_xListener
.is() )
349 throw ListenerAlreadySetException();
353 xMyListenerImpl
= Reference
< XEventListener
> ::query( m_xMyListenerImpl
);
358 xSource
->addEventListener( xMyListenerImpl
);
364 Reference
< XResultSet
> xResultSet
= xSource
->getStaticResultSet();
365 impl_InitResultSetOne( xResultSet
);
366 return m_xMyResultOne
;
370 void SAL_CALL DynamicResultSetWrapper
371 ::setListener( const Reference
<
372 XDynamicResultSetListener
> & Listener
)
373 throw( ListenerAlreadySetException
, RuntimeException
, std::exception
)
375 impl_EnsureNotDisposed();
377 Reference
< XDynamicResultSet
> xSource
= NULL
;
378 Reference
< XDynamicResultSetListener
> xMyListenerImpl
= NULL
;
380 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
381 if( m_xListener
.is() )
382 throw ListenerAlreadySetException();
384 throw ListenerAlreadySetException();
386 m_xListener
= Listener
;
387 addEventListener( Reference
< XEventListener
>::query( Listener
) );
390 xMyListenerImpl
= m_xMyListenerImpl
;
393 xSource
->setListener( xMyListenerImpl
);
395 m_aListenerSet
.set();
399 void SAL_CALL DynamicResultSetWrapper
400 ::connectToCache( const Reference
< XDynamicResultSet
> & xCache
)
401 throw( ListenerAlreadySetException
, AlreadyInitializedException
, ServiceNotFoundException
, RuntimeException
, std::exception
)
403 impl_EnsureNotDisposed();
405 if( m_xListener
.is() )
406 throw ListenerAlreadySetException();
408 throw ListenerAlreadySetException();
410 Reference
< XSourceInitialization
> xTarget( xCache
, UNO_QUERY
);
411 OSL_ENSURE( xTarget
.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
412 if( xTarget
.is() && m_xContext
.is() )
414 //@todo m_aSourceSet.wait();?
416 Reference
< XCachedDynamicResultSetStubFactory
> xStubFactory
;
419 xStubFactory
= CachedDynamicResultSetStubFactory::create( m_xContext
);
421 catch ( Exception
const & )
425 if( xStubFactory
.is() )
427 xStubFactory
->connectToCache(
428 this, xCache
, Sequence
< NumberedSortingInfo
> (), NULL
);
432 OSL_FAIL( "could not connect to cache" );
433 throw ServiceNotFoundException();
437 sal_Int16 SAL_CALL DynamicResultSetWrapper
439 throw( RuntimeException
, std::exception
)
441 impl_EnsureNotDisposed();
444 Reference
< XDynamicResultSet
> xSource
= NULL
;
446 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
449 return xSource
->getCapabilities();
454 // class DynamicResultSetWrapperListener
458 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
459 DynamicResultSetWrapper
* pOwner
)
465 DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
471 // XInterface methods.
473 void SAL_CALL
DynamicResultSetWrapperListener::acquire()
476 OWeakObject::acquire();
479 void SAL_CALL
DynamicResultSetWrapperListener::release()
482 OWeakObject::release();
485 css::uno::Any SAL_CALL
DynamicResultSetWrapperListener::queryInterface( const css::uno::Type
& rType
)
486 throw( css::uno::RuntimeException
, std::exception
)
488 css::uno::Any aRet
= cppu::queryInterface( rType
,
489 (static_cast< XDynamicResultSetListener
* >(this)),
490 (static_cast< XEventListener
* >(this))
492 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
495 // XDynamicResultSetListener methods:
498 void SAL_CALL DynamicResultSetWrapperListener
499 ::disposing( const EventObject
& rEventObject
)
500 throw( RuntimeException
, std::exception
)
502 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
505 m_pOwner
->impl_disposing( rEventObject
);
509 void SAL_CALL DynamicResultSetWrapperListener
510 ::notify( const ListEvent
& Changes
)
511 throw( RuntimeException
, std::exception
)
513 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
516 m_pOwner
->impl_notify( Changes
);
523 void SAL_CALL DynamicResultSetWrapperListener
526 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
531 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */