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