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