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