1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmlhelp.hxx" 30 #include <ucbhelper/contentidentifier.hxx> 31 #include <com/sun/star/ucb/OpenMode.hpp> 32 #include <com/sun/star/uno/Reference.h> 33 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ 34 #include <com/sun/star/beans/PropertyAttribute.hpp> 35 #endif 36 #include <com/sun/star/ucb/ListActionType.hpp> 37 #include <com/sun/star/ucb/XSourceInitialization.hpp> 38 #include <ucbhelper/resultsetmetadata.hxx> 39 40 #include "resultsetbase.hxx" 41 42 using namespace chelp; 43 using namespace com::sun::star; 44 45 ResultSetBase::ResultSetBase( const uno::Reference< lang::XMultiServiceFactory >& xMSF, 46 const uno::Reference< ucb::XContentProvider >& xProvider, 47 sal_Int32 nOpenMode, 48 const uno::Sequence< beans::Property >& seq, 49 const uno::Sequence< ucb::NumberedSortingInfo >& seqSort ) 50 : m_xMSF( xMSF ), 51 m_xProvider( xProvider ), 52 m_nRow( -1 ), 53 m_nWasNull( true ), 54 m_nOpenMode( nOpenMode ), 55 m_bRowCountFinal( true ), 56 m_sProperty( seq ), 57 m_sSortingInfo( seqSort ), 58 m_pDisposeEventListeners( 0 ), 59 m_pRowCountListeners( 0 ), 60 m_pIsFinalListeners( 0 ) 61 { 62 } 63 64 ResultSetBase::~ResultSetBase() 65 { 66 delete m_pIsFinalListeners; 67 delete m_pRowCountListeners; 68 delete m_pDisposeEventListeners; 69 } 70 71 72 // XInterface 73 74 void SAL_CALL 75 ResultSetBase::acquire( 76 void ) 77 throw() 78 { 79 OWeakObject::acquire(); 80 } 81 82 83 void SAL_CALL 84 ResultSetBase::release( 85 void ) 86 throw() 87 { 88 OWeakObject::release(); 89 } 90 91 92 93 uno::Any SAL_CALL 94 ResultSetBase::queryInterface( 95 const uno::Type& rType ) 96 throw( uno::RuntimeException ) 97 { 98 uno::Any aRet = cppu::queryInterface( rType, 99 SAL_STATIC_CAST( lang::XComponent*, this), 100 SAL_STATIC_CAST( sdbc::XRow*, this), 101 SAL_STATIC_CAST( sdbc::XResultSet*, this), 102 SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this), 103 SAL_STATIC_CAST( beans::XPropertySet*, this ), 104 SAL_STATIC_CAST( ucb::XContentAccess*, this) ); 105 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 106 } 107 108 109 110 // XComponent 111 112 113 void SAL_CALL 114 ResultSetBase::addEventListener( 115 const uno::Reference< lang::XEventListener >& Listener ) 116 throw( uno::RuntimeException ) 117 { 118 osl::MutexGuard aGuard( m_aMutex ); 119 120 if ( ! m_pDisposeEventListeners ) 121 m_pDisposeEventListeners = 122 new cppu::OInterfaceContainerHelper( m_aMutex ); 123 124 m_pDisposeEventListeners->addInterface( Listener ); 125 } 126 127 128 void SAL_CALL 129 ResultSetBase::removeEventListener( 130 const uno::Reference< lang::XEventListener >& Listener ) 131 throw( uno::RuntimeException ) 132 { 133 osl::MutexGuard aGuard( m_aMutex ); 134 135 if ( m_pDisposeEventListeners ) 136 m_pDisposeEventListeners->removeInterface( Listener ); 137 } 138 139 140 141 void SAL_CALL 142 ResultSetBase::dispose() 143 throw( uno::RuntimeException ) 144 { 145 osl::MutexGuard aGuard( m_aMutex ); 146 147 lang::EventObject aEvt; 148 aEvt.Source = static_cast< lang::XComponent * >( this ); 149 150 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) 151 { 152 m_pDisposeEventListeners->disposeAndClear( aEvt ); 153 } 154 if( m_pRowCountListeners && m_pRowCountListeners->getLength() ) 155 { 156 m_pRowCountListeners->disposeAndClear( aEvt ); 157 } 158 if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() ) 159 { 160 m_pIsFinalListeners->disposeAndClear( aEvt ); 161 } 162 } 163 164 165 166 // XResultSet 167 168 sal_Bool SAL_CALL 169 ResultSetBase::next( 170 void ) 171 throw( sdbc::SQLException, 172 uno::RuntimeException ) 173 { 174 sal_Bool test; 175 m_nRow++; 176 if( sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) 177 test = true; 178 else 179 test = false; 180 return test; 181 } 182 183 184 sal_Bool SAL_CALL 185 ResultSetBase::isBeforeFirst( 186 void ) 187 throw( sdbc::SQLException, 188 uno::RuntimeException ) 189 { 190 return m_nRow == -1; 191 } 192 193 194 sal_Bool SAL_CALL 195 ResultSetBase::isAfterLast( 196 void ) 197 throw( sdbc::SQLException, 198 uno::RuntimeException ) 199 { 200 return sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size(); // Cannot happen, if m_aFolder.isOpen() 201 } 202 203 204 sal_Bool SAL_CALL 205 ResultSetBase::isFirst( 206 void ) 207 throw( sdbc::SQLException, 208 uno::RuntimeException ) 209 { 210 return m_nRow == 0; 211 } 212 213 214 sal_Bool SAL_CALL 215 ResultSetBase::isLast( 216 void ) 217 throw( sdbc::SQLException, 218 uno::RuntimeException) 219 { 220 if( sal::static_int_cast<sal_uInt32>( m_nRow ) == m_aItems.size() - 1 ) 221 return true; 222 else 223 return false; 224 } 225 226 227 void SAL_CALL 228 ResultSetBase::beforeFirst( 229 void ) 230 throw( sdbc::SQLException, 231 uno::RuntimeException) 232 { 233 m_nRow = -1; 234 } 235 236 237 void SAL_CALL 238 ResultSetBase::afterLast( 239 void ) 240 throw( sdbc::SQLException, 241 uno::RuntimeException ) 242 { 243 m_nRow = m_aItems.size(); 244 } 245 246 247 sal_Bool SAL_CALL 248 ResultSetBase::first( 249 void ) 250 throw( sdbc::SQLException, 251 uno::RuntimeException) 252 { 253 m_nRow = -1; 254 return next(); 255 } 256 257 258 sal_Bool SAL_CALL 259 ResultSetBase::last( 260 void ) 261 throw( sdbc::SQLException, 262 uno::RuntimeException ) 263 { 264 m_nRow = m_aItems.size() - 1; 265 return true; 266 } 267 268 269 sal_Int32 SAL_CALL 270 ResultSetBase::getRow( 271 void ) 272 throw( sdbc::SQLException, 273 uno::RuntimeException) 274 { 275 // Test, whether behind last row 276 if( -1 == m_nRow || sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size() ) 277 return 0; 278 else 279 return m_nRow+1; 280 } 281 282 283 sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row ) 284 throw( sdbc::SQLException, uno::RuntimeException) 285 { 286 if( row >= 0 ) 287 m_nRow = row - 1; 288 else 289 { 290 last(); 291 m_nRow += ( row + 1 ); 292 if( m_nRow < -1 ) 293 m_nRow = -1; 294 } 295 296 return 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); 297 } 298 299 300 301 302 sal_Bool SAL_CALL 303 ResultSetBase::relative( 304 sal_Int32 row ) 305 throw( sdbc::SQLException, 306 uno::RuntimeException) 307 { 308 if( isAfterLast() || isBeforeFirst() ) 309 throw sdbc::SQLException(); 310 311 if( row > 0 ) 312 while( row-- ) 313 next(); 314 else if( row < 0 ) 315 while( row++ && m_nRow > -1 ) 316 previous(); 317 318 return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); 319 } 320 321 322 323 sal_Bool SAL_CALL 324 ResultSetBase::previous( 325 void ) 326 throw( sdbc::SQLException, 327 uno::RuntimeException) 328 { 329 if( sal::static_int_cast<sal_uInt32>( m_nRow ) > m_aItems.size() ) 330 m_nRow = m_aItems.size(); // Correct Handling of afterLast 331 if( 0 <= m_nRow ) -- m_nRow; 332 333 return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); 334 } 335 336 337 void SAL_CALL 338 ResultSetBase::refreshRow( 339 void ) 340 throw( sdbc::SQLException, 341 uno::RuntimeException) 342 { 343 } 344 345 346 sal_Bool SAL_CALL 347 ResultSetBase::rowUpdated( 348 void ) 349 throw( sdbc::SQLException, 350 uno::RuntimeException ) 351 { 352 return false; 353 } 354 355 sal_Bool SAL_CALL 356 ResultSetBase::rowInserted( 357 void ) 358 throw( sdbc::SQLException, 359 uno::RuntimeException ) 360 { 361 return false; 362 } 363 364 sal_Bool SAL_CALL 365 ResultSetBase::rowDeleted( 366 void ) 367 throw( sdbc::SQLException, 368 uno::RuntimeException ) 369 { 370 return false; 371 } 372 373 374 uno::Reference< uno::XInterface > SAL_CALL 375 ResultSetBase::getStatement( 376 void ) 377 throw( sdbc::SQLException, 378 uno::RuntimeException ) 379 { 380 uno::Reference< uno::XInterface > test( 0 ); 381 return test; 382 } 383 384 385 // XCloseable 386 387 void SAL_CALL 388 ResultSetBase::close( 389 void ) 390 throw( sdbc::SQLException, 391 uno::RuntimeException) 392 { 393 } 394 395 396 rtl::OUString SAL_CALL 397 ResultSetBase::queryContentIdentifierString( 398 void ) 399 throw( uno::RuntimeException ) 400 { 401 if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) 402 return m_aPath[m_nRow]; 403 else 404 return rtl::OUString(); 405 } 406 407 408 uno::Reference< ucb::XContentIdentifier > SAL_CALL 409 ResultSetBase::queryContentIdentifier( 410 void ) 411 throw( uno::RuntimeException ) 412 { 413 if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) 414 { 415 rtl::OUString url = queryContentIdentifierString(); 416 if( ! m_aIdents[m_nRow].is() && url.getLength() ) 417 m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >( 418 new ::ucbhelper::ContentIdentifier( m_xMSF,url ) ); 419 return m_aIdents[m_nRow]; 420 } 421 422 return uno::Reference< ucb::XContentIdentifier >(); 423 } 424 425 426 uno::Reference< ucb::XContent > SAL_CALL 427 ResultSetBase::queryContent( 428 void ) 429 throw( uno::RuntimeException ) 430 { 431 if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) 432 return m_xProvider->queryContent( queryContentIdentifier() ); 433 else 434 return uno::Reference< ucb::XContent >(); 435 } 436 437 438 439 class XPropertySetInfoImpl 440 : public cppu::OWeakObject, 441 public beans::XPropertySetInfo 442 { 443 public: 444 445 XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq ) 446 : m_aSeq( aSeq ) 447 { 448 } 449 450 void SAL_CALL acquire( void ) 451 throw() 452 { 453 OWeakObject::acquire(); 454 } 455 456 457 void SAL_CALL release( void ) 458 throw() 459 { 460 OWeakObject::release(); 461 } 462 463 uno::Any SAL_CALL queryInterface( const uno::Type& rType ) 464 throw( uno::RuntimeException ) 465 { 466 uno::Any aRet = cppu::queryInterface( rType, 467 SAL_STATIC_CAST( beans::XPropertySetInfo*, this ) ); 468 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 469 } 470 471 uno::Sequence< beans::Property > SAL_CALL getProperties() 472 throw( uno::RuntimeException ) 473 { 474 return m_aSeq; 475 } 476 477 beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) 478 throw( beans::UnknownPropertyException, 479 uno::RuntimeException) 480 { 481 for( int i = 0; i < m_aSeq.getLength(); ++i ) 482 if( aName == m_aSeq[i].Name ) 483 return m_aSeq[i]; 484 throw beans::UnknownPropertyException(); 485 } 486 487 sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) 488 throw( uno::RuntimeException ) 489 { 490 for( int i = 0; i < m_aSeq.getLength(); ++i ) 491 if( Name == m_aSeq[i].Name ) 492 return true; 493 return false; 494 } 495 496 private: 497 498 uno::Sequence< beans::Property > m_aSeq; 499 }; 500 501 502 503 // XPropertySet 504 uno::Reference< beans::XPropertySetInfo > SAL_CALL 505 ResultSetBase::getPropertySetInfo() 506 throw( uno::RuntimeException) 507 { 508 uno::Sequence< beans::Property > seq(2); 509 seq[0].Name = rtl::OUString::createFromAscii( "RowCount" ); 510 seq[0].Handle = -1; 511 seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) ); 512 seq[0].Attributes = beans::PropertyAttribute::READONLY; 513 514 seq[1].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" ); 515 seq[1].Handle = -1; 516 seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) ); 517 seq[1].Attributes = beans::PropertyAttribute::READONLY; 518 519 //t 520 return uno::Reference< beans::XPropertySetInfo > ( new XPropertySetInfoImpl( seq ) ); 521 } 522 523 524 525 void SAL_CALL ResultSetBase::setPropertyValue( 526 const rtl::OUString& aPropertyName, const uno::Any& aValue ) 527 throw( beans::UnknownPropertyException, 528 beans::PropertyVetoException, 529 lang::IllegalArgumentException, 530 lang::WrappedTargetException, 531 uno::RuntimeException) 532 { 533 (void)aValue; 534 535 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) || 536 aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 537 return; 538 539 throw beans::UnknownPropertyException(); 540 } 541 542 543 uno::Any SAL_CALL ResultSetBase::getPropertyValue( 544 const rtl::OUString& PropertyName ) 545 throw( beans::UnknownPropertyException, 546 lang::WrappedTargetException, 547 uno::RuntimeException) 548 { 549 if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) 550 { 551 uno::Any aAny; 552 aAny <<= m_bRowCountFinal; 553 return aAny; 554 } 555 else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 556 { 557 uno::Any aAny; 558 sal_Int32 count = m_aItems.size(); 559 aAny <<= count; 560 return aAny; 561 } 562 else 563 throw beans::UnknownPropertyException(); 564 } 565 566 567 void SAL_CALL ResultSetBase::addPropertyChangeListener( 568 const rtl::OUString& aPropertyName, 569 const uno::Reference< beans::XPropertyChangeListener >& xListener ) 570 throw( beans::UnknownPropertyException, 571 lang::WrappedTargetException, 572 uno::RuntimeException) 573 { 574 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) 575 { 576 osl::MutexGuard aGuard( m_aMutex ); 577 if ( ! m_pIsFinalListeners ) 578 m_pIsFinalListeners = 579 new cppu::OInterfaceContainerHelper( m_aMutex ); 580 581 m_pIsFinalListeners->addInterface( xListener ); 582 } 583 else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 584 { 585 osl::MutexGuard aGuard( m_aMutex ); 586 if ( ! m_pRowCountListeners ) 587 m_pRowCountListeners = 588 new cppu::OInterfaceContainerHelper( m_aMutex ); 589 m_pRowCountListeners->addInterface( xListener ); 590 } 591 else 592 throw beans::UnknownPropertyException(); 593 } 594 595 596 void SAL_CALL ResultSetBase::removePropertyChangeListener( 597 const rtl::OUString& aPropertyName, 598 const uno::Reference< beans::XPropertyChangeListener >& aListener ) 599 throw( beans::UnknownPropertyException, 600 lang::WrappedTargetException, 601 uno::RuntimeException) 602 { 603 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) && 604 m_pIsFinalListeners ) 605 { 606 osl::MutexGuard aGuard( m_aMutex ); 607 m_pIsFinalListeners->removeInterface( aListener ); 608 } 609 else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) && 610 m_pRowCountListeners ) 611 { 612 osl::MutexGuard aGuard( m_aMutex ); 613 m_pRowCountListeners->removeInterface( aListener ); 614 } 615 else 616 throw beans::UnknownPropertyException(); 617 } 618 619 620 void SAL_CALL ResultSetBase::addVetoableChangeListener( 621 const rtl::OUString& PropertyName, 622 const uno::Reference< beans::XVetoableChangeListener >& aListener ) 623 throw( beans::UnknownPropertyException, 624 lang::WrappedTargetException, 625 uno::RuntimeException) 626 { 627 (void)PropertyName; 628 (void)aListener; 629 } 630 631 632 void SAL_CALL ResultSetBase::removeVetoableChangeListener( 633 const rtl::OUString& PropertyName, 634 const uno::Reference< beans::XVetoableChangeListener >& aListener ) 635 throw( beans::UnknownPropertyException, 636 lang::WrappedTargetException, 637 uno::RuntimeException) 638 { 639 (void)PropertyName; 640 (void)aListener; 641 } 642 643 644 645 // XResultSetMetaDataSupplier 646 uno::Reference< sdbc::XResultSetMetaData > SAL_CALL 647 ResultSetBase::getMetaData( 648 void ) 649 throw( sdbc::SQLException, 650 uno::RuntimeException ) 651 { 652 ::ucbhelper::ResultSetMetaData* p = 653 new ::ucbhelper::ResultSetMetaData( 654 m_xMSF, m_sProperty ); 655 return uno::Reference< sdbc::XResultSetMetaData >( p ); 656 } 657