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