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