Update ooo320-m1
[ooovba.git] / ucb / source / cacher / dynamicresultsetwrapper.cxx
blob7ff6e85f4713d1c70177d50ab4c89d5a6ca7e59f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dynamicresultsetwrapper.cxx,v $
10 * $Revision: 1.7 $
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_ucb.hxx"
34 #include <dynamicresultsetwrapper.hxx>
35 #include <ucbhelper/macros.hxx>
36 #include <osl/diagnose.h>
37 #include <rtl/ustring.hxx>
38 #include <com/sun/star/ucb/ListActionType.hpp>
39 #include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
40 #include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::sdbc;
44 using namespace com::sun::star::ucb;
45 using namespace com::sun::star::uno;
46 using namespace cppu;
47 using namespace rtl;
49 //--------------------------------------------------------------------------
50 //--------------------------------------------------------------------------
51 // class DynamicResultSetWrapper
52 //--------------------------------------------------------------------------
53 //--------------------------------------------------------------------------
55 DynamicResultSetWrapper::DynamicResultSetWrapper(
56 Reference< XDynamicResultSet > xOrigin
57 , const Reference< XMultiServiceFactory > & xSMgr )
59 : m_bDisposed( sal_False )
60 , m_bInDispose( sal_False )
61 , m_pDisposeEventListeners( NULL )
62 , m_xSMgr( xSMgr )
63 , m_bStatic( sal_False )
64 , m_bGotWelcome( sal_False )
65 , m_xSource( xOrigin )
66 , m_xSourceResultOne( NULL )
67 , m_xSourceResultTwo( NULL )
68 // , m_xSourceResultCurrent( NULL )
69 // , m_bUseOne( NULL )
70 , m_xMyResultOne( NULL )
71 , m_xMyResultTwo( NULL )
72 , m_xListener( NULL )
74 m_pMyListenerImpl = new DynamicResultSetWrapperListener( this );
75 m_xMyListenerImpl = Reference< XDynamicResultSetListener >( m_pMyListenerImpl );
76 //call impl_init() at the end of constructor of derived class
79 void SAL_CALL DynamicResultSetWrapper::impl_init()
81 //call this at the end of constructor of derived class
84 Reference< XDynamicResultSet > xSource = NULL;
86 osl::Guard< osl::Mutex > aGuard( m_aMutex );
87 xSource = m_xSource;
88 m_xSource = NULL;
90 if( xSource.is() )
91 setSource( xSource );
94 DynamicResultSetWrapper::~DynamicResultSetWrapper()
96 //call impl_deinit() at start of destructor of derived class
98 delete m_pDisposeEventListeners;
101 void SAL_CALL DynamicResultSetWrapper::impl_deinit()
103 //call this at start of destructor of derived class
105 m_pMyListenerImpl->impl_OwnerDies();
108 void SAL_CALL DynamicResultSetWrapper
109 ::impl_EnsureNotDisposed()
110 throw( DisposedException, RuntimeException )
112 osl::Guard< osl::Mutex > aGuard( m_aMutex );
113 if( m_bDisposed )
114 throw DisposedException();
117 //virtual
118 void SAL_CALL DynamicResultSetWrapper
119 ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
121 osl::Guard< osl::Mutex > aGuard( m_aMutex );
122 OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
123 m_xSourceResultOne = xResultSet;
124 m_xMyResultOne = xResultSet;
127 //virtual
128 void SAL_CALL DynamicResultSetWrapper
129 ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
131 osl::Guard< osl::Mutex > aGuard( m_aMutex );
132 OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
133 m_xSourceResultTwo = xResultSet;
134 m_xMyResultTwo = xResultSet;
137 //--------------------------------------------------------------------------
138 // XInterface methods.
139 //--------------------------------------------------------------------------
140 //list all interfaces inclusive baseclasses of interfaces
141 QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
142 SAL_STATIC_CAST( XComponent*, this ) //base of XDynamicResultSet
143 , SAL_STATIC_CAST( XDynamicResultSet*, this )
144 , SAL_STATIC_CAST( XSourceInitialization*, this )
145 QUERYINTERFACE_IMPL_END
147 //--------------------------------------------------------------------------
148 // XComponent methods.
149 //--------------------------------------------------------------------------
150 // virtual
151 void SAL_CALL DynamicResultSetWrapper
152 ::dispose() throw( RuntimeException )
154 impl_EnsureNotDisposed();
156 Reference< XComponent > xSourceComponent;
158 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
159 if( m_bInDispose || m_bDisposed )
160 return;
161 m_bInDispose = sal_True;
163 xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);
165 if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
167 EventObject aEvt;
168 aEvt.Source = static_cast< XComponent * >( this );
170 aGuard.clear();
171 m_pDisposeEventListeners->disposeAndClear( aEvt );
175 /* //@todo ?? ( only if java collection needs to long )
176 if( xSourceComponent.is() )
177 xSourceComponent->dispose();
180 osl::Guard< osl::Mutex > aGuard( m_aMutex );
181 m_bDisposed = sal_True;
182 m_bInDispose = sal_False;
185 //--------------------------------------------------------------------------
186 // virtual
187 void SAL_CALL DynamicResultSetWrapper
188 ::addEventListener( const Reference< XEventListener >& Listener )
189 throw( RuntimeException )
191 impl_EnsureNotDisposed();
192 osl::Guard< osl::Mutex > aGuard( m_aMutex );
194 if ( !m_pDisposeEventListeners )
195 m_pDisposeEventListeners =
196 new OInterfaceContainerHelper( m_aContainerMutex );
198 m_pDisposeEventListeners->addInterface( Listener );
201 //--------------------------------------------------------------------------
202 // virtual
203 void SAL_CALL DynamicResultSetWrapper
204 ::removeEventListener( const Reference< XEventListener >& Listener )
205 throw( RuntimeException )
207 impl_EnsureNotDisposed();
208 osl::Guard< osl::Mutex > aGuard( m_aMutex );
210 if ( m_pDisposeEventListeners )
211 m_pDisposeEventListeners->removeInterface( Listener );
214 //--------------------------------------------------------------------------
215 // own methods
216 //--------------------------------------------------------------------------
218 //virtual
219 void SAL_CALL DynamicResultSetWrapper
220 ::impl_disposing( const EventObject& )
221 throw( RuntimeException )
223 impl_EnsureNotDisposed();
225 osl::Guard< osl::Mutex > aGuard( m_aMutex );
227 if( !m_xSource.is() )
228 return;
230 //release all references to the broadcaster:
231 m_xSource.clear();
232 m_xSourceResultOne.clear();//?? or only when not static??
233 m_xSourceResultTwo.clear();//??
234 //@todo m_xMyResultOne.clear(); ???
235 //@todo m_xMyResultTwo.clear(); ???
238 //virtual
239 void SAL_CALL DynamicResultSetWrapper
240 ::impl_notify( const ListEvent& Changes )
241 throw( RuntimeException )
243 impl_EnsureNotDisposed();
244 //@todo
246 <p>The Listener is allowed to blockade this call, until he really want to go
247 to the new version. The only situation, where the listener has to return the
248 update call at once is, while he disposes his broadcaster or while he is
249 removing himsef as listener (otherwise you deadlock)!!!
251 // handle the actions in the list
253 ListEvent aNewEvent;
254 aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
255 aNewEvent.Changes = Changes.Changes;
258 osl::Guard< osl::Mutex > aGuard( m_aMutex );
259 for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
261 ListAction& rAction = aNewEvent.Changes[i];
262 switch( rAction.ListActionType )
264 case ListActionType::WELCOME:
266 WelcomeDynamicResultSetStruct aWelcome;
267 if( rAction.ActionInfo >>= aWelcome )
269 impl_InitResultSetOne( aWelcome.Old );
270 impl_InitResultSetTwo( aWelcome.New );
271 m_bGotWelcome = sal_True;
273 aWelcome.Old = m_xMyResultOne;
274 aWelcome.New = m_xMyResultTwo;
276 rAction.ActionInfo <<= aWelcome;
278 else
280 OSL_ENSURE( sal_False, "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
281 //throw RuntimeException();
283 break;
287 OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
290 if( !m_xListener.is() )
291 m_aListenerSet.wait();
292 m_xListener->notify( aNewEvent );
295 m_bUseOne = !m_bUseOne;
296 if( m_bUseOne )
297 m_xSourceResultCurrent = m_xSourceResultOne;
298 else
299 m_xSourceResultCurrent = m_xSourceResultTwo;
303 //--------------------------------------------------------------------------
304 // XSourceInitialization
305 //--------------------------------------------------------------------------
306 //virtual
307 void SAL_CALL DynamicResultSetWrapper
308 ::setSource( const Reference< XInterface > & Source )
309 throw( AlreadyInitializedException, RuntimeException )
311 impl_EnsureNotDisposed();
313 osl::Guard< osl::Mutex > aGuard( m_aMutex );
314 if( m_xSource.is() )
316 throw AlreadyInitializedException();
320 Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
321 OSL_ENSURE( xSourceDynamic.is(),
322 "the given source is not of required type XDynamicResultSet" );
324 Reference< XDynamicResultSetListener > xListener = NULL;
325 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
327 sal_Bool bStatic = sal_False;
329 osl::Guard< osl::Mutex > aGuard( m_aMutex );
330 m_xSource = xSourceDynamic;
331 xListener = m_xListener;
332 bStatic = m_bStatic;
333 xMyListenerImpl = m_xMyListenerImpl;
335 if( xListener.is() )
336 xSourceDynamic->setListener( m_xMyListenerImpl );
337 else if( bStatic )
339 Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
340 xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
342 m_aSourceSet.set();
345 //--------------------------------------------------------------------------
346 // XDynamicResultSet
347 //--------------------------------------------------------------------------
348 //virtual
349 Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
350 ::getStaticResultSet()
351 throw( ListenerAlreadySetException, RuntimeException )
353 impl_EnsureNotDisposed();
355 Reference< XDynamicResultSet > xSource = NULL;
356 Reference< XEventListener > xMyListenerImpl = NULL;
358 osl::Guard< osl::Mutex > aGuard( m_aMutex );
359 if( m_xListener.is() )
360 throw ListenerAlreadySetException();
362 xSource = m_xSource;
363 m_bStatic = sal_True;
364 xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
367 if( xSource.is() )
369 Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
370 xSourceComponent->addEventListener( xMyListenerImpl );
372 if( !xSource.is() )
373 m_aSourceSet.wait();
376 Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
377 impl_InitResultSetOne( xResultSet );
378 return m_xMyResultOne;
381 //virtual
382 void SAL_CALL DynamicResultSetWrapper
383 ::setListener( const Reference<
384 XDynamicResultSetListener > & Listener )
385 throw( ListenerAlreadySetException, RuntimeException )
387 impl_EnsureNotDisposed();
389 Reference< XDynamicResultSet > xSource = NULL;
390 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
392 osl::Guard< osl::Mutex > aGuard( m_aMutex );
393 if( m_xListener.is() )
394 throw ListenerAlreadySetException();
395 if( m_bStatic )
396 throw ListenerAlreadySetException();
398 m_xListener = Listener;
399 addEventListener( Reference< XEventListener >::query( Listener ) );
401 xSource = m_xSource;
402 xMyListenerImpl = m_xMyListenerImpl;
404 if ( xSource.is() )
405 xSource->setListener( xMyListenerImpl );
407 m_aListenerSet.set();
410 //virtual
411 void SAL_CALL DynamicResultSetWrapper
412 ::connectToCache( const Reference< XDynamicResultSet > & xCache )
413 throw( ListenerAlreadySetException, AlreadyInitializedException, ServiceNotFoundException, RuntimeException )
415 impl_EnsureNotDisposed();
417 if( m_xListener.is() )
418 throw ListenerAlreadySetException();
419 if( m_bStatic )
420 throw ListenerAlreadySetException();
422 Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
423 OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
424 if( xTarget.is() && m_xSMgr.is() )
426 //@todo m_aSourceSet.wait();?
428 Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
431 xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
432 m_xSMgr->createInstance(
433 OUString::createFromAscii(
434 "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
435 UNO_QUERY );
437 catch ( Exception const & )
441 if( xStubFactory.is() )
443 xStubFactory->connectToCache(
444 this, xCache, Sequence< NumberedSortingInfo > (), NULL );
445 return;
448 OSL_ENSURE( sal_False, "could not connect to cache" );
449 throw ServiceNotFoundException();
452 //virtual
453 sal_Int16 SAL_CALL DynamicResultSetWrapper
454 ::getCapabilities()
455 throw( RuntimeException )
457 impl_EnsureNotDisposed();
459 m_aSourceSet.wait();
460 Reference< XDynamicResultSet > xSource = NULL;
462 osl::Guard< osl::Mutex > aGuard( m_aMutex );
463 xSource = m_xSource;
465 return xSource->getCapabilities();
468 //--------------------------------------------------------------------------
469 //--------------------------------------------------------------------------
470 // class DynamicResultSetWrapperListener
471 //--------------------------------------------------------------------------
472 //--------------------------------------------------------------------------
474 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
475 DynamicResultSetWrapper* pOwner )
476 : m_pOwner( pOwner )
481 DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
486 //--------------------------------------------------------------------------
487 // XInterface methods.
488 //--------------------------------------------------------------------------
489 //list all interfaces inclusive baseclasses of interfaces
490 XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
491 , XDynamicResultSetListener
492 , XEventListener //base of XDynamicResultSetListener
495 //--------------------------------------------------------------------------
496 // XDynamicResultSetListener methods:
497 //--------------------------------------------------------------------------
498 //virtual
499 void SAL_CALL DynamicResultSetWrapperListener
500 ::disposing( const EventObject& rEventObject )
501 throw( RuntimeException )
503 osl::Guard< osl::Mutex > aGuard( m_aMutex );
505 if( m_pOwner )
506 m_pOwner->impl_disposing( rEventObject );
509 //virtual
510 void SAL_CALL DynamicResultSetWrapperListener
511 ::notify( const ListEvent& Changes )
512 throw( RuntimeException )
514 osl::Guard< osl::Mutex > aGuard( m_aMutex );
516 if( m_pOwner )
517 m_pOwner->impl_notify( Changes );
520 //--------------------------------------------------------------------------
521 // own methods:
522 //--------------------------------------------------------------------------
524 void SAL_CALL DynamicResultSetWrapperListener
525 ::impl_OwnerDies()
527 osl::Guard< osl::Mutex > aGuard( m_aMutex );
529 m_pOwner = NULL;