1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
25 #include "osl/diagnose.h"
26 #include <rtl/uri.hxx>
27 #include <rtl/ustrbuf.hxx>
29 #include <osl/file.hxx>
30 #include <com/sun/star/lang/IllegalAccessException.hpp>
31 #include <com/sun/star/beans/IllegalTypeException.hpp>
32 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
33 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
34 #include <com/sun/star/ucb/NameClash.hpp>
35 #include <com/sun/star/ucb/Store.hpp>
36 #include <com/sun/star/ucb/XContentIdentifier.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/ucb/XContentAccess.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/io/XSeekable.hpp>
41 #include <com/sun/star/io/XTruncate.hpp>
42 #include <com/sun/star/ucb/OpenCommandArgument.hpp>
43 #include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
44 #include <com/sun/star/ucb/TransferInfo.hpp>
45 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
46 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
47 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
48 #include <rtl/string.hxx>
49 #include "filerror.hxx"
50 #include "filglob.hxx"
52 #include "filinpstr.hxx"
54 #include "filrset.hxx"
62 using namespace fileaccess
;
63 using namespace com::sun::star
;
64 using namespace com::sun::star::ucb
;
66 #if OSL_DEBUG_LEVEL > 0
67 #define THROW_WHERE SAL_WHERE
69 #define THROW_WHERE ""
72 shell::UnqPathData::UnqPathData()
83 shell::UnqPathData::UnqPathData( const UnqPathData
& a
)
84 : properties( a
.properties
),
85 notifier( a
.notifier
),
93 shell::UnqPathData
& shell::UnqPathData::operator=( UnqPathData
& a
)
95 properties
= a
.properties
;
96 notifier
= a
.notifier
;
108 shell::UnqPathData::~UnqPathData()
114 shell::MyProperty::MyProperty( const OUString
& __PropertyName
)
115 : PropertyName( __PropertyName
)
118 , State(beans::PropertyState_AMBIGUOUS_VALUE
)
124 shell::MyProperty::MyProperty( const bool& __isNative
,
125 const OUString
& __PropertyName
,
126 const sal_Int32
& __Handle
,
127 const com::sun::star::uno::Type
& __Typ
,
128 const com::sun::star::uno::Any
& __Value
,
129 const com::sun::star::beans::PropertyState
& __State
,
130 const sal_Int16
& __Attributes
)
131 : PropertyName( __PropertyName
),
133 isNative( __isNative
),
137 Attributes( __Attributes
)
142 shell::MyProperty::~MyProperty()
148 #include "filinl.hxx"
151 shell::shell( const uno::Reference
< uno::XComponentContext
>& rxContext
,
152 FileProvider
* pProvider
, bool bWithConfig
)
154 m_bWithConfig( bWithConfig
),
155 m_pProvider( pProvider
),
156 m_xContext( rxContext
),
158 CasePreservingURL( "CasePreservingURL" ),
159 IsDocument( "IsDocument" ),
160 IsFolder( "IsFolder" ),
161 DateModified( "DateModified" ),
163 IsVolume( "IsVolume" ),
164 IsRemoveable( "IsRemoveable" ),
165 IsRemote( "IsRemote" ),
166 IsCompactDisc( "IsCompactDisc" ),
167 IsFloppy( "IsFloppy" ),
168 IsHidden( "IsHidden" ),
169 ContentType( "ContentType" ),
170 IsReadOnly( "IsReadOnly" ),
171 CreatableContentsInfo( "CreatableContentsInfo" ),
172 FolderContentType( "application/vnd.sun.staroffice.fsys-folder" ),
173 FileContentType( "application/vnd.sun.staroffice.fsys-file" ),
177 m_aDefaultProperties
.insert( MyProperty( true,
180 cppu::UnoType
<OUString
>::get(),
182 beans::PropertyState_DEFAULT_VALUE
,
183 beans::PropertyAttribute::MAYBEVOID
184 | beans::PropertyAttribute::BOUND
) );
187 m_aDefaultProperties
.insert(
191 cppu::UnoType
<OUString
>::get(),
193 beans::PropertyState_DEFAULT_VALUE
,
194 beans::PropertyAttribute::MAYBEVOID
195 | beans::PropertyAttribute::BOUND
196 | beans::PropertyAttribute::READONLY
) );
200 m_aDefaultProperties
.insert( MyProperty( true,
203 cppu::UnoType
<sal_Bool
>::get(),
205 beans::PropertyState_DEFAULT_VALUE
,
206 beans::PropertyAttribute::MAYBEVOID
207 | beans::PropertyAttribute::BOUND
208 | beans::PropertyAttribute::READONLY
) );
212 m_aDefaultProperties
.insert( MyProperty( true,
215 cppu::UnoType
<sal_Bool
>::get(),
217 beans::PropertyState_DEFAULT_VALUE
,
218 beans::PropertyAttribute::MAYBEVOID
219 | beans::PropertyAttribute::BOUND
220 | beans::PropertyAttribute::READONLY
) );
223 m_aDefaultProperties
.insert( MyProperty( true,
226 cppu::UnoType
<sal_Bool
>::get(),
228 beans::PropertyState_DEFAULT_VALUE
,
229 beans::PropertyAttribute::MAYBEVOID
230 | beans::PropertyAttribute::BOUND
231 | beans::PropertyAttribute::READONLY
) );
235 m_aDefaultProperties
.insert( MyProperty( true,
238 cppu::UnoType
<sal_Bool
>::get(),
240 beans::PropertyState_DEFAULT_VALUE
,
241 beans::PropertyAttribute::MAYBEVOID
242 | beans::PropertyAttribute::BOUND
243 | beans::PropertyAttribute::READONLY
) );
246 m_aDefaultProperties
.insert( MyProperty( true,
249 cppu::UnoType
<sal_Bool
>::get(),
251 beans::PropertyState_DEFAULT_VALUE
,
252 beans::PropertyAttribute::MAYBEVOID
253 | beans::PropertyAttribute::BOUND
254 | beans::PropertyAttribute::READONLY
) );
257 m_aDefaultProperties
.insert( MyProperty( true,
260 cppu::UnoType
<sal_Bool
>::get(),
262 beans::PropertyState_DEFAULT_VALUE
,
263 beans::PropertyAttribute::MAYBEVOID
264 | beans::PropertyAttribute::BOUND
265 | beans::PropertyAttribute::READONLY
) );
268 m_aDefaultProperties
.insert( MyProperty( true,
271 cppu::UnoType
<sal_Bool
>::get(),
273 beans::PropertyState_DEFAULT_VALUE
,
274 beans::PropertyAttribute::MAYBEVOID
275 | beans::PropertyAttribute::BOUND
276 | beans::PropertyAttribute::READONLY
) );
279 m_aDefaultProperties
.insert(
284 cppu::UnoType
<sal_Bool
>::get(),
286 beans::PropertyState_DEFAULT_VALUE
,
287 beans::PropertyAttribute::MAYBEVOID
288 | beans::PropertyAttribute::BOUND
292 | beans::PropertyAttribute::READONLY
)); // under unix/linux only readable
299 m_aDefaultProperties
.insert( MyProperty( false,
302 cppu::UnoType
<OUString
>::get(),
304 beans::PropertyState_DEFAULT_VALUE
,
305 beans::PropertyAttribute::MAYBEVOID
306 | beans::PropertyAttribute::BOUND
307 | beans::PropertyAttribute::READONLY
) );
311 m_aDefaultProperties
.insert( MyProperty( true,
314 cppu::UnoType
<util::DateTime
>::get(),
316 beans::PropertyState_DEFAULT_VALUE
,
317 beans::PropertyAttribute::MAYBEVOID
318 | beans::PropertyAttribute::BOUND
) );
321 m_aDefaultProperties
.insert( MyProperty( true,
324 cppu::UnoType
<sal_Int64
>::get(),
326 beans::PropertyState_DEFAULT_VALUE
,
327 beans::PropertyAttribute::MAYBEVOID
328 | beans::PropertyAttribute::BOUND
) );
331 m_aDefaultProperties
.insert( MyProperty( true,
334 cppu::UnoType
<sal_Bool
>::get(),
336 beans::PropertyState_DEFAULT_VALUE
,
337 beans::PropertyAttribute::MAYBEVOID
338 | beans::PropertyAttribute::BOUND
) );
341 // CreatableContentsInfo
342 m_aDefaultProperties
.insert( MyProperty( true,
343 CreatableContentsInfo
,
345 cppu::UnoType
<uno::Sequence
< ucb::ContentInfo
>>::get(),
347 beans::PropertyState_DEFAULT_VALUE
,
348 beans::PropertyAttribute::MAYBEVOID
349 | beans::PropertyAttribute::BOUND
350 | beans::PropertyAttribute::READONLY
) );
353 m_sCommandInfo
[0].Name
= "getCommandInfo";
354 m_sCommandInfo
[0].Handle
= -1;
355 m_sCommandInfo
[0].ArgType
= cppu::UnoType
<void>::get();
357 m_sCommandInfo
[1].Name
= "getPropertySetInfo";
358 m_sCommandInfo
[1].Handle
= -1;
359 m_sCommandInfo
[1].ArgType
= cppu::UnoType
<void>::get();
361 m_sCommandInfo
[2].Name
= "getPropertyValues";
362 m_sCommandInfo
[2].Handle
= -1;
363 m_sCommandInfo
[2].ArgType
= cppu::UnoType
<uno::Sequence
< beans::Property
>>::get();
365 m_sCommandInfo
[3].Name
= "setPropertyValues";
366 m_sCommandInfo
[3].Handle
= -1;
367 m_sCommandInfo
[3].ArgType
= cppu::UnoType
<uno::Sequence
< beans::PropertyValue
>>::get();
369 m_sCommandInfo
[4].Name
= "open";
370 m_sCommandInfo
[4].Handle
= -1;
371 m_sCommandInfo
[4].ArgType
= cppu::UnoType
<OpenCommandArgument
>::get();
373 m_sCommandInfo
[5].Name
= "transfer";
374 m_sCommandInfo
[5].Handle
= -1;
375 m_sCommandInfo
[5].ArgType
= cppu::UnoType
<TransferInfo
>::get();
377 m_sCommandInfo
[6].Name
= "delete";
378 m_sCommandInfo
[6].Handle
= -1;
379 m_sCommandInfo
[6].ArgType
= cppu::UnoType
<sal_Bool
>::get();
381 m_sCommandInfo
[7].Name
= "insert";
382 m_sCommandInfo
[7].Handle
= -1;
383 m_sCommandInfo
[7].ArgType
= cppu::UnoType
<InsertCommandArgument
>::get();
385 m_sCommandInfo
[7].Name
= "createNewContent";
386 m_sCommandInfo
[7].Handle
= -1;
387 m_sCommandInfo
[7].ArgType
= cppu::UnoType
<ucb::ContentInfo
>::get();
391 uno::Reference
< XPropertySetRegistryFactory
> xRegFac
= ucb::Store::create( m_xContext
);
392 // Open/create a registry
393 m_xFileRegistry
= xRegFac
->createPropertySetRegistry( OUString() );
403 /*********************************************************************************/
405 /* de/registerNotifier-Implementation */
407 /*********************************************************************************/
410 // This two methods register and deregister a change listener for the content belonging
415 shell::registerNotifier( const OUString
& aUnqPath
, Notifier
* pNotifier
)
417 osl::MutexGuard
aGuard( m_aMutex
);
419 ContentMap::iterator it
=
420 m_aContent
.insert( ContentMap::value_type( aUnqPath
,UnqPathData() ) ).first
;
422 if( ! it
->second
.notifier
)
423 it
->second
.notifier
= new NotifierList();
425 std::list
< Notifier
* >& nlist
= *( it
->second
.notifier
);
427 std::list
<Notifier
*>::iterator it1
= nlist
.begin();
428 while( it1
!= nlist
.end() ) // Every "Notifier" only once
430 if( *it1
== pNotifier
) return;
433 nlist
.push_back( pNotifier
);
439 shell::deregisterNotifier( const OUString
& aUnqPath
,Notifier
* pNotifier
)
441 osl::MutexGuard
aGuard( m_aMutex
);
443 ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
444 if( it
== m_aContent
.end() )
447 it
->second
.notifier
->remove( pNotifier
);
449 if( ! it
->second
.notifier
->size() )
450 m_aContent
.erase( it
);
455 /*********************************************************************************/
457 /* de/associate-Implementation */
459 /*********************************************************************************/
461 // Used to associate and deassociate a new property with
462 // the content belonging to URL UnqPath.
463 // The default value and the attributes are input
467 shell::associate( const OUString
& aUnqPath
,
468 const OUString
& PropertyName
,
469 const uno::Any
& DefaultValue
,
470 const sal_Int16 Attributes
)
471 throw( beans::PropertyExistException
,
472 beans::IllegalTypeException
,
473 uno::RuntimeException
)
475 MyProperty
newProperty( false,
478 DefaultValue
.getValueType(),
480 beans::PropertyState_DEFAULT_VALUE
,
483 shell::PropertySet::iterator it1
= m_aDefaultProperties
.find( newProperty
);
484 if( it1
!= m_aDefaultProperties
.end() )
485 throw beans::PropertyExistException( THROW_WHERE
);
488 osl::MutexGuard
aGuard( m_aMutex
);
490 ContentMap::iterator it
= m_aContent
.insert( ContentMap::value_type( aUnqPath
,UnqPathData() ) ).first
;
492 // Load the XPersistentPropertySetInfo and create it, if it does not exist
495 PropertySet
& properties
= *(it
->second
.properties
);
496 it1
= properties
.find( newProperty
);
497 if( it1
!= properties
.end() )
498 throw beans::PropertyExistException(THROW_WHERE
);
500 // Property does not exist
501 properties
.insert( newProperty
);
502 it
->second
.xC
->addProperty( PropertyName
,Attributes
,DefaultValue
);
504 notifyPropertyAdded( getPropertySetListeners( aUnqPath
), PropertyName
);
511 shell::deassociate( const OUString
& aUnqPath
,
512 const OUString
& PropertyName
)
513 throw( beans::UnknownPropertyException
,
514 beans::NotRemoveableException
,
515 uno::RuntimeException
)
517 MyProperty
oldProperty( PropertyName
);
519 shell::PropertySet::iterator it1
= m_aDefaultProperties
.find( oldProperty
);
520 if( it1
!= m_aDefaultProperties
.end() )
521 throw beans::NotRemoveableException( THROW_WHERE
);
523 osl::MutexGuard
aGuard( m_aMutex
);
525 ContentMap::iterator it
= m_aContent
.insert( ContentMap::value_type( aUnqPath
,UnqPathData() ) ).first
;
529 PropertySet
& properties
= *(it
->second
.properties
);
531 it1
= properties
.find( oldProperty
);
532 if( it1
== properties
.end() )
533 throw beans::UnknownPropertyException( THROW_WHERE
);
535 properties
.erase( it1
);
537 if( it
->second
.xC
.is() )
538 it
->second
.xC
->removeProperty( PropertyName
);
540 if( properties
.size() == 9 )
542 MyProperty
ContentTProperty( ContentType
);
544 if( properties
.find( ContentTProperty
)->getState() == beans::PropertyState_DEFAULT_VALUE
)
549 if(m_xFileRegistry
.is())
550 m_xFileRegistry
->removePropertySet( aUnqPath
);
553 notifyPropertyRemoved( getPropertySetListeners( aUnqPath
), PropertyName
);
559 /*********************************************************************************/
561 /* page-Implementation */
563 /*********************************************************************************/
565 // Given an xOutputStream, this method writes the content of the file belonging to
566 // URL aUnqPath into the XOutputStream
570 void SAL_CALL
shell::page( sal_Int32 CommandId
,
571 const OUString
& aUnqPath
,
572 const uno::Reference
< io::XOutputStream
>& xOutputStream
)
575 uno::Reference
< XContentProvider
> xProvider( m_pProvider
);
576 osl::File
aFile( aUnqPath
);
577 osl::FileBase::RC err
= aFile
.open( osl_File_OpenFlag_Read
);
579 if( err
!= osl::FileBase::E_None
)
582 installError( CommandId
,
583 TASKHANDLING_OPEN_FILE_FOR_PAGING
,
588 const sal_uInt64 bfz
= 4*1024;
590 sal_uInt64 nrc
; // Retrieved number of Bytes;
594 err
= aFile
.read( (void*) BFF
,bfz
,nrc
);
595 if( err
== osl::FileBase::E_None
)
597 uno::Sequence
< sal_Int8
> seq( BFF
, (sal_uInt32
)nrc
);
600 xOutputStream
->writeBytes( seq
);
602 catch (const io::NotConnectedException
&)
604 installError( CommandId
,
605 TASKHANDLING_NOTCONNECTED_FOR_PAGING
);
608 catch (const io::BufferSizeExceededException
&)
610 installError( CommandId
,
611 TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING
);
614 catch (const io::IOException
&)
616 installError( CommandId
,
617 TASKHANDLING_IOEXCEPTION_FOR_PAGING
);
623 installError( CommandId
,
624 TASKHANDLING_READING_FILE_FOR_PAGING
,
628 } while( nrc
== bfz
);
636 xOutputStream
->closeOutput();
638 catch (const io::NotConnectedException
&)
641 catch (const io::BufferSizeExceededException
&)
644 catch (const io::IOException
&)
650 /*********************************************************************************/
652 /* open-Implementation */
654 /*********************************************************************************/
656 // Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
660 uno::Reference
< io::XInputStream
> SAL_CALL
661 shell::open( sal_Int32 CommandId
,
662 const OUString
& aUnqPath
,
666 XInputStream_impl
* xInputStream
= new XInputStream_impl( this, aUnqPath
, bLock
); // from filinpstr.hxx
668 sal_Int32 ErrorCode
= xInputStream
->CtorSuccess();
670 if( ErrorCode
!= TASKHANDLER_NO_ERROR
)
672 installError( CommandId
,
674 xInputStream
->getMinorError() );
680 return uno::Reference
< io::XInputStream
>( xInputStream
);
686 /*********************************************************************************/
688 /* open for read/write access-Implementation */
690 /*********************************************************************************/
692 // Given a file URL aUnqPath, this methods returns a XStream which can be used
693 // to read and write from/to the file.
697 uno::Reference
< io::XStream
> SAL_CALL
698 shell::open_rw( sal_Int32 CommandId
,
699 const OUString
& aUnqPath
,
703 XStream_impl
* xStream
= new XStream_impl( this, aUnqPath
, bLock
); // from filstr.hxx
705 sal_Int32 ErrorCode
= xStream
->CtorSuccess();
707 if( ErrorCode
!= TASKHANDLER_NO_ERROR
)
709 installError( CommandId
,
711 xStream
->getMinorError() );
716 return uno::Reference
< io::XStream
>( xStream
);
721 /*********************************************************************************/
723 /* ls-Implementation */
725 /*********************************************************************************/
727 // This method returns the result set containing the children of the directory belonging
728 // to file URL aUnqPath
732 uno::Reference
< XDynamicResultSet
> SAL_CALL
733 shell::ls( sal_Int32 CommandId
,
734 const OUString
& aUnqPath
,
735 const sal_Int32 OpenMode
,
736 const uno::Sequence
< beans::Property
>& seq
,
737 const uno::Sequence
< NumberedSortingInfo
>& seqSort
)
740 XResultSet_impl
* p
= new XResultSet_impl( this,aUnqPath
,OpenMode
,seq
,seqSort
);
742 sal_Int32 ErrorCode
= p
->CtorSuccess();
744 if( ErrorCode
!= TASKHANDLER_NO_ERROR
)
746 installError( CommandId
,
748 p
->getMinorError() );
754 return uno::Reference
< XDynamicResultSet
> ( p
);
760 /*********************************************************************************/
762 /* info_c implementation */
764 /*********************************************************************************/
767 uno::Reference
< XCommandInfo
> SAL_CALL
771 XCommandInfo_impl
* p
= new XCommandInfo_impl( this );
772 return uno::Reference
< XCommandInfo
>( p
);
778 /*********************************************************************************/
780 /* info_p-Implementation */
782 /*********************************************************************************/
783 // Info for the properties
785 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
786 shell::info_p( const OUString
& aUnqPath
)
789 osl::MutexGuard
aGuard( m_aMutex
);
790 XPropertySetInfo_impl
* p
= new XPropertySetInfo_impl( this,aUnqPath
);
791 return uno::Reference
< beans::XPropertySetInfo
>( p
);
797 /*********************************************************************************/
799 /* setv-Implementation */
801 /*********************************************************************************/
803 // Sets the values of the properties belonging to fileURL aUnqPath
807 uno::Sequence
< uno::Any
> SAL_CALL
808 shell::setv( const OUString
& aUnqPath
,
809 const uno::Sequence
< beans::PropertyValue
>& values
)
812 osl::MutexGuard
aGuard( m_aMutex
);
814 sal_Int32 propChanged
= 0;
815 uno::Sequence
< uno::Any
> ret( values
.getLength() );
816 uno::Sequence
< beans::PropertyChangeEvent
> seqChanged( values
.getLength() );
818 shell::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
819 PropertySet
& properties
= *( it
->second
.properties
);
820 shell::PropertySet::iterator it1
;
823 for( sal_Int32 i
= 0; i
< values
.getLength(); ++i
)
825 MyProperty
toset( values
[i
].Name
);
826 it1
= properties
.find( toset
);
827 if( it1
== properties
.end() )
829 ret
[i
] <<= beans::UnknownPropertyException( THROW_WHERE
);
833 aAny
= it1
->getValue();
834 if( aAny
== values
[i
].Value
)
835 continue; // nothing needs to be changed
837 if( it1
->getAttributes() & beans::PropertyAttribute::READONLY
)
839 ret
[i
] <<= lang::IllegalAccessException( THROW_WHERE
);
843 seqChanged
[ propChanged
].PropertyName
= values
[i
].Name
;
844 seqChanged
[ propChanged
].PropertyHandle
= -1;
845 seqChanged
[ propChanged
].Further
= false;
846 seqChanged
[ propChanged
].OldValue
<<= aAny
;
847 seqChanged
[ propChanged
++ ].NewValue
= values
[i
].Value
;
849 it1
->setValue( values
[i
].Value
); // Put the new value into the local cash
851 if( ! it1
->IsNative() )
853 // Also put logical properties into storage
854 if( !it
->second
.xS
.is() )
857 if( ( values
[i
].Name
== ContentType
) &&
858 it1
->getState() == beans::PropertyState_DEFAULT_VALUE
)
859 { // Special logic for ContentType
860 // 09.07.01: Not reached anymore, because ContentType is readonly
861 it1
->setState( beans::PropertyState_DIRECT_VALUE
);
862 it
->second
.xC
->addProperty( values
[i
].Name
,
863 beans::PropertyAttribute::MAYBEVOID
,
869 it
->second
.xS
->setPropertyValue( values
[i
].Name
,values
[i
].Value
);
871 catch (const uno::Exception
&e
)
873 --propChanged
; // unsuccessful setting
880 // Setting of physical file properties
881 if( values
[i
].Name
== Size
)
883 sal_Int64 newSize
= 0;
884 if( values
[i
].Value
>>= newSize
)
885 { // valid value for the size
886 osl::File
aFile(aUnqPath
);
888 aFile
.open(osl_File_OpenFlag_Write
) != osl::FileBase::E_None
||
889 aFile
.setSize(sal_uInt64(newSize
)) != osl::FileBase::E_None
||
890 aFile
.close() != osl::FileBase::E_None
;
894 --propChanged
; // unsuccessful setting
895 uno::Sequence
< uno::Any
> names( 1 );
896 ret
[0] <<= beans::PropertyValue(
898 uno::makeAny(aUnqPath
),
899 beans::PropertyState_DIRECT_VALUE
);
900 IOErrorCode
ioError(IOErrorCode_GENERAL
);
901 ret
[i
] <<= InteractiveAugmentedIOException(
904 task::InteractionClassification_ERROR
,
910 ret
[i
] <<= beans::IllegalTypeException( THROW_WHERE
);
912 else if(values
[i
].Name
== IsReadOnly
||
913 values
[i
].Name
== IsHidden
)
916 if( values
[i
].Value
>>= value
)
918 osl::DirectoryItem aDirItem
;
919 osl::FileBase::RC err
=
920 osl::DirectoryItem::get(aUnqPath
,aDirItem
);
921 sal_uInt64
nAttributes(0);
922 if(err
== osl::FileBase::E_None
)
924 osl::FileStatus
aFileStatus(osl_FileStatus_Mask_Attributes
);
925 err
= aDirItem
.getFileStatus(aFileStatus
);
926 if(err
== osl::FileBase::E_None
&&
927 aFileStatus
.isValid(osl_FileStatus_Mask_Attributes
))
928 nAttributes
= aFileStatus
.getAttributes();
930 // now we have the attributes provided all went well.
931 if(err
== osl::FileBase::E_None
) {
932 if(values
[i
].Name
== IsReadOnly
)
934 nAttributes
&= ~(osl_File_Attribute_OwnWrite
|
935 osl_File_Attribute_GrpWrite
|
936 osl_File_Attribute_OthWrite
|
937 osl_File_Attribute_ReadOnly
);
939 nAttributes
|= osl_File_Attribute_ReadOnly
;
942 osl_File_Attribute_OwnWrite
|
943 osl_File_Attribute_GrpWrite
|
944 osl_File_Attribute_OthWrite
);
946 else if(values
[i
].Name
== IsHidden
)
948 nAttributes
&= ~(osl_File_Attribute_Hidden
);
950 nAttributes
|= osl_File_Attribute_Hidden
;
952 err
= osl::File::setAttributes(
953 aUnqPath
,nAttributes
);
956 if( err
!= osl::FileBase::E_None
)
958 --propChanged
; // unsuccessful setting
959 uno::Sequence
< uno::Any
> names( 1 );
960 names
[0] <<= beans::PropertyValue(
962 uno::makeAny(aUnqPath
),
963 beans::PropertyState_DIRECT_VALUE
);
967 case osl::FileBase::E_NOMEM
:
968 // not enough memory for allocating structures <br>
969 ioError
= IOErrorCode_OUT_OF_MEMORY
;
971 case osl::FileBase::E_INVAL
:
972 // the format of the parameters was not valid<p>
973 ioError
= IOErrorCode_INVALID_PARAMETER
;
975 case osl::FileBase::E_NAMETOOLONG
:
976 // File name too long<br>
977 ioError
= IOErrorCode_NAME_TOO_LONG
;
979 case osl::FileBase::E_NOENT
:
980 // No such file or directory<br>
981 case osl::FileBase::E_NOLINK
:
982 // Link has been severed<br>
983 ioError
= IOErrorCode_NOT_EXISTING
;
985 case osl::FileBase::E_ROFS
:
986 // #i4735# handle ROFS transparently
988 case osl::FileBase::E_PERM
:
989 case osl::FileBase::E_ACCES
:
990 // permission denied<br>
991 ioError
= IOErrorCode_ACCESS_DENIED
;
993 case osl::FileBase::E_LOOP
:
994 // Too many symbolic links encountered<br>
995 case osl::FileBase::E_FAULT
:
997 case osl::FileBase::E_IO
:
999 case osl::FileBase::E_NOSYS
:
1000 // Function not implemented<br>
1001 case osl::FileBase::E_MULTIHOP
:
1002 // Multihop attempted<br>
1003 case osl::FileBase::E_INTR
:
1004 // function call was interrupted<p>
1006 ioError
= IOErrorCode_GENERAL
;
1009 ret
[i
] <<= InteractiveAugmentedIOException(
1012 task::InteractionClassification_ERROR
,
1018 ret
[i
] <<= beans::IllegalTypeException( THROW_WHERE
);
1025 seqChanged
.realloc( propChanged
);
1026 notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath
),seqChanged
);
1032 /*********************************************************************************/
1034 /* getv-Implementation */
1036 /*********************************************************************************/
1038 // Reads the values of the properties belonging to fileURL aUnqPath;
1039 // Returns an XRow object containing the values in the requested order.
1043 uno::Reference
< sdbc::XRow
> SAL_CALL
1044 shell::getv( sal_Int32 CommandId
,
1045 const OUString
& aUnqPath
,
1046 const uno::Sequence
< beans::Property
>& properties
)
1049 uno::Sequence
< uno::Any
> seq( properties
.getLength() );
1052 getMaskFromProperties( n_Mask
,properties
);
1053 osl::FileStatus
aFileStatus( n_Mask
);
1055 osl::DirectoryItem aDirItem
;
1056 osl::FileBase::RC nError1
= osl::DirectoryItem::get( aUnqPath
,aDirItem
);
1057 if( nError1
!= osl::FileBase::E_None
)
1058 installError(CommandId
,
1059 TASKHANDLING_OPEN_FILE_FOR_PAGING
, // BEAWARE, REUSED
1062 osl::FileBase::RC nError2
= aDirItem
.getFileStatus( aFileStatus
);
1063 if( nError1
== osl::FileBase::E_None
&&
1064 nError2
!= osl::FileBase::E_None
)
1065 installError(CommandId
,
1066 TASKHANDLING_OPEN_FILE_FOR_PAGING
, // BEAWARE, REUSED
1070 osl::MutexGuard
aGuard( m_aMutex
);
1072 shell::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
1073 commit( it
,aFileStatus
);
1075 shell::PropertySet::iterator it1
;
1076 PropertySet
& propset
= *(it
->second
.properties
);
1078 for( sal_Int32 i
= 0; i
< seq
.getLength(); ++i
)
1080 MyProperty
readProp( properties
[i
].Name
);
1081 it1
= propset
.find( readProp
);
1082 if( it1
== propset
.end() )
1083 seq
[i
] = uno::Any();
1085 seq
[i
] = it1
->getValue();
1089 XRow_impl
* p
= new XRow_impl( this,seq
);
1090 return uno::Reference
< sdbc::XRow
>( p
);
1094 /********************************************************************************/
1096 /* transfer-commandos */
1098 /********************************************************************************/
1101 /********************************************************************************/
1103 /* move-implementation */
1105 /********************************************************************************/
1107 // Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
1111 shell::move( sal_Int32 CommandId
,
1112 const OUString
& srcUnqPath
,
1113 const OUString
& dstUnqPathIn
,
1114 const sal_Int32 NameClash
)
1117 // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
1118 // srcUnqPath and dstUnqPathIn are equal
1119 if( srcUnqPath
== dstUnqPathIn
)
1122 osl::FileBase::RC nError
;
1123 OUString
dstUnqPath( dstUnqPathIn
);
1127 case NameClash::KEEP
:
1129 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1130 if( nError
!= osl::FileBase::E_None
&& nError
!= osl::FileBase::E_EXIST
)
1132 installError( CommandId
,
1133 TASKHANDLING_KEEPERROR_FOR_MOVE
,
1139 case NameClash::OVERWRITE
:
1141 // stat to determine whether we have a symlink
1142 OUString
targetPath(dstUnqPath
);
1144 osl::FileStatus
aStatus(osl_FileStatus_Mask_Type
|osl_FileStatus_Mask_LinkTargetURL
);
1145 osl::DirectoryItem aItem
;
1146 osl::DirectoryItem::get(dstUnqPath
,aItem
);
1147 aItem
.getFileStatus(aStatus
);
1149 if( aStatus
.isValid(osl_FileStatus_Mask_Type
) &&
1150 aStatus
.isValid(osl_FileStatus_Mask_LinkTargetURL
) &&
1151 aStatus
.getFileType() == osl::FileStatus::Link
)
1152 targetPath
= aStatus
.getLinkTargetURL();
1154 // Will do nothing if file does not exist.
1155 osl::File::remove( targetPath
);
1157 nError
= osl_File_move( srcUnqPath
,targetPath
);
1158 if( nError
!= osl::FileBase::E_None
)
1160 installError( CommandId
,
1161 TASKHANDLING_OVERWRITE_FOR_MOVE
,
1167 case NameClash::RENAME
:
1169 OUString newDstUnqPath
;
1170 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1171 if( nError
== osl::FileBase::E_EXIST
)
1173 // "invent" a new valid title.
1175 sal_Int32 nPos
= -1;
1176 sal_Int32 nLastDot
= dstUnqPath
.lastIndexOf( '.' );
1177 sal_Int32 nLastSlash
= dstUnqPath
.lastIndexOf( '/' );
1178 if( ( nLastSlash
< nLastDot
) // dot is part of last(!) path segment
1179 && ( nLastSlash
!= ( nLastDot
- 1 ) ) ) // file name does not start with a dot
1182 nPos
= dstUnqPath
.getLength();
1188 newDstUnqPath
= dstUnqPath
;
1190 OUString aPostfix
= "_" + OUString::number( ++nTry
);
1192 newDstUnqPath
= newDstUnqPath
.replaceAt( nPos
, 0, aPostfix
);
1194 nError
= osl_File_move( srcUnqPath
,newDstUnqPath
,true );
1196 while( ( nError
== osl::FileBase::E_EXIST
) && ( nTry
< 10000 ) );
1199 if( nError
== osl::FileBase::E_EXIST
)
1201 installError( CommandId
,
1202 TASKHANDLING_RENAME_FOR_MOVE
);
1205 else if( nError
!= osl::FileBase::E_None
)
1207 installError( CommandId
,
1208 TASKHANDLING_RENAMEMOVE_FOR_MOVE
,
1213 dstUnqPath
= newDstUnqPath
;
1217 case NameClash::ERROR
:
1219 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1220 if( nError
== osl::FileBase::E_EXIST
)
1222 installError( CommandId
,
1223 TASKHANDLING_NAMECLASH_FOR_MOVE
);
1226 else if( nError
!= osl::FileBase::E_None
)
1228 installError( CommandId
,
1229 TASKHANDLING_NAMECLASHMOVE_FOR_MOVE
,
1235 case NameClash::ASK
:
1238 nError
= osl_File_move( srcUnqPath
,dstUnqPath
,true );
1239 if( nError
== osl::FileBase::E_EXIST
)
1241 installError( CommandId
,
1242 TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE
,
1250 // Determine, whether we have moved a file or a folder
1251 osl::DirectoryItem aItem
;
1252 nError
= osl::DirectoryItem::get( dstUnqPath
,aItem
);
1253 if( nError
!= osl::FileBase::E_None
)
1255 installError( CommandId
,
1256 TASKHANDLING_TRANSFER_BY_MOVE_SOURCE
,
1260 osl::FileStatus
aStatus( osl_FileStatus_Mask_Type
);
1261 nError
= aItem
.getFileStatus( aStatus
);
1262 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( osl_FileStatus_Mask_Type
) )
1264 installError( CommandId
,
1265 TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT
,
1269 bool isDocument
= ( aStatus
.getFileType() == osl::FileStatus::Regular
);
1272 copyPersistentSet( srcUnqPath
,dstUnqPath
,!isDocument
);
1274 OUString aDstParent
= getParentName( dstUnqPath
);
1275 OUString aSrcParent
= getParentName( srcUnqPath
);
1277 notifyInsert( getContentEventListeners( aDstParent
),dstUnqPath
);
1278 if( aDstParent
!= aSrcParent
)
1279 notifyContentRemoved( getContentEventListeners( aSrcParent
),srcUnqPath
);
1281 notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath
,dstUnqPath
,!isDocument
) );
1282 erasePersistentSet( srcUnqPath
,!isDocument
);
1287 /********************************************************************************/
1289 /* copy-implementation */
1291 /********************************************************************************/
1293 // Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
1299 TaskManager
& task
, sal_Int32 id
, OUString
const & fileUrl
,
1300 osl::DirectoryItem
* item
, osl::FileStatus::Type
* type
)
1302 OSL_ASSERT(item
!= 0 && type
!= 0);
1303 osl::FileBase::RC err
= osl::DirectoryItem::get(fileUrl
, *item
);
1304 if (err
!= osl::FileBase::E_None
) {
1305 task
.installError(id
, TASKHANDLING_TRANSFER_BY_COPY_SOURCE
, err
);
1308 osl::FileStatus
stat(osl_FileStatus_Mask_Type
);
1309 err
= item
->getFileStatus(stat
);
1310 if (err
!= osl::FileBase::E_None
) {
1311 task
.installError(id
, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT
, err
);
1314 *type
= stat
.getFileType();
1322 sal_Int32 CommandId
,
1323 const OUString
& srcUnqPath
,
1324 const OUString
& dstUnqPathIn
,
1325 sal_Int32 NameClash
)
1328 osl::FileBase::RC nError
;
1329 OUString
dstUnqPath( dstUnqPathIn
);
1331 // Resolve symbolic links within the source path. If srcUnqPath denotes a
1332 // symbolic link (targeting either a file or a folder), the contents of the
1333 // target is copied (recursively, in the case of a folder). However, if
1334 // recursively copying the contents of a folder causes a symbolic link to be
1335 // copied, the symbolic link itself is copied.
1336 osl::DirectoryItem item
;
1337 osl::FileStatus::Type type
;
1338 if (!getType(*this, CommandId
, srcUnqPath
, &item
, &type
)) {
1341 OUString rslvdSrcUnqPath
;
1342 if (type
== osl::FileStatus::Link
) {
1343 osl::FileStatus
stat(osl_FileStatus_Mask_LinkTargetURL
);
1344 nError
= item
.getFileStatus(stat
);
1345 if (nError
!= osl::FileBase::E_None
) {
1347 CommandId
, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT
, nError
);
1350 rslvdSrcUnqPath
= stat
.getLinkTargetURL();
1351 if (!getType(*this, CommandId
, srcUnqPath
, &item
, &type
)) {
1355 rslvdSrcUnqPath
= srcUnqPath
;
1359 = type
!= osl::FileStatus::Directory
&& type
!= osl::FileStatus::Volume
;
1360 sal_Int32 IsWhat
= isDocument
? -1 : 1;
1364 case NameClash::KEEP
:
1366 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1367 if( nError
!= osl::FileBase::E_None
&& nError
!= osl::FileBase::E_EXIST
)
1369 installError( CommandId
,
1370 TASKHANDLING_KEEPERROR_FOR_COPY
,
1376 case NameClash::OVERWRITE
:
1378 // remove (..., MustExist = sal_False).
1379 remove( CommandId
, dstUnqPath
, IsWhat
, false );
1382 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,false );
1383 if( nError
!= osl::FileBase::E_None
)
1385 installError( CommandId
,
1386 TASKHANDLING_OVERWRITE_FOR_COPY
,
1392 case NameClash::RENAME
:
1394 OUString newDstUnqPath
;
1395 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1397 if( nError
== osl::FileBase::E_EXIST
)
1399 // "invent" a new valid title.
1401 sal_Int32 nPos
= -1;
1402 sal_Int32 nLastDot
= dstUnqPath
.lastIndexOf( '.' );
1403 sal_Int32 nLastSlash
= dstUnqPath
.lastIndexOf( '/' );
1404 if ( ( nLastSlash
< nLastDot
) // dot is part of last(!) path segment
1405 && ( nLastSlash
!= ( nLastDot
- 1 ) ) ) // file name does not start with a dot
1408 nPos
= dstUnqPath
.getLength();
1414 newDstUnqPath
= dstUnqPath
;
1416 OUString aPostfix
= "_" + OUString::number( ++nTry
);
1418 newDstUnqPath
= newDstUnqPath
.replaceAt( nPos
, 0, aPostfix
);
1420 nError
= copy_recursive( rslvdSrcUnqPath
,newDstUnqPath
,IsWhat
,true );
1422 while( ( nError
== osl::FileBase::E_EXIST
) && ( nTry
< 10000 ) );
1425 if( nError
== osl::FileBase::E_EXIST
)
1427 installError( CommandId
,
1428 TASKHANDLING_RENAME_FOR_COPY
);
1431 else if( nError
!= osl::FileBase::E_None
)
1433 installError( CommandId
,
1434 TASKHANDLING_RENAMEMOVE_FOR_COPY
,
1439 dstUnqPath
= newDstUnqPath
;
1443 case NameClash::ERROR
:
1445 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1447 if( nError
== osl::FileBase::E_EXIST
)
1449 installError( CommandId
,
1450 TASKHANDLING_NAMECLASH_FOR_COPY
);
1453 else if( nError
!= osl::FileBase::E_None
)
1455 installError( CommandId
,
1456 TASKHANDLING_NAMECLASHMOVE_FOR_COPY
,
1462 case NameClash::ASK
:
1465 nError
= copy_recursive( rslvdSrcUnqPath
,dstUnqPath
,IsWhat
,true );
1467 if( nError
== osl::FileBase::E_EXIST
)
1469 installError( CommandId
,
1470 TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY
,
1478 copyPersistentSet( srcUnqPath
,dstUnqPath
, !isDocument
);
1479 notifyInsert( getContentEventListeners( getParentName( dstUnqPath
) ),dstUnqPath
);
1484 /********************************************************************************/
1486 /* remove-implementation */
1488 /********************************************************************************/
1490 // Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
1491 // Return: success of operation
1496 shell::remove( sal_Int32 CommandId
,
1497 const OUString
& aUnqPath
,
1502 sal_Int32 nMask
= osl_FileStatus_Mask_Type
| osl_FileStatus_Mask_FileURL
;
1504 osl::DirectoryItem aItem
;
1505 osl::FileStatus
aStatus( nMask
);
1506 osl::FileBase::RC nError
;
1508 if( IsWhat
== 0 ) // Determine whether we are removing a directory or a file
1510 nError
= osl::DirectoryItem::get( aUnqPath
, aItem
);
1511 if( nError
!= osl::FileBase::E_None
)
1515 installError( CommandId
,
1516 TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE
,
1519 return (!MustExist
);
1522 nError
= aItem
.getFileStatus( aStatus
);
1523 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( nMask
) )
1525 installError( CommandId
,
1526 TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE
,
1527 nError
!= osl::FileBase::E_None
? nError
: TASKHANDLER_NO_ERROR
);
1531 if( aStatus
.getFileType() == osl::FileStatus::Regular
||
1532 aStatus
.getFileType() == osl::FileStatus::Link
)
1533 IsWhat
= -1; // RemoveFile
1534 else if( aStatus
.getFileType() == osl::FileStatus::Directory
||
1535 aStatus
.getFileType() == osl::FileStatus::Volume
)
1536 IsWhat
= +1; // RemoveDirectory
1540 if( IsWhat
== -1 ) // Removing a file
1542 nError
= osl::File::remove( aUnqPath
);
1543 if( nError
!= osl::FileBase::E_None
)
1547 installError( CommandId
,
1548 TASKHANDLING_DELETEFILE_FOR_REMOVE
,
1551 return (!MustExist
);
1555 notifyContentDeleted( getContentDeletedEventListeners(aUnqPath
) );
1556 erasePersistentSet( aUnqPath
); // Removes from XPersistentPropertySet
1559 else if( IsWhat
== +1 ) // Removing a directory
1561 osl::Directory
aDirectory( aUnqPath
);
1563 nError
= aDirectory
.open();
1564 if( nError
!= osl::FileBase::E_None
)
1568 installError( CommandId
,
1569 TASKHANDLING_OPENDIRECTORY_FOR_REMOVE
,
1572 return (!MustExist
);
1575 bool whileSuccess
= true;
1576 sal_Int32 recurse
= 0;
1579 nError
= aDirectory
.getNextItem( aItem
);
1580 while( nError
== osl::FileBase::E_None
)
1582 nError
= aItem
.getFileStatus( aStatus
);
1583 if( nError
!= osl::FileBase::E_None
|| ! aStatus
.isValid( nMask
) )
1585 installError( CommandId
,
1586 TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE
,
1587 nError
!= osl::FileBase::E_None
? nError
: TASKHANDLER_NO_ERROR
);
1588 whileSuccess
= false;
1592 if( aStatus
.getFileType() == osl::FileStatus::Regular
||
1593 aStatus
.getFileType() == osl::FileStatus::Link
)
1595 else if( aStatus
.getFileType() == osl::FileStatus::Directory
||
1596 aStatus
.getFileType() == osl::FileStatus::Volume
)
1599 name
= aStatus
.getFileURL();
1600 whileSuccess
= remove(
1601 CommandId
, name
, recurse
, MustExist
);
1605 nError
= aDirectory
.getNextItem( aItem
);
1610 if( ! whileSuccess
)
1611 return false; // error code is installed
1613 if( nError
!= osl::FileBase::E_NOENT
)
1615 installError( CommandId
,
1616 TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE
,
1621 nError
= osl::Directory::remove( aUnqPath
);
1622 if( nError
!= osl::FileBase::E_None
)
1626 installError( CommandId
,
1627 TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE
,
1630 return (!MustExist
);
1634 notifyContentDeleted( getContentDeletedEventListeners(aUnqPath
) );
1635 erasePersistentSet( aUnqPath
);
1638 else // Don't know what to remove
1640 installError( CommandId
,
1641 TASKHANDLING_FILETYPE_FOR_REMOVE
);
1649 /********************************************************************************/
1651 /* mkdir-implementation */
1653 /********************************************************************************/
1655 // Creates new directory with given URL, recursively if necessary
1656 // Return:: success of operation
1660 shell::mkdir( sal_Int32 CommandId
,
1661 const OUString
& rUnqPath
,
1667 // remove trailing slash
1668 if ( rUnqPath
.endsWith("/") )
1669 aUnqPath
= rUnqPath
.copy( 0, rUnqPath
.getLength() - 1 );
1671 aUnqPath
= rUnqPath
;
1673 osl::FileBase::RC nError
= osl::Directory::create( aUnqPath
);
1677 case osl::FileBase::E_EXIST
: // Directory cannot be overwritten
1681 installError( CommandId
,
1682 TASKHANDLING_FOLDER_EXISTS_MKDIR
);
1688 case osl::FileBase::E_INVAL
:
1690 installError(CommandId
,
1691 TASKHANDLING_INVALID_NAME_MKDIR
);
1694 case osl::FileBase::E_None
:
1696 OUString aPrtPath
= getParentName( aUnqPath
);
1697 notifyInsert( getContentEventListeners( aPrtPath
),aUnqPath
);
1704 TASKHANDLING_CREATEDIRECTORY_MKDIR
);
1709 /********************************************************************************/
1711 /* mkfil-implementation */
1713 /********************************************************************************/
1715 // Creates new file with given URL.
1716 // The content of aInputStream becomes the content of the file
1717 // Return:: success of operation
1721 shell::mkfil( sal_Int32 CommandId
,
1722 const OUString
& aUnqPath
,
1724 const uno::Reference
< io::XInputStream
>& aInputStream
)
1727 // return value unimportant
1728 bool bSuccess
= write( CommandId
,
1734 OUString aPrtPath
= getParentName( aUnqPath
);
1735 notifyInsert( getContentEventListeners( aPrtPath
),aUnqPath
);
1741 /********************************************************************************/
1743 /* write-implementation */
1745 /********************************************************************************/
1747 // writes to the file with given URL.
1748 // The content of aInputStream becomes the content of the file
1749 // Return:: success of operation
1753 shell::write( sal_Int32 CommandId
,
1754 const OUString
& aUnqPath
,
1756 const uno::Reference
< io::XInputStream
>& aInputStream
)
1759 if( ! aInputStream
.is() )
1761 installError( CommandId
,
1762 TASKHANDLING_INPUTSTREAM_FOR_WRITE
);
1766 // Create parent path, if necessary.
1767 if ( ! ensuredir( CommandId
,
1768 getParentName( aUnqPath
),
1769 TASKHANDLING_ENSUREDIR_FOR_WRITE
) )
1772 osl::FileBase::RC err
;
1773 osl::File
aFile( aUnqPath
);
1777 err
= aFile
.open( osl_File_OpenFlag_Write
| osl_File_OpenFlag_Create
);
1779 if( err
!= osl::FileBase::E_None
)
1782 err
= aFile
.open( osl_File_OpenFlag_Write
);
1784 if( err
!= osl::FileBase::E_None
)
1786 installError( CommandId
,
1787 TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE
,
1792 // the existing file was just opened and should be overwritten now,
1793 // truncate it first
1795 err
= aFile
.setSize( 0 );
1796 if( err
!= osl::FileBase::E_None
)
1798 installError( CommandId
,
1799 TASKHANDLING_FILESIZE_FOR_WRITE
,
1807 err
= aFile
.open( osl_File_OpenFlag_Read
| osl_File_OpenFlag_NoLock
);
1808 if( err
== osl::FileBase::E_None
) // The file exists and shall not be overwritten
1810 installError( CommandId
,
1811 TASKHANDLING_NOREPLACE_FOR_WRITE
, // Now an exception
1818 // as a temporary solution the creation does not lock the file at all
1819 // in future it should be possible to create the file without lock explicitly
1820 err
= aFile
.open( osl_File_OpenFlag_Write
| osl_File_OpenFlag_Create
| osl_File_OpenFlag_NoLock
);
1822 if( err
!= osl::FileBase::E_None
)
1825 installError( CommandId
,
1826 TASKHANDLING_NO_OPEN_FILE_FOR_WRITE
,
1832 bool bSuccess
= true;
1834 sal_uInt64 nWrittenBytes
;
1835 sal_Int32 nReadBytes
= 0, nRequestedBytes
= 32768 /*32k*/;
1836 uno::Sequence
< sal_Int8
> seq( nRequestedBytes
);
1842 nReadBytes
= aInputStream
->readBytes( seq
,
1845 catch( const io::NotConnectedException
& )
1847 installError( CommandId
,
1848 TASKHANDLING_NOTCONNECTED_FOR_WRITE
);
1852 catch( const io::BufferSizeExceededException
& )
1854 installError( CommandId
,
1855 TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE
);
1859 catch( const io::IOException
& )
1861 installError( CommandId
,
1862 TASKHANDLING_IOEXCEPTION_FOR_WRITE
);
1869 const sal_Int8
* p
= seq
.getConstArray();
1871 err
= aFile
.write( ((void*)(p
)),
1872 sal_uInt64( nReadBytes
),
1875 if( err
!= osl::FileBase::E_None
)
1877 installError( CommandId
,
1878 TASKHANDLING_FILEIOERROR_FOR_WRITE
,
1883 else if( nWrittenBytes
!= sal_uInt64( nReadBytes
) )
1885 installError( CommandId
,
1886 TASKHANDLING_FILEIOERROR_FOR_NO_SPACE
);
1891 } while( nReadBytes
== nRequestedBytes
);
1893 err
= aFile
.close();
1894 if( err
!= osl::FileBase::E_None
)
1896 installError( CommandId
,
1897 TASKHANDLING_FILEIOERROR_FOR_WRITE
,
1907 /*********************************************************************************/
1909 /* insertDefaultProperties-Implementation */
1911 /*********************************************************************************/
1914 void SAL_CALL
shell::insertDefaultProperties( const OUString
& aUnqPath
)
1916 osl::MutexGuard
aGuard( m_aMutex
);
1918 ContentMap::iterator it
=
1919 m_aContent
.insert( ContentMap::value_type( aUnqPath
,UnqPathData() ) ).first
;
1923 MyProperty
ContentTProperty( ContentType
);
1925 PropertySet
& properties
= *(it
->second
.properties
);
1926 bool ContentNotDefau
= properties
.find( ContentTProperty
) != properties
.end();
1928 shell::PropertySet::iterator it1
= m_aDefaultProperties
.begin();
1929 while( it1
!= m_aDefaultProperties
.end() )
1931 if( ContentNotDefau
&& it1
->getPropertyName() == ContentType
)
1936 properties
.insert( *it1
);
1944 /******************************************************************************/
1946 /* mapping of file urls */
1947 /* to uncpath and vice versa */
1949 /******************************************************************************/
1952 bool SAL_CALL
shell::getUnqFromUrl( const OUString
& Url
, OUString
& Unq
)
1954 if ( Url
== "file:///" || Url
== "file://localhost/" || Url
== "file://127.0.0.1/" )
1960 bool err
= osl::FileBase::E_None
!= osl::FileBase::getSystemPathFromFileURL( Url
,Unq
);
1964 sal_Int32 l
= Unq
.getLength()-1;
1965 if( ! err
&& Unq
.endsWith("/") &&
1966 Unq
.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) != -1 )
1967 Unq
= Unq
.copy(0, l
);
1974 bool SAL_CALL
shell::getUrlFromUnq( const OUString
& Unq
,OUString
& Url
)
1976 bool err
= osl::FileBase::E_None
!= osl::FileBase::getSystemPathFromFileURL( Unq
,Url
);
1985 // Helper function for public copy
1987 osl::FileBase::RC SAL_CALL
1988 shell::copy_recursive( const OUString
& srcUnqPath
,
1989 const OUString
& dstUnqPath
,
1990 sal_Int32 TypeToCopy
,
1991 bool testExistBeforeCopy
)
1994 osl::FileBase::RC err
= osl::FileBase::E_None
;
1996 if( TypeToCopy
== -1 ) // Document
1998 err
= osl_File_copy( srcUnqPath
,dstUnqPath
,testExistBeforeCopy
);
2000 else if( TypeToCopy
== +1 ) // Folder
2002 osl::Directory
aDir( srcUnqPath
);
2005 err
= osl::Directory::create( dstUnqPath
);
2006 osl::FileBase::RC next
= err
;
2007 if( err
== osl::FileBase::E_None
)
2009 sal_Int32 n_Mask
= osl_FileStatus_Mask_FileURL
| osl_FileStatus_Mask_FileName
| osl_FileStatus_Mask_Type
;
2011 osl::DirectoryItem aDirItem
;
2013 while( err
== osl::FileBase::E_None
&& ( next
= aDir
.getNextItem( aDirItem
) ) == osl::FileBase::E_None
)
2016 osl::FileStatus
aFileStatus( n_Mask
);
2017 aDirItem
.getFileStatus( aFileStatus
);
2018 if( aFileStatus
.isValid( osl_FileStatus_Mask_Type
) )
2019 IsDoc
= aFileStatus
.getFileType() == osl::FileStatus::Regular
;
2021 // Getting the information for the next recursive copy
2022 sal_Int32 newTypeToCopy
= IsDoc
? -1 : +1;
2024 OUString newSrcUnqPath
;
2025 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileURL
) )
2026 newSrcUnqPath
= aFileStatus
.getFileURL();
2028 OUString newDstUnqPath
= dstUnqPath
;
2030 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileName
) )
2031 tit
= rtl::Uri::encode( aFileStatus
.getFileName(),
2032 rtl_UriCharClassPchar
,
2033 rtl_UriEncodeIgnoreEscapes
,
2034 RTL_TEXTENCODING_UTF8
);
2036 if( !newDstUnqPath
.endsWith( "/" ) )
2037 newDstUnqPath
+= "/";
2039 newDstUnqPath
+= tit
;
2041 if ( newSrcUnqPath
!= dstUnqPath
)
2042 err
= copy_recursive( newSrcUnqPath
,newDstUnqPath
,newTypeToCopy
,false );
2045 if( err
== osl::FileBase::E_None
&& next
!= osl::FileBase::E_NOENT
)
2056 // Helper function for mkfil,mkdir and write
2057 // Creates whole path
2058 // returns success of the operation
2061 bool SAL_CALL
shell::ensuredir( sal_Int32 CommandId
,
2062 const OUString
& rUnqPath
,
2063 sal_Int32 errorCode
)
2068 if ( rUnqPath
.isEmpty() )
2071 if ( rUnqPath
.endsWith("/") )
2072 aPath
= rUnqPath
.copy( 0, rUnqPath
.getLength() - 1 );
2076 #if HAVE_FEATURE_MACOSX_SANDBOX
2078 // Avoid annoying sandbox messages in the system.log from the
2079 // below aDirectory.open(), which ends up calling opendir().
2080 // Surely it is easier to just call stat()? Calling stat() on an
2081 // arbitrary (?) directory does not seem to cause any sandbox
2082 // violation, while opendir() does. (Sorry I could not be bothered
2083 // to use some complex cross-platform abstraction over stat() here
2084 // in this OS X specific code block.)
2088 if( osl::FileBase::getSystemPathFromFileURL( aPath
, aDirName
) == osl::FileBase::E_None
&&
2089 stat(OUStringToOString( aDirName
, RTL_TEXTENCODING_UTF8
).getStr(), &s
) == 0 &&
2090 S_ISDIR( s
.st_mode
) )
2094 // HACK: create directory on a mount point with nobrowse option
2095 // returns ENOSYS in any case !!
2096 osl::Directory
aDirectory( aPath
);
2097 osl::FileBase::RC nError
= aDirectory
.open();
2100 if( nError
== osl::File::E_None
)
2103 nError
= osl::Directory::create( aPath
);
2105 if( nError
== osl::File::E_None
)
2106 notifyInsert( getContentEventListeners( getParentName( aPath
) ),aPath
);
2108 bool bSuccess
= ( nError
== osl::File::E_None
|| nError
== osl::FileBase::E_EXIST
);
2112 OUString aParentDir
= getParentName( aPath
);
2114 if ( aParentDir
!= aPath
)
2115 { // Create first the parent directory
2116 bSuccess
= ensuredir( CommandId
,
2117 getParentName( aPath
),
2120 // After parent directory structure exists try it one's more
2123 { // Parent directory exists, retry creation of directory
2124 nError
= osl::Directory::create( aPath
);
2126 if( nError
== osl::File::E_None
)
2127 notifyInsert( getContentEventListeners( getParentName( aPath
) ),aPath
);
2129 bSuccess
=( nError
== osl::File::E_None
|| nError
== osl::FileBase::E_EXIST
);
2135 installError( CommandId
,
2146 // Given a sequence of properties seq, this method determines the mask
2147 // used to instantiate a osl::FileStatus, so that a call to
2148 // osl::DirectoryItem::getFileStatus fills the required fields.
2153 shell::getMaskFromProperties(
2155 const uno::Sequence
< beans::Property
>& seq
)
2158 for(sal_Int32 j
= 0; j
< seq
.getLength(); ++j
) {
2159 if(seq
[j
].Name
== Title
)
2160 n_Mask
|= osl_FileStatus_Mask_FileName
;
2161 else if(seq
[j
].Name
== CasePreservingURL
)
2162 n_Mask
|= osl_FileStatus_Mask_FileURL
;
2163 else if(seq
[j
].Name
== IsDocument
||
2164 seq
[j
].Name
== IsFolder
||
2165 seq
[j
].Name
== IsVolume
||
2166 seq
[j
].Name
== IsRemoveable
||
2167 seq
[j
].Name
== IsRemote
||
2168 seq
[j
].Name
== IsCompactDisc
||
2169 seq
[j
].Name
== IsFloppy
||
2170 seq
[j
].Name
== ContentType
)
2171 n_Mask
|= (osl_FileStatus_Mask_Type
| osl_FileStatus_Mask_LinkTargetURL
);
2172 else if(seq
[j
].Name
== Size
)
2173 n_Mask
|= (osl_FileStatus_Mask_FileSize
|
2174 osl_FileStatus_Mask_Type
|
2175 osl_FileStatus_Mask_LinkTargetURL
);
2176 else if(seq
[j
].Name
== IsHidden
||
2177 seq
[j
].Name
== IsReadOnly
)
2178 n_Mask
|= osl_FileStatus_Mask_Attributes
;
2179 else if(seq
[j
].Name
== DateModified
)
2180 n_Mask
|= osl_FileStatus_Mask_ModifyTime
;
2186 /*********************************************************************************/
2188 /* load-Implementation */
2190 /*********************************************************************************/
2192 // Load the properties from configuration, if create == true create them.
2193 // The Properties are stored under the url belonging to it->first.
2197 shell::load( const ContentMap::iterator
& it
, bool create
)
2199 if( ! it
->second
.properties
)
2200 it
->second
.properties
= new PropertySet
;
2202 if( ( ! it
->second
.xS
.is() ||
2203 ! it
->second
.xC
.is() ||
2204 ! it
->second
.xA
.is() )
2205 && m_xFileRegistry
.is() )
2208 uno::Reference
< ucb::XPersistentPropertySet
> xS
= m_xFileRegistry
->openPropertySet( it
->first
,create
);
2211 uno::Reference
< beans::XPropertyContainer
> xC( xS
,uno::UNO_QUERY
);
2212 uno::Reference
< beans::XPropertyAccess
> xA( xS
,uno::UNO_QUERY
);
2218 // Now put in all values in the storage in the local hash;
2220 PropertySet
& properties
= *(it
->second
.properties
);
2221 uno::Sequence
< beans::Property
> seq
= xS
->getPropertySetInfo()->getProperties();
2223 for( sal_Int32 i
= 0; i
< seq
.getLength(); ++i
)
2225 MyProperty
readProp( false,
2229 xS
->getPropertyValue( seq
[i
].Name
),
2230 beans::PropertyState_DIRECT_VALUE
,
2231 seq
[i
].Attributes
);
2232 if( properties
.find( readProp
) == properties
.end() )
2233 properties
.insert( readProp
);
2238 // Catastrophic error
2246 /*********************************************************************************/
2248 /* commit-Implementation */
2250 /*********************************************************************************/
2251 // Commit inserts the determined properties in the filestatus object into
2252 // the internal map, so that is possible to determine on a subsequent
2253 // setting of file properties which properties have changed without filestat
2257 shell::commit( const shell::ContentMap::iterator
& it
,
2258 const osl::FileStatus
& aFileStatus
)
2261 shell::PropertySet::iterator it1
;
2263 if( it
->second
.properties
== 0 )
2265 OUString aPath
= it
->first
;
2266 insertDefaultProperties( aPath
);
2269 PropertySet
& properties
= *( it
->second
.properties
);
2271 it1
= properties
.find( MyProperty( Title
) );
2272 if( it1
!= properties
.end() )
2274 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileName
) )
2276 aAny
<<= aFileStatus
.getFileName();
2277 it1
->setValue( aAny
);
2281 it1
= properties
.find( MyProperty( CasePreservingURL
) );
2282 if( it1
!= properties
.end() )
2284 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileURL
) )
2286 aAny
<<= aFileStatus
.getFileURL();
2287 it1
->setValue( aAny
);
2292 bool isDirectory
,isFile
,isVolume
,isRemoveable
,isRemote
,isFloppy
,isCompactDisc
;
2294 sal_Int64 dirSize
= 0;
2296 if( aFileStatus
.isValid( osl_FileStatus_Mask_FileSize
) )
2297 dirSize
= aFileStatus
.getFileSize();
2299 if( aFileStatus
.isValid( osl_FileStatus_Mask_Type
) )
2301 if( osl::FileStatus::Link
== aFileStatus
.getFileType() &&
2302 aFileStatus
.isValid( osl_FileStatus_Mask_LinkTargetURL
) )
2304 osl::DirectoryItem aDirItem
;
2305 osl::FileStatus
aFileStatus2( osl_FileStatus_Mask_Type
);
2306 if( osl::FileBase::E_None
== osl::DirectoryItem::get( aFileStatus
.getLinkTargetURL(),aDirItem
) &&
2307 osl::FileBase::E_None
== aDirItem
.getFileStatus( aFileStatus2
) &&
2308 aFileStatus2
.isValid( osl_FileStatus_Mask_Type
) )
2310 isVolume
= osl::FileStatus::Volume
== aFileStatus2
.getFileType();
2312 osl::FileStatus::Volume
== aFileStatus2
.getFileType() ||
2313 osl::FileStatus::Directory
== aFileStatus2
.getFileType();
2315 osl::FileStatus::Regular
== aFileStatus2
.getFileType();
2317 if( aFileStatus2
.isValid( osl_FileStatus_Mask_FileSize
) )
2318 dirSize
= aFileStatus2
.getFileSize();
2322 // extremely ugly, but otherwise default construction
2323 // of aDirItem and aFileStatus2
2324 // before the preciding if
2325 isVolume
= osl::FileStatus::Volume
== aFileStatus
.getFileType();
2327 osl::FileStatus::Volume
== aFileStatus
.getFileType() ||
2328 osl::FileStatus::Directory
== aFileStatus
.getFileType();
2330 osl::FileStatus::Regular
== aFileStatus
.getFileType();
2335 isVolume
= osl::FileStatus::Volume
== aFileStatus
.getFileType();
2337 osl::FileStatus::Volume
== aFileStatus
.getFileType() ||
2338 osl::FileStatus::Directory
== aFileStatus
.getFileType();
2340 osl::FileStatus::Regular
== aFileStatus
.getFileType();
2343 it1
= properties
.find( MyProperty( IsVolume
) );
2344 if( it1
!= properties
.end() )
2345 it1
->setValue( uno::makeAny( isVolume
) );
2347 it1
= properties
.find( MyProperty( IsFolder
) );
2348 if( it1
!= properties
.end() )
2349 it1
->setValue( uno::makeAny( isDirectory
) );
2351 it1
= properties
.find( MyProperty( IsDocument
) );
2352 if( it1
!= properties
.end() )
2353 it1
->setValue( uno::makeAny( isFile
) );
2355 osl::VolumeInfo
aVolumeInfo( osl_VolumeInfo_Mask_Attributes
);
2357 osl::FileBase::E_None
== osl::Directory::getVolumeInfo( it
->first
,aVolumeInfo
) &&
2358 aVolumeInfo
.isValid( osl_VolumeInfo_Mask_Attributes
) )
2360 // Retrieve the flags;
2361 isRemote
= aVolumeInfo
.getRemoteFlag();
2362 isRemoveable
= aVolumeInfo
.getRemoveableFlag();
2363 isCompactDisc
= aVolumeInfo
.getCompactDiscFlag();
2364 isFloppy
= aVolumeInfo
.getFloppyDiskFlag();
2366 it1
= properties
.find( MyProperty( IsRemote
) );
2367 if( it1
!= properties
.end() )
2368 it1
->setValue( uno::makeAny( isRemote
) );
2370 it1
= properties
.find( MyProperty( IsRemoveable
) );
2371 if( it1
!= properties
.end() )
2372 it1
->setValue( uno::makeAny( isRemoveable
) );
2374 it1
= properties
.find( MyProperty( IsCompactDisc
) );
2375 if( it1
!= properties
.end() )
2376 it1
->setValue( uno::makeAny( isCompactDisc
) );
2378 it1
= properties
.find( MyProperty( IsFloppy
) );
2379 if( it1
!= properties
.end() )
2380 it1
->setValue( uno::makeAny( isFloppy
) );
2386 it1
= properties
.find( MyProperty( IsRemote
) );
2387 if( it1
!= properties
.end() )
2388 it1
->setValue( aAny
);
2390 it1
= properties
.find( MyProperty( IsRemoveable
) );
2391 if( it1
!= properties
.end() )
2392 it1
->setValue( aAny
);
2394 it1
= properties
.find( MyProperty( IsCompactDisc
) );
2395 if( it1
!= properties
.end() )
2396 it1
->setValue( aAny
);
2398 it1
= properties
.find( MyProperty( IsFloppy
) );
2399 if( it1
!= properties
.end() )
2400 it1
->setValue( aAny
);
2405 isDirectory
= false;
2408 it1
= properties
.find( MyProperty( Size
) );
2409 if( it1
!= properties
.end() )
2410 it1
->setValue( uno::makeAny( dirSize
) );
2412 it1
= properties
.find( MyProperty( IsReadOnly
) );
2413 if( it1
!= properties
.end() )
2415 if( aFileStatus
.isValid( osl_FileStatus_Mask_Attributes
) )
2417 sal_uInt64 Attr
= aFileStatus
.getAttributes();
2418 bool readonly
= ( Attr
& osl_File_Attribute_ReadOnly
) != 0;
2419 it1
->setValue( uno::makeAny( readonly
) );
2423 it1
= properties
.find( MyProperty( IsHidden
) );
2424 if( it1
!= properties
.end() )
2426 if( aFileStatus
.isValid( osl_FileStatus_Mask_Attributes
) )
2428 sal_uInt64 Attr
= aFileStatus
.getAttributes();
2429 bool ishidden
= ( Attr
& osl_File_Attribute_Hidden
) != 0;
2430 it1
->setValue( uno::makeAny( ishidden
) );
2434 it1
= properties
.find( MyProperty( DateModified
) );
2435 if( it1
!= properties
.end() )
2437 if( aFileStatus
.isValid( osl_FileStatus_Mask_ModifyTime
) )
2439 TimeValue temp
= aFileStatus
.getModifyTime();
2441 // Convert system time to local time (for EA)
2442 TimeValue myLocalTime
;
2443 if (!osl_getLocalTimeFromSystemTime( &temp
, &myLocalTime
))
2447 "cannot convert (" << temp
.Seconds
<< ", " << temp
.Nanosec
2448 << ") to local time");
2452 oslDateTime myDateTime
;
2453 osl_getDateTimeFromTimeValue( &myLocalTime
, &myDateTime
);
2454 util::DateTime aDateTime
;
2456 aDateTime
.NanoSeconds
= myDateTime
.NanoSeconds
;
2457 aDateTime
.Seconds
= myDateTime
.Seconds
;
2458 aDateTime
.Minutes
= myDateTime
.Minutes
;
2459 aDateTime
.Hours
= myDateTime
.Hours
;
2460 aDateTime
.Day
= myDateTime
.Day
;
2461 aDateTime
.Month
= myDateTime
.Month
;
2462 aDateTime
.Year
= myDateTime
.Year
;
2463 it1
->setValue( uno::makeAny( aDateTime
) );
2467 it1
= properties
.find( MyProperty( CreatableContentsInfo
) );
2468 if( it1
!= properties
.end() )
2469 it1
->setValue( uno::makeAny(
2470 isDirectory
|| !aFileStatus
.isValid( osl_FileStatus_Mask_Type
)
2471 ? queryCreatableContentsInfo()
2472 : uno::Sequence
< ucb::ContentInfo
>() ) );
2476 // Special optimized method for getting the properties of a
2477 // directoryitem, which is returned by osl::DirectoryItem::getNextItem()
2480 uno::Reference
< sdbc::XRow
> SAL_CALL
2482 Notifier
* pNotifier
,
2483 const uno::Sequence
< beans::Property
>& properties
,
2484 osl::DirectoryItem
& aDirItem
,
2488 uno::Sequence
< uno::Any
> seq( properties
.getLength() );
2491 getMaskFromProperties( n_Mask
,properties
);
2493 // Always retrieve the type and the target URL because item might be a link
2494 osl::FileStatus
aFileStatus( n_Mask
|
2495 osl_FileStatus_Mask_FileURL
|
2496 osl_FileStatus_Mask_Type
|
2497 osl_FileStatus_Mask_LinkTargetURL
);
2499 osl::FileBase::RC aRes
= aDirItem
.getFileStatus( aFileStatus
);
2500 if ( aRes
== osl::FileBase::E_None
)
2502 aUnqPath
= aFileStatus
.getFileURL();
2504 // If the directory item type is a link retrieve the type of the target
2506 if ( aFileStatus
.getFileType() == osl::FileStatus::Link
)
2510 osl::FileBase::RC result
= osl::FileBase::E_INVAL
;
2511 osl::DirectoryItem aTargetItem
;
2512 osl::DirectoryItem::get( aFileStatus
.getLinkTargetURL(), aTargetItem
);
2513 if ( aTargetItem
.is() )
2515 osl::FileStatus
aTargetStatus( osl_FileStatus_Mask_Type
);
2517 if ( osl::FileBase::E_None
==
2518 ( result
= aTargetItem
.getFileStatus( aTargetStatus
) ) )
2520 aTargetStatus
.getFileType() == osl::FileStatus::Regular
;
2524 aIsRegular
= aFileStatus
.getFileType() == osl::FileStatus::Regular
;
2526 registerNotifier( aUnqPath
,pNotifier
);
2527 insertDefaultProperties( aUnqPath
);
2529 osl::MutexGuard
aGuard( m_aMutex
);
2531 shell::ContentMap::iterator it
= m_aContent
.find( aUnqPath
);
2532 commit( it
,aFileStatus
);
2534 shell::PropertySet::iterator it1
;
2535 PropertySet
& propset
= *(it
->second
.properties
);
2537 for( sal_Int32 i
= 0; i
< seq
.getLength(); ++i
)
2539 MyProperty
readProp( properties
[i
].Name
);
2540 it1
= propset
.find( readProp
);
2541 if( it1
== propset
.end() )
2542 seq
[i
] = uno::Any();
2544 seq
[i
] = it1
->getValue();
2547 deregisterNotifier( aUnqPath
,pNotifier
);
2549 XRow_impl
* p
= new XRow_impl( this,seq
);
2550 return uno::Reference
< sdbc::XRow
>( p
);
2561 std::list
< ContentEventNotifier
* >* SAL_CALL
2562 shell::getContentEventListeners( const OUString
& aName
)
2564 std::list
< ContentEventNotifier
* >* p
= new std::list
< ContentEventNotifier
* >;
2565 std::list
< ContentEventNotifier
* >& listeners
= *p
;
2567 osl::MutexGuard
aGuard( m_aMutex
);
2568 shell::ContentMap::iterator it
= m_aContent
.find( aName
);
2569 if( it
!= m_aContent
.end() && it
->second
.notifier
)
2571 std::list
<Notifier
*>& listOfNotifiers
= *( it
->second
.notifier
);
2572 std::list
<Notifier
*>::iterator it1
= listOfNotifiers
.begin();
2573 while( it1
!= listOfNotifiers
.end() )
2575 Notifier
* pointer
= *it1
;
2576 ContentEventNotifier
* notifier
= pointer
->cCEL();
2578 listeners
.push_back( notifier
);
2588 std::list
< ContentEventNotifier
* >* SAL_CALL
2589 shell::getContentDeletedEventListeners( const OUString
& aName
)
2591 std::list
< ContentEventNotifier
* >* p
= new std::list
< ContentEventNotifier
* >;
2592 std::list
< ContentEventNotifier
* >& listeners
= *p
;
2594 osl::MutexGuard
aGuard( m_aMutex
);
2595 shell::ContentMap::iterator it
= m_aContent
.find( aName
);
2596 if( it
!= m_aContent
.end() && it
->second
.notifier
)
2598 std::list
<Notifier
*>& listOfNotifiers
= *( it
->second
.notifier
);
2599 std::list
<Notifier
*>::iterator it1
= listOfNotifiers
.begin();
2600 while( it1
!= listOfNotifiers
.end() )
2602 Notifier
* pointer
= *it1
;
2603 ContentEventNotifier
* notifier
= pointer
->cDEL();
2605 listeners
.push_back( notifier
);
2615 shell::notifyInsert( std::list
< ContentEventNotifier
* >* listeners
,const OUString
& aChildName
)
2617 std::list
< ContentEventNotifier
* >::iterator it
= listeners
->begin();
2618 while( it
!= listeners
->end() )
2620 (*it
)->notifyChildInserted( aChildName
);
2629 shell::notifyContentDeleted( std::list
< ContentEventNotifier
* >* listeners
)
2631 std::list
< ContentEventNotifier
* >::iterator it
= listeners
->begin();
2632 while( it
!= listeners
->end() )
2634 (*it
)->notifyDeleted();
2643 shell::notifyContentRemoved( std::list
< ContentEventNotifier
* >* listeners
,
2644 const OUString
& aChildName
)
2646 std::list
< ContentEventNotifier
* >::iterator it
= listeners
->begin();
2647 while( it
!= listeners
->end() )
2649 (*it
)->notifyRemoved( aChildName
);
2659 std::list
< PropertySetInfoChangeNotifier
* >* SAL_CALL
2660 shell::getPropertySetListeners( const OUString
& aName
)
2662 std::list
< PropertySetInfoChangeNotifier
* >* p
= new std::list
< PropertySetInfoChangeNotifier
* >;
2663 std::list
< PropertySetInfoChangeNotifier
* >& listeners
= *p
;
2665 osl::MutexGuard
aGuard( m_aMutex
);
2666 shell::ContentMap::iterator it
= m_aContent
.find( aName
);
2667 if( it
!= m_aContent
.end() && it
->second
.notifier
)
2669 std::list
<Notifier
*>& listOfNotifiers
= *( it
->second
.notifier
);
2670 std::list
<Notifier
*>::iterator it1
= listOfNotifiers
.begin();
2671 while( it1
!= listOfNotifiers
.end() )
2673 Notifier
* pointer
= *it1
;
2674 PropertySetInfoChangeNotifier
* notifier
= pointer
->cPSL();
2676 listeners
.push_back( notifier
);
2686 shell::notifyPropertyAdded( std::list
< PropertySetInfoChangeNotifier
* >* listeners
,
2687 const OUString
& aPropertyName
)
2689 std::list
< PropertySetInfoChangeNotifier
* >::iterator it
= listeners
->begin();
2690 while( it
!= listeners
->end() )
2692 (*it
)->notifyPropertyAdded( aPropertyName
);
2701 shell::notifyPropertyRemoved( std::list
< PropertySetInfoChangeNotifier
* >* listeners
,
2702 const OUString
& aPropertyName
)
2704 std::list
< PropertySetInfoChangeNotifier
* >::iterator it
= listeners
->begin();
2705 while( it
!= listeners
->end() )
2707 (*it
)->notifyPropertyRemoved( aPropertyName
);
2716 std::vector
< std::list
< ContentEventNotifier
* >* >* SAL_CALL
2717 shell::getContentExchangedEventListeners( const OUString
& aOldPrefix
,
2718 const OUString
& aNewPrefix
,
2722 std::vector
< std::list
< ContentEventNotifier
* >* >* aVectorOnHeap
=
2723 new std::vector
< std::list
< ContentEventNotifier
* >* >;
2724 std::vector
< std::list
< ContentEventNotifier
* >* >& aVector
= *aVectorOnHeap
;
2729 std::vector
< OUString
> oldChildList
;
2732 osl::MutexGuard
aGuard( m_aMutex
);
2734 if( ! withChildren
)
2736 aOldName
= aOldPrefix
;
2737 aNewName
= aNewPrefix
;
2742 ContentMap::iterator itnames
= m_aContent
.begin();
2743 while( itnames
!= m_aContent
.end() )
2745 if( isChild( aOldPrefix
,itnames
->first
) )
2747 oldChildList
.push_back( itnames
->first
);
2751 count
= oldChildList
.size();
2755 for( sal_Int32 j
= 0; j
< count
; ++j
)
2757 std::list
< ContentEventNotifier
* >* p
= new std::list
< ContentEventNotifier
* >;
2758 std::list
< ContentEventNotifier
* >& listeners
= *p
;
2762 aOldName
= oldChildList
[j
];
2763 aNewName
= newName( aNewPrefix
,aOldPrefix
,aOldName
);
2766 shell::ContentMap::iterator itold
= m_aContent
.find( aOldName
);
2767 if( itold
!= m_aContent
.end() )
2769 shell::ContentMap::iterator itnew
= m_aContent
.insert(
2770 ContentMap::value_type( aNewName
,UnqPathData() ) ).first
;
2772 // copy Ownership also
2773 delete itnew
->second
.properties
;
2774 itnew
->second
.properties
= itold
->second
.properties
;
2775 itold
->second
.properties
= 0;
2777 // copy existing list
2778 std::list
< Notifier
* >* copyList
= itnew
->second
.notifier
;
2779 itnew
->second
.notifier
= itold
->second
.notifier
;
2780 itold
->second
.notifier
= 0;
2782 m_aContent
.erase( itold
);
2784 if( itnew
!= m_aContent
.end() && itnew
->second
.notifier
)
2786 std::list
<Notifier
*>& listOfNotifiers
= *( itnew
->second
.notifier
);
2787 std::list
<Notifier
*>::iterator it1
= listOfNotifiers
.begin();
2788 while( it1
!= listOfNotifiers
.end() )
2790 Notifier
* pointer
= *it1
;
2791 ContentEventNotifier
* notifier
= pointer
->cEXC( aNewName
);
2793 listeners
.push_back( notifier
);
2798 // Merge with preexisting notifiers
2799 // However, these may be in status BaseContent::Deleted
2802 std::list
< Notifier
* >::iterator copyIt
= copyList
->begin();
2803 while( copyIt
!= copyList
->end() )
2805 itnew
->second
.notifier
->push_back( *copyIt
);
2811 aVector
.push_back( p
);
2815 return aVectorOnHeap
;
2821 shell::notifyContentExchanged( std::vector
< std::list
< ContentEventNotifier
* >* >* listeners_vec
)
2823 std::list
< ContentEventNotifier
* >* listeners
;
2824 for( sal_uInt32 i
= 0; i
< listeners_vec
->size(); ++i
)
2826 listeners
= (*listeners_vec
)[i
];
2827 std::list
< ContentEventNotifier
* >::iterator it
= listeners
->begin();
2828 while( it
!= listeners
->end() )
2830 (*it
)->notifyExchanged();
2836 delete listeners_vec
;
2841 std::list
< PropertyChangeNotifier
* >* SAL_CALL
2842 shell::getPropertyChangeNotifier( const OUString
& aName
)
2844 std::list
< PropertyChangeNotifier
* >* p
= new std::list
< PropertyChangeNotifier
* >;
2845 std::list
< PropertyChangeNotifier
* >& listeners
= *p
;
2847 osl::MutexGuard
aGuard( m_aMutex
);
2848 shell::ContentMap::iterator it
= m_aContent
.find( aName
);
2849 if( it
!= m_aContent
.end() && it
->second
.notifier
)
2851 std::list
<Notifier
*>& listOfNotifiers
= *( it
->second
.notifier
);
2852 std::list
<Notifier
*>::iterator it1
= listOfNotifiers
.begin();
2853 while( it1
!= listOfNotifiers
.end() )
2855 Notifier
* pointer
= *it1
;
2856 PropertyChangeNotifier
* notifier
= pointer
->cPCL();
2858 listeners
.push_back( notifier
);
2867 void SAL_CALL
shell::notifyPropertyChanges( std::list
< PropertyChangeNotifier
* >* listeners
,
2868 const uno::Sequence
< beans::PropertyChangeEvent
>& seqChanged
)
2870 std::list
< PropertyChangeNotifier
* >::iterator it
= listeners
->begin();
2871 while( it
!= listeners
->end() )
2873 (*it
)->notifyPropertyChanged( seqChanged
);
2883 /********************************************************************************/
2884 /* remove persistent propertyset */
2885 /********************************************************************************/
2888 shell::erasePersistentSet( const OUString
& aUnqPath
,
2891 if( ! m_xFileRegistry
.is() )
2893 OSL_ASSERT( m_xFileRegistry
.is() );
2897 uno::Sequence
< OUString
> seqNames
;
2901 uno::Reference
< container::XNameAccess
> xName( m_xFileRegistry
,uno::UNO_QUERY
);
2902 seqNames
= xName
->getElementNames();
2905 sal_Int32 count
= withChildren
? seqNames
.getLength() : 1;
2908 old_Name
= aUnqPath
;
2910 for( sal_Int32 j
= 0; j
< count
; ++j
)
2912 if( withChildren
&& ! ( isChild( old_Name
,seqNames
[j
] ) ) )
2917 old_Name
= seqNames
[j
];
2921 // Release possible references
2922 osl::MutexGuard
aGuard( m_aMutex
);
2923 ContentMap::iterator it
= m_aContent
.find( old_Name
);
2924 if( it
!= m_aContent
.end() )
2930 delete it
->second
.properties
;
2931 it
->second
.properties
= 0;
2935 if( m_xFileRegistry
.is() )
2936 m_xFileRegistry
->removePropertySet( old_Name
);
2943 /********************************************************************************/
2944 /* copy persistent propertyset */
2945 /* from srcUnqPath to dstUnqPath */
2946 /********************************************************************************/
2950 shell::copyPersistentSet( const OUString
& srcUnqPath
,
2951 const OUString
& dstUnqPath
,
2954 if( ! m_xFileRegistry
.is() )
2956 OSL_ASSERT( m_xFileRegistry
.is() );
2960 uno::Sequence
< OUString
> seqNames
;
2964 uno::Reference
< container::XNameAccess
> xName( m_xFileRegistry
,uno::UNO_QUERY
);
2965 seqNames
= xName
->getElementNames();
2968 sal_Int32 count
= withChildren
? seqNames
.getLength() : 1;
2971 old_Name
= srcUnqPath
,
2972 new_Name
= dstUnqPath
;
2974 for( sal_Int32 j
= 0; j
< count
; ++j
)
2976 if( withChildren
&& ! ( isChild( srcUnqPath
,seqNames
[j
] ) ) )
2981 old_Name
= seqNames
[j
];
2982 new_Name
= newName( dstUnqPath
,srcUnqPath
,old_Name
);
2985 uno::Reference
< XPersistentPropertySet
> x_src
;
2987 if( m_xFileRegistry
.is() )
2989 x_src
= m_xFileRegistry
->openPropertySet( old_Name
,false );
2990 m_xFileRegistry
->removePropertySet( new_Name
);
2995 uno::Sequence
< beans::Property
> seqProperty
=
2996 x_src
->getPropertySetInfo()->getProperties();
2998 if( seqProperty
.getLength() )
3000 uno::Reference
< XPersistentPropertySet
>
3001 x_dstS
= m_xFileRegistry
->openPropertySet( new_Name
,true );
3002 uno::Reference
< beans::XPropertyContainer
>
3003 x_dstC( x_dstS
,uno::UNO_QUERY
);
3005 for( sal_Int32 i
= 0; i
< seqProperty
.getLength(); ++i
)
3007 x_dstC
->addProperty( seqProperty
[i
].Name
,
3008 seqProperty
[i
].Attributes
,
3009 x_src
->getPropertyValue( seqProperty
[i
].Name
) );
3013 } // end for( sal_Int...
3016 uno::Sequence
< ucb::ContentInfo
> shell::queryCreatableContentsInfo()
3018 uno::Sequence
< ucb::ContentInfo
> seq(2);
3021 seq
[0].Type
= FileContentType
;
3022 seq
[0].Attributes
= ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
3023 | ucb::ContentInfoAttribute::KIND_DOCUMENT
;
3025 uno::Sequence
< beans::Property
> props( 1 );
3026 props
[0] = beans::Property(
3029 cppu::UnoType
<OUString
>::get(),
3030 beans::PropertyAttribute::MAYBEVOID
3031 | beans::PropertyAttribute::BOUND
);
3032 seq
[0].Properties
= props
;
3035 seq
[1].Type
= FolderContentType
;
3036 seq
[1].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
3037 seq
[1].Properties
= props
;
3041 /*******************************************************************************/
3043 /* some miscellaneous static functions */
3045 /*******************************************************************************/
3048 shell::getScheme( OUString
& Scheme
)
3054 shell::getImplementationName_static()
3056 return OUString("com.sun.star.comp.ucb.FileProvider");
3060 uno::Sequence
< OUString
> SAL_CALL
3061 shell::getSupportedServiceNames_static()
3063 OUString
Supported("com.sun.star.ucb.FileContentProvider");
3064 com::sun::star::uno::Sequence
< OUString
> Seq( &Supported
,1 );
3068 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */