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 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 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 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 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 ) 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 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 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 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 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 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 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 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 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 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 467 DynamicResultSetWrapperListener::DynamicResultSetWrapperListener( 468 DynamicResultSetWrapper* pOwner ) 469 : m_pOwner( pOwner ) 470 { 471 472 } 473 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 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 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 518 ::impl_OwnerDies() 519 { 520 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 521 522 m_pOwner = NULL; 523 } 524 525