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_cacher.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