Line data Source code
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 :
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>
28 :
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;
33 : using namespace cppu;
34 :
35 : using ::rtl::OUString;
36 :
37 : //--------------------------------------------------------------------------
38 : //--------------------------------------------------------------------------
39 : // class DynamicResultSetWrapper
40 : //--------------------------------------------------------------------------
41 : //--------------------------------------------------------------------------
42 :
43 0 : DynamicResultSetWrapper::DynamicResultSetWrapper(
44 : Reference< XDynamicResultSet > xOrigin
45 : , const Reference< XComponentContext > & rxContext )
46 :
47 : : m_bDisposed( sal_False )
48 : , m_bInDispose( sal_False )
49 : , m_pDisposeEventListeners( NULL )
50 : , m_xContext( rxContext )
51 : , m_bStatic( sal_False )
52 : , m_bGotWelcome( sal_False )
53 : , m_xSource( xOrigin )
54 : , m_xSourceResultOne( NULL )
55 : , m_xSourceResultTwo( NULL )
56 : // , m_xSourceResultCurrent( NULL )
57 : // , m_bUseOne( NULL )
58 : , m_xMyResultOne( NULL )
59 : , m_xMyResultTwo( NULL )
60 0 : , m_xListener( NULL )
61 : {
62 0 : m_pMyListenerImpl = new DynamicResultSetWrapperListener( this );
63 0 : m_xMyListenerImpl = Reference< XDynamicResultSetListener >( m_pMyListenerImpl );
64 : //call impl_init() at the end of constructor of derived class
65 0 : };
66 :
67 0 : void SAL_CALL DynamicResultSetWrapper::impl_init()
68 : {
69 : //call this at the end of constructor of derived class
70 : //
71 :
72 0 : Reference< XDynamicResultSet > xSource = NULL;
73 : {
74 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
75 0 : xSource = m_xSource;
76 0 : m_xSource = NULL;
77 : }
78 0 : if( xSource.is() )
79 0 : setSource( xSource );
80 0 : }
81 :
82 0 : DynamicResultSetWrapper::~DynamicResultSetWrapper()
83 : {
84 : //call impl_deinit() at start of destructor of derived class
85 :
86 0 : delete m_pDisposeEventListeners;
87 0 : };
88 :
89 0 : void SAL_CALL DynamicResultSetWrapper::impl_deinit()
90 : {
91 : //call this at start of destructor of derived class
92 : //
93 0 : m_pMyListenerImpl->impl_OwnerDies();
94 0 : }
95 :
96 0 : void SAL_CALL DynamicResultSetWrapper
97 : ::impl_EnsureNotDisposed()
98 : throw( DisposedException, RuntimeException )
99 : {
100 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
101 0 : if( m_bDisposed )
102 0 : throw DisposedException();
103 0 : }
104 :
105 : //virtual
106 0 : void SAL_CALL DynamicResultSetWrapper
107 : ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
108 : {
109 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
110 : OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
111 0 : m_xSourceResultOne = xResultSet;
112 0 : m_xMyResultOne = xResultSet;
113 0 : }
114 :
115 : //virtual
116 0 : void SAL_CALL DynamicResultSetWrapper
117 : ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
118 : {
119 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
120 : OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
121 0 : m_xSourceResultTwo = xResultSet;
122 0 : m_xMyResultTwo = xResultSet;
123 0 : }
124 :
125 : //--------------------------------------------------------------------------
126 : // XInterface methods.
127 : //--------------------------------------------------------------------------
128 : //list all interfaces inclusive baseclasses of interfaces
129 0 : QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
130 : (static_cast< XComponent* >(this)) //base of XDynamicResultSet
131 : , (static_cast< XDynamicResultSet* >(this))
132 : , (static_cast< XSourceInitialization* >(this))
133 0 : QUERYINTERFACE_IMPL_END
134 :
135 : //--------------------------------------------------------------------------
136 : // XComponent methods.
137 : //--------------------------------------------------------------------------
138 : // virtual
139 0 : void SAL_CALL DynamicResultSetWrapper
140 : ::dispose() throw( RuntimeException )
141 : {
142 0 : impl_EnsureNotDisposed();
143 :
144 0 : Reference< XComponent > xSourceComponent;
145 : {
146 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
147 0 : if( m_bInDispose || m_bDisposed )
148 0 : return;
149 0 : m_bInDispose = sal_True;
150 :
151 0 : xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);
152 :
153 0 : if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
154 : {
155 0 : EventObject aEvt;
156 0 : aEvt.Source = static_cast< XComponent * >( this );
157 :
158 0 : aGuard.clear();
159 0 : m_pDisposeEventListeners->disposeAndClear( aEvt );
160 0 : }
161 : }
162 :
163 : /* //@todo ?? ( only if java collection needs to long )
164 : if( xSourceComponent.is() )
165 : xSourceComponent->dispose();
166 : */
167 :
168 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
169 0 : m_bDisposed = sal_True;
170 0 : m_bInDispose = sal_False;
171 : }
172 :
173 : //--------------------------------------------------------------------------
174 : // virtual
175 0 : void SAL_CALL DynamicResultSetWrapper
176 : ::addEventListener( const Reference< XEventListener >& Listener )
177 : throw( RuntimeException )
178 : {
179 0 : impl_EnsureNotDisposed();
180 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
181 :
182 0 : if ( !m_pDisposeEventListeners )
183 : m_pDisposeEventListeners =
184 0 : new OInterfaceContainerHelper( m_aContainerMutex );
185 :
186 0 : m_pDisposeEventListeners->addInterface( Listener );
187 0 : }
188 :
189 : //--------------------------------------------------------------------------
190 : // virtual
191 0 : void SAL_CALL DynamicResultSetWrapper
192 : ::removeEventListener( const Reference< XEventListener >& Listener )
193 : throw( RuntimeException )
194 : {
195 0 : impl_EnsureNotDisposed();
196 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
197 :
198 0 : if ( m_pDisposeEventListeners )
199 0 : m_pDisposeEventListeners->removeInterface( Listener );
200 0 : }
201 :
202 : //--------------------------------------------------------------------------
203 : // own methods
204 : //--------------------------------------------------------------------------
205 :
206 : //virtual
207 0 : void SAL_CALL DynamicResultSetWrapper
208 : ::impl_disposing( const EventObject& )
209 : throw( RuntimeException )
210 : {
211 0 : impl_EnsureNotDisposed();
212 :
213 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
214 :
215 0 : if( !m_xSource.is() )
216 0 : return;
217 :
218 : //release all references to the broadcaster:
219 0 : m_xSource.clear();
220 0 : m_xSourceResultOne.clear();//?? or only when not static??
221 0 : m_xSourceResultTwo.clear();//??
222 : //@todo m_xMyResultOne.clear(); ???
223 : //@todo m_xMyResultTwo.clear(); ???
224 : }
225 :
226 : //virtual
227 0 : void SAL_CALL DynamicResultSetWrapper
228 : ::impl_notify( const ListEvent& Changes )
229 : throw( RuntimeException )
230 : {
231 0 : impl_EnsureNotDisposed();
232 : //@todo
233 : /*
234 : <p>The Listener is allowed to blockade this call, until he really want to go
235 : to the new version. The only situation, where the listener has to return the
236 : update call at once is, while he disposes his broadcaster or while he is
237 : removing himsef as listener (otherwise you deadlock)!!!
238 : */
239 : // handle the actions in the list
240 :
241 0 : ListEvent aNewEvent;
242 0 : aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
243 0 : aNewEvent.Changes = Changes.Changes;
244 :
245 : {
246 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
247 0 : for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
248 : {
249 0 : ListAction& rAction = aNewEvent.Changes[i];
250 0 : switch( rAction.ListActionType )
251 : {
252 : case ListActionType::WELCOME:
253 : {
254 0 : WelcomeDynamicResultSetStruct aWelcome;
255 0 : if( rAction.ActionInfo >>= aWelcome )
256 : {
257 0 : impl_InitResultSetOne( aWelcome.Old );
258 0 : impl_InitResultSetTwo( aWelcome.New );
259 0 : m_bGotWelcome = sal_True;
260 :
261 0 : aWelcome.Old = m_xMyResultOne;
262 0 : aWelcome.New = m_xMyResultTwo;
263 :
264 0 : rAction.ActionInfo <<= aWelcome;
265 : }
266 : else
267 : {
268 : OSL_FAIL( "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
269 : //throw RuntimeException();
270 : }
271 0 : break;
272 : }
273 : }
274 : }
275 0 : OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
276 : }
277 :
278 0 : if( !m_xListener.is() )
279 0 : m_aListenerSet.wait();
280 0 : m_xListener->notify( aNewEvent );
281 :
282 : /*
283 : m_bUseOne = !m_bUseOne;
284 : if( m_bUseOne )
285 : m_xSourceResultCurrent = m_xSourceResultOne;
286 : else
287 : m_xSourceResultCurrent = m_xSourceResultTwo;
288 : */
289 0 : }
290 :
291 : //--------------------------------------------------------------------------
292 : // XSourceInitialization
293 : //--------------------------------------------------------------------------
294 : //virtual
295 0 : void SAL_CALL DynamicResultSetWrapper
296 : ::setSource( const Reference< XInterface > & Source )
297 : throw( AlreadyInitializedException, RuntimeException )
298 : {
299 0 : impl_EnsureNotDisposed();
300 : {
301 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
302 0 : if( m_xSource.is() )
303 : {
304 0 : throw AlreadyInitializedException();
305 0 : }
306 : }
307 :
308 0 : Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
309 : OSL_ENSURE( xSourceDynamic.is(),
310 : "the given source is not of required type XDynamicResultSet" );
311 :
312 0 : Reference< XDynamicResultSetListener > xListener = NULL;
313 0 : Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
314 :
315 0 : sal_Bool bStatic = sal_False;
316 : {
317 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
318 0 : m_xSource = xSourceDynamic;
319 0 : xListener = m_xListener;
320 0 : bStatic = m_bStatic;
321 0 : xMyListenerImpl = m_xMyListenerImpl;
322 : }
323 0 : if( xListener.is() )
324 0 : xSourceDynamic->setListener( m_xMyListenerImpl );
325 0 : else if( bStatic )
326 : {
327 0 : Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
328 0 : xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
329 : }
330 0 : m_aSourceSet.set();
331 0 : }
332 :
333 : //--------------------------------------------------------------------------
334 : // XDynamicResultSet
335 : //--------------------------------------------------------------------------
336 : //virtual
337 0 : Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
338 : ::getStaticResultSet()
339 : throw( ListenerAlreadySetException, RuntimeException )
340 : {
341 0 : impl_EnsureNotDisposed();
342 :
343 0 : Reference< XDynamicResultSet > xSource = NULL;
344 0 : Reference< XEventListener > xMyListenerImpl = NULL;
345 : {
346 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
347 0 : if( m_xListener.is() )
348 0 : throw ListenerAlreadySetException();
349 :
350 0 : xSource = m_xSource;
351 0 : m_bStatic = sal_True;
352 0 : xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
353 : }
354 :
355 0 : if( xSource.is() )
356 : {
357 0 : Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
358 0 : xSourceComponent->addEventListener( xMyListenerImpl );
359 : }
360 0 : if( !xSource.is() )
361 0 : m_aSourceSet.wait();
362 :
363 :
364 0 : Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
365 0 : impl_InitResultSetOne( xResultSet );
366 0 : return m_xMyResultOne;
367 : }
368 :
369 : //virtual
370 0 : void SAL_CALL DynamicResultSetWrapper
371 : ::setListener( const Reference<
372 : XDynamicResultSetListener > & Listener )
373 : throw( ListenerAlreadySetException, RuntimeException )
374 : {
375 0 : impl_EnsureNotDisposed();
376 :
377 0 : Reference< XDynamicResultSet > xSource = NULL;
378 0 : Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
379 : {
380 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
381 0 : if( m_xListener.is() )
382 0 : throw ListenerAlreadySetException();
383 0 : if( m_bStatic )
384 0 : throw ListenerAlreadySetException();
385 :
386 0 : m_xListener = Listener;
387 0 : addEventListener( Reference< XEventListener >::query( Listener ) );
388 :
389 0 : xSource = m_xSource;
390 0 : xMyListenerImpl = m_xMyListenerImpl;
391 : }
392 0 : if ( xSource.is() )
393 0 : xSource->setListener( xMyListenerImpl );
394 :
395 0 : m_aListenerSet.set();
396 0 : }
397 :
398 : //virtual
399 0 : void SAL_CALL DynamicResultSetWrapper
400 : ::connectToCache( const Reference< XDynamicResultSet > & xCache )
401 : throw( ListenerAlreadySetException, AlreadyInitializedException, ServiceNotFoundException, RuntimeException )
402 : {
403 0 : impl_EnsureNotDisposed();
404 :
405 0 : if( m_xListener.is() )
406 0 : throw ListenerAlreadySetException();
407 0 : if( m_bStatic )
408 0 : throw ListenerAlreadySetException();
409 :
410 0 : Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
411 : OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
412 0 : if( xTarget.is() && m_xContext.is() )
413 : {
414 : //@todo m_aSourceSet.wait();?
415 :
416 0 : Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
417 : try
418 : {
419 0 : xStubFactory = CachedDynamicResultSetStubFactory::create( m_xContext );
420 : }
421 0 : catch ( Exception const & )
422 : {
423 : }
424 :
425 0 : if( xStubFactory.is() )
426 : {
427 0 : xStubFactory->connectToCache(
428 0 : this, xCache, Sequence< NumberedSortingInfo > (), NULL );
429 0 : return;
430 0 : }
431 : }
432 : OSL_FAIL( "could not connect to cache" );
433 0 : throw ServiceNotFoundException();
434 : }
435 :
436 : //virtual
437 0 : sal_Int16 SAL_CALL DynamicResultSetWrapper
438 : ::getCapabilities()
439 : throw( RuntimeException )
440 : {
441 0 : impl_EnsureNotDisposed();
442 :
443 0 : m_aSourceSet.wait();
444 0 : Reference< XDynamicResultSet > xSource = NULL;
445 : {
446 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
447 0 : xSource = m_xSource;
448 : }
449 0 : return xSource->getCapabilities();
450 : }
451 :
452 : //--------------------------------------------------------------------------
453 : //--------------------------------------------------------------------------
454 : // class DynamicResultSetWrapperListener
455 : //--------------------------------------------------------------------------
456 : //--------------------------------------------------------------------------
457 :
458 0 : DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
459 : DynamicResultSetWrapper* pOwner )
460 0 : : m_pOwner( pOwner )
461 : {
462 :
463 0 : }
464 :
465 0 : DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
466 : {
467 :
468 0 : }
469 :
470 : //--------------------------------------------------------------------------
471 : // XInterface methods.
472 : //--------------------------------------------------------------------------
473 : //list all interfaces inclusive baseclasses of interfaces
474 0 : XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
475 : , XDynamicResultSetListener
476 : , XEventListener //base of XDynamicResultSetListener
477 : );
478 :
479 : //--------------------------------------------------------------------------
480 : // XDynamicResultSetListener methods:
481 : //--------------------------------------------------------------------------
482 : //virtual
483 0 : void SAL_CALL DynamicResultSetWrapperListener
484 : ::disposing( const EventObject& rEventObject )
485 : throw( RuntimeException )
486 : {
487 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
488 :
489 0 : if( m_pOwner )
490 0 : m_pOwner->impl_disposing( rEventObject );
491 0 : }
492 :
493 : //virtual
494 0 : void SAL_CALL DynamicResultSetWrapperListener
495 : ::notify( const ListEvent& Changes )
496 : throw( RuntimeException )
497 : {
498 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
499 :
500 0 : if( m_pOwner )
501 0 : m_pOwner->impl_notify( Changes );
502 0 : }
503 :
504 : //--------------------------------------------------------------------------
505 : // own methods:
506 : //--------------------------------------------------------------------------
507 :
508 0 : void SAL_CALL DynamicResultSetWrapperListener
509 : ::impl_OwnerDies()
510 : {
511 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
512 :
513 0 : m_pOwner = NULL;
514 0 : }
515 :
516 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|