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