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