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