1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "contentenumeration.hxx"
21 #include <svtools/imagemgr.hxx>
23 #include <com/sun/star/sdbc/XResultSet.hpp>
24 #include <com/sun/star/sdbc/XRow.hpp>
25 #include <com/sun/star/ucb/CommandAbortedException.hpp>
26 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
27 #include <com/sun/star/ucb/XContentAccess.hpp>
28 #include <com/sun/star/util/DateTime.hpp>
29 #include <com/sun/star/document/DocumentProperties.hpp>
30 #include <comphelper/processfactory.hxx>
31 #include <comphelper/sequence.hxx>
32 #include <vcl/svapp.hxx>
33 #include <osl/mutex.hxx>
34 #include <osl/diagnose.h>
35 #include <comphelper/diagnose_ex.hxx>
36 #include <tools/urlobj.hxx>
44 #define ROW_DATE_MOD 3
45 #define ROW_DATE_CREATE 4
46 #define ROW_IS_FOLDER 5
47 #define ROW_TARGET_URL 6
48 #define ROW_IS_HIDDEN 7
49 #define ROW_IS_VOLUME 8
50 #define ROW_IS_REMOTE 9
51 #define ROW_IS_REMOVABLE 10
52 #define ROW_IS_FLOPPY 11
53 #define ROW_IS_COMPACTDISC 12
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::uno::Sequence
;
57 using ::com::sun::star::uno::Exception
;
58 using ::com::sun::star::uno::UNO_QUERY
;
59 using ::com::sun::star::util::DateTime
;
60 using ::com::sun::star::sdbc::XResultSet
;
61 using ::com::sun::star::sdbc::XRow
;
62 using ::com::sun::star::ucb::XDynamicResultSet
;
63 using ::com::sun::star::ucb::CommandAbortedException
;
64 using ::com::sun::star::ucb::XContentAccess
;
65 using ::com::sun::star::ucb::XCommandEnvironment
;
66 using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
;
69 //= FileViewContentEnumerator
72 FileViewContentEnumerator::FileViewContentEnumerator(
73 const Reference
< XCommandEnvironment
>& _rxCommandEnv
,
74 ContentData
& _rContentToFill
, ::osl::Mutex
& _rContentMutex
)
75 :Thread ( "FileViewContentEnumerator" )
76 ,m_rContent ( _rContentToFill
)
77 ,m_rContentMutex ( _rContentMutex
)
78 ,m_xCommandEnv ( _rxCommandEnv
)
79 ,m_pResultHandler ( nullptr )
80 ,m_bCancelled ( false )
85 FileViewContentEnumerator::~FileViewContentEnumerator()
90 void FileViewContentEnumerator::cancel()
92 std::unique_lock
aGuard( m_aMutex
);
94 m_pResultHandler
= nullptr;
95 m_aFolder
.aContent
= ::ucbhelper::Content();
96 m_aFolder
.sURL
.clear();
100 EnumerationResult
FileViewContentEnumerator::enumerateFolderContentSync(
101 const FolderDescriptor
& _rFolder
,
102 const css::uno::Sequence
< OUString
>& rDenyList
)
105 std::unique_lock
aGuard( m_aMutex
);
106 m_aFolder
= _rFolder
;
107 m_pResultHandler
= nullptr;
108 m_rDenyList
= rDenyList
;
110 return enumerateFolderContent();
114 void FileViewContentEnumerator::enumerateFolderContent(
115 const FolderDescriptor
& _rFolder
, IEnumerationResultHandler
* _pResultHandler
)
117 std::unique_lock
aGuard( m_aMutex
);
118 m_aFolder
= _rFolder
;
119 m_pResultHandler
= _pResultHandler
;
121 OSL_ENSURE( m_aFolder
.aContent
.get().is() || !m_aFolder
.sURL
.isEmpty(),
122 "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
125 //TODO: a protocol is missing how to join with the launched thread
126 // before exit(3), to ensure the thread is no longer relying on any
127 // infrastructure while that infrastructure is being shut down in
132 EnumerationResult
FileViewContentEnumerator::enumerateFolderContent()
134 EnumerationResult eResult
= EnumerationResult::ERROR
;
138 Reference
< XResultSet
> xResultSet
;
139 Sequence
< OUString
> aProps
{ u
"Title"_ustr
,
141 u
"DateModified"_ustr
,
148 u
"IsRemoveable"_ustr
,
150 u
"IsCompactDisc"_ustr
};
152 Reference
< XCommandEnvironment
> xEnvironment
;
155 FolderDescriptor aFolder
;
157 std::unique_lock
aGuard( m_aMutex
);
159 xEnvironment
= m_xCommandEnv
;
161 if ( !aFolder
.aContent
.get().is() )
163 aFolder
.aContent
= ::ucbhelper::Content( aFolder
.sURL
, xEnvironment
, comphelper::getProcessComponentContext() );
165 std::unique_lock
aGuard( m_aMutex
);
166 m_aFolder
.aContent
= aFolder
.aContent
;
170 Reference
< XDynamicResultSet
> xDynResultSet
= aFolder
.aContent
.createDynamicCursor( aProps
, INCLUDE_FOLDERS_AND_DOCUMENTS
);
172 if ( xDynResultSet
.is() )
173 xResultSet
= xDynResultSet
->getStaticResultSet();
175 catch( CommandAbortedException
& )
177 TOOLS_WARN_EXCEPTION( "svtools.contnr", "");
183 if ( xResultSet
.is() )
185 Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
186 Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
192 bool bCancelled
= false;
193 while ( !bCancelled
&& xResultSet
->next() )
195 bool bIsHidden
= xRow
->getBoolean( ROW_IS_HIDDEN
);
196 // don't show hidden files
197 if ( !bIsHidden
|| xRow
->wasNull() )
199 aDT
= xRow
->getTimestamp( ROW_DATE_MOD
);
200 bool bContainsDate
= !xRow
->wasNull();
201 if ( !bContainsDate
)
203 aDT
= xRow
->getTimestamp( ROW_DATE_CREATE
);
204 bContainsDate
= !xRow
->wasNull();
207 OUString aContentURL
= xContentAccess
->queryContentIdentifierString();
208 OUString aTargetURL
= xRow
->getString( ROW_TARGET_URL
);
209 bool bHasTargetURL
= !xRow
->wasNull() && !aTargetURL
.isEmpty();
211 OUString sRealURL
= bHasTargetURL
? aTargetURL
: aContentURL
;
213 // check for restrictions
215 std::unique_lock
aGuard( m_aMutex
);
216 if ( /* m_rDenyList.hasElements() && */ URLOnDenyList ( sRealURL
) )
220 std::unique_ptr
<SortingData_Impl
> pData(new SortingData_Impl
);
221 pData
->maTargetURL
= sRealURL
;
223 pData
->mbIsFolder
= xRow
->getBoolean( ROW_IS_FOLDER
) && !xRow
->wasNull();
224 pData
->mbIsVolume
= xRow
->getBoolean( ROW_IS_VOLUME
) && !xRow
->wasNull();
225 pData
->mbIsRemote
= xRow
->getBoolean( ROW_IS_REMOTE
) && !xRow
->wasNull();
226 pData
->mbIsRemoveable
= xRow
->getBoolean( ROW_IS_REMOVABLE
) && !xRow
->wasNull();
227 pData
->mbIsFloppy
= xRow
->getBoolean( ROW_IS_FLOPPY
) && !xRow
->wasNull();
228 pData
->mbIsCompactDisc
= xRow
->getBoolean( ROW_IS_COMPACTDISC
) && !xRow
->wasNull();
229 pData
->SetNewTitle( xRow
->getString( ROW_TITLE
) );
230 pData
->maSize
= xRow
->getLong( ROW_SIZE
);
232 if ( bHasTargetURL
&&
233 INetURLObject( aContentURL
).GetProtocol() == INetProtocol::VndSunStarHier
)
235 ::ucbhelper::Content
aCnt( aTargetURL
, xEnvironment
, comphelper::getProcessComponentContext() );
238 aCnt
.getPropertyValue(u
"Size"_ustr
) >>= pData
->maSize
;
239 aCnt
.getPropertyValue(u
"DateModified"_ustr
) >>= aDT
;
246 pData
->maModDate
= ::DateTime( aDT
);
249 if ( pData
->mbIsFolder
)
251 ::svtools::VolumeInfo
aVolInfo( pData
->mbIsVolume
, pData
->mbIsRemote
,
252 pData
->mbIsRemoveable
, pData
->mbIsFloppy
,
253 pData
->mbIsCompactDisc
);
254 pData
->maType
= SvFileInformationManager::GetFolderDescription( aVolInfo
);
257 pData
->maType
= SvFileInformationManager::GetFileDescription(
258 INetURLObject( pData
->maTargetURL
) );
261 ::osl::MutexGuard
aGuard( m_rContentMutex
);
262 m_rContent
.push_back( std::move(pData
) );
267 std::unique_lock
aGuard( m_aMutex
);
268 bCancelled
= m_bCancelled
;
271 eResult
= EnumerationResult::SUCCESS
;
273 catch( Exception
const & )
275 TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception while enumerating");
279 catch( Exception
const & )
281 TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent" );
284 IEnumerationResultHandler
* pHandler
= nullptr;
286 std::unique_lock
aGuard( m_aMutex
);
287 pHandler
= m_pResultHandler
;
289 return EnumerationResult::ERROR
;
293 ::osl::MutexGuard
aGuard( m_rContentMutex
);
294 if ( eResult
!= EnumerationResult::SUCCESS
)
295 // clear any "intermediate" and unfinished result
300 pHandler
->enumerationDone( eResult
);
305 bool FileViewContentEnumerator::URLOnDenyList ( std::u16string_view sRealURL
)
307 std::u16string_view::size_type pos
= sRealURL
.rfind('/');
308 pos
= (pos
!= std::u16string_view::npos
) ? pos
+ 1 : 0;
309 std::u16string_view entryName
= sRealURL
.substr(pos
);
311 return comphelper::findValue(m_rDenyList
, entryName
) != -1;
315 void FileViewContentEnumerator::execute()
317 enumerateFolderContent();
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */