LibreOffice Module ucb (master) 1
dynamicresultsetwrapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
23#include <osl/diagnose.h>
24#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
25#include <com/sun/star/ucb/ListActionType.hpp>
26#include <com/sun/star/ucb/ListenerAlreadySetException.hpp>
27#include <com/sun/star/ucb/ServiceNotFoundException.hpp>
28#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
29#include <com/sun/star/ucb/CachedDynamicResultSetStubFactory.hpp>
30
31using namespace com::sun::star::lang;
32using namespace com::sun::star::sdbc;
33using namespace com::sun::star::ucb;
34using namespace com::sun::star::uno;
35using namespace comphelper;
36
37
38
39
41 Reference< XDynamicResultSet > const & xOrigin
42 , const Reference< XComponentContext > & rxContext )
43
44 : m_bDisposed( false )
45 , m_bInDispose( false )
46 , m_xContext( rxContext )
47 , m_bStatic( false )
48 , m_bGotWelcome( false )
49 , m_xSource( xOrigin )
50 // , m_xSourceResultCurrent( NULL )
51 // , m_bUseOne( NULL )
52{
54 //call impl_init() at the end of constructor of derived class
55};
56
58{
59 //call this at the end of constructor of derived class
60
61
63 {
64 osl::Guard< osl::Mutex > aGuard( m_aMutex );
65 xSource = m_xSource;
66 m_xSource = nullptr;
67 }
68 if( xSource.is() )
69 setSource( xSource );
70}
71
73{
74 //call impl_deinit() at start of destructor of derived class
75};
76
78{
79 //call this at start of destructor of derived class
80
81 m_xMyListenerImpl->impl_OwnerDies();
82}
83
85{
86 osl::Guard< osl::Mutex > aGuard( m_aMutex );
87 if( m_bDisposed )
88 throw DisposedException();
89}
90
91//virtual
93{
94 osl::Guard< osl::Mutex > aGuard( m_aMutex );
95 OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
96 m_xSourceResultOne = xResultSet;
97 m_xMyResultOne = xResultSet;
98}
99
100//virtual
102{
103 osl::Guard< osl::Mutex > aGuard( m_aMutex );
104 OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
105 m_xSourceResultTwo = xResultSet;
106 m_xMyResultTwo = xResultSet;
107}
108
109// XInterface methods.
110css::uno::Any SAL_CALL DynamicResultSetWrapper::queryInterface( const css::uno::Type & rType )
111{
112 //list all interfaces inclusive baseclasses of interfaces
113 css::uno::Any aRet = cppu::queryInterface( rType,
114 static_cast< XComponent* >(this), //base of XDynamicResultSet
115 static_cast< XDynamicResultSet* >(this),
116 static_cast< XSourceInitialization* >(this)
117 );
118 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
119}
120
121// XComponent methods.
122
123// virtual
125{
127
128 Reference< XComponent > xSourceComponent;
129 {
130 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
132 return;
133 m_bInDispose = true;
134
135 xSourceComponent = m_xSource;
136
138 {
139 EventObject aEvt;
140 aEvt.Source = static_cast< XComponent * >( this );
141
142 aGuard.clear();
143 m_pDisposeEventListeners->disposeAndClear( aEvt );
144 }
145 }
146
147 /* //@todo ?? ( only if java collection needs to long )
148 if( xSourceComponent.is() )
149 xSourceComponent->dispose();
150 */
151
152 osl::Guard< osl::Mutex > aGuard( m_aMutex );
153 m_bDisposed = true;
154 m_bInDispose = false;
155}
156
157
158// virtual
160{
162 osl::Guard< osl::Mutex > aGuard( m_aMutex );
163
167
168 m_pDisposeEventListeners->addInterface( Listener );
169}
170
171
172// virtual
174{
176 osl::Guard< osl::Mutex > aGuard( m_aMutex );
177
179 m_pDisposeEventListeners->removeInterface( Listener );
180}
181
182
183// own methods
184
185
186//virtual
188{
190
191 osl::Guard< osl::Mutex > aGuard( m_aMutex );
192
193 if( !m_xSource.is() )
194 return;
195
196 //release all references to the broadcaster:
197 m_xSource.clear();
198 m_xSourceResultOne.clear();//?? or only when not static??
199 m_xSourceResultTwo.clear();//??
200 //@todo m_xMyResultOne.clear(); ???
201 //@todo m_xMyResultTwo.clear(); ???
202}
203
204//virtual
205void DynamicResultSetWrapper::impl_notify( const ListEvent& Changes )
206{
208 //@todo
209 /*
210 <p>The Listener is allowed to blockade this call, until he really want to go
211 to the new version. The only situation, where the listener has to return the
212 update call at once is, while he disposes his broadcaster or while he is
213 removing himself as listener (otherwise you deadlock)!!!
214 */
215 // handle the actions in the list
216
217 ListEvent aNewEvent;
218 aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
219 aNewEvent.Changes = Changes.Changes;
220
221 {
222 osl::Guard< osl::Mutex > aGuard( m_aMutex );
223 for( ListAction& rAction : asNonConstRange(aNewEvent.Changes) )
224 {
225 if (m_bGotWelcome)
226 break;
227
228 switch( rAction.ListActionType )
229 {
230 case ListActionType::WELCOME:
231 {
232 WelcomeDynamicResultSetStruct aWelcome;
233 if( rAction.ActionInfo >>= aWelcome )
234 {
235 impl_InitResultSetOne( aWelcome.Old );
236 impl_InitResultSetTwo( aWelcome.New );
237 m_bGotWelcome = true;
238
239 aWelcome.Old = m_xMyResultOne;
240 aWelcome.New = m_xMyResultTwo;
241
242 rAction.ActionInfo <<= aWelcome;
243 }
244 else
245 {
246 OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
247 //throw RuntimeException();
248 }
249 break;
250 }
251 }
252 }
253 OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
254 }
255
256 if( !m_xListener.is() )
257 m_aListenerSet.wait();
258 m_xListener->notify( aNewEvent );
259
260 /*
261 m_bUseOne = !m_bUseOne;
262 if( m_bUseOne )
263 m_xSourceResultCurrent = m_xSourceResultOne;
264 else
265 m_xSourceResultCurrent = m_xSourceResultTwo;
266 */
267}
268
269
270// XSourceInitialization
271
272//virtual
274{
276 {
277 osl::Guard< osl::Mutex > aGuard( m_aMutex );
278 if( m_xSource.is() )
279 {
280 throw AlreadyInitializedException();
281 }
282 }
283
284 Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
285 OSL_ENSURE( xSourceDynamic.is(),
286 "the given source is not of required type XDynamicResultSet" );
287
290
291 bool bStatic = false;
292 {
293 osl::Guard< osl::Mutex > aGuard( m_aMutex );
294 m_xSource = xSourceDynamic;
295 xListener = m_xListener;
296 bStatic = m_bStatic;
297 xMyListenerImpl = m_xMyListenerImpl.get();
298 }
299 if( xListener.is() )
300 xSourceDynamic->setListener( m_xMyListenerImpl );
301 else if( bStatic )
302 {
303 Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
304 xSourceComponent->addEventListener( xMyListenerImpl );
305 }
306 m_aSourceSet.set();
307}
308
309
310// XDynamicResultSet
311
312//virtual
314{
316
318 Reference< XEventListener > xMyListenerImpl;
319 {
320 osl::Guard< osl::Mutex > aGuard( m_aMutex );
321 if( m_xListener.is() )
322 throw ListenerAlreadySetException();
323
324 xSource = m_xSource;
325 m_bStatic = true;
326 xMyListenerImpl = m_xMyListenerImpl.get();
327 }
328
329 if( xSource.is() )
330 {
331 xSource->addEventListener( xMyListenerImpl );
332 }
333 if( !xSource.is() )
334 m_aSourceSet.wait();
335
336
337 Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
338 impl_InitResultSetOne( xResultSet );
339 return m_xMyResultOne;
340}
341
342//virtual
344{
346
349 {
350 osl::Guard< osl::Mutex > aGuard( m_aMutex );
351 if( m_xListener.is() )
352 throw ListenerAlreadySetException();
353 if( m_bStatic )
354 throw ListenerAlreadySetException();
355
356 m_xListener = Listener;
357 addEventListener( Listener );
358
359 xSource = m_xSource;
360 xMyListenerImpl = m_xMyListenerImpl.get();
361 }
362 if ( xSource.is() )
363 xSource->setListener( xMyListenerImpl );
364
365 m_aListenerSet.set();
366}
367
368//virtual
370{
372
373 if( m_xListener.is() )
374 throw ListenerAlreadySetException();
375 if( m_bStatic )
376 throw ListenerAlreadySetException();
377
378 Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
379 OSL_ENSURE( xTarget.is(), "The given Target doesn't have the required interface 'XSourceInitialization'" );
380 if( xTarget.is() && m_xContext.is() )
381 {
382 //@todo m_aSourceSet.wait();?
383
385 try
386 {
387 xStubFactory = CachedDynamicResultSetStubFactory::create( m_xContext );
388 }
389 catch ( Exception const & )
390 {
391 }
392
393 if( xStubFactory.is() )
394 {
395 xStubFactory->connectToCache(
396 this, xCache, Sequence< NumberedSortingInfo > (), nullptr );
397 return;
398 }
399 }
400 OSL_FAIL( "could not connect to cache" );
401 throw ServiceNotFoundException();
402}
403
404//virtual
406{
408
409 m_aSourceSet.wait();
411 {
412 osl::Guard< osl::Mutex > aGuard( m_aMutex );
413 xSource = m_xSource;
414 }
415 return xSource->getCapabilities();
416}
417
418
419
420
423 : m_pOwner( pOwner )
424{
425
426}
427
429{
430
431}
432
433
434// XInterface methods.
435
437 noexcept
438{
439 OWeakObject::acquire();
440}
441
443 noexcept
444{
445 OWeakObject::release();
446}
447
448css::uno::Any SAL_CALL DynamicResultSetWrapperListener::queryInterface( const css::uno::Type & rType )
449{
450 css::uno::Any aRet = cppu::queryInterface( rType,
451 static_cast< XDynamicResultSetListener* >(this),
452 static_cast< XEventListener* >(this)
453 );
454 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
455}
456
457// XDynamicResultSetListener methods:
458
459//virtual
460void SAL_CALL DynamicResultSetWrapperListener::disposing( const EventObject& rEventObject )
461{
462 osl::Guard< osl::Mutex > aGuard( m_aMutex );
463
464 if( m_pOwner )
465 m_pOwner->impl_disposing( rEventObject );
466}
467
468//virtual
469void SAL_CALL DynamicResultSetWrapperListener::notify( const ListEvent& Changes )
470{
471 osl::Guard< osl::Mutex > aGuard( m_aMutex );
472
473 if( m_pOwner )
474 m_pOwner->impl_notify( Changes );
475}
476
477
478// own methods:
479
480
482{
483 osl::Guard< osl::Mutex > aGuard( m_aMutex );
484
485 m_pOwner = nullptr;
486}
487
488/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual void SAL_CALL acquire() noexcept override
virtual void SAL_CALL release() noexcept override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual void SAL_CALL notify(const css::ucb::ListEvent &Changes) override
DynamicResultSetWrapperListener(DynamicResultSetWrapper *pOwner)
osl::Mutex m_aContainerMutex
In dispose call.
rtl::Reference< DynamicResultSetWrapperListener > m_xMyListenerImpl
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Reference< css::ucb::XDynamicResultSet > m_xSource
virtual ~DynamicResultSetWrapper() override
virtual void impl_InitResultSetTwo(const css::uno::Reference< css::sdbc::XResultSet > &xResultSet)
std::unique_ptr< comphelper::OInterfaceContainerHelper3< css::lang::XEventListener > > m_pDisposeEventListeners
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
css::uno::Reference< css::ucb::XDynamicResultSetListener > m_xListener
virtual void SAL_CALL dispose() override
virtual void impl_disposing(const css::lang::EventObject &Source)
virtual void SAL_CALL setSource(const css::uno::Reference< css::uno::XInterface > &Source) override
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL getStaticResultSet() override
virtual void SAL_CALL setListener(const css::uno::Reference< css::ucb::XDynamicResultSetListener > &Listener) override
DynamicResultSetWrapper(css::uno::Reference< css::ucb::XDynamicResultSet > const &xOrigin, const css::uno::Reference< css::uno::XComponentContext > &rxContext)
void impl_notify(const css::ucb::ListEvent &Changes)
css::uno::Reference< css::sdbc::XResultSet > m_xMyResultOne
virtual void SAL_CALL connectToCache(const css::uno::Reference< css::ucb::XDynamicResultSet > &xCache) override
virtual sal_Int16 SAL_CALL getCapabilities() override
css::uno::Reference< css::sdbc::XResultSet > m_xSourceResultTwo
css::uno::Reference< css::sdbc::XResultSet > m_xSourceResultOne
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
css::uno::Reference< css::sdbc::XResultSet > m_xMyResultTwo
bool m_bInDispose
Dispose call ready.
virtual void impl_InitResultSetOne(const css::uno::Reference< css::sdbc::XResultSet > &xResultSet)
const Reference< XRow > m_xSource
Reference< XInterface > xTarget
bool m_bDisposed
SvLinkSource * pOwner
@ Exception
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
ContentProvider * m_pOwner
Definition: pkgprovider.cxx:58