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