Updated core
[LibreOffice.git] / ucb / source / cacher / dynamicresultsetwrapper.cxx
blob3faca33ec7aadaaaf4fa8dda2b1c969ea30df7cb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
33 using namespace cppu;
36 //--------------------------------------------------------------------------
37 //--------------------------------------------------------------------------
38 // class DynamicResultSetWrapper
39 //--------------------------------------------------------------------------
40 //--------------------------------------------------------------------------
42 DynamicResultSetWrapper::DynamicResultSetWrapper(
43 Reference< XDynamicResultSet > xOrigin
44 , const Reference< XComponentContext > & rxContext )
46 : m_bDisposed( sal_False )
47 , m_bInDispose( sal_False )
48 , m_pDisposeEventListeners( NULL )
49 , m_xContext( rxContext )
50 , m_bStatic( sal_False )
51 , m_bGotWelcome( sal_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 )
59 , m_xListener( 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 );
74 xSource = m_xSource;
75 m_xSource = NULL;
77 if( xSource.is() )
78 setSource( xSource );
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 );
100 if( m_bDisposed )
101 throw DisposedException();
104 //virtual
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;
114 //virtual
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 //--------------------------------------------------------------------------
125 // XInterface methods.
126 //--------------------------------------------------------------------------
127 //list all interfaces inclusive baseclasses of interfaces
128 QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
129 (static_cast< XComponent* >(this)) //base of XDynamicResultSet
130 , (static_cast< XDynamicResultSet* >(this))
131 , (static_cast< XSourceInitialization* >(this))
132 QUERYINTERFACE_IMPL_END
134 //--------------------------------------------------------------------------
135 // XComponent methods.
136 //--------------------------------------------------------------------------
137 // virtual
138 void SAL_CALL DynamicResultSetWrapper
139 ::dispose() throw( RuntimeException )
141 impl_EnsureNotDisposed();
143 Reference< XComponent > xSourceComponent;
145 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
146 if( m_bInDispose || m_bDisposed )
147 return;
148 m_bInDispose = sal_True;
150 xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);
152 if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
154 EventObject aEvt;
155 aEvt.Source = static_cast< XComponent * >( this );
157 aGuard.clear();
158 m_pDisposeEventListeners->disposeAndClear( aEvt );
162 /* //@todo ?? ( only if java collection needs to long )
163 if( xSourceComponent.is() )
164 xSourceComponent->dispose();
167 osl::Guard< osl::Mutex > aGuard( m_aMutex );
168 m_bDisposed = sal_True;
169 m_bInDispose = sal_False;
172 //--------------------------------------------------------------------------
173 // virtual
174 void SAL_CALL DynamicResultSetWrapper
175 ::addEventListener( const Reference< XEventListener >& Listener )
176 throw( RuntimeException )
178 impl_EnsureNotDisposed();
179 osl::Guard< osl::Mutex > aGuard( m_aMutex );
181 if ( !m_pDisposeEventListeners )
182 m_pDisposeEventListeners =
183 new OInterfaceContainerHelper( m_aContainerMutex );
185 m_pDisposeEventListeners->addInterface( Listener );
188 //--------------------------------------------------------------------------
189 // virtual
190 void SAL_CALL DynamicResultSetWrapper
191 ::removeEventListener( const Reference< XEventListener >& Listener )
192 throw( RuntimeException )
194 impl_EnsureNotDisposed();
195 osl::Guard< osl::Mutex > aGuard( m_aMutex );
197 if ( m_pDisposeEventListeners )
198 m_pDisposeEventListeners->removeInterface( Listener );
201 //--------------------------------------------------------------------------
202 // own methods
203 //--------------------------------------------------------------------------
205 //virtual
206 void SAL_CALL DynamicResultSetWrapper
207 ::impl_disposing( const EventObject& )
208 throw( RuntimeException )
210 impl_EnsureNotDisposed();
212 osl::Guard< osl::Mutex > aGuard( m_aMutex );
214 if( !m_xSource.is() )
215 return;
217 //release all references to the broadcaster:
218 m_xSource.clear();
219 m_xSourceResultOne.clear();//?? or only when not static??
220 m_xSourceResultTwo.clear();//??
221 //@todo m_xMyResultOne.clear(); ???
222 //@todo m_xMyResultTwo.clear(); ???
225 //virtual
226 void SAL_CALL DynamicResultSetWrapper
227 ::impl_notify( const ListEvent& Changes )
228 throw( RuntimeException )
230 impl_EnsureNotDisposed();
231 //@todo
233 <p>The Listener is allowed to blockade this call, until he really want to go
234 to the new version. The only situation, where the listener has to return the
235 update call at once is, while he disposes his broadcaster or while he is
236 removing himsef as listener (otherwise you deadlock)!!!
238 // handle the actions in the list
240 ListEvent aNewEvent;
241 aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
242 aNewEvent.Changes = Changes.Changes;
245 osl::Guard< osl::Mutex > aGuard( m_aMutex );
246 for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
248 ListAction& rAction = aNewEvent.Changes[i];
249 switch( rAction.ListActionType )
251 case ListActionType::WELCOME:
253 WelcomeDynamicResultSetStruct aWelcome;
254 if( rAction.ActionInfo >>= aWelcome )
256 impl_InitResultSetOne( aWelcome.Old );
257 impl_InitResultSetTwo( aWelcome.New );
258 m_bGotWelcome = sal_True;
260 aWelcome.Old = m_xMyResultOne;
261 aWelcome.New = m_xMyResultTwo;
263 rAction.ActionInfo <<= aWelcome;
265 else
267 OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
268 //throw RuntimeException();
270 break;
274 OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
277 if( !m_xListener.is() )
278 m_aListenerSet.wait();
279 m_xListener->notify( aNewEvent );
282 m_bUseOne = !m_bUseOne;
283 if( m_bUseOne )
284 m_xSourceResultCurrent = m_xSourceResultOne;
285 else
286 m_xSourceResultCurrent = m_xSourceResultTwo;
290 //--------------------------------------------------------------------------
291 // XSourceInitialization
292 //--------------------------------------------------------------------------
293 //virtual
294 void SAL_CALL DynamicResultSetWrapper
295 ::setSource( const Reference< XInterface > & Source )
296 throw( AlreadyInitializedException, RuntimeException )
298 impl_EnsureNotDisposed();
300 osl::Guard< osl::Mutex > aGuard( m_aMutex );
301 if( m_xSource.is() )
303 throw AlreadyInitializedException();
307 Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
308 OSL_ENSURE( xSourceDynamic.is(),
309 "the given source is not of required type XDynamicResultSet" );
311 Reference< XDynamicResultSetListener > xListener = NULL;
312 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
314 sal_Bool bStatic = sal_False;
316 osl::Guard< osl::Mutex > aGuard( m_aMutex );
317 m_xSource = xSourceDynamic;
318 xListener = m_xListener;
319 bStatic = m_bStatic;
320 xMyListenerImpl = m_xMyListenerImpl;
322 if( xListener.is() )
323 xSourceDynamic->setListener( m_xMyListenerImpl );
324 else if( bStatic )
326 Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
327 xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
329 m_aSourceSet.set();
332 //--------------------------------------------------------------------------
333 // XDynamicResultSet
334 //--------------------------------------------------------------------------
335 //virtual
336 Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
337 ::getStaticResultSet()
338 throw( ListenerAlreadySetException, RuntimeException )
340 impl_EnsureNotDisposed();
342 Reference< XDynamicResultSet > xSource = NULL;
343 Reference< XEventListener > xMyListenerImpl = NULL;
345 osl::Guard< osl::Mutex > aGuard( m_aMutex );
346 if( m_xListener.is() )
347 throw ListenerAlreadySetException();
349 xSource = m_xSource;
350 m_bStatic = sal_True;
351 xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
354 if( xSource.is() )
356 Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
357 xSourceComponent->addEventListener( xMyListenerImpl );
359 if( !xSource.is() )
360 m_aSourceSet.wait();
363 Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
364 impl_InitResultSetOne( xResultSet );
365 return m_xMyResultOne;
368 //virtual
369 void SAL_CALL DynamicResultSetWrapper
370 ::setListener( const Reference<
371 XDynamicResultSetListener > & Listener )
372 throw( ListenerAlreadySetException, RuntimeException )
374 impl_EnsureNotDisposed();
376 Reference< XDynamicResultSet > xSource = NULL;
377 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
379 osl::Guard< osl::Mutex > aGuard( m_aMutex );
380 if( m_xListener.is() )
381 throw ListenerAlreadySetException();
382 if( m_bStatic )
383 throw ListenerAlreadySetException();
385 m_xListener = Listener;
386 addEventListener( Reference< XEventListener >::query( Listener ) );
388 xSource = m_xSource;
389 xMyListenerImpl = m_xMyListenerImpl;
391 if ( xSource.is() )
392 xSource->setListener( xMyListenerImpl );
394 m_aListenerSet.set();
397 //virtual
398 void SAL_CALL DynamicResultSetWrapper
399 ::connectToCache( const Reference< XDynamicResultSet > & xCache )
400 throw( ListenerAlreadySetException, AlreadyInitializedException, ServiceNotFoundException, RuntimeException )
402 impl_EnsureNotDisposed();
404 if( m_xListener.is() )
405 throw ListenerAlreadySetException();
406 if( m_bStatic )
407 throw ListenerAlreadySetException();
409 Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
410 OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
411 if( xTarget.is() && m_xContext.is() )
413 //@todo m_aSourceSet.wait();?
415 Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
418 xStubFactory = CachedDynamicResultSetStubFactory::create( m_xContext );
420 catch ( Exception const & )
424 if( xStubFactory.is() )
426 xStubFactory->connectToCache(
427 this, xCache, Sequence< NumberedSortingInfo > (), NULL );
428 return;
431 OSL_FAIL( "could not connect to cache" );
432 throw ServiceNotFoundException();
435 //virtual
436 sal_Int16 SAL_CALL DynamicResultSetWrapper
437 ::getCapabilities()
438 throw( RuntimeException )
440 impl_EnsureNotDisposed();
442 m_aSourceSet.wait();
443 Reference< XDynamicResultSet > xSource = NULL;
445 osl::Guard< osl::Mutex > aGuard( m_aMutex );
446 xSource = m_xSource;
448 return xSource->getCapabilities();
451 //--------------------------------------------------------------------------
452 //--------------------------------------------------------------------------
453 // class DynamicResultSetWrapperListener
454 //--------------------------------------------------------------------------
455 //--------------------------------------------------------------------------
457 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
458 DynamicResultSetWrapper* pOwner )
459 : m_pOwner( pOwner )
464 DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
469 //--------------------------------------------------------------------------
470 // XInterface methods.
471 //--------------------------------------------------------------------------
472 //list all interfaces inclusive baseclasses of interfaces
473 XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
474 , XDynamicResultSetListener
475 , XEventListener //base of XDynamicResultSetListener
478 //--------------------------------------------------------------------------
479 // XDynamicResultSetListener methods:
480 //--------------------------------------------------------------------------
481 //virtual
482 void SAL_CALL DynamicResultSetWrapperListener
483 ::disposing( const EventObject& rEventObject )
484 throw( RuntimeException )
486 osl::Guard< osl::Mutex > aGuard( m_aMutex );
488 if( m_pOwner )
489 m_pOwner->impl_disposing( rEventObject );
492 //virtual
493 void SAL_CALL DynamicResultSetWrapperListener
494 ::notify( const ListEvent& Changes )
495 throw( RuntimeException )
497 osl::Guard< osl::Mutex > aGuard( m_aMutex );
499 if( m_pOwner )
500 m_pOwner->impl_notify( Changes );
503 //--------------------------------------------------------------------------
504 // own methods:
505 //--------------------------------------------------------------------------
507 void SAL_CALL DynamicResultSetWrapperListener
508 ::impl_OwnerDies()
510 osl::Guard< osl::Mutex > aGuard( m_aMutex );
512 m_pOwner = NULL;
515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */