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: dynamicresultsetwrapper.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_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
;
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
)
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
)
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
);
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
);
114 throw DisposedException();
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
;
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 //--------------------------------------------------------------------------
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
)
161 m_bInDispose
= sal_True
;
163 xSourceComponent
= Reference
< XComponent
>(m_xSource
, UNO_QUERY
);
165 if( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
168 aEvt
.Source
= static_cast< XComponent
* >( this );
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 //--------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
216 //--------------------------------------------------------------------------
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() )
230 //release all references to the broadcaster:
232 m_xSourceResultOne
.clear();//?? or only when not static??
233 m_xSourceResultTwo
.clear();//??
234 //@todo m_xMyResultOne.clear(); ???
235 //@todo m_xMyResultTwo.clear(); ???
239 void SAL_CALL DynamicResultSetWrapper
240 ::impl_notify( const ListEvent
& Changes
)
241 throw( RuntimeException
)
243 impl_EnsureNotDisposed();
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
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
;
280 OSL_ENSURE( sal_False
, "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
281 //throw RuntimeException();
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;
297 m_xSourceResultCurrent = m_xSourceResultOne;
299 m_xSourceResultCurrent = m_xSourceResultTwo;
303 //--------------------------------------------------------------------------
304 // XSourceInitialization
305 //--------------------------------------------------------------------------
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
);
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
;
333 xMyListenerImpl
= m_xMyListenerImpl
;
336 xSourceDynamic
->setListener( m_xMyListenerImpl
);
339 Reference
< XComponent
> xSourceComponent( Source
, UNO_QUERY
);
340 xSourceComponent
->addEventListener( Reference
< XEventListener
> ::query( xMyListenerImpl
) );
345 //--------------------------------------------------------------------------
347 //--------------------------------------------------------------------------
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();
363 m_bStatic
= sal_True
;
364 xMyListenerImpl
= Reference
< XEventListener
> ::query( m_xMyListenerImpl
);
369 Reference
< XComponent
> xSourceComponent( xSource
, UNO_QUERY
);
370 xSourceComponent
->addEventListener( xMyListenerImpl
);
376 Reference
< XResultSet
> xResultSet
= xSource
->getStaticResultSet();
377 impl_InitResultSetOne( xResultSet
);
378 return m_xMyResultOne
;
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();
396 throw ListenerAlreadySetException();
398 m_xListener
= Listener
;
399 addEventListener( Reference
< XEventListener
>::query( Listener
) );
402 xMyListenerImpl
= m_xMyListenerImpl
;
405 xSource
->setListener( xMyListenerImpl
);
407 m_aListenerSet
.set();
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();
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" ) ),
437 catch ( Exception
const & )
441 if( xStubFactory
.is() )
443 xStubFactory
->connectToCache(
444 this, xCache
, Sequence
< NumberedSortingInfo
> (), NULL
);
448 OSL_ENSURE( sal_False
, "could not connect to cache" );
449 throw ServiceNotFoundException();
453 sal_Int16 SAL_CALL DynamicResultSetWrapper
455 throw( RuntimeException
)
457 impl_EnsureNotDisposed();
460 Reference
< XDynamicResultSet
> xSource
= NULL
;
462 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
465 return xSource
->getCapabilities();
468 //--------------------------------------------------------------------------
469 //--------------------------------------------------------------------------
470 // class DynamicResultSetWrapperListener
471 //--------------------------------------------------------------------------
472 //--------------------------------------------------------------------------
474 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
475 DynamicResultSetWrapper
* 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 //--------------------------------------------------------------------------
499 void SAL_CALL DynamicResultSetWrapperListener
500 ::disposing( const EventObject
& rEventObject
)
501 throw( RuntimeException
)
503 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
506 m_pOwner
->impl_disposing( rEventObject
);
510 void SAL_CALL DynamicResultSetWrapperListener
511 ::notify( const ListEvent
& Changes
)
512 throw( RuntimeException
)
514 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
517 m_pOwner
->impl_notify( Changes
);
520 //--------------------------------------------------------------------------
522 //--------------------------------------------------------------------------
524 void SAL_CALL DynamicResultSetWrapperListener
527 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);