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 {
104 osl::Guard< osl::Mutex > aGuard( m_aMutex );
105 if( m_bDisposed )
106 throw DisposedException();
107 }
108
109 //virtual
110 void SAL_CALL DynamicResultSetWrapper
impl_InitResultSetOne(const Reference<XResultSet> & xResultSet)111 ::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
112 {
113 osl::Guard< osl::Mutex > aGuard( m_aMutex );
114 OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
115 m_xSourceResultOne = xResultSet;
116 m_xMyResultOne = xResultSet;
117 }
118
119 //virtual
120 void SAL_CALL DynamicResultSetWrapper
impl_InitResultSetTwo(const Reference<XResultSet> & xResultSet)121 ::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
122 {
123 osl::Guard< osl::Mutex > aGuard( m_aMutex );
124 OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
125 m_xSourceResultTwo = xResultSet;
126 m_xMyResultTwo = xResultSet;
127 }
128
129 //--------------------------------------------------------------------------
130 // XInterface methods.
131 //--------------------------------------------------------------------------
132 //list all interfaces inclusive baseclasses of interfaces
133 QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
SAL_STATIC_CAST(XComponent *,this)134 SAL_STATIC_CAST( XComponent*, this ) //base of XDynamicResultSet
135 , SAL_STATIC_CAST( XDynamicResultSet*, this )
136 , SAL_STATIC_CAST( XSourceInitialization*, this )
137 QUERYINTERFACE_IMPL_END
138
139 //--------------------------------------------------------------------------
140 // XComponent methods.
141 //--------------------------------------------------------------------------
142 // virtual
143 void SAL_CALL DynamicResultSetWrapper
144 ::dispose()
145 {
146 impl_EnsureNotDisposed();
147
148 Reference< XComponent > xSourceComponent;
149 {
150 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
151 if( m_bInDispose || m_bDisposed )
152 return;
153 m_bInDispose = sal_True;
154
155 xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);
156
157 if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
158 {
159 EventObject aEvt;
160 aEvt.Source = static_cast< XComponent * >( this );
161
162 aGuard.clear();
163 m_pDisposeEventListeners->disposeAndClear( aEvt );
164 }
165 }
166
167 /* //@todo ?? ( only if java collection needs to long )
168 if( xSourceComponent.is() )
169 xSourceComponent->dispose();
170 */
171
172 osl::Guard< osl::Mutex > aGuard( m_aMutex );
173 m_bDisposed = sal_True;
174 m_bInDispose = sal_False;
175 }
176
177 //--------------------------------------------------------------------------
178 // virtual
179 void SAL_CALL DynamicResultSetWrapper
addEventListener(const Reference<XEventListener> & Listener)180 ::addEventListener( const Reference< XEventListener >& Listener )
181 {
182 impl_EnsureNotDisposed();
183 osl::Guard< osl::Mutex > aGuard( m_aMutex );
184
185 if ( !m_pDisposeEventListeners )
186 m_pDisposeEventListeners =
187 new OInterfaceContainerHelper( m_aContainerMutex );
188
189 m_pDisposeEventListeners->addInterface( Listener );
190 }
191
192 //--------------------------------------------------------------------------
193 // virtual
194 void SAL_CALL DynamicResultSetWrapper
removeEventListener(const Reference<XEventListener> & Listener)195 ::removeEventListener( const Reference< XEventListener >& Listener )
196 {
197 impl_EnsureNotDisposed();
198 osl::Guard< osl::Mutex > aGuard( m_aMutex );
199
200 if ( m_pDisposeEventListeners )
201 m_pDisposeEventListeners->removeInterface( Listener );
202 }
203
204 //--------------------------------------------------------------------------
205 // own methods
206 //--------------------------------------------------------------------------
207
208 //virtual
209 void SAL_CALL DynamicResultSetWrapper
impl_disposing(const EventObject &)210 ::impl_disposing( const EventObject& )
211 {
212 impl_EnsureNotDisposed();
213
214 osl::Guard< osl::Mutex > aGuard( m_aMutex );
215
216 if( !m_xSource.is() )
217 return;
218
219 //release all references to the broadcaster:
220 m_xSource.clear();
221 m_xSourceResultOne.clear();//?? or only when not static??
222 m_xSourceResultTwo.clear();//??
223 //@todo m_xMyResultOne.clear(); ???
224 //@todo m_xMyResultTwo.clear(); ???
225 }
226
227 //virtual
228 void SAL_CALL DynamicResultSetWrapper
impl_notify(const ListEvent & Changes)229 ::impl_notify( const ListEvent& Changes )
230 {
231 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 ListEvent aNewEvent;
242 aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
243 aNewEvent.Changes = Changes.Changes;
244
245 {
246 osl::Guard< osl::Mutex > aGuard( m_aMutex );
247 for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
248 {
249 ListAction& rAction = aNewEvent.Changes[i];
250 switch( rAction.ListActionType )
251 {
252 case ListActionType::WELCOME:
253 {
254 WelcomeDynamicResultSetStruct aWelcome;
255 if( rAction.ActionInfo >>= aWelcome )
256 {
257 impl_InitResultSetOne( aWelcome.Old );
258 impl_InitResultSetTwo( aWelcome.New );
259 m_bGotWelcome = sal_True;
260
261 aWelcome.Old = m_xMyResultOne;
262 aWelcome.New = m_xMyResultTwo;
263
264 rAction.ActionInfo <<= aWelcome;
265 }
266 else
267 {
268 OSL_ENSURE( sal_False, "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
269 //throw RuntimeException();
270 }
271 break;
272 }
273 }
274 }
275 OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
276 }
277
278 if( !m_xListener.is() )
279 m_aListenerSet.wait();
280 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 }
290
291 //--------------------------------------------------------------------------
292 // XSourceInitialization
293 //--------------------------------------------------------------------------
294 //virtual
295 void SAL_CALL DynamicResultSetWrapper
setSource(const Reference<XInterface> & Source)296 ::setSource( const Reference< XInterface > & Source )
297 {
298 impl_EnsureNotDisposed();
299 {
300 osl::Guard< osl::Mutex > aGuard( m_aMutex );
301 if( m_xSource.is() )
302 {
303 throw AlreadyInitializedException();
304 }
305 }
306
307 Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
308 OSL_ENSURE( xSourceDynamic.is(),
309 "the given source is not of required type XDynamicResultSet" );
310
311 Reference< XDynamicResultSetListener > xListener = NULL;
312 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
313
314 sal_Bool bStatic = sal_False;
315 {
316 osl::Guard< osl::Mutex > aGuard( m_aMutex );
317 m_xSource = xSourceDynamic;
318 xListener = m_xListener;
319 bStatic = m_bStatic;
320 xMyListenerImpl = m_xMyListenerImpl;
321 }
322 if( xListener.is() )
323 xSourceDynamic->setListener( m_xMyListenerImpl );
324 else if( bStatic )
325 {
326 Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
327 xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
328 }
329 m_aSourceSet.set();
330 }
331
332 //--------------------------------------------------------------------------
333 // XDynamicResultSet
334 //--------------------------------------------------------------------------
335 //virtual
336 Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
getStaticResultSet()337 ::getStaticResultSet()
338 {
339 impl_EnsureNotDisposed();
340
341 Reference< XDynamicResultSet > xSource = NULL;
342 Reference< XEventListener > xMyListenerImpl = NULL;
343 {
344 osl::Guard< osl::Mutex > aGuard( m_aMutex );
345 if( m_xListener.is() )
346 throw ListenerAlreadySetException();
347
348 xSource = m_xSource;
349 m_bStatic = sal_True;
350 xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
351 }
352
353 if( xSource.is() )
354 {
355 Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
356 xSourceComponent->addEventListener( xMyListenerImpl );
357 }
358 if( !xSource.is() )
359 m_aSourceSet.wait();
360
361
362 Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
363 impl_InitResultSetOne( xResultSet );
364 return m_xMyResultOne;
365 }
366
367 //virtual
368 void SAL_CALL DynamicResultSetWrapper
setListener(const Reference<XDynamicResultSetListener> & Listener)369 ::setListener( const Reference<
370 XDynamicResultSetListener > & Listener )
371 {
372 impl_EnsureNotDisposed();
373
374 Reference< XDynamicResultSet > xSource = NULL;
375 Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
376 {
377 osl::Guard< osl::Mutex > aGuard( m_aMutex );
378 if( m_xListener.is() )
379 throw ListenerAlreadySetException();
380 if( m_bStatic )
381 throw ListenerAlreadySetException();
382
383 m_xListener = Listener;
384 addEventListener( Reference< XEventListener >::query( Listener ) );
385
386 xSource = m_xSource;
387 xMyListenerImpl = m_xMyListenerImpl;
388 }
389 if ( xSource.is() )
390 xSource->setListener( xMyListenerImpl );
391
392 m_aListenerSet.set();
393 }
394
395 //virtual
396 void SAL_CALL DynamicResultSetWrapper
connectToCache(const Reference<XDynamicResultSet> & xCache)397 ::connectToCache( const Reference< XDynamicResultSet > & xCache )
398 {
399 impl_EnsureNotDisposed();
400
401 if( m_xListener.is() )
402 throw ListenerAlreadySetException();
403 if( m_bStatic )
404 throw ListenerAlreadySetException();
405
406 Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
407 OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
408 if( xTarget.is() && m_xSMgr.is() )
409 {
410 //@todo m_aSourceSet.wait();?
411
412 Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
413 try
414 {
415 xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
416 m_xSMgr->createInstance(
417 OUString::createFromAscii(
418 "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
419 UNO_QUERY );
420 }
421 catch ( Exception const & )
422 {
423 }
424
425 if( xStubFactory.is() )
426 {
427 xStubFactory->connectToCache(
428 this, xCache, Sequence< NumberedSortingInfo > (), NULL );
429 return;
430 }
431 }
432 OSL_ENSURE( sal_False, "could not connect to cache" );
433 throw ServiceNotFoundException();
434 }
435
436 //virtual
437 sal_Int16 SAL_CALL DynamicResultSetWrapper
getCapabilities()438 ::getCapabilities()
439 {
440 impl_EnsureNotDisposed();
441
442 m_aSourceSet.wait();
443 Reference< XDynamicResultSet > xSource = NULL;
444 {
445 osl::Guard< osl::Mutex > aGuard( m_aMutex );
446 xSource = m_xSource;
447 }
448 return xSource->getCapabilities();
449 }
450
451 //--------------------------------------------------------------------------
452 //--------------------------------------------------------------------------
453 // class DynamicResultSetWrapperListener
454 //--------------------------------------------------------------------------
455 //--------------------------------------------------------------------------
456
DynamicResultSetWrapperListener(DynamicResultSetWrapper * pOwner)457 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
458 DynamicResultSetWrapper* pOwner )
459 : m_pOwner( pOwner )
460 {
461
462 }
463
~DynamicResultSetWrapperListener()464 DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
465 {
466
467 }
468
469 //--------------------------------------------------------------------------
470 // XInterface methods.
471 //--------------------------------------------------------------------------
472 //list all interfaces inclusive baseclasses of interfaces
473 XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
474 , XDynamicResultSetListener
475 , XEventListener //base of XDynamicResultSetListener
476 );
477
478 //--------------------------------------------------------------------------
479 // XDynamicResultSetListener methods:
480 //--------------------------------------------------------------------------
481 //virtual
482 void SAL_CALL DynamicResultSetWrapperListener
disposing(const EventObject & rEventObject)483 ::disposing( const EventObject& rEventObject )
484 {
485 osl::Guard< osl::Mutex > aGuard( m_aMutex );
486
487 if( m_pOwner )
488 m_pOwner->impl_disposing( rEventObject );
489 }
490
491 //virtual
492 void SAL_CALL DynamicResultSetWrapperListener
notify(const ListEvent & Changes)493 ::notify( const ListEvent& Changes )
494 {
495 osl::Guard< osl::Mutex > aGuard( m_aMutex );
496
497 if( m_pOwner )
498 m_pOwner->impl_notify( Changes );
499 }
500
501 //--------------------------------------------------------------------------
502 // own methods:
503 //--------------------------------------------------------------------------
504
505 void SAL_CALL DynamicResultSetWrapperListener
impl_OwnerDies()506 ::impl_OwnerDies()
507 {
508 osl::Guard< osl::Mutex > aGuard( m_aMutex );
509
510 m_pOwner = NULL;
511 }
512