LibreOffice Module ucb (master) 1
filtask.cxx
Go to the documentation of this file.
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 <config_features.h>
21
22#include <sal/config.h>
23#include <sal/log.hxx>
24
25#if HAVE_FEATURE_MACOSX_SANDBOX
26#include <sys/stat.h>
27#endif
28
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>
48#include <rtl/ref.hxx>
49#include <rtl/uri.hxx>
50
51#include "filtask.hxx"
52#include "filcmd.hxx"
53#include "filglob.hxx"
54#include "filinpstr.hxx"
55#include "filprp.hxx"
56#include "filrset.hxx"
57#include "filstr.hxx"
58#include "prov.hxx"
59
60/******************************************************************************/
61/* */
62/* TaskHandling */
63/* */
64/******************************************************************************/
65
66
67using namespace fileaccess;
68using namespace com::sun::star;
69using namespace com::sun::star::uno;
70using namespace com::sun::star::ucb;
71
72#if OSL_DEBUG_LEVEL > 0
73#define THROW_WHERE SAL_WHERE
74#else
75#define THROW_WHERE ""
76#endif
77
78TaskManager::UnqPathData::UnqPathData() = default;
79
80TaskManager::UnqPathData::UnqPathData(TaskManager::UnqPathData&&) = default;
81
82
83TaskManager::UnqPathData::~UnqPathData()
84{
85}
86
87TaskManager::MyProperty::MyProperty( const OUString& thePropertyName )
88 : PropertyName( thePropertyName )
89 , Handle(-1)
90 , isNative(false)
91 , State(beans::PropertyState_AMBIGUOUS_VALUE)
92 , Attributes(0)
93{
94 // empty
95}
96
98 const OUString& thePropertyName,
99 sal_Int32 theHandle,
100 const css::uno::Type& theTyp,
101 const css::uno::Any& theValue,
102 const css::beans::PropertyState& theState,
103 sal_Int16 theAttributes )
104 : PropertyName( thePropertyName ),
105 Handle( theHandle ),
106 isNative( theisNative ),
107 Typ( theTyp ),
108 Value( theValue ),
109 State( theState ),
110 Attributes( theAttributes )
111{
112 // empty
113}
114
115#include "filinl.hxx"
116
117 // Default properties
118
119constexpr OUStringLiteral Title( u"Title" );
120constexpr OUStringLiteral CasePreservingURL( u"CasePreservingURL" );
121constexpr OUStringLiteral IsDocument( u"IsDocument" );
122constexpr OUStringLiteral IsFolder( u"IsFolder" );
123constexpr OUStringLiteral DateModified( u"DateModified" );
124constexpr OUStringLiteral Size( u"Size" );
125constexpr OUStringLiteral IsVolume( u"IsVolume" );
126constexpr OUStringLiteral IsRemoveable( u"IsRemoveable" );
127constexpr OUStringLiteral IsRemote( u"IsRemote" );
128constexpr OUStringLiteral IsCompactDisc( u"IsCompactDisc" );
129constexpr OUStringLiteral IsFloppy( u"IsFloppy" );
130constexpr OUStringLiteral IsHidden( u"IsHidden" );
131constexpr OUStringLiteral ContentType( u"ContentType" );
132constexpr OUStringLiteral IsReadOnly( u"IsReadOnly" );
133constexpr OUStringLiteral CreatableContentsInfo( u"CreatableContentsInfo" );
134
135TaskManager::TaskManager( const uno::Reference< uno::XComponentContext >& rxContext,
136 FileProvider* pProvider, bool bWithConfig )
137 : m_nCommandId( 0 ),
138 m_pProvider( pProvider ),
139 m_xContext( rxContext ),
140 // Commands
142 { /* Name */ "getCommandInfo",
143 /* Handle */ -1,
144 /* ArgType */ cppu::UnoType<void>::get() },
145
146 { /* Name */ "getPropertySetInfo",
147 /* Handle */ -1,
148 /* ArgType */ cppu::UnoType<void>::get() },
149
150 { /* Name */ "getPropertyValues",
151 /* Handle */ -1,
153
154 { /* Name */ "setPropertyValues",
155 /* Handle */ -1,
157
158 { /* Name */ "open",
159 /* Handle */ -1,
161
162 { /* Name */ "transfer",
163 /* Handle */ -1,
164 /* ArgType */ cppu::UnoType<TransferInfo>::get() },
165
166 { /* Name */ "delete",
167 /* Handle */ -1,
168 /* ArgType */ cppu::UnoType<sal_Bool>::get() },
169
170 { /* Name */ "insert",
171 /* Handle */ -1,
173
174 { /* Name */ "createNewContent",
175 /* Handle */ -1,
176 /* ArgType */ cppu::UnoType<ucb::ContentInfo>::get() } }
177{
178 // Title
179 m_aDefaultProperties.insert( MyProperty( true,
180 Title,
181 -1 ,
183 uno::Any(),
184 beans::PropertyState_DEFAULT_VALUE,
185 beans::PropertyAttribute::MAYBEVOID
186 | beans::PropertyAttribute::BOUND ) );
187
188 // CasePreservingURL
189 m_aDefaultProperties.insert(
190 MyProperty( true,
192 -1 ,
194 uno::Any(),
195 beans::PropertyState_DEFAULT_VALUE,
196 beans::PropertyAttribute::MAYBEVOID
197 | beans::PropertyAttribute::BOUND
198 | beans::PropertyAttribute::READONLY ) );
199
200
201 // IsFolder
202 m_aDefaultProperties.insert( MyProperty( true,
203 IsFolder,
204 -1 ,
206 uno::Any(),
207 beans::PropertyState_DEFAULT_VALUE,
208 beans::PropertyAttribute::MAYBEVOID
209 | beans::PropertyAttribute::BOUND
210 | beans::PropertyAttribute::READONLY ) );
211
212
213 // IsDocument
214 m_aDefaultProperties.insert( MyProperty( true,
216 -1 ,
218 uno::Any(),
219 beans::PropertyState_DEFAULT_VALUE,
220 beans::PropertyAttribute::MAYBEVOID
221 | beans::PropertyAttribute::BOUND
222 | beans::PropertyAttribute::READONLY ) );
223
224 // Removable
225 m_aDefaultProperties.insert( MyProperty( true,
226 IsVolume,
227 -1 ,
229 uno::Any(),
230 beans::PropertyState_DEFAULT_VALUE,
231 beans::PropertyAttribute::MAYBEVOID
232 | beans::PropertyAttribute::BOUND
233 | beans::PropertyAttribute::READONLY ) );
234
235
236 // Removable
237 m_aDefaultProperties.insert( MyProperty( true,
239 -1 ,
241 uno::Any(),
242 beans::PropertyState_DEFAULT_VALUE,
243 beans::PropertyAttribute::MAYBEVOID
244 | beans::PropertyAttribute::BOUND
245 | beans::PropertyAttribute::READONLY ) );
246
247 // Remote
248 m_aDefaultProperties.insert( MyProperty( true,
249 IsRemote,
250 -1 ,
252 uno::Any(),
253 beans::PropertyState_DEFAULT_VALUE,
254 beans::PropertyAttribute::MAYBEVOID
255 | beans::PropertyAttribute::BOUND
256 | beans::PropertyAttribute::READONLY ) );
257
258 // CompactDisc
259 m_aDefaultProperties.insert( MyProperty( true,
261 -1 ,
263 uno::Any(),
264 beans::PropertyState_DEFAULT_VALUE,
265 beans::PropertyAttribute::MAYBEVOID
266 | beans::PropertyAttribute::BOUND
267 | beans::PropertyAttribute::READONLY ) );
268
269 // Floppy
270 m_aDefaultProperties.insert( MyProperty( true,
271 IsFloppy,
272 -1 ,
274 uno::Any(),
275 beans::PropertyState_DEFAULT_VALUE,
276 beans::PropertyAttribute::MAYBEVOID
277 | beans::PropertyAttribute::BOUND
278 | beans::PropertyAttribute::READONLY ) );
279
280 // Hidden
281 m_aDefaultProperties.insert(
282 MyProperty(
283 true,
284 IsHidden,
285 -1 ,
287 uno::Any(),
288 beans::PropertyState_DEFAULT_VALUE,
289 beans::PropertyAttribute::MAYBEVOID
290 | beans::PropertyAttribute::BOUND
291#if defined(_WIN32)
292 ));
293#else
294 | beans::PropertyAttribute::READONLY)); // under unix/linux only readable
295#endif
296
297
298 // ContentType
299 m_aDefaultProperties.insert( MyProperty( false,
301 -1 ,
303 uno::Any(OUString()),
304 beans::PropertyState_DEFAULT_VALUE,
305 beans::PropertyAttribute::MAYBEVOID
306 | beans::PropertyAttribute::BOUND
307 | beans::PropertyAttribute::READONLY ) );
308
309
310 // DateModified
311 m_aDefaultProperties.insert( MyProperty( true,
313 -1 ,
315 uno::Any(),
316 beans::PropertyState_DEFAULT_VALUE,
317 beans::PropertyAttribute::MAYBEVOID
318 | beans::PropertyAttribute::BOUND ) );
319
320 // Size
321 m_aDefaultProperties.insert( MyProperty( true,
322 Size,
323 -1,
325 uno::Any(),
326 beans::PropertyState_DEFAULT_VALUE,
327 beans::PropertyAttribute::MAYBEVOID
328 | beans::PropertyAttribute::BOUND ) );
329
330 // IsReadOnly
331 m_aDefaultProperties.insert( MyProperty( true,
333 -1 ,
335 uno::Any(),
336 beans::PropertyState_DEFAULT_VALUE,
337 beans::PropertyAttribute::MAYBEVOID
338 | beans::PropertyAttribute::BOUND ) );
339
340
341 // CreatableContentsInfo
342 m_aDefaultProperties.insert( MyProperty( true,
344 -1 ,
345 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
346 uno::Any(),
347 beans::PropertyState_DEFAULT_VALUE,
348 beans::PropertyAttribute::MAYBEVOID
349 | beans::PropertyAttribute::BOUND
350 | beans::PropertyAttribute::READONLY ) );
351
352 if(bWithConfig)
353 {
354 uno::Reference< XPropertySetRegistryFactory > xRegFac = ucb::Store::create( m_xContext );
355 // Open/create a registry
356 m_xFileRegistry = xRegFac->createPropertySetRegistry( OUString() );
357 }
358}
359
360
362{
363}
364
365
366void
368 sal_Int32 CommandId,
369 const uno::Reference< XCommandEnvironment >& xCommandEnv )
370{
371 std::unique_lock aGuard( m_aMutex );
372 TaskMap::iterator it = m_aTaskMap.find( CommandId );
373 if( it != m_aTaskMap.end() )
374 {
375 throw DuplicateCommandIdentifierException( OSL_LOG_PREFIX );
376 }
377 m_aTaskMap.emplace( CommandId, TaskHandling( xCommandEnv ));
378}
379
380
381void
382TaskManager::endTask( sal_Int32 CommandId,
383 const OUString& aUncPath,
384 BaseContent* pContent)
385{
386 std::unique_lock aGuard( m_aMutex );
387 TaskMap::iterator it = m_aTaskMap.find( CommandId );
388 if( it == m_aTaskMap.end() )
389 return;
390
391 sal_Int32 ErrorCode = it->second.getInstalledError();
392 sal_Int32 MinorCode = it->second.getMinorErrorCode();
393 bool isHandled = it->second.isHandled();
394
396 = it->second.getCommandEnvironment();
397
398 m_aTaskMap.erase( it );
399
400 aGuard.unlock();
401
404 ErrorCode,
405 MinorCode,
406 xComEnv,
407 aUncPath,
408 pContent,
409 isHandled);
410}
411
412
413void TaskManager::clearError( sal_Int32 CommandId )
414{
415 std::unique_lock aGuard( m_aMutex );
416 TaskMap::iterator it = m_aTaskMap.find( CommandId );
417 if( it != m_aTaskMap.end() )
418 it->second.clearError();
419}
420
421
422void TaskManager::retrieveError( sal_Int32 CommandId,
423 sal_Int32 &ErrorCode,
424 sal_Int32 &minorCode)
425{
426 std::unique_lock aGuard( m_aMutex );
427 TaskMap::iterator it = m_aTaskMap.find( CommandId );
428 if( it != m_aTaskMap.end() )
429 {
430 ErrorCode = it->second.getInstalledError();
431 minorCode = it->second. getMinorErrorCode();
432 }
433}
434
435
436void TaskManager::installError( sal_Int32 CommandId,
437 sal_Int32 ErrorCode,
438 sal_Int32 MinorCode )
439{
440 std::unique_lock aGuard( m_aMutex );
441 TaskMap::iterator it = m_aTaskMap.find( CommandId );
442 if( it != m_aTaskMap.end() )
443 it->second.installError( ErrorCode,MinorCode );
444}
445
446
447sal_Int32
449{
450 std::unique_lock aGuard( m_aMutex );
451 return ++m_nCommandId;
452}
453
454
456 sal_Int32 CommandId,
457 const uno::Reference< task::XInteractionRequest >& request )
458{
459 std::unique_lock aGuard( m_aMutex );
460 TaskMap::iterator it = m_aTaskMap.find( CommandId );
461 uno::Reference< task::XInteractionHandler > xInt;
462 if( it != m_aTaskMap.end() )
463 {
464 xInt = it->second.getInteractionHandler();
465 if( xInt.is() )
466 xInt->handle( request );
467 it->second.setHandled();
468 }
469}
470
471/*********************************************************************************/
472/* */
473/* de/registerNotifier-Implementation */
474/* */
475/*********************************************************************************/
476
477
478// This two methods register and deregister a change listener for the content belonging
479// to URL aUnqPath
480
481
482void
483TaskManager::registerNotifier( const OUString& aUnqPath, Notifier* pNotifier )
484{
485 std::unique_lock aGuard( m_aMutex );
486
487 ContentMap::iterator it =
488 m_aContent.emplace( aUnqPath, UnqPathData() ).first;
489
490 std::vector< Notifier* >& nlist = it->second.notifier;
491
492 std::vector<Notifier*>::iterator it1 = std::find(nlist.begin(), nlist.end(), pNotifier);
493 if( it1 != nlist.end() ) // Every "Notifier" only once
494 {
495 return;
496 }
497 nlist.push_back( pNotifier );
498}
499
500
501void
502TaskManager::deregisterNotifier( const OUString& aUnqPath,Notifier* pNotifier )
503{
504 std::unique_lock aGuard( m_aMutex );
505
506 ContentMap::iterator it = m_aContent.find( aUnqPath );
507 if( it == m_aContent.end() )
508 return;
509
510 it->second.notifier.erase(std::remove(it->second.notifier.begin(), it->second.notifier.end(), pNotifier), it->second.notifier.end());
511
512 if( it->second.notifier.empty() )
513 m_aContent.erase( it );
514}
515
516
517/*********************************************************************************/
518/* */
519/* de/associate-Implementation */
520/* */
521/*********************************************************************************/
522
523// Used to associate and deassociate a new property with
524// the content belonging to URL UnqPath.
525// The default value and the attributes are input
526
527
528void
529TaskManager::associate( const OUString& aUnqPath,
530 const OUString& PropertyName,
531 const uno::Any& DefaultValue,
532 const sal_Int16 Attributes )
533{
534 MyProperty newProperty( false,
535 PropertyName,
536 -1,
537 DefaultValue.getValueType(),
538 DefaultValue,
539 beans::PropertyState_DEFAULT_VALUE,
540 Attributes );
541
542 auto it1 = m_aDefaultProperties.find( newProperty );
543 if( it1 != m_aDefaultProperties.end() )
544 throw beans::PropertyExistException( THROW_WHERE );
545
546 {
547 std::unique_lock aGuard( m_aMutex );
548
549 ContentMap::iterator it = m_aContent.emplace( aUnqPath,UnqPathData() ).first;
550
551 // Load the XPersistentPropertySetInfo and create it, if it does not exist
552 load( it,true );
553
554 PropertySet& properties = it->second.properties;
555 it1 = properties.find( newProperty );
556 if( it1 != properties.end() )
557 throw beans::PropertyExistException(THROW_WHERE );
558
559 // Property does not exist
560 properties.insert( newProperty );
561 it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
562 }
563 notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
564}
565
566
567void
568TaskManager::deassociate( const OUString& aUnqPath,
569 const OUString& PropertyName )
570{
571 MyProperty oldProperty( PropertyName );
572
573 auto it1 = m_aDefaultProperties.find( oldProperty );
574 if( it1 != m_aDefaultProperties.end() )
575 throw beans::NotRemoveableException( THROW_WHERE );
576
577 std::unique_lock aGuard( m_aMutex );
578
579 ContentMap::iterator it = m_aContent.emplace( aUnqPath,UnqPathData() ).first;
580
581 load( it, false );
582
583 PropertySet& properties = it->second.properties;
584
585 it1 = properties.find( oldProperty );
586 if( it1 == properties.end() )
587 throw beans::UnknownPropertyException( PropertyName );
588
589 properties.erase( it1 );
590
591 if( it->second.xC.is() )
592 it->second.xC->removeProperty( PropertyName );
593
594 if( properties.size() == 9 )
595 {
596 MyProperty ContentTProperty( ContentType );
597
598 if( properties.find( ContentTProperty )->getState() == beans::PropertyState_DEFAULT_VALUE )
599 {
600 it->second.xS = nullptr;
601 it->second.xC = nullptr;
602 it->second.xA = nullptr;
603 if(m_xFileRegistry.is())
604 m_xFileRegistry->removePropertySet( aUnqPath );
605 }
606 }
607 aGuard.unlock();
608 notifyPropertyRemoved( getPropertySetListeners( aUnqPath ), PropertyName );
609}
610
611
612/*********************************************************************************/
613/* */
614/* page-Implementation */
615/* */
616/*********************************************************************************/
617
618// Given an xOutputStream, this method writes the content of the file belonging to
619// URL aUnqPath into the XOutputStream
620
621
622void TaskManager::page( sal_Int32 CommandId,
623 const OUString& aUnqPath,
624 const uno::Reference< io::XOutputStream >& xOutputStream )
625{
626 osl::File aFile( aUnqPath );
627 osl::FileBase::RC err = aFile.open( osl_File_OpenFlag_Read );
628
629 if( err != osl::FileBase::E_None )
630 {
631 aFile.close();
632 installError( CommandId,
634 err );
635 return;
636 }
637
638 const sal_uInt64 bfz = 4*1024;
639 sal_Int8 BFF[bfz];
640 sal_uInt64 nrc; // Retrieved number of Bytes;
641
642 do
643 {
644 err = aFile.read( static_cast<void*>(BFF),bfz,nrc );
645 if( err == osl::FileBase::E_None )
646 {
647 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
648 uno::Sequence< sal_Int8 > seq( BFF, static_cast<sal_uInt32>(nrc) );
649 try
650 {
651 xOutputStream->writeBytes( seq );
652 }
653 catch (const io::NotConnectedException&)
654 {
655 installError( CommandId,
657 break;
658 }
659 catch (const io::BufferSizeExceededException&)
660 {
661 installError( CommandId,
663 break;
664 }
665 catch (const io::IOException&)
666 {
667 installError( CommandId,
669 break;
670 }
671 }
672 else
673 {
674 installError( CommandId,
676 err );
677 break;
678 }
679 } while( nrc == bfz );
680
681
682 aFile.close();
683
684
685 try
686 {
687 xOutputStream->closeOutput();
688 }
689 catch (const io::NotConnectedException&)
690 {
691 }
692 catch (const io::BufferSizeExceededException&)
693 {
694 }
695 catch (const io::IOException&)
696 {
697 }
698}
699
700
701/*********************************************************************************/
702/* */
703/* open-Implementation */
704/* */
705/*********************************************************************************/
706
707// Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
708
709
710uno::Reference< io::XInputStream >
711TaskManager::open( sal_Int32 CommandId,
712 const OUString& aUnqPath,
713 bool bLock )
714{
715 rtl::Reference<XInputStream_impl> pInputStream(new XInputStream_impl( aUnqPath, bLock )); // from filinpstr.hxx
716
717 sal_Int32 ErrorCode = pInputStream->CtorSuccess();
718
720 {
721 installError( CommandId,
722 ErrorCode,
723 pInputStream->getMinorError() );
724
725 pInputStream.clear();
726 }
727
728 return pInputStream;
729}
730
731
732/*********************************************************************************/
733/* */
734/* open for read/write access-Implementation */
735/* */
736/*********************************************************************************/
737
738// Given a file URL aUnqPath, this methods returns a XStream which can be used
739// to read and write from/to the file.
740
741
742uno::Reference< io::XStream >
743TaskManager::open_rw( sal_Int32 CommandId,
744 const OUString& aUnqPath,
745 bool bLock )
746{
747 rtl::Reference<XStream_impl> pStream(new XStream_impl( aUnqPath, bLock )); // from filstr.hxx
748
749 sal_Int32 ErrorCode = pStream->CtorSuccess();
750
752 {
753 installError( CommandId,
754 ErrorCode,
755 pStream->getMinorError() );
756
757 pStream.clear();
758 }
759 return pStream;
760}
761
762
763/*********************************************************************************/
764/* */
765/* ls-Implementation */
766/* */
767/*********************************************************************************/
768
769// This method returns the result set containing the children of the directory belonging
770// to file URL aUnqPath
771
772
773uno::Reference< XDynamicResultSet >
774TaskManager::ls( sal_Int32 CommandId,
775 const OUString& aUnqPath,
776 const sal_Int32 OpenMode,
777 const uno::Sequence< beans::Property >& seq,
778 const uno::Sequence< NumberedSortingInfo >& seqSort )
779{
780 rtl::Reference<XResultSet_impl> p(new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort ));
781
782 sal_Int32 ErrorCode = p->CtorSuccess();
783
785 {
786 installError( CommandId,
787 ErrorCode,
788 p->getMinorError() );
789
790 p.clear();
791 }
792
793 return p;
794}
795
796
797/*********************************************************************************/
798/* */
799/* info_c implementation */
800/* */
801/*********************************************************************************/
802// Info for commands
803
804uno::Reference< XCommandInfo >
806{
807 return new XCommandInfo_impl( this );
808}
809
810
811/*********************************************************************************/
812/* */
813/* info_p-Implementation */
814/* */
815/*********************************************************************************/
816// Info for the properties
817
818uno::Reference< beans::XPropertySetInfo >
819TaskManager::info_p( const OUString& aUnqPath )
820{
821 std::unique_lock aGuard( m_aMutex );
822 return new XPropertySetInfo_impl( this,aUnqPath );
823}
824
825
826/*********************************************************************************/
827/* */
828/* setv-Implementation */
829/* */
830/*********************************************************************************/
831
832// Sets the values of the properties belonging to fileURL aUnqPath
833
834
835uno::Sequence< uno::Any >
836TaskManager::setv( const OUString& aUnqPath,
837 const uno::Sequence< beans::PropertyValue >& values )
838{
839 std::unique_lock aGuard( m_aMutex );
840
841 sal_Int32 propChanged = 0;
842 uno::Sequence< uno::Any > ret( values.getLength() );
843 auto retRange = asNonConstRange(ret);
844 uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
845 auto seqChangedRange = asNonConstRange(seqChanged);
846
847 TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
848 PropertySet& properties = it->second.properties;
850 uno::Any aAny;
851
852 for( sal_Int32 i = 0; i < values.getLength(); ++i )
853 {
854 MyProperty toset( values[i].Name );
855 it1 = properties.find( toset );
856 if( it1 == properties.end() )
857 {
858 retRange[i] <<= beans::UnknownPropertyException( THROW_WHERE );
859 continue;
860 }
861
862 aAny = it1->getValue();
863 if( aAny == values[i].Value )
864 continue; // nothing needs to be changed
865
866 if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
867 {
868 retRange[i] <<= lang::IllegalAccessException( THROW_WHERE );
869 continue;
870 }
871
872 seqChangedRange[ propChanged ].PropertyName = values[i].Name;
873 seqChangedRange[ propChanged ].PropertyHandle = -1;
874 seqChangedRange[ propChanged ].Further = false;
875 seqChangedRange[ propChanged ].OldValue = aAny;
876 seqChangedRange[ propChanged++ ].NewValue = values[i].Value;
877
878 it1->setValue( values[i].Value ); // Put the new value into the local cash
879
880 if( ! it1->IsNative() )
881 {
882 // Also put logical properties into storage
883 if( !it->second.xS.is() )
884 load( it, true );
885
886 if( ( values[i].Name == ContentType ) &&
887 it1->getState() == beans::PropertyState_DEFAULT_VALUE )
888 { // Special logic for ContentType
889 // 09.07.01: Not reached anymore, because ContentType is readonly
890 it1->setState( beans::PropertyState_DIRECT_VALUE );
891 it->second.xC->addProperty( values[i].Name,
892 beans::PropertyAttribute::MAYBEVOID,
893 values[i].Value );
894 }
895
896 try
897 {
898 it->second.xS->setPropertyValue( values[i].Name,values[i].Value );
899 }
900 catch (const uno::Exception&e)
901 {
902 --propChanged; // unsuccessful setting
903 retRange[i] <<= e;
904 }
905 }
906 else
907 {
908 // native properties
909 // Setting of physical file properties
910 if( values[i].Name == Size )
911 {
912 sal_Int64 newSize = 0;
913 if( values[i].Value >>= newSize )
914 { // valid value for the size
915 osl::File aFile(aUnqPath);
916 bool err =
917 aFile.open(osl_File_OpenFlag_Write) != osl::FileBase::E_None ||
918 aFile.setSize(sal_uInt64(newSize)) != osl::FileBase::E_None ||
919 aFile.close() != osl::FileBase::E_None;
920
921 if( err )
922 {
923 --propChanged; // unsuccessful setting
924 uno::Sequence<uno::Any> names(comphelper::InitAnyPropertySequence(
925 {
926 {"Uri", uno::Any(aUnqPath)}
927 }));
928 retRange[i] <<= InteractiveAugmentedIOException(
929 OUString(),
930 nullptr,
931 task::InteractionClassification_ERROR,
932 IOErrorCode_GENERAL,
933 names );
934 }
935 }
936 else
937 retRange[i] <<= beans::IllegalTypeException( THROW_WHERE );
938 }
939 else if(values[i].Name == IsReadOnly ||
940 values[i].Name == IsHidden)
941 {
942 bool value = false;
943 if( values[i].Value >>= value )
944 {
945 osl::DirectoryItem aDirItem;
946 osl::FileBase::RC err =
947 osl::DirectoryItem::get(aUnqPath,aDirItem);
948 sal_uInt64 nAttributes(0);
949 if(err == osl::FileBase::E_None)
950 {
951 osl::FileStatus aFileStatus(osl_FileStatus_Mask_Attributes);
952 err = aDirItem.getFileStatus(aFileStatus);
953 if(err == osl::FileBase::E_None &&
954 aFileStatus.isValid(osl_FileStatus_Mask_Attributes))
955 nAttributes = aFileStatus.getAttributes();
956 }
957 // now we have the attributes provided all went well.
958 if(err == osl::FileBase::E_None) {
959 if(values[i].Name == IsReadOnly)
960 {
961 nAttributes &= ~(osl_File_Attribute_OwnWrite |
962 osl_File_Attribute_GrpWrite |
963 osl_File_Attribute_OthWrite |
964 osl_File_Attribute_ReadOnly);
965 if(value)
966 nAttributes |= osl_File_Attribute_ReadOnly;
967 else
968 nAttributes |= (
969 osl_File_Attribute_OwnWrite |
970 osl_File_Attribute_GrpWrite |
971 osl_File_Attribute_OthWrite);
972 }
973 else if(values[i].Name == IsHidden)
974 {
975 nAttributes &= ~(osl_File_Attribute_Hidden);
976 if(value)
977 nAttributes |= osl_File_Attribute_Hidden;
978 }
979 err = osl::File::setAttributes(
980 aUnqPath,nAttributes);
981 }
982
983 if( err != osl::FileBase::E_None )
984 {
985 --propChanged; // unsuccessful setting
986 uno::Sequence<uno::Any> names(comphelper::InitAnyPropertySequence(
987 {
988 {"Uri", uno::Any(aUnqPath)}
989 }));
990 IOErrorCode ioError;
991 switch( err )
992 {
993 case osl::FileBase::E_NOMEM:
994 // not enough memory for allocating structures <br>
995 ioError = IOErrorCode_OUT_OF_MEMORY;
996 break;
997 case osl::FileBase::E_INVAL:
998 // the format of the parameters was not valid<p>
999 ioError = IOErrorCode_INVALID_PARAMETER;
1000 break;
1001 case osl::FileBase::E_NAMETOOLONG:
1002 // File name too long<br>
1003 ioError = IOErrorCode_NAME_TOO_LONG;
1004 break;
1005 case osl::FileBase::E_NOENT:
1006 // No such file or directory<br>
1007 case osl::FileBase::E_NOLINK:
1008 // Link has been severed<br>
1009 ioError = IOErrorCode_NOT_EXISTING;
1010 break;
1011 case osl::FileBase::E_ROFS:
1012 // #i4735# handle ROFS transparently
1013 // as ACCESS_DENIED
1014 case osl::FileBase::E_PERM:
1015 case osl::FileBase::E_ACCES:
1016 // permission denied<br>
1017 ioError = IOErrorCode_ACCESS_DENIED;
1018 break;
1019 case osl::FileBase::E_LOOP:
1020 // Too many symbolic links encountered<br>
1021 case osl::FileBase::E_FAULT:
1022 // Bad address<br>
1023 case osl::FileBase::E_IO:
1024 // I/O error<br>
1025 case osl::FileBase::E_NOSYS:
1026 // Function not implemented<br>
1027 case osl::FileBase::E_MULTIHOP:
1028 // Multihop attempted<br>
1029 case osl::FileBase::E_INTR:
1030 // function call was interrupted<p>
1031 default:
1032 ioError = IOErrorCode_GENERAL;
1033 break;
1034 }
1035 retRange[i] <<= InteractiveAugmentedIOException(
1036 OUString(),
1037 nullptr,
1038 task::InteractionClassification_ERROR,
1039 ioError,
1040 names );
1041 }
1042 }
1043 else
1044 retRange[i] <<= beans::IllegalTypeException( THROW_WHERE );
1045 }
1046 }
1047 } // end for
1048
1049 aGuard.unlock();
1050 if( propChanged )
1051 {
1052 seqChanged.realloc( propChanged );
1053 notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath ), seqChanged );
1054 }
1055
1056 return ret;
1057}
1058
1059/*********************************************************************************/
1060/* */
1061/* getv-Implementation */
1062/* */
1063/*********************************************************************************/
1064
1065// Reads the values of the properties belonging to fileURL aUnqPath;
1066// Returns an XRow object containing the values in the requested order.
1067
1068
1069uno::Reference< sdbc::XRow >
1070TaskManager::getv( sal_Int32 CommandId,
1071 const OUString& aUnqPath,
1072 const uno::Sequence< beans::Property >& properties )
1073{
1074 uno::Sequence< uno::Any > seq( properties.getLength() );
1075
1076 sal_Int32 n_Mask;
1078 osl::FileStatus aFileStatus( n_Mask );
1079
1080 osl::DirectoryItem aDirItem;
1081 osl::FileBase::RC nError1 = osl::DirectoryItem::get( aUnqPath,aDirItem );
1082 if( nError1 != osl::FileBase::E_None )
1083 installError(CommandId,
1084 TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
1085 nError1);
1086
1087 osl::FileBase::RC nError2 = aDirItem.getFileStatus( aFileStatus );
1088 if( nError1 == osl::FileBase::E_None &&
1089 nError2 != osl::FileBase::E_None )
1090 installError(CommandId,
1091 TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
1092 nError2);
1093
1094 {
1095 std::unique_lock aGuard( m_aMutex );
1096
1097 TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
1098 commit( aGuard, it, aFileStatus );
1099
1100 PropertySet& propset = it->second.properties;
1101
1102 std::transform(properties.begin(), properties.end(), seq.getArray(),
1103 [&propset](const beans::Property& rProp) -> uno::Any {
1104 MyProperty readProp( rProp.Name );
1105 auto it1 = propset.find( readProp );
1106 if( it1 == propset.end() )
1107 return uno::Any();
1108 return it1->getValue();
1109 });
1110 }
1111
1112 return new XRow_impl( this,seq );
1113}
1114
1115
1116/********************************************************************************/
1117/* */
1118/* transfer-commandos */
1119/* */
1120/********************************************************************************/
1121
1122
1123/********************************************************************************/
1124/* */
1125/* move-implementation */
1126/* */
1127/********************************************************************************/
1128
1129// Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
1130
1131
1132void
1133TaskManager::move( sal_Int32 CommandId,
1134 const OUString& srcUnqPath,
1135 const OUString& dstUnqPathIn,
1136 const sal_Int32 NameClash )
1137{
1138 // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
1139 // srcUnqPath and dstUnqPathIn are equal
1140 if( srcUnqPath == dstUnqPathIn )
1141 return;
1142
1143 osl::FileBase::RC nError;
1144 OUString dstUnqPath( dstUnqPathIn );
1145
1146 switch( NameClash )
1147 {
1148 case NameClash::KEEP:
1149 {
1150 nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1151 if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
1152 {
1153 installError( CommandId,
1155 nError );
1156 return;
1157 }
1158 break;
1159 }
1160 case NameClash::OVERWRITE:
1161 {
1162 // stat to determine whether we have a symlink
1163 OUString targetPath(dstUnqPath);
1164
1165 osl::FileStatus aStatus(osl_FileStatus_Mask_Type|osl_FileStatus_Mask_LinkTargetURL);
1166 osl::DirectoryItem aItem;
1167 (void)osl::DirectoryItem::get(dstUnqPath,aItem);
1168 (void)aItem.getFileStatus(aStatus);
1169
1170 if( aStatus.isValid(osl_FileStatus_Mask_Type) &&
1171 aStatus.isValid(osl_FileStatus_Mask_LinkTargetURL) &&
1172 aStatus.getFileType() == osl::FileStatus::Link )
1173 targetPath = aStatus.getLinkTargetURL();
1174
1175 // Will do nothing if file does not exist.
1176 osl::File::remove( targetPath );
1177
1178 nError = osl_File_move( srcUnqPath,targetPath );
1179 if( nError != osl::FileBase::E_None )
1180 {
1181 installError( CommandId,
1183 nError );
1184 return;
1185 }
1186 break;
1187 }
1188 case NameClash::RENAME:
1189 {
1190 OUString newDstUnqPath;
1191 nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1192 if( nError == osl::FileBase::E_EXIST )
1193 {
1194 // "invent" a new valid title.
1195
1196 sal_Int32 nPos = -1;
1197 sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
1198 sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
1199 if( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
1200 && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
1201 nPos = nLastDot;
1202 else
1203 nPos = dstUnqPath.getLength();
1204
1205 sal_Int32 nTry = 0;
1206
1207 do
1208 {
1209 newDstUnqPath = dstUnqPath;
1210
1211 OUString aPostfix = "_" + OUString::number( ++nTry );
1212
1213 newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostfix );
1214
1215 nError = osl_File_move( srcUnqPath,newDstUnqPath,true );
1216 }
1217 while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
1218 }
1219
1220 if( nError == osl::FileBase::E_EXIST )
1221 {
1222 installError( CommandId,
1224 return;
1225 }
1226 else if( nError != osl::FileBase::E_None )
1227 {
1228 installError( CommandId,
1230 nError );
1231 return;
1232 }
1233 else
1234 dstUnqPath = newDstUnqPath;
1235
1236 break;
1237 }
1238 case NameClash::ERROR:
1239 {
1240 nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1241 if( nError == osl::FileBase::E_EXIST )
1242 {
1243 installError( CommandId,
1245 return;
1246 }
1247 else if( nError != osl::FileBase::E_None )
1248 {
1249 installError( CommandId,
1251 nError );
1252 return;
1253 }
1254 break;
1255 }
1256 case NameClash::ASK:
1257 default:
1258 {
1259 nError = osl_File_move( srcUnqPath,dstUnqPath,true );
1260 if( nError == osl::FileBase::E_EXIST )
1261 {
1262 installError( CommandId,
1264 NameClash::ASK);
1265 return;
1266 }
1267 }
1268 break;
1269 }
1270
1271 // Determine, whether we have moved a file or a folder
1272 osl::DirectoryItem aItem;
1273 nError = osl::DirectoryItem::get( dstUnqPath,aItem );
1274 if( nError != osl::FileBase::E_None )
1275 {
1276 installError( CommandId,
1278 nError );
1279 return;
1280 }
1281 osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
1282 nError = aItem.getFileStatus( aStatus );
1283 if( nError != osl::FileBase::E_None || ! aStatus.isValid( osl_FileStatus_Mask_Type ) )
1284 {
1285 installError( CommandId,
1287 nError );
1288 return;
1289 }
1290 bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );
1291
1292
1293 copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );
1294
1295 OUString aDstParent = getParentName( dstUnqPath );
1296 OUString aSrcParent = getParentName( srcUnqPath );
1297
1298 notifyInsert( getContentEventListeners( aDstParent ),dstUnqPath );
1299 if( aDstParent != aSrcParent )
1300 notifyContentRemoved( getContentEventListeners( aSrcParent ),srcUnqPath );
1301
1302 notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) );
1303 erasePersistentSet( srcUnqPath,!isDocument );
1304}
1305
1306
1307/********************************************************************************/
1308/* */
1309/* copy-implementation */
1310/* */
1311/********************************************************************************/
1312
1313// Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
1314
1315
1316namespace {
1317
1318bool getType(
1319 TaskManager & task, sal_Int32 id, OUString const & fileUrl,
1320 osl::DirectoryItem * item, osl::FileStatus::Type * type)
1321{
1322 OSL_ASSERT(item != nullptr && type != nullptr);
1323 osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
1324 if (err != osl::FileBase::E_None) {
1326 return false;
1327 }
1328 osl::FileStatus stat(osl_FileStatus_Mask_Type);
1329 err = item->getFileStatus(stat);
1330 if (err != osl::FileBase::E_None) {
1332 return false;
1333 }
1334 *type = stat.getFileType();
1335 return true;
1336}
1337
1338}
1339
1340void
1342 sal_Int32 CommandId,
1343 const OUString& srcUnqPath,
1344 const OUString& dstUnqPathIn,
1345 sal_Int32 NameClash )
1346{
1347 osl::FileBase::RC nError;
1348 OUString dstUnqPath( dstUnqPathIn );
1349
1350 // Resolve symbolic links within the source path. If srcUnqPath denotes a
1351 // symbolic link (targeting either a file or a folder), the contents of the
1352 // target is copied (recursively, in the case of a folder). However, if
1353 // recursively copying the contents of a folder causes a symbolic link to be
1354 // copied, the symbolic link itself is copied.
1355 osl::DirectoryItem item;
1356 osl::FileStatus::Type type;
1357 if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
1358 return;
1359 }
1360 OUString rslvdSrcUnqPath;
1361 if (type == osl::FileStatus::Link) {
1362 osl::FileStatus stat(osl_FileStatus_Mask_LinkTargetURL);
1363 nError = item.getFileStatus(stat);
1364 if (nError != osl::FileBase::E_None) {
1366 CommandId, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, nError);
1367 return;
1368 }
1369 rslvdSrcUnqPath = stat.getLinkTargetURL();
1370 if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
1371 return;
1372 }
1373 } else {
1374 rslvdSrcUnqPath = srcUnqPath;
1375 }
1376
1377 bool isDocument
1378 = type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
1379 FileUrlType IsWhat = isDocument ? FileUrlType::File : FileUrlType::Folder;
1380
1381 switch( NameClash )
1382 {
1383 case NameClash::KEEP:
1384 {
1385 nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1386 if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
1387 {
1388 installError( CommandId,
1390 nError );
1391 return;
1392 }
1393 break;
1394 }
1395 case NameClash::OVERWRITE:
1396 {
1397 // remove (..., MustExist = sal_False).
1398 remove( CommandId, dstUnqPath, IsWhat, false );
1399
1400 // copy.
1401 nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
1402 if( nError != osl::FileBase::E_None )
1403 {
1404 installError( CommandId,
1406 nError );
1407 return;
1408 }
1409 break;
1410 }
1411 case NameClash::RENAME:
1412 {
1413 OUString newDstUnqPath = dstUnqPath;
1414 nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1415
1416 if( nError == osl::FileBase::E_EXIST )
1417 {
1418 // "invent" a new valid title.
1419
1420 sal_Int32 nPos = -1;
1421 sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
1422 sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
1423 if ( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
1424 && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
1425 nPos = nLastDot;
1426 else
1427 nPos = dstUnqPath.getLength();
1428
1429 sal_Int32 nTry = 0;
1430
1431 do
1432 {
1433 newDstUnqPath = dstUnqPath;
1434
1435 OUString aPostfix = "_" + OUString::number( ++nTry );
1436
1437 newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostfix );
1438
1439 nError = copy_recursive( rslvdSrcUnqPath,newDstUnqPath,IsWhat,true );
1440 }
1441 while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
1442 }
1443
1444 if( nError == osl::FileBase::E_EXIST )
1445 {
1446 installError( CommandId,
1448 return;
1449 }
1450 else if( nError != osl::FileBase::E_None )
1451 {
1452 installError( CommandId,
1454 nError );
1455 return;
1456 }
1457 else
1458 dstUnqPath = newDstUnqPath;
1459
1460 break;
1461 }
1462 case NameClash::ERROR:
1463 {
1464 nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1465
1466 if( nError == osl::FileBase::E_EXIST )
1467 {
1468 installError( CommandId,
1470 return;
1471 }
1472 else if( nError != osl::FileBase::E_None )
1473 {
1474 installError( CommandId,
1476 nError );
1477 return;
1478 }
1479 break;
1480 }
1481 case NameClash::ASK:
1482 default:
1483 {
1484 nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
1485
1486 if( nError == osl::FileBase::E_EXIST )
1487 {
1488 installError( CommandId,
1490 NameClash);
1491 return;
1492 }
1493 break;
1494 }
1495 }
1496
1497 copyPersistentSet( srcUnqPath,dstUnqPath, !isDocument );
1498 notifyInsert( getContentEventListeners( getParentName( dstUnqPath ) ),dstUnqPath );
1499}
1500
1501
1502/********************************************************************************/
1503/* */
1504/* remove-implementation */
1505/* */
1506/********************************************************************************/
1507
1508// Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
1509// Return: success of operation
1510
1511
1512bool
1513TaskManager::remove( sal_Int32 CommandId,
1514 const OUString& aUnqPath,
1515 FileUrlType IsWhat,
1516 bool MustExist )
1517{
1518 sal_Int32 nMask = osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL;
1519
1520 osl::DirectoryItem aItem;
1521 osl::FileStatus aStatus( nMask );
1522 osl::FileBase::RC nError;
1523
1524 if( IsWhat == FileUrlType::Unknown ) // Determine whether we are removing a directory or a file
1525 {
1526 nError = osl::DirectoryItem::get( aUnqPath, aItem );
1527 if( nError != osl::FileBase::E_None )
1528 {
1529 if (MustExist)
1530 {
1531 installError( CommandId,
1533 nError );
1534 }
1535 return (!MustExist);
1536 }
1537
1538 nError = aItem.getFileStatus( aStatus );
1539 if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
1540 {
1541 installError( CommandId,
1543 nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
1544 return false;
1545 }
1546
1547 if( aStatus.getFileType() == osl::FileStatus::Regular ||
1548 aStatus.getFileType() == osl::FileStatus::Link )
1549 IsWhat = FileUrlType::File;
1550 else if( aStatus.getFileType() == osl::FileStatus::Directory ||
1551 aStatus.getFileType() == osl::FileStatus::Volume )
1552 IsWhat = FileUrlType::Folder;
1553 }
1554
1555
1556 if( IsWhat == FileUrlType::File )
1557 {
1558 nError = osl::File::remove( aUnqPath );
1559 if( nError != osl::FileBase::E_None )
1560 {
1561 if (MustExist)
1562 {
1563 installError( CommandId,
1565 nError );
1566 }
1567 return (!MustExist);
1568 }
1569 else
1570 {
1572 erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
1573 }
1574 }
1575 else if( IsWhat == FileUrlType::Folder )
1576 {
1577 osl::Directory aDirectory( aUnqPath );
1578
1579 nError = aDirectory.open();
1580 if( nError != osl::FileBase::E_None )
1581 {
1582 if (MustExist)
1583 {
1584 installError( CommandId,
1586 nError );
1587 }
1588 return (!MustExist);
1589 }
1590
1591 bool whileSuccess = true;
1593 OUString name;
1594
1595 nError = aDirectory.getNextItem( aItem );
1596 while( nError == osl::FileBase::E_None )
1597 {
1598 nError = aItem.getFileStatus( aStatus );
1599 if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
1600 {
1601 installError( CommandId,
1603 nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
1604 whileSuccess = false;
1605 break;
1606 }
1607
1608 if( aStatus.getFileType() == osl::FileStatus::Regular ||
1609 aStatus.getFileType() == osl::FileStatus::Link )
1610 recurse = FileUrlType::File;
1611 else if( aStatus.getFileType() == osl::FileStatus::Directory ||
1612 aStatus.getFileType() == osl::FileStatus::Volume )
1613 recurse = FileUrlType::Folder;
1614
1615 name = aStatus.getFileURL();
1616 whileSuccess = remove( CommandId, name, recurse, MustExist );
1617 if( !whileSuccess )
1618 break;
1619
1620 nError = aDirectory.getNextItem( aItem );
1621 }
1622
1623 aDirectory.close();
1624
1625 if( ! whileSuccess )
1626 return false; // error code is installed
1627
1628 if( nError != osl::FileBase::E_NOENT )
1629 {
1630 installError( CommandId,
1632 nError );
1633 return false;
1634 }
1635
1636 nError = osl::Directory::remove( aUnqPath );
1637 if( nError != osl::FileBase::E_None )
1638 {
1639 if (MustExist)
1640 {
1641 installError( CommandId,
1643 nError );
1644 }
1645 return (!MustExist);
1646 }
1647 else
1648 {
1650 erasePersistentSet( aUnqPath );
1651 }
1652 }
1653 else // Don't know what to remove
1654 {
1655 installError( CommandId,
1657 return false;
1658 }
1659
1660 return true;
1661}
1662
1663
1664/********************************************************************************/
1665/* */
1666/* mkdir-implementation */
1667/* */
1668/********************************************************************************/
1669
1670// Creates new directory with given URL, recursively if necessary
1671// Return:: success of operation
1672
1673
1674bool
1675TaskManager::mkdir( sal_Int32 CommandId,
1676 const OUString& rUnqPath,
1677 bool OverWrite )
1678{
1679 OUString aUnqPath;
1680
1681 // remove trailing slash
1682 if ( rUnqPath.endsWith("/") )
1683 aUnqPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
1684 else
1685 aUnqPath = rUnqPath;
1686
1687 osl::FileBase::RC nError = osl::Directory::create( aUnqPath );
1688
1689 switch ( nError )
1690 {
1691 case osl::FileBase::E_EXIST: // Directory cannot be overwritten
1692 {
1693 if( !OverWrite )
1694 {
1695 installError( CommandId,
1697 return false;
1698 }
1699 else
1700 return true;
1701 }
1702 case osl::FileBase::E_INVAL:
1703 {
1704 installError(CommandId,
1706 return false;
1707 }
1708 case osl::FileBase::E_None:
1709 {
1710 OUString aPrtPath = getParentName( aUnqPath );
1711 notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
1712 return true;
1713 }
1714 default:
1715 return ensuredir(
1716 CommandId,
1717 aUnqPath,
1719 }
1720}
1721
1722
1723/********************************************************************************/
1724/* */
1725/* mkfil-implementation */
1726/* */
1727/********************************************************************************/
1728
1729// Creates new file with given URL.
1730// The content of aInputStream becomes the content of the file
1731// Return:: success of operation
1732
1733
1734bool
1735TaskManager::mkfil( sal_Int32 CommandId,
1736 const OUString& aUnqPath,
1737 bool Overwrite,
1738 const uno::Reference< io::XInputStream >& aInputStream )
1739{
1740 // return value unimportant
1741 bool bSuccess = write( CommandId,
1742 aUnqPath,
1743 Overwrite,
1744 aInputStream );
1745 if ( bSuccess )
1746 {
1747 OUString aPrtPath = getParentName( aUnqPath );
1748 notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
1749 }
1750 return bSuccess;
1751}
1752
1753
1754/********************************************************************************/
1755/* */
1756/* write-implementation */
1757/* */
1758/********************************************************************************/
1759
1760// writes to the file with given URL.
1761// The content of aInputStream becomes the content of the file
1762// Return:: success of operation
1763
1764
1765bool
1766TaskManager::write( sal_Int32 CommandId,
1767 const OUString& aUnqPath,
1768 bool OverWrite,
1769 const uno::Reference< io::XInputStream >& aInputStream )
1770{
1771 if( ! aInputStream.is() )
1772 {
1773 installError( CommandId,
1775 return false;
1776 }
1777
1778 // Create parent path, if necessary.
1779 if ( ! ensuredir( CommandId,
1780 getParentName( aUnqPath ),
1782 return false;
1783
1784 osl::FileBase::RC err;
1785 osl::File aFile( aUnqPath );
1786
1787 if( OverWrite )
1788 {
1789 err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
1790
1791 if( err != osl::FileBase::E_None )
1792 {
1793 aFile.close();
1794 err = aFile.open( osl_File_OpenFlag_Write );
1795
1796 if( err != osl::FileBase::E_None )
1797 {
1798 installError( CommandId,
1800 err );
1801 return false;
1802 }
1803
1804 // the existing file was just opened and should be overwritten now,
1805 // truncate it first
1806
1807 err = aFile.setSize( 0 );
1808 if( err != osl::FileBase::E_None )
1809 {
1810 installError( CommandId,
1812 err );
1813 return false;
1814 }
1815 }
1816 }
1817 else
1818 {
1819 err = aFile.open( osl_File_OpenFlag_Read | osl_File_OpenFlag_NoLock );
1820 if( err == osl::FileBase::E_None ) // The file exists and shall not be overwritten
1821 {
1822 installError( CommandId,
1823 TASKHANDLING_NOREPLACE_FOR_WRITE, // Now an exception
1824 err );
1825
1826 aFile.close();
1827 return false;
1828 }
1829
1830 // as a temporary solution the creation does not lock the file at all
1831 // in future it should be possible to create the file without lock explicitly
1832 err = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock );
1833
1834 if( err != osl::FileBase::E_None )
1835 {
1836 aFile.close();
1837 installError( CommandId,
1839 err );
1840 return false;
1841 }
1842 }
1843
1844 bool bSuccess = true;
1845
1846 sal_uInt64 nWrittenBytes;
1847 sal_Int32 nReadBytes = 0, nRequestedBytes = 32768 /*32k*/;
1848 uno::Sequence< sal_Int8 > seq( nRequestedBytes );
1849
1850 do
1851 {
1852 try
1853 {
1854 nReadBytes = aInputStream->readBytes( seq,
1855 nRequestedBytes );
1856 }
1857 catch( const io::NotConnectedException& )
1858 {
1859 installError( CommandId,
1861 bSuccess = false;
1862 break;
1863 }
1864 catch( const io::BufferSizeExceededException& )
1865 {
1866 installError( CommandId,
1868 bSuccess = false;
1869 break;
1870 }
1871 catch( const io::IOException& )
1872 {
1873 installError( CommandId,
1875 bSuccess = false;
1876 break;
1877 }
1878
1879 if( nReadBytes )
1880 {
1881 const sal_Int8* p = seq.getConstArray();
1882
1883 err = aFile.write( static_cast<void const *>(p),
1884 sal_uInt64( nReadBytes ),
1885 nWrittenBytes );
1886
1887 if( err != osl::FileBase::E_None )
1888 {
1889 installError( CommandId,
1891 err );
1892 bSuccess = false;
1893 break;
1894 }
1895 else if( nWrittenBytes != sal_uInt64( nReadBytes ) )
1896 {
1897 installError( CommandId,
1899 bSuccess = false;
1900 break;
1901 }
1902 }
1903 } while( nReadBytes == nRequestedBytes );
1904
1905 err = aFile.close();
1906 if( err != osl::FileBase::E_None )
1907 {
1908 installError( CommandId,
1910 err );
1911 bSuccess = false;
1912 }
1913
1914 return bSuccess;
1915}
1916
1917
1918/*********************************************************************************/
1919/* */
1920/* insertDefaultProperties-Implementation */
1921/* */
1922/*********************************************************************************/
1923
1924
1925void TaskManager::insertDefaultProperties( const OUString& aUnqPath )
1926{
1927 std::unique_lock aGuard(m_aMutex);
1928 insertDefaultProperties(aGuard, aUnqPath);
1929}
1930
1931void TaskManager::insertDefaultProperties( std::unique_lock<std::mutex>& /*rGuard*/, const OUString& aUnqPath )
1932{
1933 ContentMap::iterator it =
1934 m_aContent.emplace( aUnqPath,UnqPathData() ).first;
1935
1936 load( it, false );
1937
1938 MyProperty ContentTProperty( ContentType );
1939
1940 PropertySet& properties = it->second.properties;
1941 bool ContentNotDefau = properties.find( ContentTProperty ) != properties.end();
1942
1943 properties.reserve(properties.size() + m_aDefaultProperties.size());
1944 for (auto const& defaultprop : m_aDefaultProperties)
1945 {
1946 if( !ContentNotDefau || defaultprop.getPropertyName() != ContentType )
1947 properties.insert( defaultprop );
1948 }
1949}
1950
1951
1952/******************************************************************************/
1953/* */
1954/* mapping of file urls */
1955/* to uncpath and vice versa */
1956/* */
1957/******************************************************************************/
1958
1959
1960bool TaskManager::getUnqFromUrl( const OUString& Url, OUString& Unq )
1961{
1962 if ( Url == "file:///" || Url == "file://localhost/" || Url == "file://127.0.0.1/" )
1963 {
1964 Unq = "file:///";
1965 return false;
1966 }
1967
1968 bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Url,Unq );
1969
1970 Unq = Url;
1971
1972 sal_Int32 l = Unq.getLength()-1;
1973 if( ! err && Unq.endsWith("/") &&
1974 Unq.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) != -1 )
1975 Unq = Unq.copy(0, l);
1976
1977 return err;
1978}
1979
1980
1981bool TaskManager::getUrlFromUnq( const OUString& Unq,OUString& Url )
1982{
1983 bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Unq,Url );
1984
1985 Url = Unq;
1986
1987 return err;
1988}
1989
1990
1991// Helper function for public copy
1992
1993osl::FileBase::RC
1994TaskManager::copy_recursive( const OUString& srcUnqPath,
1995 const OUString& dstUnqPath,
1996 FileUrlType TypeToCopy,
1997 bool testExistBeforeCopy )
1998{
1999 osl::FileBase::RC err = osl::FileBase::E_None;
2000
2001 if( TypeToCopy == FileUrlType::File ) // Document
2002 {
2003 err = osl_File_copy( srcUnqPath,dstUnqPath,testExistBeforeCopy );
2004 }
2005 else if( TypeToCopy == FileUrlType::Folder )
2006 {
2007 osl::Directory aDir( srcUnqPath );
2008 (void)aDir.open();
2009
2010 err = osl::Directory::create( dstUnqPath );
2011 osl::FileBase::RC next = err;
2012 if( err == osl::FileBase::E_None )
2013 {
2014 sal_Int32 const n_Mask = osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Type;
2015
2016 osl::DirectoryItem aDirItem;
2017
2018 while( err == osl::FileBase::E_None )
2019 {
2020 next = aDir.getNextItem( aDirItem );
2021 if (next != osl::FileBase::E_None )
2022 break;
2023 bool IsDoc = false;
2024 osl::FileStatus aFileStatus( n_Mask );
2025 aDirItem.getFileStatus( aFileStatus );
2026 if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
2027 IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
2028
2029 // Getting the information for the next recursive copy
2030 FileUrlType newTypeToCopy = IsDoc ? FileUrlType::File : FileUrlType::Folder;
2031
2032 OUString newSrcUnqPath;
2033 if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
2034 newSrcUnqPath = aFileStatus.getFileURL();
2035
2036 OUString newDstUnqPath = dstUnqPath;
2037 OUString tit;
2038 if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
2039 tit = rtl::Uri::encode( aFileStatus.getFileName(),
2040 rtl_UriCharClassPchar,
2041 rtl_UriEncodeIgnoreEscapes,
2042 RTL_TEXTENCODING_UTF8 );
2043
2044 if( !newDstUnqPath.endsWith( "/" ) )
2045 newDstUnqPath += "/";
2046
2047 newDstUnqPath += tit;
2048
2049 if ( newSrcUnqPath != dstUnqPath )
2050 err = copy_recursive( newSrcUnqPath,newDstUnqPath,newTypeToCopy,false );
2051 }
2052
2053 if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
2054 err = next;
2055 }
2056 aDir.close();
2057 }
2058
2059 return err;
2060}
2061
2062
2063// Helper function for mkfil,mkdir and write
2064// Creates whole path
2065// returns success of the operation
2066
2067
2068bool TaskManager::ensuredir( sal_Int32 CommandId,
2069 const OUString& rUnqPath,
2070 sal_Int32 errorCode )
2071{
2072 OUString aPath;
2073
2074 if ( rUnqPath.isEmpty() )
2075 return false;
2076
2077 if ( rUnqPath.endsWith("/") )
2078 aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
2079 else
2080 aPath = rUnqPath;
2081
2082#if HAVE_FEATURE_MACOSX_SANDBOX
2083
2084 // Avoid annoying sandbox messages in the system.log from the
2085 // below aDirectory.open(), which ends up calling opendir().
2086 // Surely it is easier to just call stat()? Calling stat() on an
2087 // arbitrary (?) directory does not seem to cause any sandbox
2088 // violation, while opendir() does. (Sorry I could not be bothered
2089 // to use some complex cross-platform abstraction over stat() here
2090 // in this macOS specific code block.)
2091
2092 OUString aDirName;
2093 struct stat s;
2094 if( osl::FileBase::getSystemPathFromFileURL( aPath, aDirName ) == osl::FileBase::E_None &&
2095 stat(OUStringToOString( aDirName, RTL_TEXTENCODING_UTF8).getStr(), &s ) == 0 &&
2096 S_ISDIR( s.st_mode ) )
2097 return sal_True;
2098#endif
2099
2100 // HACK: create directory on a mount point with nobrowse option
2101 // returns ENOSYS in any case !!
2102 osl::Directory aDirectory( aPath );
2103 osl::FileBase::RC nError = aDirectory.open();
2104 aDirectory.close();
2105
2106 if( nError == osl::File::E_None )
2107 return true;
2108
2109 nError = osl::Directory::create( aPath );
2110
2111 if( nError == osl::File::E_None )
2113
2114 bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
2115
2116 if( ! bSuccess )
2117 {
2118 OUString aParentDir = getParentName( aPath );
2119
2120 if ( aParentDir != aPath )
2121 { // Create first the parent directory
2122 bSuccess = ensuredir( CommandId,
2123 getParentName( aPath ),
2124 errorCode );
2125
2126 // After parent directory structure exists try it one's more
2127
2128 if ( bSuccess )
2129 { // Parent directory exists, retry creation of directory
2130 nError = osl::Directory::create( aPath );
2131
2132 if( nError == osl::File::E_None )
2134
2135 bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
2136 }
2137 }
2138 }
2139
2140 if( ! bSuccess )
2141 installError( CommandId,
2142 errorCode,
2143 nError );
2144
2145 return bSuccess;
2146}
2147
2148
2149// Given a sequence of properties seq, this method determines the mask
2150// used to instantiate an osl::FileStatus, so that a call to
2151// osl::DirectoryItem::getFileStatus fills the required fields.
2152
2153
2154void
2156 sal_Int32& n_Mask,
2157 const uno::Sequence< beans::Property >& seq )
2158{
2159 n_Mask = 0;
2160 for(const auto& rProp : seq) {
2161 if(rProp.Name == Title)
2162 n_Mask |= osl_FileStatus_Mask_FileName;
2163 else if(rProp.Name == CasePreservingURL)
2164 n_Mask |= osl_FileStatus_Mask_FileURL;
2165 else if(rProp.Name == IsDocument ||
2166 rProp.Name == IsFolder ||
2167 rProp.Name == IsVolume ||
2168 rProp.Name == IsRemoveable ||
2169 rProp.Name == IsRemote ||
2170 rProp.Name == IsCompactDisc ||
2171 rProp.Name == IsFloppy ||
2172 rProp.Name == ContentType)
2173 n_Mask |= (osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL);
2174 else if(rProp.Name == Size)
2175 n_Mask |= (osl_FileStatus_Mask_FileSize |
2176 osl_FileStatus_Mask_Type |
2177 osl_FileStatus_Mask_LinkTargetURL);
2178 else if(rProp.Name == IsHidden ||
2179 rProp.Name == IsReadOnly)
2180 n_Mask |= osl_FileStatus_Mask_Attributes;
2181 else if(rProp.Name == DateModified)
2182 n_Mask |= osl_FileStatus_Mask_ModifyTime;
2183 }
2184}
2185
2186
2187/*********************************************************************************/
2188/* */
2189/* load-Implementation */
2190/* */
2191/*********************************************************************************/
2192
2193// Load the properties from configuration, if create == true create them.
2194// The Properties are stored under the url belonging to it->first.
2195
2196
2197void
2198TaskManager::load( const ContentMap::iterator& it, bool create )
2199{
2200 if( ( it->second.xS.is() && it->second.xC.is() && it->second.xA.is() )
2201 || !m_xFileRegistry.is() )
2202 return;
2203
2204
2205 uno::Reference< ucb::XPersistentPropertySet > xS = m_xFileRegistry->openPropertySet( it->first,create );
2206 if( xS.is() )
2207 {
2208 uno::Reference< beans::XPropertyContainer > xC( xS,uno::UNO_QUERY );
2209 uno::Reference< beans::XPropertyAccess > xA( xS,uno::UNO_QUERY );
2210
2211 it->second.xS = xS;
2212 it->second.xC = xC;
2213 it->second.xA = xA;
2214
2215 // Now put in all values in the storage in the local hash;
2216
2217 PropertySet& properties = it->second.properties;
2218 const uno::Sequence< beans::Property > seq = xS->getPropertySetInfo()->getProperties();
2219
2220 for( const auto& rProp : seq )
2221 {
2222 MyProperty readProp( false,
2223 rProp.Name,
2224 rProp.Handle,
2225 rProp.Type,
2226 xS->getPropertyValue( rProp.Name ),
2227 beans::PropertyState_DIRECT_VALUE,
2228 rProp.Attributes );
2229 properties.insert( readProp );
2230 }
2231 }
2232 else if( create )
2233 {
2234 // Catastrophic error
2235 }
2236}
2237
2238
2239/*********************************************************************************/
2240/* */
2241/* commit-Implementation */
2242/* */
2243/*********************************************************************************/
2244// Commit inserts the determined properties in the filestatus object into
2245// the internal map, so that is possible to determine on a subsequent
2246// setting of file properties which properties have changed without filestat
2247
2248
2249void
2250TaskManager::commit( std::unique_lock<std::mutex>& rGuard,
2251 const TaskManager::ContentMap::iterator& it,
2252 const osl::FileStatus& aFileStatus )
2253{
2255
2256 if( it->second.properties.empty() )
2257 {
2258 OUString aPath = it->first;
2259 insertDefaultProperties( rGuard, aPath );
2260 }
2261
2262 PropertySet& properties = it->second.properties;
2263
2264 it1 = properties.find( MyProperty( Title ) );
2265 if( it1 != properties.end() )
2266 {
2267 if( aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
2268 {
2269 it1->setValue( uno::Any(aFileStatus.getFileName()) );
2270 }
2271 }
2272
2273 it1 = properties.find( MyProperty( CasePreservingURL ) );
2274 if( it1 != properties.end() )
2275 {
2276 if( aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) )
2277 {
2278 it1->setValue( uno::Any(aFileStatus.getFileURL()) );
2279 }
2280 }
2281
2282
2283 bool isDirectory;
2284
2285 sal_Int64 dirSize = 0;
2286
2287 if( aFileStatus.isValid( osl_FileStatus_Mask_FileSize ) )
2288 dirSize = aFileStatus.getFileSize();
2289
2290 if( aFileStatus.isValid( osl_FileStatus_Mask_Type ) )
2291 {
2292 bool isFile,isVolume;
2293 if( osl::FileStatus::Link == aFileStatus.getFileType() &&
2294 aFileStatus.isValid( osl_FileStatus_Mask_LinkTargetURL ) )
2295 {
2296 osl::DirectoryItem aDirItem;
2297 osl::FileStatus aFileStatus2( osl_FileStatus_Mask_Type );
2298 if( osl::FileBase::E_None == osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(),aDirItem ) &&
2299 osl::FileBase::E_None == aDirItem.getFileStatus( aFileStatus2 ) &&
2300 aFileStatus2.isValid( osl_FileStatus_Mask_Type ) )
2301 {
2302 isVolume = osl::FileStatus::Volume == aFileStatus2.getFileType();
2303 isDirectory =
2304 osl::FileStatus::Volume == aFileStatus2.getFileType() ||
2305 osl::FileStatus::Directory == aFileStatus2.getFileType();
2306 isFile =
2307 osl::FileStatus::Regular == aFileStatus2.getFileType();
2308
2309 if( aFileStatus2.isValid( osl_FileStatus_Mask_FileSize ) )
2310 dirSize = aFileStatus2.getFileSize();
2311 }
2312 else
2313 {
2314 // extremely ugly, but otherwise default construction
2315 // of aDirItem and aFileStatus2
2316 // before the preceding if
2317 isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
2318 isDirectory =
2319 osl::FileStatus::Volume == aFileStatus.getFileType() ||
2320 osl::FileStatus::Directory == aFileStatus.getFileType();
2321 isFile =
2322 osl::FileStatus::Regular == aFileStatus.getFileType();
2323 }
2324 }
2325 else
2326 {
2327 isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
2328 isDirectory =
2329 osl::FileStatus::Volume == aFileStatus.getFileType() ||
2330 osl::FileStatus::Directory == aFileStatus.getFileType();
2331 isFile =
2332 osl::FileStatus::Regular == aFileStatus.getFileType();
2333 }
2334
2335 it1 = properties.find( MyProperty( IsVolume ) );
2336 if( it1 != properties.end() )
2337 it1->setValue( uno::Any( isVolume ) );
2338
2339 it1 = properties.find( MyProperty( IsFolder ) );
2340 if( it1 != properties.end() )
2341 it1->setValue( uno::Any( isDirectory ) );
2342
2343 it1 = properties.find( MyProperty( IsDocument ) );
2344 if( it1 != properties.end() )
2345 it1->setValue( uno::Any( isFile ) );
2346
2347 osl::VolumeInfo aVolumeInfo( osl_VolumeInfo_Mask_Attributes );
2348 if( isVolume &&
2349 osl::FileBase::E_None == osl::Directory::getVolumeInfo( it->first,aVolumeInfo ) &&
2350 aVolumeInfo.isValid( osl_VolumeInfo_Mask_Attributes ) )
2351 {
2352 // Retrieve the flags;
2353 bool isRemote = aVolumeInfo.getRemoteFlag();
2354 bool isRemoveable = aVolumeInfo.getRemoveableFlag();
2355 bool isCompactDisc = aVolumeInfo.getCompactDiscFlag();
2356 bool isFloppy = aVolumeInfo.getFloppyDiskFlag();
2357
2358 it1 = properties.find( MyProperty( IsRemote ) );
2359 if( it1 != properties.end() )
2360 it1->setValue( uno::Any( isRemote ) );
2361
2362 it1 = properties.find( MyProperty( IsRemoveable ) );
2363 if( it1 != properties.end() )
2364 it1->setValue( uno::Any( isRemoveable ) );
2365
2366 it1 = properties.find( MyProperty( IsCompactDisc ) );
2367 if( it1 != properties.end() )
2368 it1->setValue( uno::Any( isCompactDisc ) );
2369
2370 it1 = properties.find( MyProperty( IsFloppy ) );
2371 if( it1 != properties.end() )
2372 it1->setValue( uno::Any( isFloppy ) );
2373 }
2374 else
2375 {
2376 uno::Any aAny(false);
2377 it1 = properties.find( MyProperty( IsRemote ) );
2378 if( it1 != properties.end() )
2379 it1->setValue( aAny );
2380
2381 it1 = properties.find( MyProperty( IsRemoveable ) );
2382 if( it1 != properties.end() )
2383 it1->setValue( aAny );
2384
2385 it1 = properties.find( MyProperty( IsCompactDisc ) );
2386 if( it1 != properties.end() )
2387 it1->setValue( aAny );
2388
2389 it1 = properties.find( MyProperty( IsFloppy ) );
2390 if( it1 != properties.end() )
2391 it1->setValue( aAny );
2392 }
2393 }
2394 else
2395 {
2396 isDirectory = false;
2397 }
2398
2399 it1 = properties.find( MyProperty( Size ) );
2400 if( it1 != properties.end() )
2401 it1->setValue( uno::Any( dirSize ) );
2402
2403 it1 = properties.find( MyProperty( IsReadOnly ) );
2404 if( it1 != properties.end() )
2405 {
2406 if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
2407 {
2408 sal_uInt64 Attr = aFileStatus.getAttributes();
2409 bool readonly = ( Attr & osl_File_Attribute_ReadOnly ) != 0;
2410 it1->setValue( uno::Any( readonly ) );
2411 }
2412 }
2413
2414 it1 = properties.find( MyProperty( IsHidden ) );
2415 if( it1 != properties.end() )
2416 {
2417 if( aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
2418 {
2419 sal_uInt64 Attr = aFileStatus.getAttributes();
2420 bool ishidden = ( Attr & osl_File_Attribute_Hidden ) != 0;
2421 it1->setValue( uno::Any( ishidden ) );
2422 }
2423 }
2424
2425 it1 = properties.find( MyProperty( DateModified ) );
2426 if( it1 != properties.end() )
2427 {
2428 if( aFileStatus.isValid( osl_FileStatus_Mask_ModifyTime ) )
2429 {
2430 TimeValue temp = aFileStatus.getModifyTime();
2431
2432 // Convert system time to local time (for EA)
2433 TimeValue myLocalTime;
2434 if (!osl_getLocalTimeFromSystemTime( &temp, &myLocalTime ))
2435 {
2436 SAL_WARN(
2437 "ucb.ucp.file",
2438 "cannot convert (" << temp.Seconds << ", " << temp.Nanosec
2439 << ") to local time");
2440 myLocalTime = temp;
2441 }
2442
2443 oslDateTime myDateTime;
2444 osl_getDateTimeFromTimeValue( &myLocalTime, &myDateTime );
2445 util::DateTime aDateTime;
2446
2447 aDateTime.NanoSeconds = myDateTime.NanoSeconds;
2448 aDateTime.Seconds = myDateTime.Seconds;
2449 aDateTime.Minutes = myDateTime.Minutes;
2450 aDateTime.Hours = myDateTime.Hours;
2451 aDateTime.Day = myDateTime.Day;
2452 aDateTime.Month = myDateTime.Month;
2453 aDateTime.Year = myDateTime.Year;
2454 it1->setValue( uno::Any( aDateTime ) );
2455 }
2456 }
2457
2459 if( it1 != properties.end() )
2460 it1->setValue( uno::Any(
2461 isDirectory || !aFileStatus.isValid( osl_FileStatus_Mask_Type )
2463 : uno::Sequence< ucb::ContentInfo >() ) );
2464}
2465
2466
2467// Special optimized method for getting the properties of a
2468// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
2469
2470
2471bool
2473 const uno::Sequence< beans::Property >& properties,
2474 osl::DirectoryItem& aDirItem,
2475 OUString& aUnqPath,
2476 bool& aIsRegular,
2477 uno::Reference< sdbc::XRow > & row )
2478{
2479 uno::Sequence< uno::Any > seq( properties.getLength() );
2480
2481 sal_Int32 n_Mask;
2483
2484 // Always retrieve the type and the target URL because item might be a link
2485 osl::FileStatus aFileStatus( n_Mask |
2486 osl_FileStatus_Mask_FileURL |
2487 osl_FileStatus_Mask_Type |
2488 osl_FileStatus_Mask_LinkTargetURL );
2489
2490 osl::FileBase::RC aRes = aDirItem.getFileStatus( aFileStatus );
2491 if ( aRes != osl::FileBase::E_None )
2492 {
2493 SAL_WARN(
2494 "ucb.ucp.file",
2495 "osl::DirectoryItem::getFileStatus failed with " << +aRes);
2496 return false;
2497 }
2498
2499 aUnqPath = aFileStatus.getFileURL();
2500
2501 // If the directory item type is a link retrieve the type of the target
2502
2503 if ( aFileStatus.getFileType() == osl::FileStatus::Link )
2504 {
2505 // Assume failure
2506 aIsRegular = false;
2507 osl::DirectoryItem aTargetItem;
2508 (void)osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
2509 if ( aTargetItem.is() )
2510 {
2511 osl::FileStatus aTargetStatus( osl_FileStatus_Mask_Type );
2512
2513 if ( osl::FileBase::E_None == aTargetItem.getFileStatus( aTargetStatus ) )
2514 aIsRegular =
2515 aTargetStatus.getFileType() == osl::FileStatus::Regular;
2516 }
2517 }
2518 else
2519 aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
2520
2521 {
2522 std::unique_lock aGuard( m_aMutex );
2523
2524 insertDefaultProperties( aGuard, aUnqPath );
2525
2526 TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
2527 commit( aGuard, it, aFileStatus );
2528
2529 PropertySet& propset = it->second.properties;
2530
2531 std::transform(properties.begin(), properties.end(), seq.getArray(),
2532 [&propset](const beans::Property& rProp) -> uno::Any {
2533 MyProperty readProp( rProp.Name );
2534 auto it1 = propset.find( readProp );
2535 if( it1 == propset.end() )
2536 return uno::Any();
2537 return it1->getValue();
2538 });
2539 }
2540
2541 row = new XRow_impl( this,seq );
2542 return true;
2543}
2544
2545
2546// EventListener
2547
2548
2549std::vector< ContentEventNotifier >
2551{
2552 std::vector< ContentEventNotifier > listeners;
2553 {
2554 std::unique_lock aGuard( m_aMutex );
2555 TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2556 if( it != m_aContent.end() && !it->second.notifier.empty() )
2557 {
2558 std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2559 for (auto const& pointer : listOfNotifiers)
2560 {
2561 std::optional<ContentEventNotifier> notifier = pointer->cCEL();
2562 if( notifier )
2563 listeners.push_back( std::move(*notifier) );
2564 }
2565 }
2566 }
2567 return listeners;
2568}
2569
2570
2571std::vector< ContentEventNotifier >
2573{
2574 std::vector< ContentEventNotifier > listeners;
2575 {
2576 std::unique_lock aGuard( m_aMutex );
2577 TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2578 if( it != m_aContent.end() && !it->second.notifier.empty() )
2579 {
2580 std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2581 for (auto const& pointer : listOfNotifiers)
2582 {
2583 std::optional<ContentEventNotifier> notifier = pointer->cDEL();
2584 if( notifier )
2585 listeners.push_back( std::move(*notifier) );
2586 }
2587 }
2588 }
2589 return listeners;
2590}
2591
2592void TaskManager::notifyInsert(const std::vector<ContentEventNotifier>& listeners,
2593 const OUString& aChildName)
2594{
2595 for (const auto & l : listeners )
2596 {
2597 l.notifyChildInserted( aChildName );
2598 }
2599}
2600
2602 const std::vector<ContentEventNotifier>& listeners)
2603{
2604 for( auto const & l : listeners )
2605 {
2606 l.notifyDeleted();
2607 }
2608}
2609
2611 const std::vector<ContentEventNotifier>& listeners, const OUString& aChildName)
2612{
2613 for( auto const & l : listeners )
2614 {
2615 l.notifyRemoved( aChildName );
2616 }
2617}
2618
2619
2620std::vector< PropertySetInfoChangeNotifier >
2622{
2623 std::vector< PropertySetInfoChangeNotifier > listeners;
2624 {
2625 std::unique_lock aGuard( m_aMutex );
2626 TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2627 if( it != m_aContent.end() && !it->second.notifier.empty() )
2628 {
2629 std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2630 for (auto const& pointer : listOfNotifiers)
2631 {
2632 std::optional<PropertySetInfoChangeNotifier> notifier = pointer->cPSL();
2633 if( notifier )
2634 listeners.push_back( std::move(*notifier) );
2635 }
2636 }
2637 }
2638 return listeners;
2639}
2640
2642 const std::vector<PropertySetInfoChangeNotifier>& listeners,
2643 const OUString& aPropertyName)
2644{
2645 for( auto const & l : listeners )
2646 {
2647 l.notifyPropertyAdded( aPropertyName );
2648 }
2649}
2650
2652 const std::vector<PropertySetInfoChangeNotifier>& listeners,
2653 const OUString& aPropertyName)
2654{
2655 for( auto const & l : listeners )
2656 {
2657 l.notifyPropertyRemoved( aPropertyName );
2658 }
2659}
2660
2661
2662std::vector< ContentEventNotifier >
2664 const OUString& aNewPrefix,
2665 bool withChildren )
2666{
2667 std::vector< ContentEventNotifier > aVector;
2668
2669 sal_Int32 count;
2670 OUString aOldName;
2671 OUString aNewName;
2672 std::vector< OUString > oldChildList;
2673
2674 {
2675 std::unique_lock aGuard( m_aMutex );
2676
2677 if( ! withChildren )
2678 {
2679 aOldName = aOldPrefix;
2680 aNewName = aNewPrefix;
2681 count = 1;
2682 }
2683 else
2684 {
2685 for (auto const& content : m_aContent)
2686 {
2687 if( isChild( aOldPrefix, content.first ) )
2688 {
2689 oldChildList.push_back( content.first );
2690 }
2691 }
2692 count = oldChildList.size();
2693 }
2694
2695
2696 for( sal_Int32 j = 0; j < count; ++j )
2697 {
2698 if( withChildren )
2699 {
2700 aOldName = oldChildList[j];
2701 aNewName = newName( aNewPrefix,aOldPrefix,aOldName );
2702 }
2703
2704 TaskManager::ContentMap::iterator itold = m_aContent.find( aOldName );
2705 if( itold != m_aContent.end() )
2706 {
2707 TaskManager::ContentMap::iterator itnew = m_aContent.emplace(
2708 aNewName,UnqPathData() ).first;
2709
2710 // copy Ownership also
2711 itnew->second.properties = std::move(itold->second.properties);
2712
2713 // copy existing list
2714 std::vector< Notifier* > copyList;
2715 std::swap(copyList, itnew->second.notifier);
2716 itnew->second.notifier = std::move(itold->second.notifier);
2717
2718 m_aContent.erase( itold );
2719
2720 if (itnew != m_aContent.end())
2721 {
2722 if (!itnew->second.notifier.empty())
2723 {
2724 std::vector<Notifier*>& listOfNotifiers = itnew->second.notifier;
2725 for (auto const& pointer : listOfNotifiers)
2726 {
2727 std::optional<ContentEventNotifier> notifier = pointer->cEXC( aNewName );
2728 if( notifier )
2729 aVector.push_back( std::move(*notifier) );
2730 }
2731 }
2732
2733 // Merge with preexisting notifiers
2734 // However, these may be in status BaseContent::Deleted
2735 itnew->second.notifier.insert(itnew->second.notifier.end(),
2736 copyList.begin(), copyList.end() );
2737 }
2738 }
2739 }
2740 }
2741
2742 return aVector;
2743}
2744
2746 const std::vector<ContentEventNotifier>& listeners_vec)
2747{
2748 for( auto & l : listeners_vec)
2749 {
2750 l.notifyExchanged();
2751 }
2752}
2753
2754
2755std::vector< PropertyChangeNotifier >
2757{
2758 std::vector< PropertyChangeNotifier > listeners;
2759 {
2760 std::unique_lock aGuard( m_aMutex );
2761 TaskManager::ContentMap::iterator it = m_aContent.find( aName );
2762 if( it != m_aContent.end() && !it->second.notifier.empty() )
2763 {
2764 std::vector<Notifier*>& listOfNotifiers = it->second.notifier;
2765 for (auto const& pointer : listOfNotifiers)
2766 {
2767 std::optional<PropertyChangeNotifier> notifier = pointer->cPCL();
2768 if( notifier )
2769 listeners.push_back( std::move(*notifier) );
2770 }
2771 }
2772 }
2773 return listeners;
2774}
2775
2777 const std::vector<PropertyChangeNotifier>& listeners,
2778 const uno::Sequence<beans::PropertyChangeEvent>& seqChanged)
2779{
2780 for( auto const & l : listeners )
2781 {
2782 l.notifyPropertyChanged( seqChanged );
2783 }
2784}
2785
2786
2787/********************************************************************************/
2788/* remove persistent propertyset */
2789/********************************************************************************/
2790
2791void
2793{
2794 {
2795 // Release possible references
2796 std::unique_lock aGuard( m_aMutex );
2797 ContentMap::iterator it = m_aContent.find( aUnqPath );
2798 if( it != m_aContent.end() )
2799 {
2800 it->second.xS = nullptr;
2801 it->second.xC = nullptr;
2802 it->second.xA = nullptr;
2803
2804 it->second.properties.clear();
2805 }
2806 }
2807
2808 m_xFileRegistry->removePropertySet( aUnqPath );
2809}
2810
2811void
2812TaskManager::erasePersistentSet( const OUString& aUnqPath,
2813 bool withChildren )
2814{
2815 if( ! m_xFileRegistry.is() )
2816 {
2817 OSL_ASSERT( m_xFileRegistry.is() );
2818 return;
2819 }
2820
2821 if( ! withChildren )
2822 {
2824 return;
2825 }
2826
2827 uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
2828 const uno::Sequence< OUString > seqNames = xName->getElementNames();
2829
2830 OUString old_Name = aUnqPath;
2831
2832 for( const auto& rName : seqNames )
2833 {
2834 if( ! ( isChild( old_Name,rName ) ) )
2835 continue;
2836
2837 old_Name = rName;
2838
2840 }
2841}
2842
2843
2844/********************************************************************************/
2845/* copy persistent propertyset */
2846/* from srcUnqPath to dstUnqPath */
2847/********************************************************************************/
2848
2849void
2851 const OUString& dstUnqPath )
2852{
2853 uno::Reference< XPersistentPropertySet > x_src =
2854 m_xFileRegistry->openPropertySet( srcUnqPath,false );
2855 m_xFileRegistry->removePropertySet( dstUnqPath );
2856
2857 if( ! x_src.is() )
2858 return;
2859
2860 const uno::Sequence< beans::Property > seqProperty =
2861 x_src->getPropertySetInfo()->getProperties();
2862
2863 if( ! seqProperty.hasElements() )
2864 return;
2865
2866 uno::Reference< XPersistentPropertySet >
2867 x_dstS = m_xFileRegistry->openPropertySet( dstUnqPath,true );
2868 uno::Reference< beans::XPropertyContainer >
2869 x_dstC( x_dstS,uno::UNO_QUERY );
2870
2871 for( const auto& rProperty : seqProperty )
2872 {
2873 x_dstC->addProperty( rProperty.Name,
2874 rProperty.Attributes,
2875 x_src->getPropertyValue( rProperty.Name ) );
2876 }
2877}
2878
2879void
2880TaskManager::copyPersistentSet( const OUString& srcUnqPath,
2881 const OUString& dstUnqPath,
2882 bool withChildren )
2883{
2884 if( ! m_xFileRegistry.is() )
2885 {
2886 OSL_ASSERT( m_xFileRegistry.is() );
2887 return;
2888 }
2889
2890 if( ! withChildren )
2891 {
2892 copyPersistentSetWithoutChildren(srcUnqPath, dstUnqPath);
2893 return;
2894 }
2895
2896 uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
2897 const uno::Sequence< OUString > seqNames = xName->getElementNames();
2898
2899 OUString new_Name;
2900
2901 for( const auto& rName : seqNames )
2902 {
2903 if( ! ( isChild( srcUnqPath,rName ) ) )
2904 continue;
2905
2906 new_Name = newName( dstUnqPath,srcUnqPath,rName );
2907
2908 copyPersistentSetWithoutChildren(rName, new_Name);
2909 }
2910}
2911
2912uno::Sequence< ucb::ContentInfo > TaskManager::queryCreatableContentsInfo()
2913{
2914
2915
2916 uno::Sequence< beans::Property > props
2917 {
2918 { "Title", -1, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND }
2919 };
2920 return
2921 {
2922 { FileContentType, ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM | ucb::ContentInfoAttribute::KIND_DOCUMENT, props },
2923 { FolderContentType, ucb::ContentInfoAttribute::KIND_FOLDER, props }
2924 };
2925}
2926
2927/*******************************************************************************/
2928/* */
2929/* some miscellaneous static functions */
2930/* */
2931/*******************************************************************************/
2932
2933void
2934TaskManager::getScheme( OUString& Scheme )
2935{
2936 Scheme = "file";
2937}
2938
2939/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Type const & get()
MyProperty(const OUString &thePropertyName)
Definition: filtask.cxx:87
std::vector< ContentEventNotifier > getContentEventListeners(const OUString &aName)
Definition: filtask.cxx:2550
static css::uno::Sequence< css::ucb::ContentInfo > queryCreatableContentsInfo()
Definition: filtask.cxx:2912
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: filtask.hxx:478
void erasePersistentSetWithoutChildren(const OUString &aUnqPath)
Definition: filtask.cxx:2792
bool mkdir(sal_Int32 CommandId, const OUString &aDirectoryName, bool OverWrite)
Creates new directory with given URL, recursively if necessary Return:: success of operation.
Definition: filtask.cxx:1675
void endTask(sal_Int32 CommandId, const OUString &aUnqPath, BaseContent *pContent)
Deinstalls the task and evaluates a possibly set error code.
Definition: filtask.cxx:382
css::uno::Sequence< css::uno::Any > setv(const OUString &aUnqPath, const css::uno::Sequence< css::beans::PropertyValue > &values)
Sets the values of the properties belonging to fileURL aUnqPath.
Definition: filtask.cxx:836
bool write(sal_Int32 CommandId, const OUString &aUnqPath, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
writes to the file with given URL.
Definition: filtask.cxx:1766
void commit(std::unique_lock< std::mutex > &rGuard, const TaskManager::ContentMap::iterator &it, const osl::FileStatus &aFileStatus)
Commit inserts the determined properties in the filestatus object into the internal map,...
Definition: filtask.cxx:2250
void registerNotifier(const OUString &aUnqPath, Notifier *pNotifier)
This two methods register and deregister a change listener for the content belonging to URL aUnqPath.
Definition: filtask.cxx:483
css::uno::Reference< css::ucb::XDynamicResultSet > ls(sal_Int32 CommandId, const OUString &aUnqPath, const sal_Int32 OpenMode, const css::uno::Sequence< css::beans::Property > &sProperty, const css::uno::Sequence< css::ucb::NumberedSortingInfo > &sSortingInfo)
This method returns the result set containing the children of the directory belonging to file URL aUn...
Definition: filtask.cxx:774
std::vector< ContentEventNotifier > getContentDeletedEventListeners(const OUString &aName)
Definition: filtask.cxx:2572
sal_Int32 getCommandId()
Definition: filtask.cxx:448
static void getScheme(OUString &Scheme)
Definition: filtask.cxx:2934
o3tl::sorted_vector< MyProperty, MyPropertyLess > PropertySet
Definition: filtask.hxx:199
static void notifyContentDeleted(const std::vector< ContentEventNotifier > &listeners)
Definition: filtask.cxx:2601
std::vector< PropertyChangeNotifier > getPropertyChangeNotifier(const OUString &aName)
Definition: filtask.cxx:2756
static constexpr OUStringLiteral FolderContentType
Definition: filtask.hxx:627
FileProvider * m_pProvider
Definition: filtask.hxx:477
void erasePersistentSet(const OUString &aUnqPath, bool withChildren=false)
Definition: filtask.cxx:2812
css::uno::Sequence< css::ucb::CommandInfo > m_sCommandInfo
Definition: filtask.hxx:636
void copyPersistentSet(const OUString &srcUnqPath, const OUString &dstUnqPath, bool withChildren)
Definition: filtask.cxx:2880
void installError(sal_Int32 CommandId, sal_Int32 ErrorCode, sal_Int32 minorCode=TASKHANDLER_NO_ERROR)
The error code may be one of the error codes defined in filerror.hxx.
Definition: filtask.cxx:436
bool mkfil(sal_Int32 CommandId, const OUString &aFileName, bool OverWrite, const css::uno::Reference< css::io::XInputStream > &aInputStream)
Creates new file with given URL.
Definition: filtask.cxx:1735
void deregisterNotifier(const OUString &aUnqPath, Notifier *pNotifier)
Definition: filtask.cxx:502
static void notifyInsert(const std::vector< ContentEventNotifier > &listeners, const OUString &aChildName)
Definition: filtask.cxx:2592
void handleTask(sal_Int32 CommandId, const css::uno::Reference< css::task::XInteractionRequest > &request)
Handles an interactionrequest.
Definition: filtask.cxx:455
static bool getUnqFromUrl(const OUString &Url, OUString &Unq)
Definition: filtask.cxx:1960
void copyPersistentSetWithoutChildren(const OUString &srcUnqPath, const OUString &dstUnqPath)
Definition: filtask.cxx:2850
static bool getUrlFromUnq(const OUString &Unq, OUString &Url)
Definition: filtask.cxx:1981
static void notifyPropertyChanges(const std::vector< PropertyChangeNotifier > &listeners, const css::uno::Sequence< css::beans::PropertyChangeEvent > &seqChanged)
Definition: filtask.cxx:2776
void load(const TaskManager::ContentMap::iterator &it, bool create)
Load the properties from configuration, if create == true create them.
Definition: filtask.cxx:2198
bool ensuredir(sal_Int32 CommandId, const OUString &aDirectoryName, sal_Int32 errorCode)
Definition: filtask.cxx:2068
css::uno::Reference< css::beans::XPropertySetInfo > info_p(const OUString &aUnqPath)
Definition: filtask.cxx:819
css::uno::Reference< css::io::XStream > open_rw(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XStream which can be used to read and write from/to...
Definition: filtask.cxx:743
void startTask(sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &xCommandEnv)
Definition: filtask.cxx:367
static void getMaskFromProperties(sal_Int32 &n_Mask, const css::uno::Sequence< css::beans::Property > &seq)
Given a Sequence of properties seq, this method determines the mask used to instantiate an osl::FileS...
Definition: filtask.cxx:2155
void clearError(sal_Int32)
Clears any error which are set on the commandid.
Definition: filtask.cxx:413
TaskManager(const css::uno::Reference< css::uno::XComponentContext > &rxContext, FileProvider *pProvider, bool bWithConfig)
Definition: filtask.cxx:135
css::uno::Reference< css::io::XInputStream > open(sal_Int32 CommandId, const OUString &aUnqPath, bool bLock)
Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
Definition: filtask.cxx:711
void insertDefaultProperties(const OUString &aUnqPath)
Definition: filtask.cxx:1925
css::uno::Reference< css::ucb::XPropertySetRegistry > m_xFileRegistry
Definition: filtask.hxx:479
PropertySet m_aDefaultProperties
Definition: filtask.hxx:635
static void notifyPropertyRemoved(const std::vector< PropertySetInfoChangeNotifier > &listeners, const OUString &aPropertyName)
Definition: filtask.cxx:2651
bool remove(sal_Int32 CommandId, const OUString &aUnqPath, FileUrlType eTypeToMove=FileUrlType::Unknown, bool MustExist=true)
Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
Definition: filtask.cxx:1513
static void notifyContentExchanged(const std::vector< ContentEventNotifier > &listeners_vec)
Definition: filtask.cxx:2745
void move(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, const sal_Int32 NameClash)
Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories )
Definition: filtask.cxx:1133
void retrieveError(sal_Int32 CommandId, sal_Int32 &ErrorCode, sal_Int32 &minorCode)
Definition: filtask.cxx:422
friend class XResultSet_impl
Definition: filtask.hxx:72
void copy(sal_Int32 CommandId, const OUString &srcUnqPath, const OUString &dstUnqPath, sal_Int32 NameClash)
Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
Definition: filtask.cxx:1341
std::vector< ContentEventNotifier > getContentExchangedEventListeners(const OUString &aOldPrefix, const OUString &aNewPrefix, bool withChildren)
Definition: filtask.cxx:2663
osl::FileBase::RC copy_recursive(const OUString &srcUnqPath, const OUString &dstUnqPath, FileUrlType TypeToCopy, bool testExistence)
Definition: filtask.cxx:1994
void deassociate(const OUString &UnqPath, const OUString &PropertyName)
Definition: filtask.cxx:568
friend class XCommandInfo_impl
Definition: filtask.hxx:73
friend class XPropertySetInfo_impl
Definition: filtask.hxx:71
css::uno::Reference< css::ucb::XCommandInfo > info_c()
Info methods.
Definition: filtask.cxx:805
void page(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Reference< css::io::XOutputStream > &xOutputStream)
Given an xOutputStream, this method writes the content of the file belonging to URL aUnqPath into the...
Definition: filtask.cxx:622
css::uno::Reference< css::sdbc::XRow > getv(sal_Int32 CommandId, const OUString &aUnqPath, const css::uno::Sequence< css::beans::Property > &properties)
Reads the values of the properties belonging to fileURL aUnqPath; Returns an XRow object containing t...
static void notifyPropertyAdded(const std::vector< PropertySetInfoChangeNotifier > &listeners, const OUString &aPropertyName)
Definition: filtask.cxx:2641
static constexpr OUStringLiteral FileContentType
Definition: filtask.hxx:629
static void notifyContentRemoved(const std::vector< ContentEventNotifier > &listeners, const OUString &aChildName)
Definition: filtask.cxx:2610
std::vector< PropertySetInfoChangeNotifier > getPropertySetListeners(const OUString &aName)
Definition: filtask.cxx:2621
void associate(const OUString &UnqPath, const OUString &PropertyName, const css::uno::Any &DefaultValue, const sal_Int16 Attributes)
Used to associate and deassociate a new property with the content belonging to URL UnqPath.
Definition: filtask.cxx:529
std::vector< Value >::const_iterator const_iterator
const_iterator find(const Value &x) const
const_iterator end() const
size_type size() const
Any value
#define TASKHANDLER_NO_ERROR
Definition: filerror.hxx:26
#define TASKHANDLING_FILETYPE_FOR_REMOVE
Definition: filerror.hxx:75
#define TASKHANDLING_FOLDER_EXISTS_MKDIR
Definition: filerror.hxx:66
#define TASKHANDLING_CREATEDIRECTORY_MKDIR
Definition: filerror.hxx:68
#define TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE
Definition: filerror.hxx:76
#define TASKHANDLING_TRANSFER_BY_COPY_SOURCE
Definition: filerror.hxx:93
#define TASKHANDLING_IOEXCEPTION_FOR_WRITE
Definition: filerror.hxx:58
#define TASKHANDLING_FILEIOERROR_FOR_WRITE
Definition: filerror.hxx:59
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCE
Definition: filerror.hxx:83
#define TASKHANDLING_OPEN_FILE_FOR_PAGING
Definition: filerror.hxx:40
#define TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE
Definition: filerror.hxx:77
#define TASKHANDLING_NAMECLASH_FOR_COPY
Definition: filerror.hxx:99
#define TASKHANDLING_INPUTSTREAM_FOR_WRITE
Definition: filerror.hxx:62
#define TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE
Definition: filerror.hxx:74
#define TASKHANDLING_KEEPERROR_FOR_MOVE
Definition: filerror.hxx:85
#define TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT
Definition: filerror.hxx:94
#define TASKHANDLING_READING_FILE_FOR_PAGING
Definition: filerror.hxx:44
#define TASKHANDLING_NAMECLASHMOVE_FOR_COPY
Definition: filerror.hxx:100
#define TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE
Definition: filerror.hxx:71
#define TASKHANDLING_NAMECLASHMOVE_FOR_MOVE
Definition: filerror.hxx:87
#define TASKHANDLING_RENAMEMOVE_FOR_MOVE
Definition: filerror.hxx:91
#define TASKHANDLING_OVERWRITE_FOR_COPY
Definition: filerror.hxx:96
#define TASKHANDLING_DELETEFILE_FOR_REMOVE
Definition: filerror.hxx:73
#define TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE
Definition: filerror.hxx:70
#define TASKHANDLING_RENAME_FOR_MOVE
Definition: filerror.hxx:90
#define TASKHANDLING_RENAME_FOR_COPY
Definition: filerror.hxx:97
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT
Definition: filerror.hxx:84
#define TASKHANDLING_ENSUREDIR_FOR_WRITE
Definition: filerror.hxx:64
#define TASKHANDLING_RENAMEMOVE_FOR_COPY
Definition: filerror.hxx:98
#define TASKHANDLING_NOREPLACE_FOR_WRITE
Definition: filerror.hxx:63
#define TASKHANDLING_NOTCONNECTED_FOR_WRITE
Definition: filerror.hxx:56
#define TASKHANDLING_OVERWRITE_FOR_MOVE
Definition: filerror.hxx:89
#define TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE
Definition: filerror.hxx:54
#define TASKHANDLING_KEEPERROR_FOR_COPY
Definition: filerror.hxx:95
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE
Definition: filerror.hxx:57
#define TASKHANDLING_INVALID_NAME_MKDIR
Definition: filerror.hxx:67
#define TASKHANDLING_FILEIOERROR_FOR_NO_SPACE
Definition: filerror.hxx:60
#define TASKHANDLING_NAMECLASH_FOR_MOVE
Definition: filerror.hxx:86
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING
Definition: filerror.hxx:42
#define TASKHANDLING_NOTCONNECTED_FOR_PAGING
Definition: filerror.hxx:41
#define TASKHANDLING_OPENDIRECTORY_FOR_REMOVE
Definition: filerror.hxx:72
#define TASKHANDLING_IOEXCEPTION_FOR_PAGING
Definition: filerror.hxx:43
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE
Definition: filerror.hxx:88
#define TASKHANDLING_NO_OPEN_FILE_FOR_WRITE
Definition: filerror.hxx:55
#define TASKHANDLING_FILESIZE_FOR_WRITE
Definition: filerror.hxx:61
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY
Definition: filerror.hxx:101
constexpr OUStringLiteral IsRemoveable(u"IsRemoveable")
constexpr OUStringLiteral ContentType(u"ContentType")
constexpr OUStringLiteral IsRemote(u"IsRemote")
constexpr OUStringLiteral IsCompactDisc(u"IsCompactDisc")
constexpr OUStringLiteral IsDocument(u"IsDocument")
constexpr OUStringLiteral IsVolume(u"IsVolume")
#define THROW_WHERE
Definition: filtask.cxx:73
constexpr OUStringLiteral DateModified(u"DateModified")
constexpr OUStringLiteral CasePreservingURL(u"CasePreservingURL")
constexpr OUStringLiteral IsFloppy(u"IsFloppy")
constexpr OUStringLiteral IsHidden(u"IsHidden")
constexpr OUStringLiteral IsReadOnly(u"IsReadOnly")
constexpr OUStringLiteral CreatableContentsInfo(u"CreatableContentsInfo")
constexpr OUStringLiteral IsFolder(u"IsFolder")
ErrorCode
const char * name
OUString aName
void * p
sal_uInt16 nPos
#define SAL_WARN(area, stream)
err
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
OUString getParentName(std::u16string_view aFileName)
Definition: filglob.cxx:194
osl::FileBase::RC osl_File_move(const OUString &strPath, const OUString &strDestPath, bool test)
special move: On test = true, the implementation determines whether the destination exists and return...
Definition: filglob.cxx:224
osl::FileBase::RC osl_File_copy(const OUString &strPath, const OUString &strDestPath, bool test)
special copy: On test = true, the implementation determines whether the destination exists and return...
Definition: filglob.cxx:209
void throw_handler(sal_Int32 errorCode, sal_Int32 minorCode, const Reference< XCommandEnvironment > &xEnv, const OUString &aUncPath, BaseContent *pContent, bool isHandled)
Definition: filglob.cxx:238
OUString newName(std::u16string_view aNewPrefix, std::u16string_view aOldPrefix, std::u16string_view old_Name)
Definition: filglob.cxx:176
bool isChild(std::u16string_view srcUnqPath, std::u16string_view dstUnqPath)
Definition: filglob.cxx:156
Value
int i
Title
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
dictionary props
State
bool getType(BSTR name, Type &type)
std::vector< char * > values
sal_Int16 nAttributes
OUString Name
#define sal_True
signed char sal_Int8
ResultType type