|  | /************************************************************** | 
|  | * | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements.  See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership.  The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License.  You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied.  See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | * | 
|  | *************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  | // MARKER(update_precomp.py): autogen include statement, do not remove | 
|  | #include "precompiled_svtools.hxx" | 
|  | #include "contentenumeration.hxx" | 
|  | #include <svl/urlfilter.hxx> | 
|  | #include <svtools/inettbc.hxx> | 
|  | #include <svtools/imagemgr.hxx> | 
|  |  | 
|  | /** === begin UNO includes === **/ | 
|  | #include <com/sun/star/beans/XPropertySet.hpp> | 
|  | #include <com/sun/star/sdbc/XResultSet.hpp> | 
|  | #include <com/sun/star/sdbc/XRow.hpp> | 
|  | #include <com/sun/star/ucb/XDynamicResultSet.hpp> | 
|  | #include <com/sun/star/ucb/XContentAccess.hpp> | 
|  | #include <com/sun/star/util/DateTime.hpp> | 
|  | #include <com/sun/star/lang/XMultiServiceFactory.hpp> | 
|  | /** === end UNO includes === **/ | 
|  | #include <comphelper/processfactory.hxx> | 
|  | #include <tools/debug.hxx> | 
|  | #include <vcl/svapp.hxx> | 
|  | #include <vos/mutex.hxx> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | //........................................................................ | 
|  | namespace svt | 
|  | { | 
|  | //........................................................................ | 
|  |  | 
|  | #define ROW_TITLE           1 | 
|  | #define ROW_SIZE            2 | 
|  | #define ROW_DATE_MOD        3 | 
|  | #define ROW_DATE_CREATE     4 | 
|  | #define ROW_IS_FOLDER       5 | 
|  | #define ROW_TARGET_URL      6 | 
|  | #define ROW_IS_HIDDEN		7 | 
|  | #define ROW_IS_VOLUME		8 | 
|  | #define ROW_IS_REMOTE		9 | 
|  | #define ROW_IS_REMOVEABLE	10 | 
|  | #define ROW_IS_FLOPPY		11 | 
|  | #define ROW_IS_COMPACTDISC	12 | 
|  |  | 
|  | #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \ | 
|  | aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \ | 
|  | Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) ); | 
|  |  | 
|  | using ::com::sun::star::uno::Reference; | 
|  | using ::com::sun::star::uno::Sequence; | 
|  | using ::com::sun::star::uno::Exception; | 
|  | using ::com::sun::star::uno::UNO_QUERY; | 
|  | using ::com::sun::star::uno::Any; | 
|  | using ::com::sun::star::util::DateTime; | 
|  | using ::com::sun::star::sdbc::XResultSet; | 
|  | using ::com::sun::star::sdbc::XRow; | 
|  | using ::com::sun::star::ucb::XDynamicResultSet; | 
|  | using ::com::sun::star::ucb::CommandAbortedException; | 
|  | using ::com::sun::star::ucb::XContentAccess; | 
|  | using ::com::sun::star::ucb::XCommandEnvironment; | 
|  | using ::com::sun::star::beans::XPropertySet; | 
|  | using ::rtl::OUString; | 
|  | using ::ucbhelper::ResultSetInclude; | 
|  | using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; | 
|  |  | 
|  | //==================================================================== | 
|  | //= FileViewContentEnumerator | 
|  | //==================================================================== | 
|  | //-------------------------------------------------------------------- | 
|  | FileViewContentEnumerator::FileViewContentEnumerator( | 
|  | const Reference< XCommandEnvironment >& _rxCommandEnv, | 
|  | ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex, | 
|  | const IContentTitleTranslation* _pTranslator ) | 
|  | :m_rContent              ( _rContentToFill ) | 
|  | ,m_rContentMutex         ( _rContentMutex  ) | 
|  | ,m_refCount              ( 0               ) | 
|  | ,m_xCommandEnv           ( _rxCommandEnv   ) | 
|  | ,m_pFilter               ( NULL            ) | 
|  | ,m_pTranslator           ( _pTranslator    ) | 
|  | ,m_bCancelled            ( false           ) | 
|  | ,m_rBlackList			 ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() ) | 
|  | { | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | FileViewContentEnumerator::~FileViewContentEnumerator() | 
|  | { | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | void FileViewContentEnumerator::cancel() | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | m_bCancelled = true; | 
|  | m_pResultHandler = NULL; | 
|  | m_pTranslator = NULL; | 
|  | m_pFilter = NULL; | 
|  | m_aFolder.aContent = ::ucbhelper::Content(); | 
|  | m_aFolder.sURL = String(); | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync( | 
|  | const FolderDescriptor& _rFolder, | 
|  | const IUrlFilter* _pFilter, | 
|  | const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) | 
|  | { | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | m_aFolder = _rFolder; | 
|  | m_pFilter = _pFilter; | 
|  | m_pResultHandler = NULL; | 
|  | m_rBlackList = rBlackList; | 
|  | } | 
|  | return enumerateFolderContent(); | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | void FileViewContentEnumerator::enumerateFolderContent( | 
|  | const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler ) | 
|  | { | 
|  | // ensure that we don't get deleted while herein | 
|  | acquire(); | 
|  | // the matching "release" will be called in onTerminated | 
|  | // Note that onTerminated is only called if run was left normally. | 
|  | // If somebody terminates the thread from the outside, then onTerminated | 
|  | // will never be called. However, our terminate method is not accessible | 
|  | // to our clients, so the only class which could misbehave is this class | 
|  | // here itself ... | 
|  |  | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | m_aFolder = _rFolder; | 
|  | m_pFilter = _pFilter; | 
|  | m_pResultHandler = _pResultHandler; | 
|  |  | 
|  | OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(), | 
|  | "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" ); | 
|  |  | 
|  | // start the thread | 
|  | create(); | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | oslInterlockedCount SAL_CALL FileViewContentEnumerator::acquire() | 
|  | { | 
|  | return osl_incrementInterlockedCount( &m_refCount ); | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | oslInterlockedCount SAL_CALL FileViewContentEnumerator::release() | 
|  | { | 
|  | if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) | 
|  | { | 
|  | delete this; | 
|  | return 0; | 
|  | } | 
|  | return m_refCount; | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | EnumerationResult FileViewContentEnumerator::enumerateFolderContent() | 
|  | { | 
|  | EnumerationResult eResult = ERROR; | 
|  | try | 
|  | { | 
|  |  | 
|  | Reference< XResultSet > xResultSet; | 
|  | Sequence< OUString > aProps(12); | 
|  |  | 
|  | aProps[0] = OUString::createFromAscii( "Title" ); | 
|  | aProps[1] = OUString::createFromAscii( "Size" ); | 
|  | aProps[2] = OUString::createFromAscii( "DateModified" ); | 
|  | aProps[3] = OUString::createFromAscii( "DateCreated" ); | 
|  | aProps[4] = OUString::createFromAscii( "IsFolder" ); | 
|  | aProps[5] = OUString::createFromAscii( "TargetURL" ); | 
|  | aProps[6] = OUString::createFromAscii( "IsHidden" ); | 
|  | aProps[7] = OUString::createFromAscii( "IsVolume" ); | 
|  | aProps[8] = OUString::createFromAscii( "IsRemote" ); | 
|  | aProps[9] = OUString::createFromAscii( "IsRemoveable" ); | 
|  | aProps[10] = OUString::createFromAscii( "IsFloppy" ); | 
|  | aProps[11] = OUString::createFromAscii( "IsCompactDisc" ); | 
|  |  | 
|  | Reference< XCommandEnvironment > xEnvironment; | 
|  | try | 
|  | { | 
|  | FolderDescriptor aFolder; | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | aFolder = m_aFolder; | 
|  | xEnvironment = m_xCommandEnv; | 
|  | } | 
|  | if ( !aFolder.aContent.get().is() ) | 
|  | { | 
|  | aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment ); | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | m_aFolder.aContent = aFolder.aContent; | 
|  | } | 
|  | } | 
|  |  | 
|  | Reference< XDynamicResultSet > xDynResultSet; | 
|  | ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS; | 
|  | xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude ); | 
|  |  | 
|  | if ( xDynResultSet.is() ) | 
|  | xResultSet = xDynResultSet->getStaticResultSet(); | 
|  | } | 
|  | catch( CommandAbortedException& ) | 
|  | { | 
|  | DBG_ERRORFILE( "createCursor: CommandAbortedException" ); | 
|  | } | 
|  | catch( Exception& ) | 
|  | { | 
|  | } | 
|  |  | 
|  | bool bCancelled = false; | 
|  | if ( xResultSet.is() ) | 
|  | { | 
|  | Reference< XRow > xRow( xResultSet, UNO_QUERY ); | 
|  | Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); | 
|  |  | 
|  | try | 
|  | { | 
|  | SortingData_Impl* pData; | 
|  | DateTime aDT; | 
|  |  | 
|  | while ( !bCancelled && xResultSet->next() ) | 
|  | { | 
|  | sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN ); | 
|  | // don't show hidden files | 
|  | if ( !bIsHidden || xRow->wasNull() ) | 
|  | { | 
|  | pData = NULL; | 
|  |  | 
|  | aDT = xRow->getTimestamp( ROW_DATE_MOD ); | 
|  | sal_Bool bContainsDate = !xRow->wasNull(); | 
|  | if ( !bContainsDate ) | 
|  | { | 
|  | aDT = xRow->getTimestamp( ROW_DATE_CREATE ); | 
|  | bContainsDate = !xRow->wasNull(); | 
|  | } | 
|  |  | 
|  | OUString aContentURL = xContentAccess->queryContentIdentifierString(); | 
|  | OUString aTargetURL = xRow->getString( ROW_TARGET_URL ); | 
|  | sal_Bool bHasTargetURL = !xRow->wasNull() && aTargetURL.getLength() > 0; | 
|  |  | 
|  | OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL; | 
|  |  | 
|  | // check for restrictions | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) ) | 
|  | continue; | 
|  |  | 
|  | if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) ) | 
|  | continue; | 
|  | } | 
|  |  | 
|  | pData = new SortingData_Impl; | 
|  | pData->maTargetURL = sRealURL; | 
|  |  | 
|  | pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull(); | 
|  | pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull(); | 
|  | pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull(); | 
|  | pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull(); | 
|  | pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull(); | 
|  | pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull(); | 
|  | pData->SetNewTitle( xRow->getString( ROW_TITLE ) ); | 
|  | pData->maSize = xRow->getLong( ROW_SIZE ); | 
|  |  | 
|  | if ( bHasTargetURL && | 
|  | INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER ) | 
|  | { | 
|  | ::ucbhelper::Content aCnt( aTargetURL, xEnvironment ); | 
|  | try | 
|  | { | 
|  | aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= pData->maSize; | 
|  | aCnt.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aDT; | 
|  | } | 
|  | catch (...) {} | 
|  | } | 
|  |  | 
|  | if ( bContainsDate ) | 
|  | { | 
|  | CONVERT_DATETIME( aDT, pData->maModDate ); | 
|  | } | 
|  |  | 
|  | if ( pData->mbIsFolder ) | 
|  | { | 
|  | ::vos::OGuard aGuard( Application::GetSolarMutex() ); | 
|  | ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote, | 
|  | pData->mbIsRemoveable, pData->mbIsFloppy, | 
|  | pData->mbIsCompactDisc ); | 
|  | pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo ); | 
|  | } | 
|  | else | 
|  | pData->maType = SvFileInformationManager::GetFileDescription( | 
|  | INetURLObject( pData->maTargetURL ) ); | 
|  |  | 
|  | // replace names on demand | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | if( m_pTranslator ) | 
|  | { | 
|  | OUString sNewTitle; | 
|  | sal_Bool bTranslated = sal_False; | 
|  |  | 
|  | if ( pData->mbIsFolder ) | 
|  | bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle ); | 
|  | else | 
|  | bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle ); | 
|  |  | 
|  | if ( bTranslated ) | 
|  | pData->ChangeTitle( sNewTitle ); | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_rContentMutex ); | 
|  | m_rContent.push_back( pData ); | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | bCancelled = m_bCancelled; | 
|  | } | 
|  | } | 
|  | eResult = SUCCESS; | 
|  | } | 
|  | catch( CommandAbortedException& ) | 
|  | { | 
|  | DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" ); | 
|  | } | 
|  | catch( Exception& ) | 
|  | { | 
|  | DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" ); | 
|  | } | 
|  | } | 
|  | } | 
|  | catch( CommandAbortedException& ) | 
|  | { | 
|  | DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" ); | 
|  | } | 
|  | catch( Exception& ) | 
|  | { | 
|  | DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" ); | 
|  | } | 
|  |  | 
|  | IEnumerationResultHandler* pHandler = NULL; | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | pHandler = m_pResultHandler; | 
|  | if ( m_bCancelled ) | 
|  | return ERROR; | 
|  | } | 
|  |  | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_rContentMutex ); | 
|  | if ( eResult != SUCCESS ) | 
|  | // clear any "intermediate" and unfinished result | 
|  | m_rContent.clear(); | 
|  | } | 
|  |  | 
|  | if ( pHandler ) | 
|  | pHandler->enumerationDone( eResult ); | 
|  | return eResult; | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  |  | 
|  | sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL ) | 
|  | { | 
|  | ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( rtl::OUString::createFromAscii("/")) +1 ); | 
|  |  | 
|  | for (int i = 0; i < m_rBlackList.getLength() ; i++) | 
|  | { | 
|  | if ( entryName.equals(  m_rBlackList[i] ) ) | 
|  | return true; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const | 
|  | { | 
|  | sal_Bool bRet = sal_False; | 
|  |  | 
|  | try | 
|  | { | 
|  | ::osl::MutexGuard aGuard( m_aMutex ); | 
|  | if( !m_xDocInfo.is() ) | 
|  | { | 
|  | m_xDocInfo = m_xDocInfo.query( | 
|  | ::comphelper::getProcessServiceFactory()->createInstance( | 
|  | String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") ) | 
|  | ) | 
|  | ); | 
|  | } | 
|  |  | 
|  | DBG_ASSERT( m_xDocInfo.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" ); | 
|  | if ( !m_xDocInfo.is() ) | 
|  | return sal_False; | 
|  |  | 
|  | m_xDocInfo->loadFromURL( _rTargetURL ); | 
|  | Reference< XPropertySet > xPropSet( m_xDocInfo, UNO_QUERY ); | 
|  |  | 
|  | Any aAny = xPropSet->getPropertyValue( OUString::createFromAscii( "Title" ) ); | 
|  |  | 
|  | OUString sTitle; | 
|  | if ( ( aAny >>= sTitle ) && sTitle.getLength() > 0 ) | 
|  | { | 
|  | _rRet = sTitle; | 
|  | bRet = sal_True; | 
|  | } | 
|  | } | 
|  | catch ( const Exception& ) | 
|  | { | 
|  | } | 
|  |  | 
|  | return bRet; | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | void SAL_CALL FileViewContentEnumerator::run() | 
|  | { | 
|  | enumerateFolderContent(); | 
|  | } | 
|  |  | 
|  | //-------------------------------------------------------------------- | 
|  | void SAL_CALL FileViewContentEnumerator::onTerminated() | 
|  | { | 
|  | release(); | 
|  | } | 
|  |  | 
|  | //........................................................................ | 
|  | } // namespace svt | 
|  | //........................................................................ |