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