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 31 /************************************************************************** 32 TODO 33 ************************************************************************** 34 35 *************************************************************************/ 36 37 #include <vector> 38 #include <osl/diagnose.h> 39 #include <com/sun/star/container/XEnumeration.hpp> 40 #include <com/sun/star/container/XNamed.hpp> 41 #include <ucbhelper/contentidentifier.hxx> 42 #include <ucbhelper/providerhelper.hxx> 43 #include "pkgdatasupplier.hxx" 44 #include "pkgcontent.hxx" 45 #include "pkgprovider.hxx" 46 47 #include "../inc/urihelper.hxx" 48 49 using namespace com::sun::star; 50 using namespace package_ucp; 51 52 namespace package_ucp 53 { 54 55 //========================================================================= 56 // 57 // struct ResultListEntry. 58 // 59 //========================================================================= 60 61 struct ResultListEntry 62 { 63 rtl::OUString aURL; 64 uno::Reference< ucb::XContentIdentifier > xId; 65 uno::Reference< ucb::XContent > xContent; 66 uno::Reference< sdbc::XRow > xRow; 67 68 ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {} 69 }; 70 71 //========================================================================= 72 // 73 // ResultList. 74 // 75 //========================================================================= 76 77 typedef std::vector< ResultListEntry* > ResultList; 78 79 //========================================================================= 80 // 81 // struct DataSupplier_Impl. 82 // 83 //========================================================================= 84 85 struct DataSupplier_Impl 86 { 87 osl::Mutex m_aMutex; 88 ResultList m_aResults; 89 rtl::Reference< Content > m_xContent; 90 uno::Reference< lang::XMultiServiceFactory > m_xSMgr; 91 uno::Reference< container::XEnumeration > m_xFolderEnum; 92 sal_Int32 m_nOpenMode; 93 sal_Bool m_bCountFinal; 94 sal_Bool m_bThrowException; 95 96 DataSupplier_Impl( 97 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 98 const rtl::Reference< Content >& rContent, 99 sal_Int32 nOpenMode ) 100 : m_xContent( rContent ), m_xSMgr( rxSMgr ), 101 m_xFolderEnum( rContent->getIterator() ), m_nOpenMode( nOpenMode ), 102 m_bCountFinal( !m_xFolderEnum.is() ), m_bThrowException( m_bCountFinal ) 103 {} 104 ~DataSupplier_Impl(); 105 }; 106 107 //========================================================================= 108 DataSupplier_Impl::~DataSupplier_Impl() 109 { 110 ResultList::const_iterator it = m_aResults.begin(); 111 ResultList::const_iterator end = m_aResults.end(); 112 113 while ( it != end ) 114 { 115 delete (*it); 116 it++; 117 } 118 } 119 120 } 121 122 //========================================================================= 123 //========================================================================= 124 // 125 // DataSupplier Implementation. 126 // 127 //========================================================================= 128 //========================================================================= 129 130 DataSupplier::DataSupplier( 131 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 132 const rtl::Reference< Content >& rContent, 133 sal_Int32 nOpenMode ) 134 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) ) 135 { 136 } 137 138 //========================================================================= 139 // virtual 140 DataSupplier::~DataSupplier() 141 { 142 delete m_pImpl; 143 } 144 145 //========================================================================= 146 // virtual 147 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex ) 148 { 149 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 150 151 if ( nIndex < m_pImpl->m_aResults.size() ) 152 { 153 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL; 154 if ( aId.getLength() ) 155 { 156 // Already cached. 157 return aId; 158 } 159 } 160 161 if ( getResult( nIndex ) ) 162 { 163 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL. 164 return m_pImpl->m_aResults[ nIndex ]->aURL; 165 } 166 return rtl::OUString(); 167 } 168 169 //========================================================================= 170 // virtual 171 uno::Reference< ucb::XContentIdentifier > 172 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex ) 173 { 174 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 175 176 if ( nIndex < m_pImpl->m_aResults.size() ) 177 { 178 uno::Reference< ucb::XContentIdentifier > xId 179 = m_pImpl->m_aResults[ nIndex ]->xId; 180 if ( xId.is() ) 181 { 182 // Already cached. 183 return xId; 184 } 185 } 186 187 rtl::OUString aId = queryContentIdentifierString( nIndex ); 188 if ( aId.getLength() ) 189 { 190 uno::Reference< ucb::XContentIdentifier > xId 191 = new ::ucbhelper::ContentIdentifier( aId ); 192 m_pImpl->m_aResults[ nIndex ]->xId = xId; 193 return xId; 194 } 195 return uno::Reference< ucb::XContentIdentifier >(); 196 } 197 198 //========================================================================= 199 // virtual 200 uno::Reference< ucb::XContent > DataSupplier::queryContent( 201 sal_uInt32 nIndex ) 202 { 203 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 204 205 if ( nIndex < m_pImpl->m_aResults.size() ) 206 { 207 uno::Reference< ucb::XContent > xContent 208 = m_pImpl->m_aResults[ nIndex ]->xContent; 209 if ( xContent.is() ) 210 { 211 // Already cached. 212 return xContent; 213 } 214 } 215 216 uno::Reference< ucb::XContentIdentifier > xId 217 = queryContentIdentifier( nIndex ); 218 if ( xId.is() ) 219 { 220 try 221 { 222 uno::Reference< ucb::XContent > xContent 223 = m_pImpl->m_xContent->getProvider()->queryContent( xId ); 224 m_pImpl->m_aResults[ nIndex ]->xContent = xContent; 225 return xContent; 226 227 } 228 catch ( ucb::IllegalIdentifierException const & ) 229 { 230 } 231 } 232 return uno::Reference< ucb::XContent >(); 233 } 234 235 //========================================================================= 236 // virtual 237 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex ) 238 { 239 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 240 241 if ( m_pImpl->m_aResults.size() > nIndex ) 242 { 243 // Result already present. 244 return sal_True; 245 } 246 247 // Result not (yet) present. 248 249 if ( m_pImpl->m_bCountFinal ) 250 return sal_False; 251 252 // Try to obtain result... 253 254 sal_uInt32 nOldCount = m_pImpl->m_aResults.size(); 255 sal_Bool bFound = sal_False; 256 sal_uInt32 nPos = nOldCount; 257 258 while ( m_pImpl->m_xFolderEnum->hasMoreElements() ) 259 { 260 try 261 { 262 uno::Reference< container::XNamed > xNamed; 263 m_pImpl->m_xFolderEnum->nextElement() >>= xNamed; 264 265 if ( !xNamed.is() ) 266 { 267 OSL_ENSURE( sal_False, 268 "DataSupplier::getResult - Got no XNamed!" ); 269 break; 270 } 271 272 rtl::OUString aName = xNamed->getName(); 273 274 if ( !aName.getLength() ) 275 { 276 OSL_ENSURE( sal_False, 277 "DataSupplier::getResult - Empty name!" ); 278 break; 279 } 280 281 // Assemble URL for child. 282 rtl::OUString aURL = assembleChildURL( aName ); 283 284 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) ); 285 286 if ( nPos == nIndex ) 287 { 288 // Result obtained. 289 bFound = sal_True; 290 break; 291 } 292 293 nPos++; 294 } 295 catch ( container::NoSuchElementException const & ) 296 { 297 m_pImpl->m_bThrowException = sal_True; 298 break; 299 } 300 catch ( lang::WrappedTargetException const & ) 301 { 302 m_pImpl->m_bThrowException = sal_True; 303 break; 304 } 305 } 306 307 if ( !bFound ) 308 m_pImpl->m_bCountFinal = sal_True; 309 310 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get(); 311 if ( xResultSet.is() ) 312 { 313 // Callbacks follow! 314 aGuard.clear(); 315 316 if ( nOldCount < m_pImpl->m_aResults.size() ) 317 xResultSet->rowCountChanged( 318 nOldCount, m_pImpl->m_aResults.size() ); 319 320 if ( m_pImpl->m_bCountFinal ) 321 xResultSet->rowCountFinal(); 322 } 323 324 return bFound; 325 } 326 327 //========================================================================= 328 // virtual 329 sal_uInt32 DataSupplier::totalCount() 330 { 331 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 332 333 if ( m_pImpl->m_bCountFinal ) 334 return m_pImpl->m_aResults.size(); 335 336 sal_uInt32 nOldCount = m_pImpl->m_aResults.size(); 337 338 while ( m_pImpl->m_xFolderEnum->hasMoreElements() ) 339 { 340 try 341 { 342 uno::Reference< container::XNamed > xNamed; 343 m_pImpl->m_xFolderEnum->nextElement() >>= xNamed; 344 345 if ( !xNamed.is() ) 346 { 347 OSL_ENSURE( sal_False, 348 "DataSupplier::getResult - Got no XNamed!" ); 349 break; 350 } 351 352 rtl::OUString aName = xNamed->getName(); 353 354 if ( !aName.getLength() ) 355 { 356 OSL_ENSURE( sal_False, 357 "DataSupplier::getResult - Empty name!" ); 358 break; 359 } 360 361 // Assemble URL for child. 362 rtl::OUString aURL = assembleChildURL( aName ); 363 364 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) ); 365 } 366 catch ( container::NoSuchElementException const & ) 367 { 368 m_pImpl->m_bThrowException = sal_True; 369 break; 370 } 371 catch ( lang::WrappedTargetException const & ) 372 { 373 m_pImpl->m_bThrowException = sal_True; 374 break; 375 } 376 } 377 378 m_pImpl->m_bCountFinal = sal_True; 379 380 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get(); 381 if ( xResultSet.is() ) 382 { 383 // Callbacks follow! 384 aGuard.clear(); 385 386 if ( nOldCount < m_pImpl->m_aResults.size() ) 387 xResultSet->rowCountChanged( 388 nOldCount, m_pImpl->m_aResults.size() ); 389 390 xResultSet->rowCountFinal(); 391 } 392 393 return m_pImpl->m_aResults.size(); 394 } 395 396 //========================================================================= 397 // virtual 398 sal_uInt32 DataSupplier::currentCount() 399 { 400 return m_pImpl->m_aResults.size(); 401 } 402 403 //========================================================================= 404 // virtual 405 sal_Bool DataSupplier::isCountFinal() 406 { 407 return m_pImpl->m_bCountFinal; 408 } 409 410 //========================================================================= 411 // virtual 412 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( 413 sal_uInt32 nIndex ) 414 { 415 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 416 417 if ( nIndex < m_pImpl->m_aResults.size() ) 418 { 419 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow; 420 if ( xRow.is() ) 421 { 422 // Already cached. 423 return xRow; 424 } 425 } 426 427 if ( getResult( nIndex ) ) 428 { 429 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues( 430 m_pImpl->m_xSMgr, 431 getResultSet()->getProperties(), 432 static_cast< ContentProvider * >( 433 m_pImpl->m_xContent->getProvider().get() ), 434 queryContentIdentifierString( nIndex ) ); 435 m_pImpl->m_aResults[ nIndex ]->xRow = xRow; 436 return xRow; 437 } 438 439 return uno::Reference< sdbc::XRow >(); 440 } 441 442 //========================================================================= 443 // virtual 444 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex ) 445 { 446 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 447 448 if ( nIndex < m_pImpl->m_aResults.size() ) 449 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >(); 450 } 451 452 //========================================================================= 453 // virtual 454 void DataSupplier::close() 455 { 456 } 457 458 //========================================================================= 459 // virtual 460 void DataSupplier::validate() 461 throw( ucb::ResultSetException ) 462 { 463 if ( m_pImpl->m_bThrowException ) 464 throw ucb::ResultSetException(); 465 } 466 467 //========================================================================= 468 ::rtl::OUString DataSupplier::assembleChildURL( const ::rtl::OUString& aName ) 469 { 470 rtl::OUString aURL; 471 rtl::OUString aContURL 472 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(); 473 sal_Int32 nParam = aContURL.indexOf( '?' ); 474 if ( nParam >= 0 ) 475 { 476 aURL = aContURL.copy( 0, nParam ); 477 478 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' ); 479 if ( nPackageUrlEnd != aURL.getLength() - 1 ) 480 aURL += rtl::OUString::createFromAscii( "/" ); 481 482 aURL += ::ucb_impl::urihelper::encodeSegment( aName ); 483 aURL += aContURL.copy( nParam ); 484 } 485 else 486 { 487 aURL = aContURL; 488 489 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' ); 490 if ( nPackageUrlEnd != aURL.getLength() - 1 ) 491 aURL += rtl::OUString::createFromAscii( "/" ); 492 493 aURL += ::ucb_impl::urihelper::encodeSegment( aName ); 494 } 495 return aURL; 496 } 497 498 499