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