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_svtools.hxx" 30 #include "contentenumeration.hxx" 31 #include <svl/urlfilter.hxx> 32 #include <svtools/inettbc.hxx> 33 #include <svtools/imagemgr.hxx> 34 35 /** === begin UNO includes === **/ 36 #include <com/sun/star/beans/XPropertySet.hpp> 37 #include <com/sun/star/sdbc/XResultSet.hpp> 38 #include <com/sun/star/sdbc/XRow.hpp> 39 #include <com/sun/star/ucb/XDynamicResultSet.hpp> 40 #include <com/sun/star/ucb/XContentAccess.hpp> 41 #include <com/sun/star/util/DateTime.hpp> 42 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 43 /** === end UNO includes === **/ 44 #include <comphelper/processfactory.hxx> 45 #include <tools/debug.hxx> 46 #include <vcl/svapp.hxx> 47 #include <vos/mutex.hxx> 48 49 #include <memory> 50 51 //........................................................................ 52 namespace svt 53 { 54 //........................................................................ 55 56 #define ROW_TITLE 1 57 #define ROW_SIZE 2 58 #define ROW_DATE_MOD 3 59 #define ROW_DATE_CREATE 4 60 #define ROW_IS_FOLDER 5 61 #define ROW_TARGET_URL 6 62 #define ROW_IS_HIDDEN 7 63 #define ROW_IS_VOLUME 8 64 #define ROW_IS_REMOTE 9 65 #define ROW_IS_REMOVEABLE 10 66 #define ROW_IS_FLOPPY 11 67 #define ROW_IS_COMPACTDISC 12 68 69 #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \ 70 aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \ 71 Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) ); 72 73 using ::com::sun::star::uno::Reference; 74 using ::com::sun::star::uno::Sequence; 75 using ::com::sun::star::uno::Exception; 76 using ::com::sun::star::uno::UNO_QUERY; 77 using ::com::sun::star::uno::Any; 78 using ::com::sun::star::util::DateTime; 79 using ::com::sun::star::sdbc::XResultSet; 80 using ::com::sun::star::sdbc::XRow; 81 using ::com::sun::star::ucb::XDynamicResultSet; 82 using ::com::sun::star::ucb::CommandAbortedException; 83 using ::com::sun::star::ucb::XContentAccess; 84 using ::com::sun::star::ucb::XCommandEnvironment; 85 using ::com::sun::star::beans::XPropertySet; 86 using ::rtl::OUString; 87 using ::ucbhelper::ResultSetInclude; 88 using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; 89 90 //==================================================================== 91 //= FileViewContentEnumerator 92 //==================================================================== 93 //-------------------------------------------------------------------- 94 FileViewContentEnumerator::FileViewContentEnumerator( 95 const Reference< XCommandEnvironment >& _rxCommandEnv, 96 ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex, 97 const IContentTitleTranslation* _pTranslator ) 98 :m_rContent ( _rContentToFill ) 99 ,m_rContentMutex ( _rContentMutex ) 100 ,m_refCount ( 0 ) 101 ,m_xCommandEnv ( _rxCommandEnv ) 102 ,m_pFilter ( NULL ) 103 ,m_pTranslator ( _pTranslator ) 104 ,m_bCancelled ( false ) 105 ,m_rBlackList ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() ) 106 { 107 } 108 109 //-------------------------------------------------------------------- 110 FileViewContentEnumerator::~FileViewContentEnumerator() 111 { 112 } 113 114 //-------------------------------------------------------------------- 115 void FileViewContentEnumerator::cancel() 116 { 117 ::osl::MutexGuard aGuard( m_aMutex ); 118 m_bCancelled = true; 119 m_pResultHandler = NULL; 120 m_pTranslator = NULL; 121 m_pFilter = NULL; 122 m_aFolder.aContent = ::ucbhelper::Content(); 123 m_aFolder.sURL = String(); 124 } 125 126 //-------------------------------------------------------------------- 127 EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync( 128 const FolderDescriptor& _rFolder, 129 const IUrlFilter* _pFilter, 130 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) 131 { 132 { 133 ::osl::MutexGuard aGuard( m_aMutex ); 134 m_aFolder = _rFolder; 135 m_pFilter = _pFilter; 136 m_pResultHandler = NULL; 137 m_rBlackList = rBlackList; 138 } 139 return enumerateFolderContent(); 140 } 141 142 //-------------------------------------------------------------------- 143 void FileViewContentEnumerator::enumerateFolderContent( 144 const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler ) 145 { 146 // ensure that we don't get deleted while herein 147 acquire(); 148 // the matching "release" will be called in onTerminated 149 // Note that onTerminated is only called if run was left normally. 150 // If somebody terminates the thread from the outside, then onTerminated 151 // will never be called. However, our terminate method is not accessible 152 // to our clients, so the only class which could misbehave is this class 153 // here itself ... 154 155 ::osl::MutexGuard aGuard( m_aMutex ); 156 m_aFolder = _rFolder; 157 m_pFilter = _pFilter; 158 m_pResultHandler = _pResultHandler; 159 160 OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(), 161 "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" ); 162 163 // start the thread 164 create(); 165 } 166 167 //-------------------------------------------------------------------- 168 oslInterlockedCount SAL_CALL FileViewContentEnumerator::acquire() 169 { 170 return osl_incrementInterlockedCount( &m_refCount ); 171 } 172 173 //-------------------------------------------------------------------- 174 oslInterlockedCount SAL_CALL FileViewContentEnumerator::release() 175 { 176 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) 177 { 178 delete this; 179 return 0; 180 } 181 return m_refCount; 182 } 183 184 //-------------------------------------------------------------------- 185 EnumerationResult FileViewContentEnumerator::enumerateFolderContent() 186 { 187 EnumerationResult eResult = ERROR; 188 try 189 { 190 191 Reference< XResultSet > xResultSet; 192 Sequence< OUString > aProps(12); 193 194 aProps[0] = OUString::createFromAscii( "Title" ); 195 aProps[1] = OUString::createFromAscii( "Size" ); 196 aProps[2] = OUString::createFromAscii( "DateModified" ); 197 aProps[3] = OUString::createFromAscii( "DateCreated" ); 198 aProps[4] = OUString::createFromAscii( "IsFolder" ); 199 aProps[5] = OUString::createFromAscii( "TargetURL" ); 200 aProps[6] = OUString::createFromAscii( "IsHidden" ); 201 aProps[7] = OUString::createFromAscii( "IsVolume" ); 202 aProps[8] = OUString::createFromAscii( "IsRemote" ); 203 aProps[9] = OUString::createFromAscii( "IsRemoveable" ); 204 aProps[10] = OUString::createFromAscii( "IsFloppy" ); 205 aProps[11] = OUString::createFromAscii( "IsCompactDisc" ); 206 207 Reference< XCommandEnvironment > xEnvironment; 208 try 209 { 210 FolderDescriptor aFolder; 211 { 212 ::osl::MutexGuard aGuard( m_aMutex ); 213 aFolder = m_aFolder; 214 xEnvironment = m_xCommandEnv; 215 } 216 if ( !aFolder.aContent.get().is() ) 217 { 218 aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment ); 219 { 220 ::osl::MutexGuard aGuard( m_aMutex ); 221 m_aFolder.aContent = aFolder.aContent; 222 } 223 } 224 225 Reference< XDynamicResultSet > xDynResultSet; 226 ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS; 227 xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude ); 228 229 if ( xDynResultSet.is() ) 230 xResultSet = xDynResultSet->getStaticResultSet(); 231 } 232 catch( CommandAbortedException& ) 233 { 234 DBG_ERRORFILE( "createCursor: CommandAbortedException" ); 235 } 236 catch( Exception& ) 237 { 238 } 239 240 bool bCancelled = false; 241 if ( xResultSet.is() ) 242 { 243 Reference< XRow > xRow( xResultSet, UNO_QUERY ); 244 Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 245 246 try 247 { 248 SortingData_Impl* pData; 249 DateTime aDT; 250 251 while ( !bCancelled && xResultSet->next() ) 252 { 253 sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN ); 254 // don't show hidden files 255 if ( !bIsHidden || xRow->wasNull() ) 256 { 257 pData = NULL; 258 259 aDT = xRow->getTimestamp( ROW_DATE_MOD ); 260 sal_Bool bContainsDate = !xRow->wasNull(); 261 if ( !bContainsDate ) 262 { 263 aDT = xRow->getTimestamp( ROW_DATE_CREATE ); 264 bContainsDate = !xRow->wasNull(); 265 } 266 267 OUString aContentURL = xContentAccess->queryContentIdentifierString(); 268 OUString aTargetURL = xRow->getString( ROW_TARGET_URL ); 269 sal_Bool bHasTargetURL = !xRow->wasNull() && aTargetURL.getLength() > 0; 270 271 OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL; 272 273 // check for restrictions 274 { 275 ::osl::MutexGuard aGuard( m_aMutex ); 276 if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) ) 277 continue; 278 279 if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) ) 280 continue; 281 } 282 283 pData = new SortingData_Impl; 284 pData->maTargetURL = sRealURL; 285 286 pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull(); 287 pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull(); 288 pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull(); 289 pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull(); 290 pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull(); 291 pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull(); 292 pData->SetNewTitle( xRow->getString( ROW_TITLE ) ); 293 pData->maSize = xRow->getLong( ROW_SIZE ); 294 295 if ( bHasTargetURL && 296 INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER ) 297 { 298 ::ucbhelper::Content aCnt( aTargetURL, xEnvironment ); 299 try 300 { 301 aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= pData->maSize; 302 aCnt.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aDT; 303 } 304 catch (...) {} 305 } 306 307 if ( bContainsDate ) 308 { 309 CONVERT_DATETIME( aDT, pData->maModDate ); 310 } 311 312 if ( pData->mbIsFolder ) 313 { 314 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 315 ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote, 316 pData->mbIsRemoveable, pData->mbIsFloppy, 317 pData->mbIsCompactDisc ); 318 pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo ); 319 } 320 else 321 pData->maType = SvFileInformationManager::GetFileDescription( 322 INetURLObject( pData->maTargetURL ) ); 323 324 // replace names on demand 325 { 326 ::osl::MutexGuard aGuard( m_aMutex ); 327 if( m_pTranslator ) 328 { 329 OUString sNewTitle; 330 sal_Bool bTranslated = sal_False; 331 332 if ( pData->mbIsFolder ) 333 bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle ); 334 else 335 bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle ); 336 337 if ( bTranslated ) 338 pData->ChangeTitle( sNewTitle ); 339 } 340 } 341 342 { 343 ::osl::MutexGuard aGuard( m_rContentMutex ); 344 m_rContent.push_back( pData ); 345 } 346 } 347 348 { 349 ::osl::MutexGuard aGuard( m_aMutex ); 350 bCancelled = m_bCancelled; 351 } 352 } 353 eResult = SUCCESS; 354 } 355 catch( CommandAbortedException& ) 356 { 357 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" ); 358 } 359 catch( Exception& ) 360 { 361 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" ); 362 } 363 } 364 } 365 catch( CommandAbortedException& ) 366 { 367 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" ); 368 } 369 catch( Exception& ) 370 { 371 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" ); 372 } 373 374 IEnumerationResultHandler* pHandler = NULL; 375 { 376 ::osl::MutexGuard aGuard( m_aMutex ); 377 pHandler = m_pResultHandler; 378 if ( m_bCancelled ) 379 return ERROR; 380 } 381 382 { 383 ::osl::MutexGuard aGuard( m_rContentMutex ); 384 if ( eResult != SUCCESS ) 385 // clear any "intermediate" and unfinished result 386 m_rContent.clear(); 387 } 388 389 if ( pHandler ) 390 pHandler->enumerationDone( eResult ); 391 return eResult; 392 } 393 394 //-------------------------------------------------------------------- 395 396 sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL ) 397 { 398 ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( rtl::OUString::createFromAscii("/")) +1 ); 399 400 for (int i = 0; i < m_rBlackList.getLength() ; i++) 401 { 402 if ( entryName.equals( m_rBlackList[i] ) ) 403 return true; 404 } 405 406 return false; 407 } 408 409 //-------------------------------------------------------------------- 410 sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const 411 { 412 sal_Bool bRet = sal_False; 413 414 try 415 { 416 ::osl::MutexGuard aGuard( m_aMutex ); 417 if( !m_xDocInfo.is() ) 418 { 419 m_xDocInfo = m_xDocInfo.query( 420 ::comphelper::getProcessServiceFactory()->createInstance( 421 String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") ) 422 ) 423 ); 424 } 425 426 DBG_ASSERT( m_xDocInfo.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" ); 427 if ( !m_xDocInfo.is() ) 428 return sal_False; 429 430 m_xDocInfo->loadFromURL( _rTargetURL ); 431 Reference< XPropertySet > xPropSet( m_xDocInfo, UNO_QUERY ); 432 433 Any aAny = xPropSet->getPropertyValue( OUString::createFromAscii( "Title" ) ); 434 435 OUString sTitle; 436 if ( ( aAny >>= sTitle ) && sTitle.getLength() > 0 ) 437 { 438 _rRet = sTitle; 439 bRet = sal_True; 440 } 441 } 442 catch ( const Exception& ) 443 { 444 } 445 446 return bRet; 447 } 448 449 //-------------------------------------------------------------------- 450 void SAL_CALL FileViewContentEnumerator::run() 451 { 452 enumerateFolderContent(); 453 } 454 455 //-------------------------------------------------------------------- 456 void SAL_CALL FileViewContentEnumerator::onTerminated() 457 { 458 release(); 459 } 460 461 //........................................................................ 462 } // namespace svt 463 //........................................................................ 464 465