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_ucb.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 #include "ftpresultsetbase.hxx" 40 41 using namespace ftp; 42 using namespace com::sun::star; 43 44 ResultSetBase::ResultSetBase( 45 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( 99 rType, 100 SAL_STATIC_CAST( lang::XComponent*, this), 101 SAL_STATIC_CAST( sdbc::XRow*, this), 102 SAL_STATIC_CAST( sdbc::XResultSet*, this), 103 SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this), 104 SAL_STATIC_CAST( beans::XPropertySet*, this ), 105 SAL_STATIC_CAST( ucb::XContentAccess*, this) ); 106 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 107 } 108 109 110 111 // XComponent 112 113 114 void SAL_CALL 115 ResultSetBase::addEventListener( 116 const uno::Reference< lang::XEventListener >& Listener ) 117 throw( uno::RuntimeException ) 118 { 119 osl::MutexGuard aGuard( m_aMutex ); 120 121 if ( ! m_pDisposeEventListeners ) 122 m_pDisposeEventListeners = 123 new cppu::OInterfaceContainerHelper( m_aMutex ); 124 125 m_pDisposeEventListeners->addInterface( Listener ); 126 } 127 128 129 void SAL_CALL 130 ResultSetBase::removeEventListener( 131 const uno::Reference< lang::XEventListener >& Listener ) 132 throw( uno::RuntimeException ) 133 { 134 osl::MutexGuard aGuard( m_aMutex ); 135 136 if ( m_pDisposeEventListeners ) 137 m_pDisposeEventListeners->removeInterface( Listener ); 138 } 139 140 141 142 void SAL_CALL 143 ResultSetBase::dispose() 144 throw( uno::RuntimeException ) 145 { 146 osl::MutexGuard aGuard( m_aMutex ); 147 148 lang::EventObject aEvt; 149 aEvt.Source = static_cast< lang::XComponent * >( this ); 150 151 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) 152 { 153 m_pDisposeEventListeners->disposeAndClear( aEvt ); 154 } 155 if( m_pRowCountListeners && m_pRowCountListeners->getLength() ) 156 { 157 m_pRowCountListeners->disposeAndClear( aEvt ); 158 } 159 if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() ) 160 { 161 m_pIsFinalListeners->disposeAndClear( aEvt ); 162 } 163 } 164 165 166 167 // XResultSet 168 169 sal_Bool SAL_CALL 170 ResultSetBase::next( 171 void ) 172 throw( sdbc::SQLException, 173 uno::RuntimeException ) 174 { 175 sal_Bool test; 176 if( ++m_nRow < sal::static_int_cast<sal_Int32>(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 m_nRow >= sal::static_int_cast<sal_Int32>(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( m_nRow == sal::static_int_cast<sal_Int32>(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 || m_nRow >= sal::static_int_cast<sal_Int32>(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 && m_nRow < sal::static_int_cast<sal_Int32>(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 && m_nRow < sal::static_int_cast<sal_Int32>(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( m_nRow > sal::static_int_cast<sal_Int32>(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 && m_nRow < sal::static_int_cast<sal_Int32>(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 && m_nRow < sal::static_int_cast<sal_Int32>(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 ) 412 throw( 413 uno::RuntimeException 414 ) 415 { 416 if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) 417 { 418 if(!m_aIdents[m_nRow].is()) { 419 rtl::OUString url = queryContentIdentifierString(); 420 if(url.getLength() ) 421 m_aIdents[m_nRow] = 422 uno::Reference< ucb::XContentIdentifier >( 423 new ::ucbhelper::ContentIdentifier(m_xMSF,url) ); 424 } 425 return m_aIdents[m_nRow]; 426 } 427 428 return uno::Reference<ucb::XContentIdentifier>(); 429 } 430 431 432 uno::Reference< ucb::XContent > SAL_CALL 433 ResultSetBase::queryContent( 434 void ) 435 throw( uno::RuntimeException ) 436 { 437 if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) 438 return m_xProvider->queryContent(queryContentIdentifier()); 439 else 440 return uno::Reference< ucb::XContent >(); 441 } 442 443 444 445 class XPropertySetInfoImpl 446 : public cppu::OWeakObject, 447 public beans::XPropertySetInfo 448 { 449 public: 450 451 XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq ) 452 : m_aSeq( aSeq ) 453 { 454 } 455 456 void SAL_CALL acquire( void ) 457 throw() 458 { 459 OWeakObject::acquire(); 460 } 461 462 463 void SAL_CALL release( void ) 464 throw() 465 { 466 OWeakObject::release(); 467 } 468 469 uno::Any SAL_CALL queryInterface( const uno::Type& rType ) 470 throw( uno::RuntimeException ) 471 { 472 uno::Any aRet = cppu::queryInterface( 473 rType, 474 SAL_STATIC_CAST( beans::XPropertySetInfo*, this ) ); 475 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 476 } 477 478 uno::Sequence< beans::Property > SAL_CALL getProperties() 479 throw( uno::RuntimeException ) 480 { 481 return m_aSeq; 482 } 483 484 beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) 485 throw( beans::UnknownPropertyException, 486 uno::RuntimeException) 487 { 488 for( int i = 0; i < m_aSeq.getLength(); ++i ) 489 if( aName == m_aSeq[i].Name ) 490 return m_aSeq[i]; 491 throw beans::UnknownPropertyException(); 492 } 493 494 sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) 495 throw( uno::RuntimeException ) 496 { 497 for( int i = 0; i < m_aSeq.getLength(); ++i ) 498 if( Name == m_aSeq[i].Name ) 499 return true; 500 return false; 501 } 502 503 private: 504 505 uno::Sequence< beans::Property > m_aSeq; 506 }; 507 508 509 510 // XPropertySet 511 uno::Reference< beans::XPropertySetInfo > SAL_CALL 512 ResultSetBase::getPropertySetInfo() 513 throw( uno::RuntimeException) 514 { 515 uno::Sequence< beans::Property > seq(2); 516 seq[0].Name = rtl::OUString::createFromAscii( "RowCount" ); 517 seq[0].Handle = -1; 518 seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) ); 519 seq[0].Attributes = beans::PropertyAttribute::READONLY; 520 521 seq[1].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" ); 522 seq[1].Handle = -1; 523 seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) ); 524 seq[1].Attributes = beans::PropertyAttribute::READONLY; 525 526 //t 527 return uno::Reference< beans::XPropertySetInfo > ( 528 new XPropertySetInfoImpl( seq ) ); 529 } 530 531 532 533 void SAL_CALL ResultSetBase::setPropertyValue( 534 const rtl::OUString& aPropertyName, const uno::Any& /*aValue*/ ) 535 throw( beans::UnknownPropertyException, 536 beans::PropertyVetoException, 537 lang::IllegalArgumentException, 538 lang::WrappedTargetException, 539 uno::RuntimeException) 540 { 541 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) || 542 aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 543 return; 544 545 throw beans::UnknownPropertyException(); 546 } 547 548 549 uno::Any SAL_CALL ResultSetBase::getPropertyValue( 550 const rtl::OUString& PropertyName ) 551 throw( beans::UnknownPropertyException, 552 lang::WrappedTargetException, 553 uno::RuntimeException) 554 { 555 if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) 556 { 557 uno::Any aAny; 558 aAny <<= m_bRowCountFinal; 559 return aAny; 560 } 561 else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 562 { 563 uno::Any aAny; 564 sal_Int32 count = m_aItems.size(); 565 aAny <<= count; 566 return aAny; 567 } 568 else 569 throw beans::UnknownPropertyException(); 570 } 571 572 573 void SAL_CALL ResultSetBase::addPropertyChangeListener( 574 const rtl::OUString& aPropertyName, 575 const uno::Reference< beans::XPropertyChangeListener >& xListener ) 576 throw( beans::UnknownPropertyException, 577 lang::WrappedTargetException, 578 uno::RuntimeException) 579 { 580 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) 581 { 582 osl::MutexGuard aGuard( m_aMutex ); 583 if ( ! m_pIsFinalListeners ) 584 m_pIsFinalListeners = 585 new cppu::OInterfaceContainerHelper( m_aMutex ); 586 587 m_pIsFinalListeners->addInterface( xListener ); 588 } 589 else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) 590 { 591 osl::MutexGuard aGuard( m_aMutex ); 592 if ( ! m_pRowCountListeners ) 593 m_pRowCountListeners = 594 new cppu::OInterfaceContainerHelper( m_aMutex ); 595 m_pRowCountListeners->addInterface( xListener ); 596 } 597 else 598 throw beans::UnknownPropertyException(); 599 } 600 601 602 void SAL_CALL ResultSetBase::removePropertyChangeListener( 603 const rtl::OUString& aPropertyName, 604 const uno::Reference< beans::XPropertyChangeListener >& aListener ) 605 throw( beans::UnknownPropertyException, 606 lang::WrappedTargetException, 607 uno::RuntimeException) 608 { 609 if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) && 610 m_pIsFinalListeners ) 611 { 612 osl::MutexGuard aGuard( m_aMutex ); 613 m_pIsFinalListeners->removeInterface( aListener ); 614 } 615 else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) && 616 m_pRowCountListeners ) 617 { 618 osl::MutexGuard aGuard( m_aMutex ); 619 m_pRowCountListeners->removeInterface( aListener ); 620 } 621 else 622 throw beans::UnknownPropertyException(); 623 } 624 625 626 void SAL_CALL ResultSetBase::addVetoableChangeListener( 627 const rtl::OUString& /*PropertyName*/, 628 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) 629 throw( beans::UnknownPropertyException, 630 lang::WrappedTargetException, 631 uno::RuntimeException) 632 { 633 } 634 635 636 void SAL_CALL ResultSetBase::removeVetoableChangeListener( 637 const rtl::OUString& /*PropertyName*/, 638 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) 639 throw( beans::UnknownPropertyException, 640 lang::WrappedTargetException, 641 uno::RuntimeException) 642 { 643 } 644 645 646 647 // XResultSetMetaDataSupplier 648 uno::Reference< sdbc::XResultSetMetaData > SAL_CALL 649 ResultSetBase::getMetaData( 650 void ) 651 throw( sdbc::SQLException, 652 uno::RuntimeException ) 653 { 654 ::ucbhelper::ResultSetMetaData* p = 655 new ::ucbhelper::ResultSetMetaData( 656 m_xMSF, m_sProperty ); 657 return uno::Reference< sdbc::XResultSetMetaData >( p ); 658 } 659 660 661 662 663