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 std::unique_lock 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 std::unique_lock aGuard( m_aMutex );
87 if( m_bDisposed )
88 throw DisposedException();
89}
90
91//virtual
93{
94 std::unique_lock 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 std::unique_lock 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 std::unique_lock aGuard( m_aMutex );
129 Reference< XComponent > xSourceComponent;
131 return;
132 m_bInDispose = true;
133
134 xSourceComponent = m_xSource;
135
137 {
138 EventObject aEvt;
139 aEvt.Source = static_cast< XComponent * >( this );
141 }
142
143 /* //@todo ?? ( only if java collection needs to long )
144 if( xSourceComponent.is() )
145 xSourceComponent->dispose();
146 */
147
148 m_bDisposed = true;
149 m_bInDispose = false;
150}
151
152
153// virtual
155{
157 std::unique_lock aGuard( m_aMutex );
158
159 m_aDisposeEventListeners.addInterface( aGuard, Listener );
160}
161
162
163// virtual
165{
167 std::unique_lock aGuard( m_aMutex );
168
169 m_aDisposeEventListeners.removeInterface( aGuard, Listener );
170}
171
172
173// own methods
174
175
176//virtual
178{
180
181 std::unique_lock aGuard( m_aMutex );
182
183 if( !m_xSource.is() )
184 return;
185
186 //release all references to the broadcaster:
187 m_xSource.clear();
188 m_xSourceResultOne.clear();//?? or only when not static??
189 m_xSourceResultTwo.clear();//??
190 //@todo m_xMyResultOne.clear(); ???
191 //@todo m_xMyResultTwo.clear(); ???
192}
193
194//virtual
195void DynamicResultSetWrapper::impl_notify( const ListEvent& Changes )
196{
198 //@todo
199 /*
200 <p>The Listener is allowed to blockade this call, until he really want to go
201 to the new version. The only situation, where the listener has to return the
202 update call at once is, while he disposes his broadcaster or while he is
203 removing himself as listener (otherwise you deadlock)!!!
204 */
205 // handle the actions in the list
206
207 ListEvent aNewEvent;
208 aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
209 aNewEvent.Changes = Changes.Changes;
210
211 {
212 std::unique_lock aGuard( m_aMutex );
213 for( ListAction& rAction : asNonConstRange(aNewEvent.Changes) )
214 {
215 if (m_bGotWelcome)
216 break;
217
218 switch( rAction.ListActionType )
219 {
220 case ListActionType::WELCOME:
221 {
222 WelcomeDynamicResultSetStruct aWelcome;
223 if( rAction.ActionInfo >>= aWelcome )
224 {
225 impl_InitResultSetOne( aWelcome.Old );
226 impl_InitResultSetTwo( aWelcome.New );
227 m_bGotWelcome = true;
228
229 aWelcome.Old = m_xMyResultOne;
230 aWelcome.New = m_xMyResultTwo;
231
232 rAction.ActionInfo <<= aWelcome;
233 }
234 else
235 {
236 OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
237 //throw RuntimeException();
238 }
239 break;
240 }
241 }
242 }
243 OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
244 }
245
246 if( !m_xListener.is() )
247 m_aListenerSet.wait();
248 m_xListener->notify( aNewEvent );
249
250 /*
251 m_bUseOne = !m_bUseOne;
252 if( m_bUseOne )
253 m_xSourceResultCurrent = m_xSourceResultOne;
254 else
255 m_xSourceResultCurrent = m_xSourceResultTwo;
256 */
257}
258
259
260// XSourceInitialization
261
262//virtual
264{
266 {
267 std::unique_lock aGuard( m_aMutex );
268 if( m_xSource.is() )
269 {
270 throw AlreadyInitializedException();
271 }
272 }
273
274 Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
275 OSL_ENSURE( xSourceDynamic.is(),
276 "the given source is not of required type XDynamicResultSet" );
277
280
281 bool bStatic = false;
282 {
283 std::unique_lock aGuard( m_aMutex );
284 m_xSource = xSourceDynamic;
285 xListener = m_xListener;
286 bStatic = m_bStatic;
287 xMyListenerImpl = m_xMyListenerImpl.get();
288 }
289 if( xListener.is() )
290 xSourceDynamic->setListener( m_xMyListenerImpl );
291 else if( bStatic )
292 {
293 Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
294 xSourceComponent->addEventListener( xMyListenerImpl );
295 }
296 m_aSourceSet.set();
297}
298
299
300// XDynamicResultSet
301
302//virtual
304{
306
308 Reference< XEventListener > xMyListenerImpl;
309 {
310 std::unique_lock aGuard( m_aMutex );
311 if( m_xListener.is() )
312 throw ListenerAlreadySetException();
313
314 xSource = m_xSource;
315 m_bStatic = true;
316 xMyListenerImpl = m_xMyListenerImpl.get();
317 }
318
319 if( xSource.is() )
320 {
321 xSource->addEventListener( xMyListenerImpl );
322 }
323 if( !xSource.is() )
324 m_aSourceSet.wait();
325
326
327 Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
328 impl_InitResultSetOne( xResultSet );
329 return m_xMyResultOne;
330}
331
332//virtual
334{
336
339 {
340 std::unique_lock aGuard( m_aMutex );
341 if( m_xListener.is() )
342 throw ListenerAlreadySetException();
343 if( m_bStatic )
344 throw ListenerAlreadySetException();
345
346 m_xListener = Listener;
347 addEventListener( Listener );
348
349 xSource = m_xSource;
350 xMyListenerImpl = m_xMyListenerImpl.get();
351 }
352 if ( xSource.is() )
353 xSource->setListener( xMyListenerImpl );
354
355 m_aListenerSet.set();
356}
357
358//virtual
360{
362
363 if( m_xListener.is() )
364 throw ListenerAlreadySetException();
365 if( m_bStatic )
366 throw ListenerAlreadySetException();
367
368 Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
369 OSL_ENSURE( xTarget.is(), "The given Target doesn't have the required interface 'XSourceInitialization'" );
370 if( xTarget.is() && m_xContext.is() )
371 {
372 //@todo m_aSourceSet.wait();?
373
375 try
376 {
377 xStubFactory = CachedDynamicResultSetStubFactory::create( m_xContext );
378 }
379 catch ( Exception const & )
380 {
381 }
382
383 if( xStubFactory.is() )
384 {
385 xStubFactory->connectToCache(
386 this, xCache, Sequence< NumberedSortingInfo > (), nullptr );
387 return;
388 }
389 }
390 OSL_FAIL( "could not connect to cache" );
391 throw ServiceNotFoundException();
392}
393
394//virtual
396{
398
399 m_aSourceSet.wait();
401 {
402 std::unique_lock aGuard( m_aMutex );
403 xSource = m_xSource;
404 }
405 return xSource->getCapabilities();
406}
407
408
409
410
413 : m_pOwner( pOwner )
414{
415
416}
417
419{
420
421}
422
423
424// XInterface methods.
425
427 noexcept
428{
429 OWeakObject::acquire();
430}
431
433 noexcept
434{
435 OWeakObject::release();
436}
437
438css::uno::Any SAL_CALL DynamicResultSetWrapperListener::queryInterface( const css::uno::Type & rType )
439{
440 css::uno::Any aRet = cppu::queryInterface( rType,
441 static_cast< XDynamicResultSetListener* >(this),
442 static_cast< XEventListener* >(this)
443 );
444 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
445}
446
447// XDynamicResultSetListener methods:
448
449//virtual
450void SAL_CALL DynamicResultSetWrapperListener::disposing( const EventObject& rEventObject )
451{
452 std::unique_lock aGuard( m_aMutex );
453
454 if( m_pOwner )
455 m_pOwner->impl_disposing( rEventObject );
456}
457
458//virtual
459void SAL_CALL DynamicResultSetWrapperListener::notify( const ListEvent& Changes )
460{
461 std::unique_lock aGuard( m_aMutex );
462
463 if( m_pOwner )
464 m_pOwner->impl_notify( Changes );
465}
466
467
468// own methods:
469
470
472{
473 std::unique_lock aGuard( m_aMutex );
474
475 m_pOwner = nullptr;
476}
477
478/* 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)
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)
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)
comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aDisposeEventListeners
In dispose call.
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)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
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