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 <config_features.h>
22 #include <sal/config.h>
23 #include <sal/log.hxx>
25 #if HAVE_FEATURE_MACOSX_SANDBOX
29 #include <com/sun/star/beans/IllegalTypeException.hpp>
30 #include <com/sun/star/beans/NotRemoveableException.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/beans/PropertyExistException.hpp>
33 #include <com/sun/star/io/BufferSizeExceededException.hpp>
34 #include <com/sun/star/io/NotConnectedException.hpp>
35 #include <com/sun/star/io/IOException.hpp>
36 #include <com/sun/star/lang/IllegalAccessException.hpp>
37 #include <com/sun/star/task/InteractionClassification.hpp>
38 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
39 #include <com/sun/star/ucb/DuplicateCommandIdentifierException.hpp>
40 #include <com/sun/star/ucb/IOErrorCode.hpp>
41 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
42 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
43 #include <com/sun/star/ucb/NameClash.hpp>
44 #include <com/sun/star/ucb/OpenCommandArgument.hpp>
45 #include <com/sun/star/ucb/Store.hpp>
46 #include <com/sun/star/ucb/TransferInfo.hpp>
47 #include <comphelper/propertysequence.hxx>
48 #include <osl/diagnose.h>
49 #include <rtl/ref.hxx>
50 #include <rtl/uri.hxx>
52 #include "filtask.hxx"
54 #include "filglob.hxx"
55 #include "filinpstr.hxx"
57 #include "filrset.hxx"
61 /******************************************************************************/
65 /******************************************************************************/
68 using namespace fileaccess
;
69 using namespace com::sun::star
;
70 using namespace com::sun::star::uno
;
71 using namespace com::sun::star::ucb
;
73 #if OSL_DEBUG_LEVEL > 0
74 #define THROW_WHERE SAL_WHERE
76 #define THROW_WHERE ""
79 TaskManager::UnqPathData::UnqPathData() = default;
81 TaskManager::UnqPathData::UnqPathData(TaskManager::UnqPathData
&&) = default;
84 TaskManager::UnqPathData::~UnqPathData()
88 TaskManager::MyProperty::MyProperty( const OUString
& thePropertyName
)
89 : PropertyName( thePropertyName
)
92 , State(beans::PropertyState_AMBIGUOUS_VALUE
)
98 TaskManager::MyProperty::MyProperty( bool theisNative
,
99 const OUString
& thePropertyName
,
101 const css::uno::Type
& theTyp
,
102 const css::uno::Any
& theValue
,
103 const css::beans::PropertyState
& theState
,
104 sal_Int16 theAttributes
)
105 : PropertyName( thePropertyName
),
107 isNative( theisNative
),
111 Attributes( theAttributes
)
116 #include "filinl.hxx"
118 // Default properties
120 constexpr OUString
Title( u
"Title"_ustr
);
121 constexpr OUString
CasePreservingURL( u
"CasePreservingURL"_ustr
);
122 constexpr OUString
IsDocument( u
"IsDocument"_ustr
);
123 constexpr OUString
IsFolder( u
"IsFolder"_ustr
);
124 constexpr OUString
DateModified( u
"DateModified"_ustr
);
125 constexpr OUString
Size( u
"Size"_ustr
);
126 constexpr OUString
IsVolume( u
"IsVolume"_ustr
);
127 constexpr OUString
IsRemoveable( u
"IsRemoveable"_ustr
);
128 constexpr OUString
IsRemote( u
"IsRemote"_ustr
);
129 constexpr OUString
IsCompactDisc( u
"IsCompactDisc"_ustr
);
130 constexpr OUString
IsFloppy( u
"IsFloppy"_ustr
);
131 constexpr OUString
IsHidden( u
"IsHidden"_ustr
);
132 constexpr OUString
ContentType( u
"ContentType"_ustr
);
133 constexpr OUString
IsReadOnly( u
"IsReadOnly"_ustr
);
134 constexpr OUString
CreatableContentsInfo( u
"CreatableContentsInfo"_ustr
);
136 TaskManager::TaskManager( const uno::Reference
< uno::XComponentContext
>& rxContext
,
137 FileProvider
* pProvider
, bool bWithConfig
)
139 m_pProvider( pProvider
),
140 m_xContext( rxContext
),
143 { /* Name */ u
"getCommandInfo"_ustr
,
145 /* ArgType */ cppu::UnoType
<void>::get() },
147 { /* Name */ u
"getPropertySetInfo"_ustr
,
149 /* ArgType */ cppu::UnoType
<void>::get() },
151 { /* Name */ u
"getPropertyValues"_ustr
,
153 /* ArgType */ cppu::UnoType
<uno::Sequence
< beans::Property
>>::get() },
155 { /* Name */ u
"setPropertyValues"_ustr
,
157 /* ArgType */ cppu::UnoType
<uno::Sequence
< beans::PropertyValue
>>::get() },
159 { /* Name */ u
"open"_ustr
,
161 /* ArgType */ cppu::UnoType
<OpenCommandArgument
>::get() },
163 { /* Name */ u
"transfer"_ustr
,
165 /* ArgType */ cppu::UnoType
<TransferInfo
>::get() },
167 { /* Name */ u
"delete"_ustr
,
169 /* ArgType */ cppu::UnoType
<sal_Bool
>::get() },
171 { /* Name */ u
"insert"_ustr
,
173 /* ArgType */ cppu::UnoType
<InsertCommandArgument
>::get() },
175 { /* Name */ u
"createNewContent"_ustr
,
177 /* ArgType */ cppu::UnoType
<ucb::ContentInfo
>::get() } }
180 m_aDefaultProperties
.insert( MyProperty( true,
183 cppu::UnoType
<OUString
>::get(),
185 beans::PropertyState_DEFAULT_VALUE
,
186 beans::PropertyAttribute::MAYBEVOID
187 | beans::PropertyAttribute::BOUND
) );
190 m_aDefaultProperties
.insert(
194 cppu::UnoType
<OUString
>::get(),
196 beans::PropertyState_DEFAULT_VALUE
,
197 beans::PropertyAttribute::MAYBEVOID
198 | beans::PropertyAttribute::BOUND
199 | beans::PropertyAttribute::READONLY
) );
203 m_aDefaultProperties
.insert( MyProperty( true,
206 cppu::UnoType
<sal_Bool
>::get(),
208 beans::PropertyState_DEFAULT_VALUE
,
209 beans::PropertyAttribute::MAYBEVOID
210 | beans::PropertyAttribute::BOUND
211 | beans::PropertyAttribute::READONLY
) );
215 m_aDefaultProperties
.insert( MyProperty( true,
218 cppu::UnoType
<sal_Bool
>::get(),
220 beans::PropertyState_DEFAULT_VALUE
,
221 beans::PropertyAttribute::MAYBEVOID
222 | beans::PropertyAttribute::BOUND
223 | beans::PropertyAttribute::READONLY
) );
226 m_aDefaultProperties
.insert( MyProperty( true,
229 cppu::UnoType
<sal_Bool
>::get(),
231 beans::PropertyState_DEFAULT_VALUE
,
232 beans::PropertyAttribute::MAYBEVOID
233 | beans::PropertyAttribute::BOUND
234 | beans::PropertyAttribute::READONLY
) );
238 m_aDefaultProperties
.insert( MyProperty( true,
241 cppu::UnoType
<sal_Bool
>::get(),
243 beans::PropertyState_DEFAULT_VALUE
,
244 beans::PropertyAttribute::MAYBEVOID
245 | beans::PropertyAttribute::BOUND
246 | beans::PropertyAttribute::READONLY
) );
249 m_aDefaultProperties
.insert( MyProperty( true,
252 cppu::UnoType
<sal_Bool
>::get(),
254 beans::PropertyState_DEFAULT_VALUE
,
255 beans::PropertyAttribute::MAYBEVOID
256 | beans::PropertyAttribute::BOUND
257 | beans::PropertyAttribute::READONLY
) );
260 m_aDefaultProperties
.insert( MyProperty( true,
263 cppu::UnoType
<sal_Bool
>::get(),
265 beans::PropertyState_DEFAULT_VALUE
,
266 beans::PropertyAttribute::MAYBEVOID
267 | beans::PropertyAttribute::BOUND
268 | beans::PropertyAttribute::READONLY
) );
271 m_aDefaultProperties
.insert( MyProperty( true,
274 cppu::UnoType
<sal_Bool
>::get(),
276 beans::PropertyState_DEFAULT_VALUE
,
277 beans::PropertyAttribute::MAYBEVOID
278 | beans::PropertyAttribute::BOUND
279 | beans::PropertyAttribute::READONLY
) );
282 m_aDefaultProperties
.insert(
287 cppu::UnoType
<sal_Bool
>::get(),
289 beans::PropertyState_DEFAULT_VALUE
,
290 beans::PropertyAttribute::MAYBEVOID
291 | beans::PropertyAttribute::BOUND
295 | beans::PropertyAttribute::READONLY
)); // under unix/linux only readable
300 m_aDefaultProperties
.insert( MyProperty( false,
303 cppu::UnoType
<OUString
>::get(),
304 uno::Any(OUString()),
305 beans::PropertyState_DEFAULT_VALUE
,
306 beans::PropertyAttribute::MAYBEVOID
307 | beans::PropertyAttribute::BOUND
308 | beans::PropertyAttribute::READONLY
) );
312 m_aDefaultProperties
.insert( MyProperty( true,
315 cppu::UnoType
<util::DateTime
>::get(),
317 beans::PropertyState_DEFAULT_VALUE
,
318 beans::PropertyAttribute::MAYBEVOID
319 | beans::PropertyAttribute::BOUND
) );
322 m_aDefaultProperties
.insert( MyProperty( true,
325 cppu::UnoType
<sal_Int64
>::get(),
327 beans::PropertyState_DEFAULT_VALUE
,
328 beans::PropertyAttribute::MAYBEVOID
329 | beans::PropertyAttribute::BOUND
) );
332 m_aDefaultProperties
.insert( MyProperty( true,
335 cppu::UnoType
<sal_Bool
>::get(),
337 beans::PropertyState_DEFAULT_VALUE
,
338 beans::PropertyAttribute::MAYBEVOID
339 | beans::PropertyAttribute::BOUND
) );
342 // CreatableContentsInfo
343 m_aDefaultProperties
.insert( MyProperty( true,
344 CreatableContentsInfo
,
346 cppu::UnoType
<uno::Sequence
< ucb::ContentInfo
>>::get(),
348 beans::PropertyState_DEFAULT_VALUE
,
349 beans::PropertyAttribute::MAYBEVOID
350 | beans::PropertyAttribute::BOUND
351 | beans::PropertyAttribute::READONLY
) );
355 uno::Reference
< XPropertySetRegistryFactory
> xRegFac
= ucb::Store::create( m_xContext
);
356 // Open/create a registry
357 m_xFileRegistry
= xRegFac
->createPropertySetRegistry( OUString() );
362 TaskManager::~TaskManager()
368 TaskManager::startTask(
370 const uno::Reference
< XCommandEnvironment
>& xCommandEnv
)
372 std::unique_lock
aGuard( m_aMutex
);
373 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
374 if( it
!= m_aTaskMap
.end() )
376 throw DuplicateCommandIdentifierException( OSL_LOG_PREFIX
);
378 m_aTaskMap
.emplace( CommandId
, TaskHandling( xCommandEnv
));
383 TaskManager::endTask( sal_Int32 CommandId
,
384 const OUString
& aUncPath
,
385 BaseContent
* pContent
)
387 std::unique_lock
aGuard( m_aMutex
);
388 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
389 if( it
== m_aTaskMap
.end() )
392 TaskHandlerErr ErrorCode
= it
->second
.getInstalledError();
393 sal_Int32 MinorCode
= it
->second
.getMinorErrorCode();
394 bool isHandled
= it
->second
.isHandled();
396 Reference
< XCommandEnvironment
> xComEnv
397 = it
->second
.getCommandEnvironment();
399 m_aTaskMap
.erase( it
);
403 if( ErrorCode
!= TaskHandlerErr::NO_ERROR
)
414 void TaskManager::clearError( sal_Int32 CommandId
)
416 std::unique_lock
aGuard( m_aMutex
);
417 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
418 if( it
!= m_aTaskMap
.end() )
419 it
->second
.clearError();
423 void TaskManager::retrieveError( sal_Int32 CommandId
,
424 TaskHandlerErr
&ErrorCode
,
425 sal_Int32
&minorCode
)
427 std::unique_lock
aGuard( m_aMutex
);
428 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
429 if( it
!= m_aTaskMap
.end() )
431 ErrorCode
= it
->second
.getInstalledError();
432 minorCode
= it
->second
. getMinorErrorCode();
437 void TaskManager::installError( sal_Int32 CommandId
,
438 TaskHandlerErr ErrorCode
,
439 sal_Int32 MinorCode
)
441 std::unique_lock
aGuard( m_aMutex
);
442 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
443 if( it
!= m_aTaskMap
.end() )
444 it
->second
.installError( ErrorCode
,MinorCode
);
449 TaskManager::getCommandId()
451 std::unique_lock
aGuard( m_aMutex
);
452 return ++m_nCommandId
;
456 void TaskManager::handleTask(
458 const uno::Reference
< task::XInteractionRequest
>& request
)
460 std::unique_lock
aGuard( m_aMutex
);
461 TaskMap::iterator it
= m_aTaskMap
.find( CommandId
);
462 uno::Reference
< task::XInteractionHandler
> xInt
;
463 if( it
!= m_aTaskMap
.end() )
465 xInt
= it
->second
.getInteractionHandler();
467 xInt
->handle( request
);
468 it
->second
.setHandled();
472 /*********************************************************************************/
474 /* de/registerNotifier-Implementation */
476 /*********************************************************************************/
479 // This two methods register and deregister a change listener for the content belonging
484 TaskManager::registerNotifier( const OUString
& aUnqPath
, Notifier
* pNotifier
)
486 std::unique_lock
aGuard( m_aMutex
);
488 ContentMap::iterator it
=
489 m_aContent
.emplace( aUnqPath
, UnqPathData() ).first
;
491 std::vector
< Notifier
* >& nlist
= it
->second
.notifier
;
493 std::vector
<Notifier
*>::iterator it1
= std::find(nlist
.begin(), nlist
.end(), pNotifier
);
494 if( it1
!= nlist
.end() ) // Every "Notifier" only once
498 nlist
.push_back( pNotifier
);
503 TaskManager::deregisterNotifier( const OUString
& aUnqPath
,Notifier
* pNotifier
)
505 std::unique_lock
aGuard( m_aMutex
);
507 ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
508 if( it
== m_aContent
.end() )
511 std::erase(it
->second
.notifier
, pNotifier
);
513 if( it
->second
.notifier
.empty() )
514 m_aContent
.erase( it
);
518 /*********************************************************************************/
520 /* de/associate-Implementation */
522 /*********************************************************************************/
524 // Used to associate and deassociate a new property with
525 // the content belonging to URL UnqPath.
526 // The default value and the attributes are input
530 TaskManager::associate( const OUString
& aUnqPath
,
531 const OUString
& PropertyName
,
532 const uno::Any
& DefaultValue
,
533 const sal_Int16 Attributes
)
535 MyProperty
newProperty( false,
538 DefaultValue
.getValueType(),
540 beans::PropertyState_DEFAULT_VALUE
,
543 auto it1
= m_aDefaultProperties
.find( newProperty
);
544 if( it1
!= m_aDefaultProperties
.end() )
545 throw beans::PropertyExistException( THROW_WHERE
);
548 std::unique_lock
aGuard( m_aMutex
);
550 ContentMap::iterator it
= m_aContent
.emplace( aUnqPath
,UnqPathData() ).first
;
552 // Load the XPersistentPropertySetInfo and create it, if it does not exist
555 PropertySet
& properties
= it
->second
.properties
;
556 it1
= properties
.find( newProperty
);
557 if( it1
!= properties
.end() )
558 throw beans::PropertyExistException(THROW_WHERE
);
560 // Property does not exist
561 properties
.insert( newProperty
);
562 it
->second
.xC
->addProperty( PropertyName
,Attributes
,DefaultValue
);
564 notifyPropertyAdded( getPropertySetListeners( aUnqPath
), PropertyName
);
569 TaskManager::deassociate( const OUString
& aUnqPath
,
570 const OUString
& PropertyName
)
572 MyProperty
oldProperty( PropertyName
);
574 auto it1
= m_aDefaultProperties
.find( oldProperty
);
575 if( it1
!= m_aDefaultProperties
.end() )
576 throw beans::NotRemoveableException( THROW_WHERE
);
578 std::unique_lock
aGuard( m_aMutex
);
580 ContentMap::iterator it
= m_aContent
.emplace( aUnqPath
,UnqPathData() ).first
;
584 PropertySet
& properties
= it
->second
.properties
;
586 it1
= properties
.find( oldProperty
);
587 if( it1
== properties
.end() )
588 throw beans::UnknownPropertyException( PropertyName
);
590 properties
.erase( it1
);
592 if( it
->second
.xC
.is() )
593 it
->second
.xC
->removeProperty( PropertyName
);
595 if( properties
.size() == 9 )
597 MyProperty
ContentTProperty( ContentType
);
599 if( properties
.find( ContentTProperty
)->getState() == beans::PropertyState_DEFAULT_VALUE
)
601 it
->second
.xS
= nullptr;
602 it
->second
.xC
= nullptr;
603 it
->second
.xA
= nullptr;
604 if(m_xFileRegistry
.is())
605 m_xFileRegistry
->removePropertySet( aUnqPath
);
609 notifyPropertyRemoved( getPropertySetListeners( aUnqPath
), PropertyName
);
613 /*********************************************************************************/
615 /* page-Implementation */
617 /*********************************************************************************/
619 // Given an xOutputStream, this method writes the content of the file belonging to
620 // URL aUnqPath into the XOutputStream
623 void TaskManager::page( sal_Int32 CommandId
,
624 const OUString
& aUnqPath
,
625 const uno::Reference
< io::XOutputStream
>& xOutputStream
)
627 osl::File
aFile( aUnqPath
);
628 osl::FileBase::RC err
= aFile
.open( osl_File_OpenFlag_Read
);
630 if( err
!= osl::FileBase::E_None
)
633 installError( CommandId
,
634 TaskHandlerErr::OPEN_FILE_FOR_PAGING
,
639 const sal_uInt64 bfz
= 4*1024;
641 sal_uInt64 nrc
; // Retrieved number of Bytes;
645 err
= aFile
.read( static_cast<void*>(BFF
),bfz
,nrc
);
646 if( err
== osl::FileBase::E_None
)
648 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
649 uno::Sequence
< sal_Int8
> seq( BFF
, static_cast<sal_uInt32
>(nrc
) );
652 xOutputStream
->writeBytes( seq
);
654 catch (const io::NotConnectedException
&)
656 installError( CommandId
,
657 TaskHandlerErr::NOTCONNECTED_FOR_PAGING
);
660 catch (const io::BufferSizeExceededException
&)
662 installError( CommandId
,
663 TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_PAGING
);
666 catch (const io::IOException
&)
668 installError( CommandId
,
669 TaskHandlerErr::IOEXCEPTION_FOR_PAGING
);
675 installError( CommandId
,
676 TaskHandlerErr::READING_FILE_FOR_PAGING
,
680 } while( nrc
== bfz
);
688 xOutputStream
->closeOutput();
690 catch (const io::NotConnectedException
&)
693 catch (const io::BufferSizeExceededException
&)
696 catch (const io::IOException
&)
702 /*********************************************************************************/
704 /* open-Implementation */
706 /*********************************************************************************/
708 // Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
711 uno::Reference
< io::XInputStream
>
712 TaskManager::open( sal_Int32 CommandId
,
713 const OUString
& aUnqPath
,
716 rtl::Reference
<XInputStream_impl
> pInputStream(new XInputStream_impl( aUnqPath
, bLock
)); // from filinpstr.hxx
718 TaskHandlerErr ErrorCode
= pInputStream
->CtorSuccess();
720 if( ErrorCode
!= TaskHandlerErr::NO_ERROR
)
722 installError( CommandId
,
724 pInputStream
->getMinorError() );
726 pInputStream
.clear();
733 /*********************************************************************************/
735 /* open for read/write access-Implementation */
737 /*********************************************************************************/
739 // Given a file URL aUnqPath, this methods returns a XStream which can be used
740 // to read and write from/to the file.
743 uno::Reference
< io::XStream
>
744 TaskManager::open_rw( sal_Int32 CommandId
,
745 const OUString
& aUnqPath
,
748 rtl::Reference
<XStream_impl
> pStream(new XStream_impl( aUnqPath
, bLock
)); // from filstr.hxx
750 TaskHandlerErr ErrorCode
= pStream
->CtorSuccess();
752 if( ErrorCode
!= TaskHandlerErr::NO_ERROR
)
754 installError( CommandId
,
756 pStream
->getMinorError() );
764 /*********************************************************************************/
766 /* ls-Implementation */
768 /*********************************************************************************/
770 // This method returns the result set containing the children of the directory belonging
771 // to file URL aUnqPath
774 uno::Reference
< XDynamicResultSet
>
775 TaskManager::ls( sal_Int32 CommandId
,
776 const OUString
& aUnqPath
,
777 const sal_Int32 OpenMode
,
778 const uno::Sequence
< beans::Property
>& seq
,
779 const uno::Sequence
< NumberedSortingInfo
>& seqSort
)
781 rtl::Reference
<XResultSet_impl
> p(new XResultSet_impl( this,aUnqPath
,OpenMode
,seq
,seqSort
));
783 TaskHandlerErr ErrorCode
= p
->CtorSuccess();
785 if( ErrorCode
!= TaskHandlerErr::NO_ERROR
)
787 installError( CommandId
,
789 p
->getMinorError() );
798 /*********************************************************************************/
800 /* info_c implementation */
802 /*********************************************************************************/
805 uno::Reference
< XCommandInfo
>
806 TaskManager::info_c()
808 return new XCommandInfo_impl( this );
812 /*********************************************************************************/
814 /* info_p-Implementation */
816 /*********************************************************************************/
817 // Info for the properties
819 uno::Reference
< beans::XPropertySetInfo
>
820 TaskManager::info_p( const OUString
& aUnqPath
)
822 std::unique_lock
aGuard( m_aMutex
);
823 return new XPropertySetInfo_impl( this,aUnqPath
);
827 /*********************************************************************************/
829 /* setv-Implementation */
831 /*********************************************************************************/
833 // Sets the values of the properties belonging to fileURL aUnqPath
836 uno::Sequence
< uno::Any
>
837 TaskManager::setv( const OUString
& aUnqPath
,
838 const uno::Sequence
< beans::PropertyValue
>& values
)
840 std::unique_lock
aGuard( m_aMutex
);
842 sal_Int32 propChanged
= 0;
843 uno::Sequence
< uno::Any
> ret( values
.getLength() );
844 auto retRange
= asNonConstRange(ret
);
845 uno::Sequence
< beans::PropertyChangeEvent
> seqChanged( values
.getLength() );
846 auto seqChangedRange
= asNonConstRange(seqChanged
);
848 TaskManager::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
849 PropertySet
& properties
= it
->second
.properties
;
850 TaskManager::PropertySet::const_iterator it1
;
853 for( sal_Int32 i
= 0; i
< values
.getLength(); ++i
)
855 MyProperty
toset( values
[i
].Name
);
856 it1
= properties
.find( toset
);
857 if( it1
== properties
.end() )
859 retRange
[i
] <<= beans::UnknownPropertyException( THROW_WHERE
);
863 aAny
= it1
->getValue();
864 if( aAny
== values
[i
].Value
)
865 continue; // nothing needs to be changed
867 if( it1
->getAttributes() & beans::PropertyAttribute::READONLY
)
869 retRange
[i
] <<= lang::IllegalAccessException( THROW_WHERE
);
873 seqChangedRange
[ propChanged
].PropertyName
= values
[i
].Name
;
874 seqChangedRange
[ propChanged
].PropertyHandle
= -1;
875 seqChangedRange
[ propChanged
].Further
= false;
876 seqChangedRange
[ propChanged
].OldValue
= aAny
;
877 seqChangedRange
[ propChanged
++ ].NewValue
= values
[i
].Value
;
879 it1
->setValue( values
[i
].Value
); // Put the new value into the local cash
881 if( ! it1
->IsNative() )
883 // Also put logical properties into storage
884 if( !it
->second
.xS
.is() )
887 if( ( values
[i
].Name
== ContentType
) &&
888 it1
->getState() == beans::PropertyState_DEFAULT_VALUE
)
889 { // Special logic for ContentType
890 // 09.07.01: Not reached anymore, because ContentType is readonly
891 it1
->setState( beans::PropertyState_DIRECT_VALUE
);
892 it
->second
.xC
->addProperty( values
[i
].Name
,
893 beans::PropertyAttribute::MAYBEVOID
,
899 it
->second
.xS
->setPropertyValue( values
[i
].Name
,values
[i
].Value
);
901 catch (const uno::Exception
&e
)
903 --propChanged
; // unsuccessful setting
910 // Setting of physical file properties
911 if( values
[i
].Name
== Size
)
913 sal_Int64 newSize
= 0;
914 if( values
[i
].Value
>>= newSize
)
915 { // valid value for the size
916 osl::File
aFile(aUnqPath
);
918 aFile
.open(osl_File_OpenFlag_Write
) != osl::FileBase::E_None
||
919 aFile
.setSize(sal_uInt64(newSize
)) != osl::FileBase::E_None
||
920 aFile
.close() != osl::FileBase::E_None
;
924 --propChanged
; // unsuccessful setting
925 uno::Sequence
<uno::Any
> names(comphelper::InitAnyPropertySequence(
927 {"Uri", uno::Any(aUnqPath
)}
929 retRange
[i
] <<= InteractiveAugmentedIOException(
932 task::InteractionClassification_ERROR
,
938 retRange
[i
] <<= beans::IllegalTypeException( THROW_WHERE
);
940 else if(values
[i
].Name
== IsReadOnly
||
941 values
[i
].Name
== IsHidden
)
944 if( values
[i
].Value
>>= value
)
946 osl::DirectoryItem aDirItem
;
947 osl::FileBase::RC err
=
948 osl::DirectoryItem::get(aUnqPath
,aDirItem
);
949 sal_uInt64
nAttributes(0);
950 if(err
== osl::FileBase::E_None
)
952 osl::FileStatus
aFileStatus(osl_FileStatus_Mask_Attributes
);
953 err
= aDirItem
.getFileStatus(aFileStatus
);
954 if(err
== osl::FileBase::E_None
&&
955 aFileStatus
.isValid(osl_FileStatus_Mask_Attributes
))
956 nAttributes
= aFileStatus
.getAttributes();
958 // now we have the attributes provided all went well.
959 if(err
== osl::FileBase::E_None
) {
960 if(values
[i
].Name
== IsReadOnly
)
962 nAttributes
&= ~(osl_File_Attribute_OwnWrite
|
963 osl_File_Attribute_GrpWrite
|
964 osl_File_Attribute_OthWrite
|
965 osl_File_Attribute_ReadOnly
);
967 nAttributes
|= osl_File_Attribute_ReadOnly
;
970 osl_File_Attribute_OwnWrite
|
971 osl_File_Attribute_GrpWrite
|
972 osl_File_Attribute_OthWrite
);
974 else if(values
[i
].Name
== IsHidden
)
976 nAttributes
&= ~(osl_File_Attribute_Hidden
);
978 nAttributes
|= osl_File_Attribute_Hidden
;
980 err
= osl::File::setAttributes(
981 aUnqPath
,nAttributes
);
984 if( err
!= osl::FileBase::E_None
)
986 --propChanged
; // unsuccessful setting
987 uno::Sequence
<uno::Any
> names(comphelper::InitAnyPropertySequence(
989 {"Uri", uno::Any(aUnqPath
)}
994 case osl::FileBase::E_NOMEM
:
995 // not enough memory for allocating structures <br>
996 ioError
= IOErrorCode_OUT_OF_MEMORY
;
998 case osl::FileBase::E_INVAL
:
999 // the format of the parameters was not valid<p>
1000 ioError
= IOErrorCode_INVALID_PARAMETER
;
1002 case osl::FileBase::E_NAMETOOLONG
:
1003 // File name too long<br>
1004 ioError
= IOErrorCode_NAME_TOO_LONG
;
1006 case osl::FileBase::E_NOENT
:
1007 // No such file or directory<br>
1008 case osl::FileBase::E_NOLINK
:
1009 // Link has been severed<br>
1010 ioError
= IOErrorCode_NOT_EXISTING
;
1012 case osl::FileBase::E_ROFS
:
1013 // #i4735# handle ROFS transparently
1015 case osl::FileBase::E_PERM
:
1016 case osl::FileBase::E_ACCES
:
1017 // permission denied<br>
1018 ioError
= IOErrorCode_ACCESS_DENIED
;
1020 case osl::FileBase::E_LOOP
:
1021 // Too many symbolic links encountered<br>
1022 case osl::FileBase::E_FAULT
:
1024 case osl::FileBase::E_IO
:
1026 case osl::FileBase::E_NOSYS
:
1027 // Function not implemented<br>
1028 case osl::FileBase::E_MULTIHOP
:
1029 // Multihop attempted<br>
1030 case osl::FileBase::E_INTR
:
1031 // function call was interrupted<p>
1033 ioError
= IOErrorCode_GENERAL
;
1036 retRange
[i
] <<= InteractiveAugmentedIOException(
1039 task::InteractionClassification_ERROR
,
1045 retRange
[i
] <<= beans::IllegalTypeException( THROW_WHERE
);
1053 seqChanged
.realloc( propChanged
);
1054 notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath
), seqChanged
);
1060 /*********************************************************************************/
1062 /* getv-Implementation */
1064 /*********************************************************************************/
1066 // Reads the values of the properties belonging to fileURL aUnqPath;
1067 // Returns an XRow object containing the values in the requested order.
1070 uno::Reference
< sdbc::XRow
>
1071 TaskManager::getv( sal_Int32 CommandId
,
1072 const OUString
& aUnqPath
,
1073 const uno::Sequence
< beans::Property
>& properties
)
1075 uno::Sequence
< uno::Any
> seq( properties
.getLength() );
1078 getMaskFromProperties( n_Mask
,properties
);
1079 osl::FileStatus
aFileStatus( n_Mask
);
1081 osl::DirectoryItem aDirItem
;
1082 osl::FileBase::RC nError1
= osl::DirectoryItem::get( aUnqPath
,aDirItem
);
1083 if( nError1
!= osl::FileBase::E_None
)
1084 installError(CommandId
,
1085 TaskHandlerErr::OPEN_FILE_FOR_PAGING
, // BEAWARE, REUSED
1088 osl::FileBase::RC nError2
= aDirItem
.getFileStatus( aFileStatus
);
1089 if( nError1
== osl::FileBase::E_None
&&
1090 nError2
!= osl::FileBase::E_None
)
1091 installError(CommandId
,
1092 TaskHandlerErr::OPEN_FILE_FOR_PAGING
, // BEAWARE, REUSED
1096 std::unique_lock
aGuard( m_aMutex
);
1098 TaskManager::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
1099 commit( aGuard
, it
, aFileStatus
);
1101 PropertySet
& propset
= it
->second
.properties
;
1103 std::transform(properties
.begin(), properties
.end(), seq
.getArray(),
1104 [&propset
](const beans::Property
& rProp
) -> uno::Any
{
1105 MyProperty
readProp( rProp
.Name
);
1106 auto it1
= propset
.find( readProp
);
1107 if( it1
== propset
.end() )
1109 return it1
->getValue();
1113 return new XRow_impl( this,seq
);
1117 /********************************************************************************/
1119 /* transfer-commandos */
1121 /********************************************************************************/
1124 /********************************************************************************/
1126 /* move-implementation */
1128 /********************************************************************************/
1130 // Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
1134 TaskManager::move( sal_Int32 CommandId
,
1135 const OUString
& srcUnqPath
,
1136 const OUString
& dstUnqPathIn
,
1137 const sal_Int32 NameClash
)
1139 // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
1140 // srcUnqPath and dstUnqPathIn are equal
1141 if( srcUnqPath
== dstUnqPathIn
)
1144 osl::FileBase::RC nError
;
1145 OUString
dstUnqPath( dstUnqPathIn
);
1149 case NameClash::KEEP
:
1151 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1152 if( nError
!= osl::FileBase::E_None
&& nError
!= osl::FileBase::E_EXIST
)
1154 installError( CommandId
,
1155 TaskHandlerErr::KEEPERROR_FOR_MOVE
,
1161 case NameClash::OVERWRITE
:
1163 // stat to determine whether we have a symlink
1164 OUString
targetPath(dstUnqPath
);
1166 osl::FileStatus
aStatus(osl_FileStatus_Mask_Type
|osl_FileStatus_Mask_LinkTargetURL
);
1167 osl::DirectoryItem aItem
;
1168 (void)osl::DirectoryItem::get(dstUnqPath
,aItem
);
1169 (void)aItem
.getFileStatus(aStatus
);
1171 if( aStatus
.isValid(osl_FileStatus_Mask_Type
) &&
1172 aStatus
.isValid(osl_FileStatus_Mask_LinkTargetURL
) &&
1173 aStatus
.getFileType() == osl::FileStatus::Link
)
1174 targetPath
= aStatus
.getLinkTargetURL();
1176 // Will do nothing if file does not exist.
1177 osl::File::remove( targetPath
);
1179 nError
= osl_File_move( srcUnqPath
,targetPath
);
1180 if( nError
!= osl::FileBase::E_None
)
1182 installError( CommandId
,
1183 TaskHandlerErr::OVERWRITE_FOR_MOVE
,
1189 case NameClash::RENAME
:
1191 OUString newDstUnqPath
;
1192 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1193 if( nError
== osl::FileBase::E_EXIST
)
1195 // "invent" a new valid title.
1197 sal_Int32 nPos
= -1;
1198 sal_Int32 nLastDot
= dstUnqPath
.lastIndexOf( '.' );
1199 sal_Int32 nLastSlash
= dstUnqPath
.lastIndexOf( '/' );
1200 if( ( nLastSlash
< nLastDot
) // dot is part of last(!) path segment
1201 && ( nLastSlash
!= ( nLastDot
- 1 ) ) ) // file name does not start with a dot
1204 nPos
= dstUnqPath
.getLength();
1210 newDstUnqPath
= dstUnqPath
;
1212 OUString aPostfix
= "_" + OUString::number( ++nTry
);
1214 newDstUnqPath
= newDstUnqPath
.replaceAt( nPos
, 0, aPostfix
);
1216 nError
= osl_File_move( srcUnqPath
,newDstUnqPath
,true );
1218 while( ( nError
== osl::FileBase::E_EXIST
) && ( nTry
< 10000 ) );
1221 if( nError
== osl::FileBase::E_EXIST
)
1223 installError( CommandId
,
1224 TaskHandlerErr::RENAME_FOR_MOVE
);
1227 else if( nError
!= osl::FileBase::E_None
)
1229 installError( CommandId
,
1230 TaskHandlerErr::RENAMEMOVE_FOR_MOVE
,
1235 dstUnqPath
= newDstUnqPath
;
1239 case NameClash::ERROR
:
1241 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1242 if( nError
== osl::FileBase::E_EXIST
)
1244 installError( CommandId
,
1245 TaskHandlerErr::NAMECLASH_FOR_MOVE
);
1248 else if( nError
!= osl::FileBase::E_None
)
1250 installError( CommandId
,
1251 TaskHandlerErr::NAMECLASHMOVE_FOR_MOVE
,
1257 case NameClash::ASK
:
1260 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1261 if( nError
== osl::FileBase::E_EXIST
)
1263 installError( CommandId
,
1264 TaskHandlerErr::NAMECLASHSUPPORT_FOR_MOVE
,
1272 // Determine, whether we have moved a file or a folder
1273 osl::DirectoryItem aItem
;
1274 nError
= osl::DirectoryItem::get( dstUnqPath
,aItem
);
1275 if( nError
!= osl::FileBase::E_None
)
1277 installError( CommandId
,
1278 TaskHandlerErr::TRANSFER_BY_MOVE_SOURCE
,
1282 osl::FileStatus
aStatus( osl_FileStatus_Mask_Type
);
1283 nError
= aItem
.getFileStatus( aStatus
);
1284 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( osl_FileStatus_Mask_Type
) )
1286 installError( CommandId
,
1287 TaskHandlerErr::TRANSFER_BY_MOVE_SOURCESTAT
,
1291 bool isDocument
= ( aStatus
.getFileType() == osl::FileStatus::Regular
);
1294 copyPersistentSet( srcUnqPath
,dstUnqPath
,!isDocument
);
1296 OUString aDstParent
= getParentName( dstUnqPath
);
1297 OUString aSrcParent
= getParentName( srcUnqPath
);
1299 notifyInsert( getContentEventListeners( aDstParent
),dstUnqPath
);
1300 if( aDstParent
!= aSrcParent
)
1301 notifyContentRemoved( getContentEventListeners( aSrcParent
),srcUnqPath
);
1303 notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath
,dstUnqPath
,!isDocument
) );
1304 erasePersistentSet( srcUnqPath
,!isDocument
);
1308 /********************************************************************************/
1310 /* copy-implementation */
1312 /********************************************************************************/
1314 // Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
1320 TaskManager
& task
, sal_Int32 id
, OUString
const & fileUrl
,
1321 osl::DirectoryItem
* item
, osl::FileStatus::Type
* type
)
1323 assert(item
!= nullptr && type
!= nullptr);
1324 osl::FileBase::RC err
= osl::DirectoryItem::get(fileUrl
, *item
);
1325 if (err
!= osl::FileBase::E_None
) {
1326 task
.installError(id
, TaskHandlerErr::TRANSFER_BY_COPY_SOURCE
, err
);
1329 osl::FileStatus
stat(osl_FileStatus_Mask_Type
);
1330 err
= item
->getFileStatus(stat
);
1331 if (err
!= osl::FileBase::E_None
) {
1332 task
.installError(id
, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT
, err
);
1335 *type
= stat
.getFileType();
1343 sal_Int32 CommandId
,
1344 const OUString
& srcUnqPath
,
1345 const OUString
& dstUnqPathIn
,
1346 sal_Int32 NameClash
)
1348 osl::FileBase::RC nError
;
1349 OUString
dstUnqPath( dstUnqPathIn
);
1351 // Resolve symbolic links within the source path. If srcUnqPath denotes a
1352 // symbolic link (targeting either a file or a folder), the contents of the
1353 // target is copied (recursively, in the case of a folder). However, if
1354 // recursively copying the contents of a folder causes a symbolic link to be
1355 // copied, the symbolic link itself is copied.
1356 osl::DirectoryItem item
;
1357 osl::FileStatus::Type type
;
1358 if (!getType(*this, CommandId
, srcUnqPath
, &item
, &type
)) {
1361 OUString rslvdSrcUnqPath
;
1362 if (type
== osl::FileStatus::Link
) {
1363 osl::FileStatus
stat(osl_FileStatus_Mask_LinkTargetURL
);
1364 nError
= item
.getFileStatus(stat
);
1365 if (nError
!= osl::FileBase::E_None
) {
1367 CommandId
, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT
, nError
);
1370 rslvdSrcUnqPath
= stat
.getLinkTargetURL();
1371 if (!getType(*this, CommandId
, srcUnqPath
, &item
, &type
)) {
1375 rslvdSrcUnqPath
= srcUnqPath
;
1379 = type
!= osl::FileStatus::Directory
&& type
!= osl::FileStatus::Volume
;
1380 FileUrlType IsWhat
= isDocument
? FileUrlType::File
: FileUrlType::Folder
;
1384 case NameClash::KEEP
:
1386 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1387 if( nError
!= osl::FileBase::E_None
&& nError
!= osl::FileBase::E_EXIST
)
1389 installError( CommandId
,
1390 TaskHandlerErr::KEEPERROR_FOR_COPY
,
1396 case NameClash::OVERWRITE
:
1398 // remove (..., MustExist = sal_False).
1399 remove( CommandId
, dstUnqPath
, IsWhat
, false );
1402 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,false );
1403 if( nError
!= osl::FileBase::E_None
)
1405 installError( CommandId
,
1406 TaskHandlerErr::OVERWRITE_FOR_COPY
,
1412 case NameClash::RENAME
:
1414 OUString newDstUnqPath
= dstUnqPath
;
1415 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1417 if( nError
== osl::FileBase::E_EXIST
)
1419 // "invent" a new valid title.
1421 sal_Int32 nPos
= -1;
1422 sal_Int32 nLastDot
= dstUnqPath
.lastIndexOf( '.' );
1423 sal_Int32 nLastSlash
= dstUnqPath
.lastIndexOf( '/' );
1424 if ( ( nLastSlash
< nLastDot
) // dot is part of last(!) path segment
1425 && ( nLastSlash
!= ( nLastDot
- 1 ) ) ) // file name does not start with a dot
1428 nPos
= dstUnqPath
.getLength();
1434 newDstUnqPath
= dstUnqPath
;
1436 OUString aPostfix
= "_" + OUString::number( ++nTry
);
1438 newDstUnqPath
= newDstUnqPath
.replaceAt( nPos
, 0, aPostfix
);
1440 nError
= copy_recursive( rslvdSrcUnqPath
,newDstUnqPath
,IsWhat
,true );
1442 while( ( nError
== osl::FileBase::E_EXIST
) && ( nTry
< 10000 ) );
1445 if( nError
== osl::FileBase::E_EXIST
)
1447 installError( CommandId
,
1448 TaskHandlerErr::RENAME_FOR_COPY
);
1451 else if( nError
!= osl::FileBase::E_None
)
1453 installError( CommandId
,
1454 TaskHandlerErr::RENAMEMOVE_FOR_COPY
,
1459 dstUnqPath
= newDstUnqPath
;
1463 case NameClash::ERROR
:
1465 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1467 if( nError
== osl::FileBase::E_EXIST
)
1469 installError( CommandId
,
1470 TaskHandlerErr::NAMECLASH_FOR_COPY
);
1473 else if( nError
!= osl::FileBase::E_None
)
1475 installError( CommandId
,
1476 TaskHandlerErr::NAMECLASHMOVE_FOR_COPY
,
1482 case NameClash::ASK
:
1485 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1487 if( nError
== osl::FileBase::E_EXIST
)
1489 installError( CommandId
,
1490 TaskHandlerErr::NAMECLASHSUPPORT_FOR_COPY
,
1498 copyPersistentSet( srcUnqPath
,dstUnqPath
, !isDocument
);
1499 notifyInsert( getContentEventListeners( getParentName( dstUnqPath
) ),dstUnqPath
);
1503 /********************************************************************************/
1505 /* remove-implementation */
1507 /********************************************************************************/
1509 // Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
1510 // Return: success of operation
1514 TaskManager::remove( sal_Int32 CommandId
,
1515 const OUString
& aUnqPath
,
1519 sal_Int32 nMask
= osl_FileStatus_Mask_Type
| osl_FileStatus_Mask_FileURL
;
1521 osl::DirectoryItem aItem
;
1522 osl::FileStatus
aStatus( nMask
);
1523 osl::FileBase::RC nError
;
1525 if( IsWhat
== FileUrlType::Unknown
) // Determine whether we are removing a directory or a file
1527 nError
= osl::DirectoryItem::get( aUnqPath
, aItem
);
1528 if( nError
!= osl::FileBase::E_None
)
1532 installError( CommandId
,
1533 TaskHandlerErr::NOSUCHFILEORDIR_FOR_REMOVE
,
1536 return (!MustExist
);
1539 nError
= aItem
.getFileStatus( aStatus
);
1540 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( nMask
) )
1542 installError( CommandId
,
1543 TaskHandlerErr::VALIDFILESTATUS_FOR_REMOVE
,
1544 nError
!= osl::FileBase::E_None
? nError
: 0 );
1548 if( aStatus
.getFileType() == osl::FileStatus::Regular
||
1549 aStatus
.getFileType() == osl::FileStatus::Link
)
1550 IsWhat
= FileUrlType::File
;
1551 else if( aStatus
.getFileType() == osl::FileStatus::Directory
||
1552 aStatus
.getFileType() == osl::FileStatus::Volume
)
1553 IsWhat
= FileUrlType::Folder
;
1557 if( IsWhat
== FileUrlType::File
)
1559 nError
= osl::File::remove( aUnqPath
);
1560 if( nError
!= osl::FileBase::E_None
)
1564 installError( CommandId
,
1565 TaskHandlerErr::DELETEFILE_FOR_REMOVE
,
1568 return (!MustExist
);
1572 notifyContentDeleted( getContentDeletedEventListeners(aUnqPath
) );
1573 erasePersistentSet( aUnqPath
); // Removes from XPersistentPropertySet
1576 else if( IsWhat
== FileUrlType::Folder
)
1578 osl::Directory
aDirectory( aUnqPath
);
1580 nError
= aDirectory
.open();
1581 if( nError
!= osl::FileBase::E_None
)
1585 installError( CommandId
,
1586 TaskHandlerErr::OPENDIRECTORY_FOR_REMOVE
,
1589 return (!MustExist
);
1592 bool whileSuccess
= true;
1593 FileUrlType recurse
= FileUrlType::Unknown
;
1596 nError
= aDirectory
.getNextItem( aItem
);
1597 while( nError
== osl::FileBase::E_None
)
1599 nError
= aItem
.getFileStatus( aStatus
);
1600 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( nMask
) )
1602 installError( CommandId
,
1603 TaskHandlerErr::VALIDFILESTATUSWHILE_FOR_REMOVE
,
1604 nError
!= osl::FileBase::E_None
? nError
: 0 );
1605 whileSuccess
= false;
1609 if( aStatus
.getFileType() == osl::FileStatus::Regular
||
1610 aStatus
.getFileType() == osl::FileStatus::Link
)
1611 recurse
= FileUrlType::File
;
1612 else if( aStatus
.getFileType() == osl::FileStatus::Directory
||
1613 aStatus
.getFileType() == osl::FileStatus::Volume
)
1614 recurse
= FileUrlType::Folder
;
1616 name
= aStatus
.getFileURL();
1617 whileSuccess
= remove( CommandId
, name
, recurse
, MustExist
);
1621 nError
= aDirectory
.getNextItem( aItem
);
1626 if( ! whileSuccess
)
1627 return false; // error code is installed
1629 if( nError
!= osl::FileBase::E_NOENT
)
1631 installError( CommandId
,
1632 TaskHandlerErr::DIRECTORYEXHAUSTED_FOR_REMOVE
,
1637 nError
= osl::Directory::remove( aUnqPath
);
1638 if( nError
!= osl::FileBase::E_None
)
1642 installError( CommandId
,
1643 TaskHandlerErr::DELETEDIRECTORY_FOR_REMOVE
,
1646 return (!MustExist
);
1650 notifyContentDeleted( getContentDeletedEventListeners(aUnqPath
) );
1651 erasePersistentSet( aUnqPath
);
1654 else // Don't know what to remove
1656 installError( CommandId
,
1657 TaskHandlerErr::FILETYPE_FOR_REMOVE
);
1665 /********************************************************************************/
1667 /* mkdir-implementation */
1669 /********************************************************************************/
1671 // Creates new directory with given URL, recursively if necessary
1672 // Return:: success of operation
1676 TaskManager::mkdir( sal_Int32 CommandId
,
1677 const OUString
& rUnqPath
,
1682 // remove trailing slash
1683 if ( rUnqPath
.endsWith("/") )
1684 aUnqPath
= rUnqPath
.copy( 0, rUnqPath
.getLength() - 1 );
1686 aUnqPath
= rUnqPath
;
1688 osl::FileBase::RC nError
= osl::Directory::create( aUnqPath
);
1692 case osl::FileBase::E_EXIST
: // Directory cannot be overwritten
1696 installError( CommandId
,
1697 TaskHandlerErr::FOLDER_EXISTS_MKDIR
);
1703 case osl::FileBase::E_INVAL
:
1705 installError(CommandId
,
1706 TaskHandlerErr::INVALID_NAME_MKDIR
);
1709 case osl::FileBase::E_None
:
1711 OUString aPrtPath
= getParentName( aUnqPath
);
1712 notifyInsert( getContentEventListeners( aPrtPath
),aUnqPath
);
1719 TaskHandlerErr::CREATEDIRECTORY_MKDIR
);
1724 /********************************************************************************/
1726 /* mkfil-implementation */
1728 /********************************************************************************/
1730 // Creates new file with given URL.
1731 // The content of aInputStream becomes the content of the file
1732 // Return:: success of operation
1736 TaskManager::mkfil( sal_Int32 CommandId
,
1737 const OUString
& aUnqPath
,
1739 const uno::Reference
< io::XInputStream
>& aInputStream
)
1741 // return value unimportant
1742 bool bSuccess
= write( CommandId
,
1748 OUString aPrtPath
= getParentName( aUnqPath
);
1749 notifyInsert( getContentEventListeners( aPrtPath
),aUnqPath
);
1755 /********************************************************************************/
1757 /* write-implementation */
1759 /********************************************************************************/
1761 // writes to the file with given URL.
1762 // The content of aInputStream becomes the content of the file
1763 // Return:: success of operation
1767 TaskManager::write( sal_Int32 CommandId
,
1768 const OUString
& aUnqPath
,
1770 const uno::Reference
< io::XInputStream
>& aInputStream
)
1772 if( ! aInputStream
.is() )
1774 installError( CommandId
,
1775 TaskHandlerErr::INPUTSTREAM_FOR_WRITE
);
1779 // Create parent path, if necessary.
1780 if ( ! ensuredir( CommandId
,
1781 getParentName( aUnqPath
),
1782 TaskHandlerErr::ENSUREDIR_FOR_WRITE
) )
1785 osl::FileBase::RC err
;
1786 osl::File
aFile( aUnqPath
);
1790 err
= aFile
.open( osl_File_OpenFlag_Write
| osl_File_OpenFlag_Create
);
1792 if( err
!= osl::FileBase::E_None
)
1795 err
= aFile
.open( osl_File_OpenFlag_Write
);
1797 if( err
!= osl::FileBase::E_None
)
1799 installError( CommandId
,
1800 TaskHandlerErr::NO_OPEN_FILE_FOR_OVERWRITE
,
1805 // the existing file was just opened and should be overwritten now,
1806 // truncate it first
1808 err
= aFile
.setSize( 0 );
1809 if( err
!= osl::FileBase::E_None
)
1811 installError( CommandId
,
1812 TaskHandlerErr::FILESIZE_FOR_WRITE
,
1820 err
= aFile
.open( osl_File_OpenFlag_Read
| osl_File_OpenFlag_NoLock
);
1821 if( err
== osl::FileBase::E_None
) // The file exists and shall not be overwritten
1823 installError( CommandId
,
1824 TaskHandlerErr::NOREPLACE_FOR_WRITE
, // Now an exception
1831 // as a temporary solution the creation does not lock the file at all
1832 // in future it should be possible to create the file without lock explicitly
1833 err
= aFile
.open( osl_File_OpenFlag_Write
| osl_File_OpenFlag_Create
| osl_File_OpenFlag_NoLock
);
1835 if( err
!= osl::FileBase::E_None
)
1838 installError( CommandId
,
1839 TaskHandlerErr::NO_OPEN_FILE_FOR_WRITE
,
1845 bool bSuccess
= true;
1847 sal_uInt64 nWrittenBytes
;
1848 sal_Int32 nReadBytes
= 0, nRequestedBytes
= 32768 /*32k*/;
1849 uno::Sequence
< sal_Int8
> seq( nRequestedBytes
);
1855 nReadBytes
= aInputStream
->readBytes( seq
,
1858 catch( const io::NotConnectedException
& )
1860 installError( CommandId
,
1861 TaskHandlerErr::NOTCONNECTED_FOR_WRITE
);
1865 catch( const io::BufferSizeExceededException
& )
1867 installError( CommandId
,
1868 TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_WRITE
);
1872 catch( const io::IOException
& )
1874 installError( CommandId
,
1875 TaskHandlerErr::IOEXCEPTION_FOR_WRITE
);
1882 const sal_Int8
* p
= seq
.getConstArray();
1884 err
= aFile
.write( static_cast<void const *>(p
),
1885 sal_uInt64( nReadBytes
),
1888 if( err
!= osl::FileBase::E_None
)
1890 installError( CommandId
,
1891 TaskHandlerErr::FILEIOERROR_FOR_WRITE
,
1896 else if( nWrittenBytes
!= sal_uInt64( nReadBytes
) )
1898 installError( CommandId
,
1899 TaskHandlerErr::FILEIOERROR_FOR_NO_SPACE
);
1904 } while( nReadBytes
== nRequestedBytes
);
1906 err
= aFile
.close();
1907 if( err
!= osl::FileBase::E_None
)
1909 installError( CommandId
,
1910 TaskHandlerErr::FILEIOERROR_FOR_WRITE
,
1919 /*********************************************************************************/
1921 /* insertDefaultProperties-Implementation */
1923 /*********************************************************************************/
1926 void TaskManager::insertDefaultProperties( const OUString
& aUnqPath
)
1928 std::unique_lock
aGuard(m_aMutex
);
1929 insertDefaultProperties(aGuard
, aUnqPath
);
1932 void TaskManager::insertDefaultProperties( std::unique_lock
<std::mutex
>& /*rGuard*/, const OUString
& aUnqPath
)
1934 ContentMap::iterator it
=
1935 m_aContent
.emplace( aUnqPath
,UnqPathData() ).first
;
1939 MyProperty
ContentTProperty( ContentType
);
1941 PropertySet
& properties
= it
->second
.properties
;
1942 bool ContentNotDefau
= properties
.find( ContentTProperty
) != properties
.end();
1944 properties
.reserve(properties
.size() + m_aDefaultProperties
.size());
1945 for (auto const& defaultprop
: m_aDefaultProperties
)
1947 if( !ContentNotDefau
|| defaultprop
.getPropertyName() != ContentType
)
1948 properties
.insert( defaultprop
);
1953 /******************************************************************************/
1955 /* mapping of file urls */
1956 /* to uncpath and vice versa */
1958 /******************************************************************************/
1961 bool TaskManager::getUnqFromUrl( const OUString
& Url
, OUString
& Unq
)
1963 if ( Url
== "file:///" || Url
== "file://localhost/" || Url
== "file://127.0.0.1/" )
1969 bool err
= osl::FileBase::E_None
!= osl::FileBase::getSystemPathFromFileURL( Url
,Unq
);
1973 sal_Int32 l
= Unq
.getLength()-1;
1974 if( ! err
&& Unq
.endsWith("/") &&
1975 Unq
.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) != -1 )
1976 Unq
= Unq
.copy(0, l
);
1982 bool TaskManager::getUrlFromUnq( const OUString
& Unq
,OUString
& Url
)
1984 bool err
= osl::FileBase::E_None
!= osl::FileBase::getSystemPathFromFileURL( Unq
,Url
);
1992 // Helper function for public copy
1995 TaskManager::copy_recursive( const OUString
& srcUnqPath
,
1996 const OUString
& dstUnqPath
,
1997 FileUrlType TypeToCopy
,
1998 bool testExistBeforeCopy
)
2000 osl::FileBase::RC err
= osl::FileBase::E_None
;
2002 if( TypeToCopy
== FileUrlType::File
) // Document
2004 err
= osl_File_copy( srcUnqPath
,dstUnqPath
,testExistBeforeCopy
);
2006 else if( TypeToCopy
== FileUrlType::Folder
)
2008 osl::Directory
aDir( srcUnqPath
);
2011 err
= osl::Directory::create( dstUnqPath
);
2012 osl::FileBase::RC next
= err
;
2013 if( err
== osl::FileBase::E_None
)
2015 sal_Int32
const n_Mask
= osl_FileStatus_Mask_FileURL
| osl_FileStatus_Mask_FileName
| osl_FileStatus_Mask_Type
;
2017 osl::DirectoryItem aDirItem
;
2019 while( err
== osl::FileBase::E_None
)
2021 next
= aDir
.getNextItem( aDirItem
);
2022 if (next
!= osl::FileBase::E_None
)
2025 osl::FileStatus
aFileStatus( n_Mask
);
2026 aDirItem
.getFileStatus( aFileStatus
);
2027 if( aFileStatus
.isValid( osl_FileStatus_Mask_Type
) )
2028 IsDoc
= aFileStatus
.getFileType() == osl::FileStatus::Regular
;
2030 // Getting the information for the next recursive copy
2031 FileUrlType newTypeToCopy
= IsDoc
? FileUrlType::File
: FileUrlType::Folder
;
2033 OUString newSrcUnqPath
;
2034 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileURL
) )
2035 newSrcUnqPath
= aFileStatus
.getFileURL();
2037 OUString newDstUnqPath
= dstUnqPath
;
2039 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileName
) )
2040 tit
= rtl::Uri::encode( aFileStatus
.getFileName(),
2041 rtl_UriCharClassPchar
,
2042 rtl_UriEncodeIgnoreEscapes
,
2043 RTL_TEXTENCODING_UTF8
);
2045 if( !newDstUnqPath
.endsWith( "/" ) )
2046 newDstUnqPath
+= "/";
2048 newDstUnqPath
+= tit
;
2050 if ( newSrcUnqPath
!= dstUnqPath
)
2051 err
= copy_recursive( newSrcUnqPath
,newDstUnqPath
,newTypeToCopy
,false );
2054 if( err
== osl::FileBase::E_None
&& next
!= osl::FileBase::E_NOENT
)
2064 // Helper function for mkfil,mkdir and write
2065 // Creates whole path
2066 // returns success of the operation
2069 bool TaskManager::ensuredir( sal_Int32 CommandId
,
2070 const OUString
& rUnqPath
,
2071 TaskHandlerErr errorCode
)
2075 if ( rUnqPath
.isEmpty() )
2078 if ( rUnqPath
.endsWith("/") )
2079 aPath
= rUnqPath
.copy( 0, rUnqPath
.getLength() - 1 );
2083 #if HAVE_FEATURE_MACOSX_SANDBOX
2085 // Avoid annoying sandbox messages in the system.log from the
2086 // below aDirectory.open(), which ends up calling opendir().
2087 // Surely it is easier to just call stat()? Calling stat() on an
2088 // arbitrary (?) directory does not seem to cause any sandbox
2089 // violation, while opendir() does. (Sorry I could not be bothered
2090 // to use some complex cross-platform abstraction over stat() here
2091 // in this macOS specific code block.)
2095 if( osl::FileBase::getSystemPathFromFileURL( aPath
, aDirName
) == osl::FileBase::E_None
&&
2096 stat(OUStringToOString( aDirName
, RTL_TEXTENCODING_UTF8
).getStr(), &s
) == 0 &&
2097 S_ISDIR( s
.st_mode
) )
2101 // HACK: create directory on a mount point with nobrowse option
2102 // returns ENOSYS in any case !!
2103 osl::Directory
aDirectory( aPath
);
2104 osl::FileBase::RC nError
= aDirectory
.open();
2107 if( nError
== osl::File::E_None
)
2110 nError
= osl::Directory::create( aPath
);
2112 if( nError
== osl::File::E_None
)
2113 notifyInsert( getContentEventListeners( getParentName( aPath
) ),aPath
);
2115 bool bSuccess
= ( nError
== osl::File::E_None
|| nError
== osl::FileBase::E_EXIST
);
2119 OUString aParentDir
= getParentName( aPath
);
2121 if ( aParentDir
!= aPath
)
2122 { // Create first the parent directory
2123 bSuccess
= ensuredir( CommandId
,
2124 getParentName( aPath
),
2127 // After parent directory structure exists try it one's more
2130 { // Parent directory exists, retry creation of directory
2131 nError
= osl::Directory::create( aPath
);
2133 if( nError
== osl::File::E_None
)
2134 notifyInsert( getContentEventListeners( getParentName( aPath
) ),aPath
);
2136 bSuccess
=( nError
== osl::File::E_None
|| nError
== osl::FileBase::E_EXIST
);
2142 installError( CommandId
,
2150 // Given a sequence of properties seq, this method determines the mask
2151 // used to instantiate an osl::FileStatus, so that a call to
2152 // osl::DirectoryItem::getFileStatus fills the required fields.
2156 TaskManager::getMaskFromProperties(
2158 const uno::Sequence
< beans::Property
>& seq
)
2161 for(const auto& rProp
: seq
) {
2162 if(rProp
.Name
== Title
)
2163 n_Mask
|= osl_FileStatus_Mask_FileName
;
2164 else if(rProp
.Name
== CasePreservingURL
)
2165 n_Mask
|= osl_FileStatus_Mask_FileURL
;
2166 else if(rProp
.Name
== IsDocument
||
2167 rProp
.Name
== IsFolder
||
2168 rProp
.Name
== IsVolume
||
2169 rProp
.Name
== IsRemoveable
||
2170 rProp
.Name
== IsRemote
||
2171 rProp
.Name
== IsCompactDisc
||
2172 rProp
.Name
== IsFloppy
||
2173 rProp
.Name
== ContentType
)
2174 n_Mask
|= (osl_FileStatus_Mask_Type
| osl_FileStatus_Mask_LinkTargetURL
);
2175 else if(rProp
.Name
== Size
)
2176 n_Mask
|= (osl_FileStatus_Mask_FileSize
|
2177 osl_FileStatus_Mask_Type
|
2178 osl_FileStatus_Mask_LinkTargetURL
);
2179 else if(rProp
.Name
== IsHidden
||
2180 rProp
.Name
== IsReadOnly
)
2181 n_Mask
|= osl_FileStatus_Mask_Attributes
;
2182 else if(rProp
.Name
== DateModified
)
2183 n_Mask
|= osl_FileStatus_Mask_ModifyTime
;
2188 /*********************************************************************************/
2190 /* load-Implementation */
2192 /*********************************************************************************/
2194 // Load the properties from configuration, if create == true create them.
2195 // The Properties are stored under the url belonging to it->first.
2199 TaskManager::load( const ContentMap::iterator
& it
, bool create
)
2201 if( ( it
->second
.xS
.is() && it
->second
.xC
.is() && it
->second
.xA
.is() )
2202 || !m_xFileRegistry
.is() )
2206 uno::Reference
< ucb::XPersistentPropertySet
> xS
= m_xFileRegistry
->openPropertySet( it
->first
,create
);
2210 it
->second
.xC
.set(xS
, uno::UNO_QUERY
);
2211 it
->second
.xA
.set(xS
, uno::UNO_QUERY
);
2213 // Now put in all values in the storage in the local hash;
2215 PropertySet
& properties
= it
->second
.properties
;
2216 const uno::Sequence
< beans::Property
> seq
= xS
->getPropertySetInfo()->getProperties();
2218 for( const auto& rProp
: seq
)
2220 MyProperty
readProp( false,
2224 xS
->getPropertyValue( rProp
.Name
),
2225 beans::PropertyState_DIRECT_VALUE
,
2227 properties
.insert( readProp
);
2232 // Catastrophic error
2237 /*********************************************************************************/
2239 /* commit-Implementation */
2241 /*********************************************************************************/
2242 // Commit inserts the determined properties in the filestatus object into
2243 // the internal map, so that is possible to determine on a subsequent
2244 // setting of file properties which properties have changed without filestat
2248 TaskManager::commit( std::unique_lock
<std::mutex
>& rGuard
,
2249 const TaskManager::ContentMap::iterator
& it
,
2250 const osl::FileStatus
& aFileStatus
)
2252 TaskManager::PropertySet::const_iterator it1
;
2254 if( it
->second
.properties
.empty() )
2256 OUString aPath
= it
->first
;
2257 insertDefaultProperties( rGuard
, aPath
);
2260 PropertySet
& properties
= it
->second
.properties
;
2262 it1
= properties
.find( MyProperty( Title
) );
2263 if( it1
!= properties
.end() )
2265 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileName
) )
2267 it1
->setValue( uno::Any(aFileStatus
.getFileName()) );
2271 it1
= properties
.find( MyProperty( CasePreservingURL
) );
2272 if( it1
!= properties
.end() )
2274 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileURL
) )
2276 it1
->setValue( uno::Any(aFileStatus
.getFileURL()) );
2283 sal_Int64 dirSize
= 0;
2285 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileSize
) )
2286 dirSize
= aFileStatus
.getFileSize();
2288 if( aFileStatus
.isValid( osl_FileStatus_Mask_Type
) )
2290 bool isFile
,isVolume
;
2291 if( osl::FileStatus::Link
== aFileStatus
.getFileType() &&
2292 aFileStatus
.isValid( osl_FileStatus_Mask_LinkTargetURL
) )
2294 osl::DirectoryItem aDirItem
;
2295 osl::FileStatus
aFileStatus2( osl_FileStatus_Mask_Type
);
2296 if( osl::FileBase::E_None
== osl::DirectoryItem::get( aFileStatus
.getLinkTargetURL(),aDirItem
) &&
2297 osl::FileBase::E_None
== aDirItem
.getFileStatus( aFileStatus2
) &&
2298 aFileStatus2
.isValid( osl_FileStatus_Mask_Type
) )
2300 isVolume
= osl::FileStatus::Volume
== aFileStatus2
.getFileType();
2302 osl::FileStatus::Volume
== aFileStatus2
.getFileType() ||
2303 osl::FileStatus::Directory
== aFileStatus2
.getFileType();
2305 osl::FileStatus::Regular
== aFileStatus2
.getFileType();
2307 if( aFileStatus2
.isValid( osl_FileStatus_Mask_FileSize
) )
2308 dirSize
= aFileStatus2
.getFileSize();
2312 // extremely ugly, but otherwise default construction
2313 // of aDirItem and aFileStatus2
2314 // before the preceding if
2315 isVolume
= osl::FileStatus::Volume
== aFileStatus
.getFileType();
2317 osl::FileStatus::Volume
== aFileStatus
.getFileType() ||
2318 osl::FileStatus::Directory
== aFileStatus
.getFileType();
2320 osl::FileStatus::Regular
== aFileStatus
.getFileType();
2325 isVolume
= osl::FileStatus::Volume
== aFileStatus
.getFileType();
2327 osl::FileStatus::Volume
== aFileStatus
.getFileType() ||
2328 osl::FileStatus::Directory
== aFileStatus
.getFileType();
2330 osl::FileStatus::Regular
== aFileStatus
.getFileType();
2333 it1
= properties
.find( MyProperty( IsVolume
) );
2334 if( it1
!= properties
.end() )
2335 it1
->setValue( uno::Any( isVolume
) );
2337 it1
= properties
.find( MyProperty( IsFolder
) );
2338 if( it1
!= properties
.end() )
2339 it1
->setValue( uno::Any( isDirectory
) );
2341 it1
= properties
.find( MyProperty( IsDocument
) );
2342 if( it1
!= properties
.end() )
2343 it1
->setValue( uno::Any( isFile
) );
2345 osl::VolumeInfo
aVolumeInfo( osl_VolumeInfo_Mask_Attributes
);
2347 osl::FileBase::E_None
== osl::Directory::getVolumeInfo( it
->first
,aVolumeInfo
) &&
2348 aVolumeInfo
.isValid( osl_VolumeInfo_Mask_Attributes
) )
2350 // Retrieve the flags;
2351 bool isRemote
= aVolumeInfo
.getRemoteFlag();
2352 bool isRemoveable
= aVolumeInfo
.getRemoveableFlag();
2353 bool isCompactDisc
= aVolumeInfo
.getCompactDiscFlag();
2354 bool isFloppy
= aVolumeInfo
.getFloppyDiskFlag();
2356 it1
= properties
.find( MyProperty( IsRemote
) );
2357 if( it1
!= properties
.end() )
2358 it1
->setValue( uno::Any( isRemote
) );
2360 it1
= properties
.find( MyProperty( IsRemoveable
) );
2361 if( it1
!= properties
.end() )
2362 it1
->setValue( uno::Any( isRemoveable
) );
2364 it1
= properties
.find( MyProperty( IsCompactDisc
) );
2365 if( it1
!= properties
.end() )
2366 it1
->setValue( uno::Any( isCompactDisc
) );
2368 it1
= properties
.find( MyProperty( IsFloppy
) );
2369 if( it1
!= properties
.end() )
2370 it1
->setValue( uno::Any( isFloppy
) );
2374 uno::Any
aAny(false);
2375 it1
= properties
.find( MyProperty( IsRemote
) );
2376 if( it1
!= properties
.end() )
2377 it1
->setValue( aAny
);
2379 it1
= properties
.find( MyProperty( IsRemoveable
) );
2380 if( it1
!= properties
.end() )
2381 it1
->setValue( aAny
);
2383 it1
= properties
.find( MyProperty( IsCompactDisc
) );
2384 if( it1
!= properties
.end() )
2385 it1
->setValue( aAny
);
2387 it1
= properties
.find( MyProperty( IsFloppy
) );
2388 if( it1
!= properties
.end() )
2389 it1
->setValue( aAny
);
2394 isDirectory
= false;
2397 it1
= properties
.find( MyProperty( Size
) );
2398 if( it1
!= properties
.end() )
2399 it1
->setValue( uno::Any( dirSize
) );
2401 it1
= properties
.find( MyProperty( IsReadOnly
) );
2402 if( it1
!= properties
.end() )
2404 if( aFileStatus
.isValid( osl_FileStatus_Mask_Attributes
) )
2406 sal_uInt64 Attr
= aFileStatus
.getAttributes();
2407 bool readonly
= ( Attr
& osl_File_Attribute_ReadOnly
) != 0;
2408 it1
->setValue( uno::Any( readonly
) );
2412 it1
= properties
.find( MyProperty( IsHidden
) );
2413 if( it1
!= properties
.end() )
2415 if( aFileStatus
.isValid( osl_FileStatus_Mask_Attributes
) )
2417 sal_uInt64 Attr
= aFileStatus
.getAttributes();
2418 bool ishidden
= ( Attr
& osl_File_Attribute_Hidden
) != 0;
2419 it1
->setValue( uno::Any( ishidden
) );
2423 it1
= properties
.find( MyProperty( DateModified
) );
2424 if( it1
!= properties
.end() )
2426 if( aFileStatus
.isValid( osl_FileStatus_Mask_ModifyTime
) )
2428 TimeValue temp
= aFileStatus
.getModifyTime();
2430 // Convert system time to local time (for EA)
2431 TimeValue myLocalTime
;
2432 if (!osl_getLocalTimeFromSystemTime( &temp
, &myLocalTime
))
2436 "cannot convert (" << temp
.Seconds
<< ", " << temp
.Nanosec
2437 << ") to local time");
2441 oslDateTime myDateTime
;
2442 osl_getDateTimeFromTimeValue( &myLocalTime
, &myDateTime
);
2443 util::DateTime aDateTime
;
2445 aDateTime
.NanoSeconds
= myDateTime
.NanoSeconds
;
2446 aDateTime
.Seconds
= myDateTime
.Seconds
;
2447 aDateTime
.Minutes
= myDateTime
.Minutes
;
2448 aDateTime
.Hours
= myDateTime
.Hours
;
2449 aDateTime
.Day
= myDateTime
.Day
;
2450 aDateTime
.Month
= myDateTime
.Month
;
2451 aDateTime
.Year
= myDateTime
.Year
;
2452 it1
->setValue( uno::Any( aDateTime
) );
2456 it1
= properties
.find( MyProperty( CreatableContentsInfo
) );
2457 if( it1
!= properties
.end() )
2458 it1
->setValue( uno::Any(
2459 isDirectory
|| !aFileStatus
.isValid( osl_FileStatus_Mask_Type
)
2460 ? queryCreatableContentsInfo()
2461 : uno::Sequence
< ucb::ContentInfo
>() ) );
2465 // Special optimized method for getting the properties of a
2466 // directoryitem, which is returned by osl::DirectoryItem::getNextItem()
2471 const uno::Sequence
< beans::Property
>& properties
,
2472 osl::DirectoryItem
& aDirItem
,
2475 uno::Reference
< sdbc::XRow
> & row
)
2477 uno::Sequence
< uno::Any
> seq( properties
.getLength() );
2480 getMaskFromProperties( n_Mask
,properties
);
2482 // Always retrieve the type and the target URL because item might be a link
2483 osl::FileStatus
aFileStatus( n_Mask
|
2484 osl_FileStatus_Mask_FileURL
|
2485 osl_FileStatus_Mask_Type
|
2486 osl_FileStatus_Mask_LinkTargetURL
);
2488 osl::FileBase::RC aRes
= aDirItem
.getFileStatus( aFileStatus
);
2489 if ( aRes
!= osl::FileBase::E_None
)
2493 "osl::DirectoryItem::getFileStatus failed with " << +aRes
);
2497 aUnqPath
= aFileStatus
.getFileURL();
2499 // If the directory item type is a link retrieve the type of the target
2501 if ( aFileStatus
.getFileType() == osl::FileStatus::Link
)
2505 osl::DirectoryItem aTargetItem
;
2506 (void)osl::DirectoryItem::get( aFileStatus
.getLinkTargetURL(), aTargetItem
);
2507 if ( aTargetItem
.is() )
2509 osl::FileStatus
aTargetStatus( osl_FileStatus_Mask_Type
);
2511 if ( osl::FileBase::E_None
== aTargetItem
.getFileStatus( aTargetStatus
) )
2513 aTargetStatus
.getFileType() == osl::FileStatus::Regular
;
2517 aIsRegular
= aFileStatus
.getFileType() == osl::FileStatus::Regular
;
2520 std::unique_lock
aGuard( m_aMutex
);
2522 insertDefaultProperties( aGuard
, aUnqPath
);
2524 TaskManager::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
2525 commit( aGuard
, it
, aFileStatus
);
2527 PropertySet
& propset
= it
->second
.properties
;
2529 std::transform(properties
.begin(), properties
.end(), seq
.getArray(),
2530 [&propset
](const beans::Property
& rProp
) -> uno::Any
{
2531 MyProperty
readProp( rProp
.Name
);
2532 auto it1
= propset
.find( readProp
);
2533 if( it1
== propset
.end() )
2535 return it1
->getValue();
2539 row
= new XRow_impl( this,seq
);
2547 std::vector
< ContentEventNotifier
>
2548 TaskManager::getContentEventListeners( const OUString
& aName
)
2550 std::vector
< ContentEventNotifier
> listeners
;
2552 std::unique_lock
aGuard( m_aMutex
);
2553 TaskManager::ContentMap::iterator it
= m_aContent
.find( aName
);
2554 if( it
!= m_aContent
.end() && !it
->second
.notifier
.empty() )
2556 std::vector
<Notifier
*>& listOfNotifiers
= it
->second
.notifier
;
2557 for (auto const& pointer
: listOfNotifiers
)
2559 std::optional
<ContentEventNotifier
> notifier
= pointer
->cCEL();
2561 listeners
.push_back( std::move(*notifier
) );
2569 std::vector
< ContentEventNotifier
>
2570 TaskManager::getContentDeletedEventListeners( const OUString
& aName
)
2572 std::vector
< ContentEventNotifier
> listeners
;
2574 std::unique_lock
aGuard( m_aMutex
);
2575 TaskManager::ContentMap::iterator it
= m_aContent
.find( aName
);
2576 if( it
!= m_aContent
.end() && !it
->second
.notifier
.empty() )
2578 std::vector
<Notifier
*>& listOfNotifiers
= it
->second
.notifier
;
2579 for (auto const& pointer
: listOfNotifiers
)
2581 std::optional
<ContentEventNotifier
> notifier
= pointer
->cDEL();
2583 listeners
.push_back( std::move(*notifier
) );
2590 void TaskManager::notifyInsert(const std::vector
<ContentEventNotifier
>& listeners
,
2591 const OUString
& aChildName
)
2593 for (const auto & l
: listeners
)
2595 l
.notifyChildInserted( aChildName
);
2599 void TaskManager::notifyContentDeleted(
2600 const std::vector
<ContentEventNotifier
>& listeners
)
2602 for( auto const & l
: listeners
)
2608 void TaskManager::notifyContentRemoved(
2609 const std::vector
<ContentEventNotifier
>& listeners
, const OUString
& aChildName
)
2611 for( auto const & l
: listeners
)
2613 l
.notifyRemoved( aChildName
);
2618 std::vector
< PropertySetInfoChangeNotifier
>
2619 TaskManager::getPropertySetListeners( const OUString
& aName
)
2621 std::vector
< PropertySetInfoChangeNotifier
> listeners
;
2623 std::unique_lock
aGuard( m_aMutex
);
2624 TaskManager::ContentMap::iterator it
= m_aContent
.find( aName
);
2625 if( it
!= m_aContent
.end() && !it
->second
.notifier
.empty() )
2627 std::vector
<Notifier
*>& listOfNotifiers
= it
->second
.notifier
;
2628 for (auto const& pointer
: listOfNotifiers
)
2630 std::optional
<PropertySetInfoChangeNotifier
> notifier
= pointer
->cPSL();
2632 listeners
.push_back( std::move(*notifier
) );
2639 void TaskManager::notifyPropertyAdded(
2640 const std::vector
<PropertySetInfoChangeNotifier
>& listeners
,
2641 const OUString
& aPropertyName
)
2643 for( auto const & l
: listeners
)
2645 l
.notifyPropertyAdded( aPropertyName
);
2649 void TaskManager::notifyPropertyRemoved(
2650 const std::vector
<PropertySetInfoChangeNotifier
>& listeners
,
2651 const OUString
& aPropertyName
)
2653 for( auto const & l
: listeners
)
2655 l
.notifyPropertyRemoved( aPropertyName
);
2660 std::vector
< ContentEventNotifier
>
2661 TaskManager::getContentExchangedEventListeners( const OUString
& aOldPrefix
,
2662 const OUString
& aNewPrefix
,
2665 std::vector
< ContentEventNotifier
> aVector
;
2670 std::vector
< OUString
> oldChildList
;
2673 std::unique_lock
aGuard( m_aMutex
);
2675 if( ! withChildren
)
2677 aOldName
= aOldPrefix
;
2678 aNewName
= aNewPrefix
;
2683 for (auto const& content
: m_aContent
)
2685 if( isChild( aOldPrefix
, content
.first
) )
2687 oldChildList
.push_back( content
.first
);
2690 count
= oldChildList
.size();
2694 for( sal_Int32 j
= 0; j
< count
; ++j
)
2698 aOldName
= oldChildList
[j
];
2699 aNewName
= newName( aNewPrefix
,aOldPrefix
,aOldName
);
2702 TaskManager::ContentMap::iterator itold
= m_aContent
.find( aOldName
);
2703 if( itold
!= m_aContent
.end() )
2705 TaskManager::ContentMap::iterator itnew
= m_aContent
.emplace(
2706 aNewName
,UnqPathData() ).first
;
2708 // copy Ownership also
2709 itnew
->second
.properties
= std::move(itold
->second
.properties
);
2711 // copy existing list
2712 std::vector
< Notifier
* > copyList
;
2713 std::swap(copyList
, itnew
->second
.notifier
);
2714 itnew
->second
.notifier
= std::move(itold
->second
.notifier
);
2716 m_aContent
.erase( itold
);
2718 if (itnew
!= m_aContent
.end())
2720 if (!itnew
->second
.notifier
.empty())
2722 std::vector
<Notifier
*>& listOfNotifiers
= itnew
->second
.notifier
;
2723 for (auto const& pointer
: listOfNotifiers
)
2725 std::optional
<ContentEventNotifier
> notifier
= pointer
->cEXC( aNewName
);
2727 aVector
.push_back( std::move(*notifier
) );
2731 // Merge with preexisting notifiers
2732 // However, these may be in status BaseContent::Deleted
2733 itnew
->second
.notifier
.insert(itnew
->second
.notifier
.end(),
2734 copyList
.begin(), copyList
.end() );
2743 void TaskManager::notifyContentExchanged(
2744 const std::vector
<ContentEventNotifier
>& listeners_vec
)
2746 for( auto & l
: listeners_vec
)
2748 l
.notifyExchanged();
2753 std::vector
< PropertyChangeNotifier
>
2754 TaskManager::getPropertyChangeNotifier( const OUString
& aName
)
2756 std::vector
< PropertyChangeNotifier
> listeners
;
2758 std::unique_lock
aGuard( m_aMutex
);
2759 TaskManager::ContentMap::iterator it
= m_aContent
.find( aName
);
2760 if( it
!= m_aContent
.end() && !it
->second
.notifier
.empty() )
2762 std::vector
<Notifier
*>& listOfNotifiers
= it
->second
.notifier
;
2763 for (auto const& pointer
: listOfNotifiers
)
2765 std::optional
<PropertyChangeNotifier
> notifier
= pointer
->cPCL();
2767 listeners
.push_back( std::move(*notifier
) );
2774 void TaskManager::notifyPropertyChanges(
2775 const std::vector
<PropertyChangeNotifier
>& listeners
,
2776 const uno::Sequence
<beans::PropertyChangeEvent
>& seqChanged
)
2778 for( auto const & l
: listeners
)
2780 l
.notifyPropertyChanged( seqChanged
);
2785 /********************************************************************************/
2786 /* remove persistent propertyset */
2787 /********************************************************************************/
2790 TaskManager::erasePersistentSetWithoutChildren( const OUString
& aUnqPath
)
2793 // Release possible references
2794 std::unique_lock
aGuard( m_aMutex
);
2795 ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
2796 if( it
!= m_aContent
.end() )
2798 it
->second
.xS
= nullptr;
2799 it
->second
.xC
= nullptr;
2800 it
->second
.xA
= nullptr;
2802 it
->second
.properties
.clear();
2806 m_xFileRegistry
->removePropertySet( aUnqPath
);
2810 TaskManager::erasePersistentSet( const OUString
& aUnqPath
,
2813 if( ! m_xFileRegistry
.is() )
2815 OSL_ASSERT( m_xFileRegistry
.is() );
2819 if( ! withChildren
)
2821 erasePersistentSetWithoutChildren(aUnqPath
);
2825 uno::Reference
< container::XNameAccess
> xName( m_xFileRegistry
,uno::UNO_QUERY
);
2826 const uno::Sequence
< OUString
> seqNames
= xName
->getElementNames();
2828 OUString old_Name
= aUnqPath
;
2830 for( const auto& rName
: seqNames
)
2832 if( ! ( isChild( old_Name
,rName
) ) )
2837 erasePersistentSetWithoutChildren(old_Name
);
2842 /********************************************************************************/
2843 /* copy persistent propertyset */
2844 /* from srcUnqPath to dstUnqPath */
2845 /********************************************************************************/
2848 TaskManager::copyPersistentSetWithoutChildren( const OUString
& srcUnqPath
,
2849 const OUString
& dstUnqPath
)
2851 uno::Reference
< XPersistentPropertySet
> x_src
=
2852 m_xFileRegistry
->openPropertySet( srcUnqPath
,false );
2853 m_xFileRegistry
->removePropertySet( dstUnqPath
);
2858 const uno::Sequence
< beans::Property
> seqProperty
=
2859 x_src
->getPropertySetInfo()->getProperties();
2861 if( ! seqProperty
.hasElements() )
2864 uno::Reference
< XPersistentPropertySet
>
2865 x_dstS
= m_xFileRegistry
->openPropertySet( dstUnqPath
,true );
2866 uno::Reference
< beans::XPropertyContainer
>
2867 x_dstC( x_dstS
,uno::UNO_QUERY
);
2869 for( const auto& rProperty
: seqProperty
)
2871 x_dstC
->addProperty( rProperty
.Name
,
2872 rProperty
.Attributes
,
2873 x_src
->getPropertyValue( rProperty
.Name
) );
2878 TaskManager::copyPersistentSet( const OUString
& srcUnqPath
,
2879 const OUString
& dstUnqPath
,
2882 if( ! m_xFileRegistry
.is() )
2884 OSL_ASSERT( m_xFileRegistry
.is() );
2888 if( ! withChildren
)
2890 copyPersistentSetWithoutChildren(srcUnqPath
, dstUnqPath
);
2894 uno::Reference
< container::XNameAccess
> xName( m_xFileRegistry
,uno::UNO_QUERY
);
2895 const uno::Sequence
< OUString
> seqNames
= xName
->getElementNames();
2899 for( const auto& rName
: seqNames
)
2901 if( ! ( isChild( srcUnqPath
,rName
) ) )
2904 new_Name
= newName( dstUnqPath
,srcUnqPath
,rName
);
2906 copyPersistentSetWithoutChildren(rName
, new_Name
);
2910 uno::Sequence
< ucb::ContentInfo
> TaskManager::queryCreatableContentsInfo()
2914 uno::Sequence
< beans::Property
> props
2916 { u
"Title"_ustr
, -1, cppu::UnoType
<OUString
>::get(), beans::PropertyAttribute::MAYBEVOID
| beans::PropertyAttribute::BOUND
}
2920 { FileContentType
, ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
| ucb::ContentInfoAttribute::KIND_DOCUMENT
, props
},
2921 { FolderContentType
, ucb::ContentInfoAttribute::KIND_FOLDER
, props
}
2925 /*******************************************************************************/
2927 /* some miscellaneous static functions */
2929 /*******************************************************************************/
2932 TaskManager::getScheme( OUString
& Scheme
)
2937 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */