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