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
;
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
)
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 //--------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
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
)
148 m_bInDispose
= sal_True
;
150 xSourceComponent
= Reference
< XComponent
>(m_xSource
, UNO_QUERY
);
152 if( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
155 aEvt
.Source
= static_cast< XComponent
* >( this );
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 //--------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
203 //--------------------------------------------------------------------------
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() )
217 //release all references to the broadcaster:
219 m_xSourceResultOne
.clear();//?? or only when not static??
220 m_xSourceResultTwo
.clear();//??
221 //@todo m_xMyResultOne.clear(); ???
222 //@todo m_xMyResultTwo.clear(); ???
226 void SAL_CALL DynamicResultSetWrapper
227 ::impl_notify( const ListEvent
& Changes
)
228 throw( RuntimeException
)
230 impl_EnsureNotDisposed();
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
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
;
267 OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
268 //throw RuntimeException();
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;
284 m_xSourceResultCurrent = m_xSourceResultOne;
286 m_xSourceResultCurrent = m_xSourceResultTwo;
290 //--------------------------------------------------------------------------
291 // XSourceInitialization
292 //--------------------------------------------------------------------------
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
);
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
;
320 xMyListenerImpl
= m_xMyListenerImpl
;
323 xSourceDynamic
->setListener( m_xMyListenerImpl
);
326 Reference
< XComponent
> xSourceComponent( Source
, UNO_QUERY
);
327 xSourceComponent
->addEventListener( Reference
< XEventListener
> ::query( xMyListenerImpl
) );
332 //--------------------------------------------------------------------------
334 //--------------------------------------------------------------------------
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();
350 m_bStatic
= sal_True
;
351 xMyListenerImpl
= Reference
< XEventListener
> ::query( m_xMyListenerImpl
);
356 Reference
< XComponent
> xSourceComponent( xSource
, UNO_QUERY
);
357 xSourceComponent
->addEventListener( xMyListenerImpl
);
363 Reference
< XResultSet
> xResultSet
= xSource
->getStaticResultSet();
364 impl_InitResultSetOne( xResultSet
);
365 return m_xMyResultOne
;
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();
383 throw ListenerAlreadySetException();
385 m_xListener
= Listener
;
386 addEventListener( Reference
< XEventListener
>::query( Listener
) );
389 xMyListenerImpl
= m_xMyListenerImpl
;
392 xSource
->setListener( xMyListenerImpl
);
394 m_aListenerSet
.set();
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();
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
);
431 OSL_FAIL( "could not connect to cache" );
432 throw ServiceNotFoundException();
436 sal_Int16 SAL_CALL DynamicResultSetWrapper
438 throw( RuntimeException
)
440 impl_EnsureNotDisposed();
443 Reference
< XDynamicResultSet
> xSource
= NULL
;
445 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
448 return xSource
->getCapabilities();
451 //--------------------------------------------------------------------------
452 //--------------------------------------------------------------------------
453 // class DynamicResultSetWrapperListener
454 //--------------------------------------------------------------------------
455 //--------------------------------------------------------------------------
457 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
458 DynamicResultSetWrapper
* 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 //--------------------------------------------------------------------------
482 void SAL_CALL DynamicResultSetWrapperListener
483 ::disposing( const EventObject
& rEventObject
)
484 throw( RuntimeException
)
486 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
489 m_pOwner
->impl_disposing( rEventObject
);
493 void SAL_CALL DynamicResultSetWrapperListener
494 ::notify( const ListEvent
& Changes
)
495 throw( RuntimeException
)
497 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
500 m_pOwner
->impl_notify( Changes
);
503 //--------------------------------------------------------------------------
505 //--------------------------------------------------------------------------
507 void SAL_CALL DynamicResultSetWrapperListener
510 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */