1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: contentenumeration.cxx,v $
10 * $Revision: 1.11.104.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include "contentenumeration.hxx"
34 #include <svtools/urlfilter.hxx>
35 #include <svtools/inettbc.hxx>
36 #include "imagemgr.hxx"
38 /** === begin UNO includes === **/
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/sdbc/XResultSet.hpp>
41 #include <com/sun/star/sdbc/XRow.hpp>
42 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
43 #include <com/sun/star/ucb/XContentAccess.hpp>
44 #include <com/sun/star/util/DateTime.hpp>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 /** === end UNO includes === **/
47 #include <comphelper/processfactory.hxx>
48 #include <tools/debug.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vos/mutex.hxx>
54 //........................................................................
57 //........................................................................
61 #define ROW_DATE_MOD 3
62 #define ROW_DATE_CREATE 4
63 #define ROW_IS_FOLDER 5
64 #define ROW_TARGET_URL 6
65 #define ROW_IS_HIDDEN 7
66 #define ROW_IS_VOLUME 8
67 #define ROW_IS_REMOTE 9
68 #define ROW_IS_REMOVEABLE 10
69 #define ROW_IS_FLOPPY 11
70 #define ROW_IS_COMPACTDISC 12
72 #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
73 aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
74 Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
76 using ::com::sun::star::uno::Reference
;
77 using ::com::sun::star::uno::Sequence
;
78 using ::com::sun::star::uno::Exception
;
79 using ::com::sun::star::uno::UNO_QUERY
;
80 using ::com::sun::star::uno::Any
;
81 using ::com::sun::star::util::DateTime
;
82 using ::com::sun::star::sdbc::XResultSet
;
83 using ::com::sun::star::sdbc::XRow
;
84 using ::com::sun::star::ucb::XDynamicResultSet
;
85 using ::com::sun::star::ucb::CommandAbortedException
;
86 using ::com::sun::star::ucb::XContentAccess
;
87 using ::com::sun::star::ucb::XCommandEnvironment
;
88 using ::com::sun::star::beans::XPropertySet
;
89 using ::rtl::OUString
;
90 using ::ucbhelper::ResultSetInclude
;
91 using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
;
93 //====================================================================
94 //= FileViewContentEnumerator
95 //====================================================================
96 //--------------------------------------------------------------------
97 FileViewContentEnumerator::FileViewContentEnumerator(
98 const Reference
< XCommandEnvironment
>& _rxCommandEnv
,
99 ContentData
& _rContentToFill
, ::osl::Mutex
& _rContentMutex
,
100 const IContentTitleTranslation
* _pTranslator
)
101 :m_rContent ( _rContentToFill
)
102 ,m_rContentMutex ( _rContentMutex
)
104 ,m_xCommandEnv ( _rxCommandEnv
)
106 ,m_pTranslator ( _pTranslator
)
107 ,m_bCancelled ( false )
108 ,m_rBlackList ( ::com::sun::star::uno::Sequence
< ::rtl::OUString
>() )
112 //--------------------------------------------------------------------
113 FileViewContentEnumerator::~FileViewContentEnumerator()
117 //--------------------------------------------------------------------
118 void FileViewContentEnumerator::cancel()
120 ::osl::MutexGuard
aGuard( m_aMutex
);
122 m_pResultHandler
= NULL
;
123 m_pTranslator
= NULL
;
125 m_aFolder
.aContent
= ::ucbhelper::Content();
126 m_aFolder
.sURL
= String();
129 //--------------------------------------------------------------------
130 EnumerationResult
FileViewContentEnumerator::enumerateFolderContentSync(
131 const FolderDescriptor
& _rFolder
,
132 const IUrlFilter
* _pFilter
,
133 const ::com::sun::star::uno::Sequence
< ::rtl::OUString
>& rBlackList
)
136 ::osl::MutexGuard
aGuard( m_aMutex
);
137 m_aFolder
= _rFolder
;
138 m_pFilter
= _pFilter
;
139 m_pResultHandler
= NULL
;
140 m_rBlackList
= rBlackList
;
142 return enumerateFolderContent();
145 //--------------------------------------------------------------------
146 void FileViewContentEnumerator::enumerateFolderContent(
147 const FolderDescriptor
& _rFolder
, const IUrlFilter
* _pFilter
, IEnumerationResultHandler
* _pResultHandler
)
149 // ensure that we don't get deleted while herein
151 // the matching "release" will be called in onTerminated
152 // Note that onTerminated is only called if run was left normally.
153 // If somebody terminates the thread from the outside, then onTerminated
154 // will never be called. However, our terminate method is not accessible
155 // to our clients, so the only class which could misbehave is this class
158 ::osl::MutexGuard
aGuard( m_aMutex
);
159 m_aFolder
= _rFolder
;
160 m_pFilter
= _pFilter
;
161 m_pResultHandler
= _pResultHandler
;
163 OSL_ENSURE( m_aFolder
.aContent
.get().is() || m_aFolder
.sURL
.Len(),
164 "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
170 //--------------------------------------------------------------------
171 oslInterlockedCount SAL_CALL
FileViewContentEnumerator::acquire()
173 return osl_incrementInterlockedCount( &m_refCount
);
176 //--------------------------------------------------------------------
177 oslInterlockedCount SAL_CALL
FileViewContentEnumerator::release()
179 if ( 0 == osl_decrementInterlockedCount( &m_refCount
) )
187 //--------------------------------------------------------------------
188 EnumerationResult
FileViewContentEnumerator::enumerateFolderContent()
190 EnumerationResult eResult
= ERROR
;
194 Reference
< XResultSet
> xResultSet
;
195 Sequence
< OUString
> aProps(12);
197 aProps
[0] = OUString::createFromAscii( "Title" );
198 aProps
[1] = OUString::createFromAscii( "Size" );
199 aProps
[2] = OUString::createFromAscii( "DateModified" );
200 aProps
[3] = OUString::createFromAscii( "DateCreated" );
201 aProps
[4] = OUString::createFromAscii( "IsFolder" );
202 aProps
[5] = OUString::createFromAscii( "TargetURL" );
203 aProps
[6] = OUString::createFromAscii( "IsHidden" );
204 aProps
[7] = OUString::createFromAscii( "IsVolume" );
205 aProps
[8] = OUString::createFromAscii( "IsRemote" );
206 aProps
[9] = OUString::createFromAscii( "IsRemoveable" );
207 aProps
[10] = OUString::createFromAscii( "IsFloppy" );
208 aProps
[11] = OUString::createFromAscii( "IsCompactDisc" );
210 Reference
< XCommandEnvironment
> xEnvironment
;
213 FolderDescriptor aFolder
;
215 ::osl::MutexGuard
aGuard( m_aMutex
);
217 xEnvironment
= m_xCommandEnv
;
219 if ( !aFolder
.aContent
.get().is() )
221 aFolder
.aContent
= ::ucbhelper::Content( aFolder
.sURL
, xEnvironment
);
223 ::osl::MutexGuard
aGuard( m_aMutex
);
224 m_aFolder
.aContent
= aFolder
.aContent
;
228 Reference
< XDynamicResultSet
> xDynResultSet
;
229 ResultSetInclude eInclude
= INCLUDE_FOLDERS_AND_DOCUMENTS
;
230 xDynResultSet
= aFolder
.aContent
.createDynamicCursor( aProps
, eInclude
);
232 if ( xDynResultSet
.is() )
233 xResultSet
= xDynResultSet
->getStaticResultSet();
235 catch( CommandAbortedException
& )
237 DBG_ERRORFILE( "createCursor: CommandAbortedException" );
243 bool bCancelled
= false;
244 if ( xResultSet
.is() )
246 Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
247 Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
251 SortingData_Impl
* pData
;
254 while ( !bCancelled
&& xResultSet
->next() )
256 sal_Bool bIsHidden
= xRow
->getBoolean( ROW_IS_HIDDEN
);
257 // don't show hidden files
258 if ( !bIsHidden
|| xRow
->wasNull() )
262 aDT
= xRow
->getTimestamp( ROW_DATE_MOD
);
263 sal_Bool bContainsDate
= !xRow
->wasNull();
264 if ( !bContainsDate
)
266 aDT
= xRow
->getTimestamp( ROW_DATE_CREATE
);
267 bContainsDate
= !xRow
->wasNull();
270 OUString aContentURL
= xContentAccess
->queryContentIdentifierString();
271 OUString aTargetURL
= xRow
->getString( ROW_TARGET_URL
);
272 sal_Bool bHasTargetURL
= !xRow
->wasNull() && aTargetURL
.getLength() > 0;
274 OUString sRealURL
= bHasTargetURL
? aTargetURL
: aContentURL
;
276 // check for restrictions
278 ::osl::MutexGuard
aGuard( m_aMutex
);
279 if ( m_pFilter
&& !m_pFilter
->isUrlAllowed( sRealURL
) )
282 if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL
) )
286 pData
= new SortingData_Impl
;
287 pData
->maTargetURL
= sRealURL
;
289 pData
->mbIsFolder
= xRow
->getBoolean( ROW_IS_FOLDER
) && !xRow
->wasNull();
290 pData
->mbIsVolume
= xRow
->getBoolean( ROW_IS_VOLUME
) && !xRow
->wasNull();
291 pData
->mbIsRemote
= xRow
->getBoolean( ROW_IS_REMOTE
) && !xRow
->wasNull();
292 pData
->mbIsRemoveable
= xRow
->getBoolean( ROW_IS_REMOVEABLE
) && !xRow
->wasNull();
293 pData
->mbIsFloppy
= xRow
->getBoolean( ROW_IS_FLOPPY
) && !xRow
->wasNull();
294 pData
->mbIsCompactDisc
= xRow
->getBoolean( ROW_IS_COMPACTDISC
) && !xRow
->wasNull();
295 pData
->SetNewTitle( xRow
->getString( ROW_TITLE
) );
296 pData
->maSize
= xRow
->getLong( ROW_SIZE
);
298 if ( bHasTargetURL
&&
299 INetURLObject( aContentURL
).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER
)
301 ::ucbhelper::Content
aCnt( aTargetURL
, xEnvironment
);
304 aCnt
.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= pData
->maSize
;
305 aCnt
.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aDT
;
312 CONVERT_DATETIME( aDT
, pData
->maModDate
);
315 if ( pData
->mbIsFolder
)
317 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
318 ::svtools::VolumeInfo
aVolInfo( pData
->mbIsVolume
, pData
->mbIsRemote
,
319 pData
->mbIsRemoveable
, pData
->mbIsFloppy
,
320 pData
->mbIsCompactDisc
);
321 pData
->maType
= SvFileInformationManager::GetFolderDescription( aVolInfo
);
324 pData
->maType
= SvFileInformationManager::GetFileDescription(
325 INetURLObject( pData
->maTargetURL
) );
327 // replace names on demand
329 ::osl::MutexGuard
aGuard( m_aMutex
);
333 sal_Bool bTranslated
= sal_False
;
335 if ( pData
->mbIsFolder
)
336 bTranslated
= m_pTranslator
->GetTranslation( pData
->GetTitle(), sNewTitle
);
338 bTranslated
= implGetDocTitle( pData
->maTargetURL
, sNewTitle
);
341 pData
->ChangeTitle( sNewTitle
);
346 ::osl::MutexGuard
aGuard( m_rContentMutex
);
347 m_rContent
.push_back( pData
);
352 ::osl::MutexGuard
aGuard( m_aMutex
);
353 bCancelled
= m_bCancelled
;
358 catch( CommandAbortedException
& )
360 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" );
364 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" );
368 catch( CommandAbortedException
& )
370 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" );
374 DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" );
377 IEnumerationResultHandler
* pHandler
= NULL
;
379 ::osl::MutexGuard
aGuard( m_aMutex
);
380 pHandler
= m_pResultHandler
;
386 ::osl::MutexGuard
aGuard( m_rContentMutex
);
387 if ( eResult
!= SUCCESS
)
388 // clear any "intermediate" and unfinished result
393 pHandler
->enumerationDone( eResult
);
397 //--------------------------------------------------------------------
399 sal_Bool
FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString
& sRealURL
)
401 ::rtl::OUString entryName
= sRealURL
.copy( sRealURL
.lastIndexOf( rtl::OUString::createFromAscii("/")) +1 );
403 for (int i
= 0; i
< m_rBlackList
.getLength() ; i
++)
405 if ( entryName
.equals( m_rBlackList
[i
] ) )
412 //--------------------------------------------------------------------
413 sal_Bool
FileViewContentEnumerator::implGetDocTitle( const OUString
& _rTargetURL
, OUString
& _rRet
) const
415 sal_Bool bRet
= sal_False
;
419 ::osl::MutexGuard
aGuard( m_aMutex
);
420 if( !m_xDocInfo
.is() )
422 m_xDocInfo
= m_xDocInfo
.query(
423 ::comphelper::getProcessServiceFactory()->createInstance(
424 String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") )
429 DBG_ASSERT( m_xDocInfo
.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" );
430 if ( !m_xDocInfo
.is() )
433 m_xDocInfo
->loadFromURL( _rTargetURL
);
434 Reference
< XPropertySet
> xPropSet( m_xDocInfo
, UNO_QUERY
);
436 Any aAny
= xPropSet
->getPropertyValue( OUString::createFromAscii( "Title" ) );
439 if ( ( aAny
>>= sTitle
) && sTitle
.getLength() > 0 )
445 catch ( const Exception
& )
452 //--------------------------------------------------------------------
453 void SAL_CALL
FileViewContentEnumerator::run()
455 enumerateFolderContent();
458 //--------------------------------------------------------------------
459 void SAL_CALL
FileViewContentEnumerator::onTerminated()
464 //........................................................................
466 //........................................................................