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