Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "contentenumeration.hxx"
21 : #include <svl/urlfilter.hxx>
22 : #include <svtools/inettbc.hxx>
23 : #include <svtools/imagemgr.hxx>
24 :
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/sdbc/XResultSet.hpp>
27 : #include <com/sun/star/sdbc/XRow.hpp>
28 : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
29 : #include <com/sun/star/ucb/XContentAccess.hpp>
30 : #include <com/sun/star/util/DateTime.hpp>
31 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 : #include <com/sun/star/document/DocumentProperties.hpp>
33 : #include <comphelper/processfactory.hxx>
34 : #include <tools/debug.hxx>
35 : #include <vcl/svapp.hxx>
36 : #include <osl/mutex.hxx>
37 :
38 : #include <memory>
39 :
40 : //........................................................................
41 : namespace svt
42 : {
43 : //........................................................................
44 :
45 : #define ROW_TITLE 1
46 : #define ROW_SIZE 2
47 : #define ROW_DATE_MOD 3
48 : #define ROW_DATE_CREATE 4
49 : #define ROW_IS_FOLDER 5
50 : #define ROW_TARGET_URL 6
51 : #define ROW_IS_HIDDEN 7
52 : #define ROW_IS_VOLUME 8
53 : #define ROW_IS_REMOTE 9
54 : #define ROW_IS_REMOVEABLE 10
55 : #define ROW_IS_FLOPPY 11
56 : #define ROW_IS_COMPACTDISC 12
57 :
58 : #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
59 : aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
60 : Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
61 :
62 : using ::com::sun::star::uno::Reference;
63 : using ::com::sun::star::uno::Sequence;
64 : using ::com::sun::star::uno::Exception;
65 : using ::com::sun::star::uno::UNO_QUERY;
66 : using ::com::sun::star::uno::Any;
67 : using ::com::sun::star::util::DateTime;
68 : using ::com::sun::star::sdbc::XResultSet;
69 : using ::com::sun::star::sdbc::XRow;
70 : using ::com::sun::star::ucb::XDynamicResultSet;
71 : using ::com::sun::star::ucb::CommandAbortedException;
72 : using ::com::sun::star::ucb::XContentAccess;
73 : using ::com::sun::star::ucb::XCommandEnvironment;
74 : using ::com::sun::star::beans::XPropertySet;
75 : using ::com::sun::star::beans::PropertyValue;
76 : using ::com::sun::star::document::DocumentProperties;
77 : using ::rtl::OUString;
78 : using ::ucbhelper::ResultSetInclude;
79 : using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
80 :
81 : //====================================================================
82 : //= FileViewContentEnumerator
83 : //====================================================================
84 : //--------------------------------------------------------------------
85 0 : FileViewContentEnumerator::FileViewContentEnumerator(
86 : const Reference< XCommandEnvironment >& _rxCommandEnv,
87 : ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex,
88 : const IContentTitleTranslation* _pTranslator )
89 : :Thread ( "FileViewContentEnumerator" )
90 : ,m_rContent ( _rContentToFill )
91 : ,m_rContentMutex ( _rContentMutex )
92 : ,m_xCommandEnv ( _rxCommandEnv )
93 : ,m_pFilter ( NULL )
94 : ,m_pTranslator ( _pTranslator )
95 : ,m_bCancelled ( false )
96 0 : ,m_rBlackList ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() )
97 : {
98 0 : }
99 :
100 : //--------------------------------------------------------------------
101 0 : FileViewContentEnumerator::~FileViewContentEnumerator()
102 : {
103 0 : }
104 :
105 : //--------------------------------------------------------------------
106 0 : void FileViewContentEnumerator::cancel()
107 : {
108 0 : ::osl::MutexGuard aGuard( m_aMutex );
109 0 : m_bCancelled = true;
110 0 : m_pResultHandler = NULL;
111 0 : m_pTranslator = NULL;
112 0 : m_pFilter = NULL;
113 0 : m_aFolder.aContent = ::ucbhelper::Content();
114 0 : m_aFolder.sURL = String();
115 0 : }
116 :
117 : //--------------------------------------------------------------------
118 0 : EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync(
119 : const FolderDescriptor& _rFolder,
120 : const IUrlFilter* _pFilter,
121 : const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
122 : {
123 : {
124 0 : ::osl::MutexGuard aGuard( m_aMutex );
125 0 : m_aFolder = _rFolder;
126 0 : m_pFilter = _pFilter;
127 0 : m_pResultHandler = NULL;
128 0 : m_rBlackList = rBlackList;
129 : }
130 0 : return enumerateFolderContent();
131 : }
132 :
133 : //--------------------------------------------------------------------
134 0 : void FileViewContentEnumerator::enumerateFolderContent(
135 : const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler )
136 : {
137 0 : ::osl::MutexGuard aGuard( m_aMutex );
138 0 : m_aFolder = _rFolder;
139 0 : m_pFilter = _pFilter;
140 0 : m_pResultHandler = _pResultHandler;
141 :
142 : OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(),
143 : "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
144 :
145 0 : launch();
146 : //TODO: a protocol is missing how to join with the launched thread
147 : // before exit(3), to ensure the thread is no longer relying on any
148 : // infrastructure while that infrastructure is being shut down in
149 : // atexit handlers
150 0 : }
151 :
152 : //--------------------------------------------------------------------
153 0 : EnumerationResult FileViewContentEnumerator::enumerateFolderContent()
154 : {
155 0 : EnumerationResult eResult = ERROR;
156 : try
157 : {
158 :
159 0 : Reference< XResultSet > xResultSet;
160 0 : Sequence< OUString > aProps(12);
161 :
162 0 : aProps[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ));
163 0 : aProps[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ));
164 0 : aProps[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ));
165 0 : aProps[3] = OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ));
166 0 : aProps[4] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ));
167 0 : aProps[5] = OUString( RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ));
168 0 : aProps[6] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ));
169 0 : aProps[7] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ));
170 0 : aProps[8] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemote" ));
171 0 : aProps[9] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemoveable" ));
172 0 : aProps[10] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFloppy" ));
173 0 : aProps[11] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisc" ));
174 :
175 0 : Reference< XCommandEnvironment > xEnvironment;
176 : try
177 : {
178 0 : FolderDescriptor aFolder;
179 : {
180 0 : ::osl::MutexGuard aGuard( m_aMutex );
181 0 : aFolder = m_aFolder;
182 0 : xEnvironment = m_xCommandEnv;
183 : }
184 0 : if ( !aFolder.aContent.get().is() )
185 : {
186 0 : aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment, comphelper::getProcessComponentContext() );
187 : {
188 0 : ::osl::MutexGuard aGuard( m_aMutex );
189 0 : m_aFolder.aContent = aFolder.aContent;
190 : }
191 : }
192 :
193 0 : Reference< XDynamicResultSet > xDynResultSet;
194 0 : ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS;
195 0 : xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude );
196 :
197 0 : if ( xDynResultSet.is() )
198 0 : xResultSet = xDynResultSet->getStaticResultSet();
199 : }
200 0 : catch( CommandAbortedException& )
201 : {
202 : SAL_WARN( "svtools.contnr", "createCursor: CommandAbortedException" );
203 : }
204 0 : catch( Exception& )
205 : {
206 : }
207 :
208 0 : bool bCancelled = false;
209 0 : if ( xResultSet.is() )
210 : {
211 0 : Reference< XRow > xRow( xResultSet, UNO_QUERY );
212 0 : Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
213 :
214 : try
215 : {
216 : SortingData_Impl* pData;
217 0 : DateTime aDT;
218 :
219 0 : while ( !bCancelled && xResultSet->next() )
220 : {
221 0 : sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN );
222 : // don't show hidden files
223 0 : if ( !bIsHidden || xRow->wasNull() )
224 : {
225 0 : pData = NULL;
226 :
227 0 : aDT = xRow->getTimestamp( ROW_DATE_MOD );
228 0 : sal_Bool bContainsDate = !xRow->wasNull();
229 0 : if ( !bContainsDate )
230 : {
231 0 : aDT = xRow->getTimestamp( ROW_DATE_CREATE );
232 0 : bContainsDate = !xRow->wasNull();
233 : }
234 :
235 0 : OUString aContentURL = xContentAccess->queryContentIdentifierString();
236 0 : OUString aTargetURL = xRow->getString( ROW_TARGET_URL );
237 0 : sal_Bool bHasTargetURL = !xRow->wasNull() && !aTargetURL.isEmpty();
238 :
239 0 : OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL;
240 :
241 : // check for restrictions
242 : {
243 0 : ::osl::MutexGuard aGuard( m_aMutex );
244 0 : if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) )
245 0 : continue;
246 :
247 0 : if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) )
248 0 : continue;
249 : }
250 :
251 0 : pData = new SortingData_Impl;
252 0 : pData->maTargetURL = sRealURL;
253 :
254 0 : pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull();
255 0 : pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull();
256 0 : pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull();
257 0 : pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull();
258 0 : pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull();
259 0 : pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull();
260 0 : pData->SetNewTitle( xRow->getString( ROW_TITLE ) );
261 0 : pData->maSize = xRow->getLong( ROW_SIZE );
262 :
263 0 : if ( bHasTargetURL &&
264 0 : INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER )
265 : {
266 0 : ::ucbhelper::Content aCnt( aTargetURL, xEnvironment, comphelper::getProcessComponentContext() );
267 : try
268 : {
269 0 : aCnt.getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" )) ) >>= pData->maSize;
270 0 : aCnt.getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= aDT;
271 : }
272 0 : catch (...) {}
273 : }
274 :
275 0 : if ( bContainsDate )
276 : {
277 0 : CONVERT_DATETIME( aDT, pData->maModDate );
278 : }
279 :
280 0 : if ( pData->mbIsFolder )
281 : {
282 0 : SolarMutexGuard aGuard;
283 : ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote,
284 : pData->mbIsRemoveable, pData->mbIsFloppy,
285 0 : pData->mbIsCompactDisc );
286 0 : pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
287 : }
288 : else
289 : pData->maType = SvFileInformationManager::GetFileDescription(
290 0 : INetURLObject( pData->maTargetURL ) );
291 :
292 : // replace names on demand
293 : {
294 0 : ::osl::MutexGuard aGuard( m_aMutex );
295 0 : if( m_pTranslator )
296 : {
297 0 : OUString sNewTitle;
298 0 : sal_Bool bTranslated = sal_False;
299 :
300 0 : if ( pData->mbIsFolder )
301 0 : bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle );
302 : else
303 0 : bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle );
304 :
305 0 : if ( bTranslated )
306 0 : pData->ChangeTitle( sNewTitle );
307 0 : }
308 : }
309 :
310 : {
311 0 : ::osl::MutexGuard aGuard( m_rContentMutex );
312 0 : m_rContent.push_back( pData );
313 0 : }
314 : }
315 :
316 : {
317 0 : ::osl::MutexGuard aGuard( m_aMutex );
318 0 : bCancelled = m_bCancelled;
319 : }
320 : }
321 0 : eResult = SUCCESS;
322 : }
323 0 : catch( CommandAbortedException& )
324 : {
325 : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" );
326 : }
327 0 : catch( Exception& )
328 : {
329 : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" );
330 0 : }
331 0 : }
332 : }
333 0 : catch( CommandAbortedException& )
334 : {
335 : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" );
336 : }
337 0 : catch( Exception& )
338 : {
339 : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" );
340 : }
341 :
342 0 : IEnumerationResultHandler* pHandler = NULL;
343 : {
344 0 : ::osl::MutexGuard aGuard( m_aMutex );
345 0 : pHandler = m_pResultHandler;
346 0 : if ( m_bCancelled )
347 0 : return ERROR;
348 : }
349 :
350 : {
351 0 : ::osl::MutexGuard aGuard( m_rContentMutex );
352 0 : if ( eResult != SUCCESS )
353 : // clear any "intermediate" and unfinished result
354 0 : m_rContent.clear();
355 : }
356 :
357 0 : if ( pHandler )
358 0 : pHandler->enumerationDone( eResult );
359 0 : return eResult;
360 : }
361 :
362 : //--------------------------------------------------------------------
363 :
364 0 : sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL )
365 : {
366 0 : ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( '/' ) + 1 );
367 :
368 0 : for (int i = 0; i < m_rBlackList.getLength() ; i++)
369 : {
370 0 : if ( entryName.equals( m_rBlackList[i] ) )
371 0 : return true;
372 : }
373 :
374 0 : return false;
375 : }
376 :
377 : //--------------------------------------------------------------------
378 0 : sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const
379 : {
380 0 : sal_Bool bRet = sal_False;
381 :
382 : try
383 : {
384 0 : ::osl::MutexGuard aGuard( m_aMutex );
385 0 : if (!m_xDocProps.is())
386 : {
387 : m_xDocProps.set(DocumentProperties::create(
388 0 : ::comphelper::getProcessComponentContext()));
389 : }
390 :
391 : assert(m_xDocProps.is());
392 0 : if (!m_xDocProps.is())
393 0 : return sal_False;
394 :
395 0 : m_xDocProps->loadFromMedium(_rTargetURL, Sequence<PropertyValue>());
396 :
397 0 : OUString const sTitle(m_xDocProps->getTitle());
398 0 : if (!sTitle.isEmpty())
399 : {
400 0 : _rRet = sTitle;
401 0 : bRet = sal_True;
402 0 : }
403 : }
404 0 : catch ( const Exception& )
405 : {
406 : }
407 :
408 0 : return bRet;
409 : }
410 :
411 : //--------------------------------------------------------------------
412 0 : void FileViewContentEnumerator::execute()
413 : {
414 0 : enumerateFolderContent();
415 0 : }
416 :
417 : //........................................................................
418 : } // namespace svt
419 : //........................................................................
420 :
421 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|