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 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 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 87 DynamicResultSetWrapper::~DynamicResultSetWrapper() 88 { 89 //call impl_deinit() at start of destructor of derived class 90 91 delete m_pDisposeEventListeners; 92 }; 93 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 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 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 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 ) 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 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 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 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 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 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 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 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 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 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 457 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener( 458 DynamicResultSetWrapper* pOwner ) 459 : m_pOwner( pOwner ) 460 { 461 462 } 463 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 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 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 506 ::impl_OwnerDies() 507 { 508 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 509 510 m_pOwner = NULL; 511 } 512