summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/file/shell.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/file/shell.cxx')
-rw-r--r--ucb/source/ucp/file/shell.cxx3068
1 files changed, 3068 insertions, 0 deletions
diff --git a/ucb/source/ucp/file/shell.cxx b/ucb/source/ucp/file/shell.cxx
new file mode 100644
index 000000000000..769e58c08819
--- /dev/null
+++ b/ucb/source/ucp/file/shell.cxx
@@ -0,0 +1,3068 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#ifndef INCLUDED_STL_STACK
+#include <stack>
+#define INCLUDED_STL_STACK
+#endif
+
+#include "osl/diagnose.h"
+#include <rtl/ustrbuf.hxx>
+#include <osl/time.h>
+#include <osl/file.hxx>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/beans/IllegalTypeException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument.hpp>
+#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <rtl/string.hxx>
+#include "filerror.hxx"
+#include "filglob.hxx"
+#include "filcmd.hxx"
+#include "filinpstr.hxx"
+#include "filstr.hxx"
+#include "filrset.hxx"
+#include "filrow.hxx"
+#include "filprp.hxx"
+#include "filid.hxx"
+#include "shell.hxx"
+#include "prov.hxx"
+#include "bc.hxx"
+
+
+using namespace fileaccess;
+using namespace com::sun::star;
+using namespace com::sun::star::ucb;
+
+
+shell::UnqPathData::UnqPathData()
+ : properties( 0 ),
+ notifier( 0 ),
+ xS( 0 ),
+ xC( 0 ),
+ xA( 0 )
+{
+ // empty
+}
+
+
+shell::UnqPathData::UnqPathData( const UnqPathData& a )
+ : properties( a.properties ),
+ notifier( a.notifier ),
+ xS( a.xS ),
+ xC( a.xC ),
+ xA( a.xA )
+{
+}
+
+
+shell::UnqPathData& shell::UnqPathData::operator=( UnqPathData& a )
+{
+ properties = a.properties;
+ notifier = a.notifier;
+ xS = a.xS;
+ xC = a.xC;
+ xA = a.xA;
+ a.properties = 0;
+ a.notifier = 0;
+ a.xS = 0;
+ a.xC = 0;
+ a.xA = 0;
+ return *this;
+}
+
+shell::UnqPathData::~UnqPathData()
+{
+ if( properties )
+ delete properties;
+ if( notifier )
+ delete notifier;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+shell::MyProperty::MyProperty( const rtl::OUString& __PropertyName )
+ : PropertyName( __PropertyName )
+{
+ // empty
+}
+
+
+shell::MyProperty::MyProperty( const sal_Bool& __isNative,
+ const rtl::OUString& __PropertyName,
+ const sal_Int32& __Handle,
+ const com::sun::star::uno::Type& __Typ,
+ const com::sun::star::uno::Any& __Value,
+ const com::sun::star::beans::PropertyState& __State,
+ const sal_Int16& __Attributes )
+ : PropertyName( __PropertyName ),
+ Handle( __Handle ),
+ isNative( __isNative ),
+ Typ( __Typ ),
+ Value( __Value ),
+ State( __State ),
+ Attributes( __Attributes )
+{
+ // empty
+}
+
+shell::MyProperty::~MyProperty()
+{
+ // empty for now
+}
+
+
+#include "filinl.hxx"
+
+
+shell::shell( const uno::Reference< lang::XMultiServiceFactory >& xMultiServiceFactory,
+ FileProvider* pProvider, sal_Bool bWithConfig )
+ : TaskManager(),
+ m_bWithConfig( bWithConfig ),
+ m_pProvider( pProvider ),
+ m_xMultiServiceFactory( xMultiServiceFactory ),
+ Title( rtl::OUString::createFromAscii( "Title" ) ),
+ CasePreservingURL(
+ rtl::OUString::createFromAscii( "CasePreservingURL" ) ),
+ IsDocument( rtl::OUString::createFromAscii( "IsDocument" ) ),
+ IsFolder( rtl::OUString::createFromAscii( "IsFolder" ) ),
+ DateModified( rtl::OUString::createFromAscii( "DateModified" ) ),
+ Size( rtl::OUString::createFromAscii( "Size" ) ),
+ IsVolume( rtl::OUString::createFromAscii( "IsVolume" ) ),
+ IsRemoveable( rtl::OUString::createFromAscii( "IsRemoveable" ) ),
+ IsRemote( rtl::OUString::createFromAscii( "IsRemote" ) ),
+ IsCompactDisc( rtl::OUString::createFromAscii( "IsCompactDisc" ) ),
+ IsFloppy( rtl::OUString::createFromAscii( "IsFloppy" ) ),
+ IsHidden( rtl::OUString::createFromAscii( "IsHidden" ) ),
+ ContentType( rtl::OUString::createFromAscii( "ContentType" ) ),
+ IsReadOnly( rtl::OUString::createFromAscii( "IsReadOnly" ) ),
+ CreatableContentsInfo( rtl::OUString::createFromAscii( "CreatableContentsInfo" ) ),
+ FolderContentType( rtl::OUString::createFromAscii( "application/vnd.sun.staroffice.fsys-folder" ) ),
+ FileContentType( rtl::OUString::createFromAscii( "application/vnd.sun.staroffice.fsys-file" ) ),
+ m_sCommandInfo( 9 )
+{
+ // Title
+ m_aDefaultProperties.insert( MyProperty( true,
+ Title,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // CasePreservingURL
+ m_aDefaultProperties.insert(
+ MyProperty( true,
+ CasePreservingURL,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // IsFolder
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsFolder,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // IsDocument
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsDocument,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Removable
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsVolume,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // Removable
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsRemoveable,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Remote
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsRemote,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // CompactDisc
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsCompactDisc,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Floppy
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsFloppy,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Hidden
+ m_aDefaultProperties.insert(
+ MyProperty(
+ true,
+ IsHidden,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+#if defined( WNT ) || defined( OS2 )
+ ));
+#else
+ | beans::PropertyAttribute::READONLY)); // under unix/linux only readable
+#endif
+
+
+ // ContentType
+ uno::Any aAny;
+ aAny <<= rtl::OUString();
+ m_aDefaultProperties.insert( MyProperty( false,
+ ContentType,
+ -1 ,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ aAny,
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+
+ // DateModified
+ m_aDefaultProperties.insert( MyProperty( true,
+ DateModified,
+ -1 ,
+ getCppuType( static_cast< util::DateTime* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // Size
+ m_aDefaultProperties.insert( MyProperty( true,
+ Size,
+ -1,
+ getCppuType( static_cast< sal_Int64* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+ // IsReadOnly
+ m_aDefaultProperties.insert( MyProperty( true,
+ IsReadOnly,
+ -1 ,
+ getCppuType( static_cast< sal_Bool* >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND ) );
+
+
+ // CreatableContentsInfo
+ m_aDefaultProperties.insert( MyProperty( true,
+ CreatableContentsInfo,
+ -1 ,
+ getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ uno::Any(),
+ beans::PropertyState_DEFAULT_VALUE,
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ) );
+
+ // Commands
+ m_sCommandInfo[0].Name = rtl::OUString::createFromAscii( "getCommandInfo" );
+ m_sCommandInfo[0].Handle = -1;
+ m_sCommandInfo[0].ArgType = getCppuVoidType();
+
+ m_sCommandInfo[1].Name = rtl::OUString::createFromAscii( "getPropertySetInfo" );
+ m_sCommandInfo[1].Handle = -1;
+ m_sCommandInfo[1].ArgType = getCppuVoidType();
+
+ m_sCommandInfo[2].Name = rtl::OUString::createFromAscii( "getPropertyValues" );
+ m_sCommandInfo[2].Handle = -1;
+ m_sCommandInfo[2].ArgType = getCppuType( static_cast< uno::Sequence< beans::Property >* >( 0 ) );
+
+ m_sCommandInfo[3].Name = rtl::OUString::createFromAscii( "setPropertyValues" );
+ m_sCommandInfo[3].Handle = -1;
+ m_sCommandInfo[3].ArgType = getCppuType( static_cast< uno::Sequence< beans::PropertyValue >* >( 0 ) );
+
+ m_sCommandInfo[4].Name = rtl::OUString::createFromAscii( "open" );
+ m_sCommandInfo[4].Handle = -1;
+ m_sCommandInfo[4].ArgType = getCppuType( static_cast< OpenCommandArgument* >( 0 ) );
+
+ m_sCommandInfo[5].Name = rtl::OUString::createFromAscii( "transfer" );
+ m_sCommandInfo[5].Handle = -1;
+ m_sCommandInfo[5].ArgType = getCppuType( static_cast< TransferInfo* >( 0 ) );
+
+ m_sCommandInfo[6].Name = rtl::OUString::createFromAscii( "delete" );
+ m_sCommandInfo[6].Handle = -1;
+ m_sCommandInfo[6].ArgType = getCppuType( static_cast< sal_Bool* >( 0 ) );
+
+ m_sCommandInfo[7].Name = rtl::OUString::createFromAscii( "insert" );
+ m_sCommandInfo[7].Handle = -1;
+ m_sCommandInfo[7].ArgType = getCppuType( static_cast< InsertCommandArgument* > ( 0 ) );
+
+ m_sCommandInfo[7].Name = rtl::OUString::createFromAscii( "createNewContent" );
+ m_sCommandInfo[7].Handle = -1;
+ m_sCommandInfo[7].ArgType = getCppuType( static_cast< ucb::ContentInfo * > ( 0 ) );
+
+ if(m_bWithConfig)
+ {
+ rtl::OUString Store = rtl::OUString::createFromAscii( "com.sun.star.ucb.Store" );
+ uno::Reference< XPropertySetRegistryFactory > xRegFac(
+ m_xMultiServiceFactory->createInstance( Store ),
+ uno::UNO_QUERY );
+ if ( xRegFac.is() )
+ {
+ // Open/create a registry
+ m_xFileRegistry = xRegFac->createPropertySetRegistry( rtl::OUString() );
+ }
+ }
+}
+
+
+shell::~shell()
+{
+}
+
+
+/*********************************************************************************/
+/* */
+/* de/registerNotifier-Implementation */
+/* */
+/*********************************************************************************/
+
+//
+// This two methods register and deregister a change listener for the content belonging
+// to URL aUnqPath
+//
+
+void SAL_CALL
+shell::registerNotifier( const rtl::OUString& aUnqPath, Notifier* pNotifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it =
+ m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ if( ! it->second.notifier )
+ it->second.notifier = new NotifierList();
+
+ std::list< Notifier* >& nlist = *( it->second.notifier );
+
+ std::list<Notifier*>::iterator it1 = nlist.begin();
+ while( it1 != nlist.end() ) // Every "Notifier" only once
+ {
+ if( *it1 == pNotifier ) return;
+ ++it1;
+ }
+ nlist.push_back( pNotifier );
+}
+
+
+
+void SAL_CALL
+shell::deregisterNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.find( aUnqPath );
+ if( it == m_aContent.end() )
+ return;
+
+ it->second.notifier->remove( pNotifier );
+
+ if( ! it->second.notifier->size() )
+ m_aContent.erase( it );
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* de/associate-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Used to associate and deassociate a new property with
+// the content belonging to URL UnqPath.
+// The default value and the the attributes are input
+//
+
+void SAL_CALL
+shell::associate( const rtl::OUString& aUnqPath,
+ const rtl::OUString& PropertyName,
+ const uno::Any& DefaultValue,
+ const sal_Int16 Attributes )
+ throw( beans::PropertyExistException,
+ beans::IllegalTypeException,
+ uno::RuntimeException )
+{
+ MyProperty newProperty( false,
+ PropertyName,
+ -1,
+ DefaultValue.getValueType(),
+ DefaultValue,
+ beans::PropertyState_DEFAULT_VALUE,
+ Attributes );
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.find( newProperty );
+ if( it1 != m_aDefaultProperties.end() )
+ throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ // Load the XPersistentPropertySetInfo and create it, if it does not exist
+ load( it,true );
+
+ PropertySet& properties = *(it->second.properties);
+ it1 = properties.find( newProperty );
+ if( it1 != properties.end() )
+ throw beans::PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ // Property does not exist
+ properties.insert( newProperty );
+ it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
+ }
+ notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
+}
+
+
+
+
+void SAL_CALL
+shell::deassociate( const rtl::OUString& aUnqPath,
+ const rtl::OUString& PropertyName )
+ throw( beans::UnknownPropertyException,
+ beans::NotRemoveableException,
+ uno::RuntimeException )
+{
+ MyProperty oldProperty( PropertyName );
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.find( oldProperty );
+ if( it1 != m_aDefaultProperties.end() )
+ throw beans::NotRemoveableException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it = m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ load( it,false );
+
+ PropertySet& properties = *(it->second.properties);
+
+ it1 = properties.find( oldProperty );
+ if( it1 == properties.end() )
+ throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+
+ properties.erase( it1 );
+
+ if( it->second.xC.is() )
+ it->second.xC->removeProperty( PropertyName );
+
+ if( properties.size() == 9 )
+ {
+ MyProperty ContentTProperty( ContentType );
+
+ if( properties.find( ContentTProperty )->getState() == beans::PropertyState_DEFAULT_VALUE )
+ {
+ it->second.xS = 0;
+ it->second.xC = 0;
+ it->second.xA = 0;
+ if(m_xFileRegistry.is())
+ m_xFileRegistry->removePropertySet( aUnqPath );
+ }
+ }
+ notifyPropertyRemoved( getPropertySetListeners( aUnqPath ), PropertyName );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* page-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given an xOutputStream, this method writes the content of the file belonging to
+// URL aUnqPath into the XOutputStream
+//
+
+
+void SAL_CALL shell::page( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const uno::Reference< io::XOutputStream >& xOutputStream )
+ throw()
+{
+ uno::Reference< XContentProvider > xProvider( m_pProvider );
+ osl::File aFile( aUnqPath );
+ osl::FileBase::RC err = aFile.open( OpenFlag_Read );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ installError( CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING,
+ err );
+ return;
+ }
+
+ const sal_uInt64 bfz = 4*1024;
+ sal_Int8 BFF[bfz];
+ sal_uInt64 nrc; // Retrieved number of Bytes;
+
+ do
+ {
+ err = aFile.read( (void*) BFF,bfz,nrc );
+ if( err == osl::FileBase::E_None )
+ {
+ uno::Sequence< sal_Int8 > seq( BFF, (sal_uInt32)nrc );
+ try
+ {
+ xOutputStream->writeBytes( seq );
+ }
+ catch( io::NotConnectedException )
+ {
+ installError( CommandId,
+ TASKHANDLING_NOTCONNECTED_FOR_PAGING );
+ break;
+ }
+ catch( io::BufferSizeExceededException )
+ {
+ installError( CommandId,
+ TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING );
+ break;
+ }
+ catch( io::IOException )
+ {
+ installError( CommandId,
+ TASKHANDLING_IOEXCEPTION_FOR_PAGING );
+ break;
+ }
+ }
+ else
+ {
+ installError( CommandId,
+ TASKHANDLING_READING_FILE_FOR_PAGING,
+ err );
+ break;
+ }
+ } while( nrc == bfz );
+
+
+ aFile.close();
+
+
+ try
+ {
+ xOutputStream->closeOutput();
+ }
+ catch( io::NotConnectedException )
+ {
+ }
+ catch( io::BufferSizeExceededException )
+ {
+ }
+ catch( io::IOException )
+ {
+ }
+}
+
+
+/*********************************************************************************/
+/* */
+/* open-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.
+//
+
+
+uno::Reference< io::XInputStream > SAL_CALL
+shell::open( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw()
+{
+ XInputStream_impl* xInputStream = new XInputStream_impl( this, aUnqPath, bLock ); // from filinpstr.hxx
+
+ sal_Int32 ErrorCode = xInputStream->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ xInputStream->getMinorError() );
+
+ delete xInputStream;
+ xInputStream = 0;
+ }
+
+ return uno::Reference< io::XInputStream >( xInputStream );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* open for read/write access-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Given a file URL aUnqPath, this methods returns a XStream which can be used
+// to read and write from/to the file.
+//
+
+
+uno::Reference< io::XStream > SAL_CALL
+shell::open_rw( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool bLock )
+ throw()
+{
+ XStream_impl* xStream = new XStream_impl( this, aUnqPath, bLock ); // from filstr.hxx
+
+ sal_Int32 ErrorCode = xStream->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ xStream->getMinorError() );
+
+ delete xStream;
+ xStream = 0;
+ }
+ return uno::Reference< io::XStream >( xStream );
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* ls-Implementation */
+/* */
+/*********************************************************************************/
+//
+// This method returns the result set containing the the children of the directory belonging
+// to file URL aUnqPath
+//
+
+
+uno::Reference< XDynamicResultSet > SAL_CALL
+shell::ls( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const sal_Int32 OpenMode,
+ const uno::Sequence< beans::Property >& seq,
+ const uno::Sequence< NumberedSortingInfo >& seqSort )
+ throw()
+{
+ XResultSet_impl* p = new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort );
+
+ sal_Int32 ErrorCode = p->CtorSuccess();
+
+ if( ErrorCode != TASKHANDLER_NO_ERROR )
+ {
+ installError( CommandId,
+ ErrorCode,
+ p->getMinorError() );
+
+ delete p;
+ p = 0;
+ }
+
+ return uno::Reference< XDynamicResultSet > ( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* info_c implementation */
+/* */
+/*********************************************************************************/
+// Info for commands
+
+uno::Reference< XCommandInfo > SAL_CALL
+shell::info_c()
+ throw()
+{
+ XCommandInfo_impl* p = new XCommandInfo_impl( this );
+ return uno::Reference< XCommandInfo >( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* info_p-Implementation */
+/* */
+/*********************************************************************************/
+// Info for the properties
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+shell::info_p( const rtl::OUString& aUnqPath )
+ throw()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ XPropertySetInfo_impl* p = new XPropertySetInfo_impl( this,aUnqPath );
+ return uno::Reference< beans::XPropertySetInfo >( p );
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* setv-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Sets the values of the properties belonging to fileURL aUnqPath
+//
+
+
+uno::Sequence< uno::Any > SAL_CALL
+shell::setv( const rtl::OUString& aUnqPath,
+ const uno::Sequence< beans::PropertyValue >& values )
+ throw()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 propChanged = 0;
+ uno::Sequence< uno::Any > ret( values.getLength() );
+ uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ PropertySet& properties = *( it->second.properties );
+ shell::PropertySet::iterator it1;
+ uno::Any aAny;
+
+ for( sal_Int32 i = 0; i < values.getLength(); ++i )
+ {
+ MyProperty toset( values[i].Name );
+ it1 = properties.find( toset );
+ if( it1 == properties.end() )
+ {
+ ret[i] <<= beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ continue;
+ }
+
+ aAny = it1->getValue();
+ if( aAny == values[i].Value )
+ continue; // nothing needs to be changed
+
+ if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
+ {
+ ret[i] <<= lang::IllegalAccessException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ continue;
+ }
+
+ seqChanged[ propChanged ].PropertyName = values[i].Name;
+ seqChanged[ propChanged ].PropertyHandle = -1;
+ seqChanged[ propChanged ].Further = false;
+ seqChanged[ propChanged ].OldValue <<= aAny;
+ seqChanged[ propChanged++ ].NewValue = values[i].Value;
+
+ it1->setValue( values[i].Value ); // Put the new value into the local cash
+
+ if( ! it1->IsNative() )
+ {
+ // Also put logical properties into storage
+ if( !it->second.xS.is() )
+ load( it,true );
+
+ if( ( values[i].Name == ContentType ) &&
+ it1->getState() == beans::PropertyState_DEFAULT_VALUE )
+ { // Special logic for ContentType
+ // 09.07.01: Not reached anymore, because ContentType is readonly
+ it1->setState( beans::PropertyState_DIRECT_VALUE );
+ it->second.xC->addProperty( values[i].Name,
+ beans::PropertyAttribute::MAYBEVOID,
+ values[i].Value );
+ }
+
+ try
+ {
+ it->second.xS->setPropertyValue( values[i].Name,values[i].Value );
+ }
+ catch( const uno::Exception& e )
+ {
+ --propChanged; // unsuccessful setting
+ ret[i] <<= e;
+ }
+ }
+ else
+ {
+ // native properties
+ // Setting of physical file properties
+ if( values[i].Name == Size )
+ {
+ sal_Int64 newSize = 0;
+ if( values[i].Value >>= newSize )
+ { // valid value for the size
+ osl::File aFile(aUnqPath);
+ bool err =
+ aFile.open(OpenFlag_Write) != osl::FileBase::E_None ||
+ aFile.setSize(sal_uInt64(newSize)) != osl::FileBase::E_None ||
+ aFile.close() != osl::FileBase::E_None;
+
+ if( err )
+ {
+ --propChanged; // unsuccessful setting
+ uno::Sequence< uno::Any > names( 1 );
+ ret[0] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(aUnqPath),
+ beans::PropertyState_DIRECT_VALUE);
+ IOErrorCode ioError(IOErrorCode_GENERAL);
+ ret[i] <<= InteractiveAugmentedIOException(
+ rtl::OUString(),
+ 0,
+ task::InteractionClassification_ERROR,
+ ioError,
+ names );
+ }
+ }
+ else
+ ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ else if(values[i].Name == IsReadOnly ||
+ values[i].Name == IsHidden)
+ {
+ sal_Bool value = sal_False;
+ if( values[i].Value >>= value )
+ {
+ osl::DirectoryItem aDirItem;
+ osl::FileBase::RC err =
+ osl::DirectoryItem::get(aUnqPath,aDirItem);
+ sal_uInt64 nAttributes(0);
+ if(err == osl::FileBase::E_None)
+ {
+ osl::FileStatus aFileStatus(FileStatusMask_Attributes);
+ err = aDirItem.getFileStatus(aFileStatus);
+ if(err == osl::FileBase::E_None &&
+ aFileStatus.isValid(FileStatusMask_Attributes))
+ nAttributes = aFileStatus.getAttributes();
+ }
+ // now we have the attributes provided all went well.
+ if(err == osl::FileBase::E_None) {
+ if(values[i].Name == IsReadOnly)
+ {
+ nAttributes &= ~(Attribute_OwnWrite |
+ Attribute_GrpWrite |
+ Attribute_OthWrite |
+ Attribute_ReadOnly);
+ if(value)
+ nAttributes |= Attribute_ReadOnly;
+ else
+ nAttributes |= (
+ Attribute_OwnWrite |
+ Attribute_GrpWrite |
+ Attribute_OthWrite);
+ }
+ else if(values[i].Name == IsHidden)
+ {
+ nAttributes &= ~(Attribute_Hidden);
+ if(value)
+ nAttributes |= Attribute_Hidden;
+ }
+ err = osl::File::setAttributes(
+ aUnqPath,nAttributes);
+ }
+
+ if( err != osl::FileBase::E_None )
+ {
+ --propChanged; // unsuccessful setting
+ uno::Sequence< uno::Any > names( 1 );
+ names[0] <<= beans::PropertyValue(
+ rtl::OUString::createFromAscii("Uri"), -1,
+ uno::makeAny(aUnqPath),
+ beans::PropertyState_DIRECT_VALUE);
+ IOErrorCode ioError;
+ switch( err )
+ {
+ case osl::FileBase::E_NOMEM:
+ // not enough memory for allocating structures <br>
+ ioError = IOErrorCode_OUT_OF_MEMORY;
+ break;
+ case osl::FileBase::E_INVAL:
+ // the format of the parameters was not valid<p>
+ ioError = IOErrorCode_INVALID_PARAMETER;
+ break;
+ case osl::FileBase::E_NAMETOOLONG:
+ // File name too long<br>
+ ioError = IOErrorCode_NAME_TOO_LONG;
+ break;
+ case osl::FileBase::E_NOENT:
+ // No such file or directory<br>
+ case osl::FileBase::E_NOLINK:
+ // Link has been severed<br>
+ ioError = IOErrorCode_NOT_EXISTING;
+ break;
+ case osl::FileBase::E_ROFS:
+ // #i4735# handle ROFS transparently
+ // as ACCESS_DENIED
+ case osl::FileBase::E_PERM:
+ case osl::FileBase::E_ACCES:
+ // permission denied<br>
+ ioError = IOErrorCode_ACCESS_DENIED;
+ break;
+ case osl::FileBase::E_LOOP:
+ // Too many symbolic links encountered<br>
+ case osl::FileBase::E_FAULT:
+ // Bad address<br>
+ case osl::FileBase::E_IO:
+ // I/O error<br>
+ case osl::FileBase::E_NOSYS:
+ // Function not implemented<br>
+ case osl::FileBase::E_MULTIHOP:
+ // Multihop attempted<br>
+ case osl::FileBase::E_INTR:
+ // function call was interrupted<p>
+ default:
+ ioError = IOErrorCode_GENERAL;
+ break;
+ }
+ ret[i] <<= InteractiveAugmentedIOException(
+ rtl::OUString(),
+ 0,
+ task::InteractionClassification_ERROR,
+ ioError,
+ names );
+ }
+ }
+ else
+ ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
+ }
+ }
+ } // end for
+
+ if( propChanged )
+ {
+ seqChanged.realloc( propChanged );
+ notifyPropertyChanges( getPropertyChangeNotifier( aUnqPath ),seqChanged );
+ }
+
+ return ret;
+}
+
+/*********************************************************************************/
+/* */
+/* getv-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Reads the values of the properties belonging to fileURL aUnqPath;
+// Returns an XRow object containing the values in the requested order.
+//
+
+
+uno::Reference< sdbc::XRow > SAL_CALL
+shell::getv( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ const uno::Sequence< beans::Property >& properties )
+ throw()
+{
+ uno::Sequence< uno::Any > seq( properties.getLength() );
+
+ sal_Int32 n_Mask;
+ getMaskFromProperties( n_Mask,properties );
+ osl::FileStatus aFileStatus( n_Mask );
+
+ osl::DirectoryItem aDirItem;
+ osl::FileBase::RC nError1 = osl::DirectoryItem::get( aUnqPath,aDirItem );
+ if( nError1 != osl::FileBase::E_None )
+ installError(CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
+ nError1);
+
+ osl::FileBase::RC nError2 = aDirItem.getFileStatus( aFileStatus );
+ if( nError1 == osl::FileBase::E_None &&
+ nError2 != osl::FileBase::E_None )
+ installError(CommandId,
+ TASKHANDLING_OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
+ nError2);
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ commit( it,aFileStatus );
+
+ shell::PropertySet::iterator it1;
+ PropertySet& propset = *(it->second.properties);
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( properties[i].Name );
+ it1 = propset.find( readProp );
+ if( it1 == propset.end() )
+ seq[i] = uno::Any();
+ else
+ seq[i] = it1->getValue();
+ }
+ }
+
+ XRow_impl* p = new XRow_impl( this,seq );
+ return uno::Reference< sdbc::XRow >( p );
+}
+
+
+/********************************************************************************/
+/* */
+/* transfer-commandos */
+/* */
+/********************************************************************************/
+
+
+/********************************************************************************/
+/* */
+/* move-implementation */
+/* */
+/********************************************************************************/
+//
+// Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.
+//
+
+void SAL_CALL
+shell::move( sal_Int32 CommandId,
+ const rtl::OUString srcUnqPath,
+ const rtl::OUString dstUnqPathIn,
+ const sal_Int32 NameClash )
+ throw()
+{
+ // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
+ // srcUnqPath and dstUnqPathIn are equal
+ if( srcUnqPath == dstUnqPathIn )
+ return;
+ // <--
+ //
+ osl::FileBase::RC nError;
+ rtl::OUString dstUnqPath( dstUnqPathIn );
+
+ switch( NameClash )
+ {
+ case NameClash::KEEP:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_KEEPERROR_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::OVERWRITE:
+ {
+ // stat to determine whether we have a symlink
+ rtl::OUString targetPath(dstUnqPath);
+
+ osl::FileStatus aStatus(FileStatusMask_Type|FileStatusMask_LinkTargetURL);
+ osl::DirectoryItem aItem;
+ osl::DirectoryItem::get(dstUnqPath,aItem);
+ aItem.getFileStatus(aStatus);
+
+ if( aStatus.isValid(FileStatusMask_Type) &&
+ aStatus.isValid(FileStatusMask_LinkTargetURL) &&
+ aStatus.getFileType() == osl::FileStatus::Link )
+ targetPath = aStatus.getLinkTargetURL();
+
+ // Will do nothing if file does not exist.
+ osl::File::remove( targetPath );
+
+ nError = osl_File_move( srcUnqPath,targetPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_OVERWRITE_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::RENAME:
+ {
+ rtl::OUString newDstUnqPath;
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ // "invent" a new valid title.
+
+ sal_Int32 nPos = -1;
+ sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
+ sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
+ if( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
+ && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
+ nPos = nLastDot;
+ else
+ nPos = dstUnqPath.getLength();
+
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ newDstUnqPath = dstUnqPath;
+
+ rtl::OUString aPostFix( rtl::OUString::createFromAscii( "_" ) );
+ aPostFix += rtl::OUString::valueOf( ++nTry );
+
+ newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
+
+ nError = osl_File_move( srcUnqPath,newDstUnqPath,true );
+ }
+ while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
+ }
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAME_FOR_MOVE );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAMEMOVE_FOR_MOVE,
+ nError );
+ return;
+ }
+ else
+ dstUnqPath = newDstUnqPath;
+
+ break;
+ }
+ case NameClash::ERROR:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASH_FOR_MOVE );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHMOVE_FOR_MOVE,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::ASK:
+ default:
+ {
+ nError = osl_File_move( srcUnqPath,dstUnqPath,true );
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE,
+ NameClash::ASK);
+ return;
+ }
+ }
+ break;
+ }
+
+ // Determine, whether we have moved a file or a folder
+ osl::DirectoryItem aItem;
+ nError = osl::DirectoryItem::get( dstUnqPath,aItem );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_TRANSFER_BY_MOVE_SOURCE,
+ nError );
+ return;
+ }
+ osl::FileStatus aStatus( FileStatusMask_Type );
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( FileStatusMask_Type ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT,
+ nError );
+ return;
+ }
+ sal_Bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );
+
+
+ copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );
+
+ rtl::OUString aDstParent = getParentName( dstUnqPath );
+ rtl::OUString aDstTitle = getTitle( dstUnqPath );
+
+ rtl::OUString aSrcParent = getParentName( srcUnqPath );
+ rtl::OUString aSrcTitle = getTitle( srcUnqPath );
+
+ notifyInsert( getContentEventListeners( aDstParent ),dstUnqPath );
+ if( aDstParent != aSrcParent )
+ notifyContentRemoved( getContentEventListeners( aSrcParent ),srcUnqPath );
+
+ notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) );
+ erasePersistentSet( srcUnqPath,!isDocument );
+}
+
+
+
+/********************************************************************************/
+/* */
+/* copy-implementation */
+/* */
+/********************************************************************************/
+//
+// Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories )
+//
+
+namespace {
+
+bool getType(
+ TaskManager & task, sal_Int32 id, rtl::OUString const & fileUrl,
+ osl::DirectoryItem * item, osl::FileStatus::Type * type)
+{
+ OSL_ASSERT(item != 0 && type != 0);
+ osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
+ if (err != osl::FileBase::E_None) {
+ task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCE, err);
+ return false;
+ }
+ osl::FileStatus stat(FileStatusMask_Type);
+ err = item->getFileStatus(stat);
+ if (err != osl::FileBase::E_None) {
+ task.installError(id, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, err);
+ return false;
+ }
+ *type = stat.getFileType();
+ return true;
+}
+
+}
+
+void SAL_CALL
+shell::copy(
+ sal_Int32 CommandId,
+ const rtl::OUString srcUnqPath,
+ const rtl::OUString dstUnqPathIn,
+ sal_Int32 NameClash )
+ throw()
+{
+ osl::FileBase::RC nError;
+ rtl::OUString dstUnqPath( dstUnqPathIn );
+
+ // Resolve symbolic links within the source path. If srcUnqPath denotes a
+ // symbolic link (targeting either a file or a folder), the contents of the
+ // target is copied (recursively, in the case of a folder). However, if
+ // recursively copying the contents of a folder causes a symbolic link to be
+ // copied, the symbolic link itself is copied.
+ osl::DirectoryItem item;
+ osl::FileStatus::Type type;
+ if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
+ return;
+ }
+ rtl::OUString rslvdSrcUnqPath;
+ if (type == osl::FileStatus::Link) {
+ osl::FileStatus stat(FileStatusMask_LinkTargetURL);
+ nError = item.getFileStatus(stat);
+ if (nError != osl::FileBase::E_None) {
+ installError(
+ CommandId, TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT, nError);
+ return;
+ }
+ rslvdSrcUnqPath = stat.getLinkTargetURL();
+ if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
+ return;
+ }
+ } else {
+ rslvdSrcUnqPath = srcUnqPath;
+ }
+
+ sal_Bool isDocument
+ = type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
+ sal_Int32 IsWhat = isDocument ? -1 : 1;
+
+ switch( NameClash )
+ {
+ case NameClash::KEEP:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+ if( nError != osl::FileBase::E_None && nError != osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_KEEPERROR_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::OVERWRITE:
+ {
+ // remove (..., MustExist = sal_False).
+ remove( CommandId, dstUnqPath, IsWhat, sal_False );
+
+ // copy.
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
+ if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_OVERWRITE_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::RENAME:
+ {
+ rtl::OUString newDstUnqPath;
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ // "invent" a new valid title.
+
+ sal_Int32 nPos = -1;
+ sal_Int32 nLastDot = dstUnqPath.lastIndexOf( '.' );
+ sal_Int32 nLastSlash = dstUnqPath.lastIndexOf( '/' );
+ if ( ( nLastSlash < nLastDot ) // dot is part of last(!) path segment
+ && ( nLastSlash != ( nLastDot - 1 ) ) ) // file name does not start with a dot
+ nPos = nLastDot;
+ else
+ nPos = dstUnqPath.getLength();
+
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ newDstUnqPath = dstUnqPath;
+
+ rtl::OUString aPostFix( rtl::OUString::createFromAscii( "_" ) );
+ aPostFix += rtl::OUString::valueOf( ++nTry );
+
+ newDstUnqPath = newDstUnqPath.replaceAt( nPos, 0, aPostFix );
+
+ nError = copy_recursive( rslvdSrcUnqPath,newDstUnqPath,IsWhat,true );
+ }
+ while( ( nError == osl::FileBase::E_EXIST ) && ( nTry < 10000 ) );
+ }
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAME_FOR_COPY );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_RENAMEMOVE_FOR_COPY,
+ nError );
+ return;
+ }
+ else
+ dstUnqPath = newDstUnqPath;
+
+ break;
+ }
+ case NameClash::ERROR:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASH_FOR_COPY );
+ return;
+ }
+ else if( nError != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHMOVE_FOR_COPY,
+ nError );
+ return;
+ }
+ break;
+ }
+ case NameClash::ASK:
+ default:
+ {
+ nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,true );
+
+ if( nError == osl::FileBase::E_EXIST )
+ {
+ installError( CommandId,
+ TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY,
+ NameClash);
+ return;
+ }
+ break;
+ }
+ }
+
+ copyPersistentSet( srcUnqPath,dstUnqPath, !isDocument );
+ notifyInsert( getContentEventListeners( getParentName( dstUnqPath ) ),dstUnqPath );
+}
+
+
+
+/********************************************************************************/
+/* */
+/* remove-implementation */
+/* */
+/********************************************************************************/
+//
+// Deletes the content belonging to fileURL aUnqPath( recursively in case of directory )
+// Return: success of operation
+//
+
+
+sal_Bool SAL_CALL
+shell::remove( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Int32 IsWhat,
+ sal_Bool MustExist )
+ throw()
+{
+ sal_Int32 nMask = FileStatusMask_Type | FileStatusMask_FileURL;
+
+ osl::DirectoryItem aItem;
+ osl::FileStatus aStatus( nMask );
+ osl::FileBase::RC nError;
+
+ if( IsWhat == 0 ) // Determine whether we are removing a directory or a file
+ {
+ nError = osl::DirectoryItem::get( aUnqPath, aItem );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE,
+ nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
+ return sal_False;
+ }
+
+ if( aStatus.getFileType() == osl::FileStatus::Regular ||
+ aStatus.getFileType() == osl::FileStatus::Link )
+ IsWhat = -1; // RemoveFile
+ else if( aStatus.getFileType() == osl::FileStatus::Directory ||
+ aStatus.getFileType() == osl::FileStatus::Volume )
+ IsWhat = +1; // RemoveDirectory
+ }
+
+
+ if( IsWhat == -1 ) // Removing a file
+ {
+ nError = osl::File::remove( aUnqPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_DELETEFILE_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+ else
+ {
+ notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
+ erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
+ }
+ }
+ else if( IsWhat == +1 ) // Removing a directory
+ {
+ osl::Directory aDirectory( aUnqPath );
+
+ nError = aDirectory.open();
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_OPENDIRECTORY_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+
+ sal_Bool whileSuccess = sal_True;
+ sal_Int32 recurse = 0;
+ rtl::OUString name;
+
+ nError = aDirectory.getNextItem( aItem );
+ while( nError == osl::FileBase::E_None )
+ {
+ nError = aItem.getFileStatus( aStatus );
+ if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE,
+ nError != osl::FileBase::E_None ? nError : TASKHANDLER_NO_ERROR );
+ whileSuccess = sal_False;
+ break;
+ }
+
+ if( aStatus.getFileType() == osl::FileStatus::Regular ||
+ aStatus.getFileType() == osl::FileStatus::Link )
+ recurse = -1;
+ else if( aStatus.getFileType() == osl::FileStatus::Directory ||
+ aStatus.getFileType() == osl::FileStatus::Volume )
+ recurse = +1;
+
+ name = aStatus.getFileURL();
+ whileSuccess = remove(
+ CommandId, name, recurse, MustExist );
+ if( !whileSuccess )
+ break;
+
+ nError = aDirectory.getNextItem( aItem );
+ }
+
+ aDirectory.close();
+
+ if( ! whileSuccess )
+ return sal_False; // error code is installed
+
+ if( nError != osl::FileBase::E_NOENT )
+ {
+ installError( CommandId,
+ TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE,
+ nError );
+ return sal_False;
+ }
+
+ nError = osl::Directory::remove( aUnqPath );
+ if( nError != osl::FileBase::E_None )
+ {
+ if (MustExist)
+ {
+ installError( CommandId,
+ TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE,
+ nError );
+ }
+ return (!MustExist);
+ }
+ else
+ {
+ notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
+ erasePersistentSet( aUnqPath );
+ }
+ }
+ else // Don't know what to remove
+ {
+ installError( CommandId,
+ TASKHANDLING_FILETYPE_FOR_REMOVE );
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+
+/********************************************************************************/
+/* */
+/* mkdir-implementation */
+/* */
+/********************************************************************************/
+//
+// Creates new directory with given URL, recursively if necessary
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::mkdir( sal_Int32 CommandId,
+ const rtl::OUString& rUnqPath,
+ sal_Bool OverWrite )
+ throw()
+{
+ rtl::OUString aUnqPath;
+
+ // remove trailing slash
+ if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
+ aUnqPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
+ else
+ aUnqPath = rUnqPath;
+
+ osl::FileBase::RC nError = osl::Directory::create( aUnqPath );
+
+ switch ( nError )
+ {
+ case osl::FileBase::E_EXIST: // Directory cannot be overwritten
+ {
+ if( !OverWrite )
+ {
+ installError( CommandId,
+ TASKHANDLING_FOLDER_EXISTS_MKDIR );
+ return sal_False;
+ }
+ else
+ return sal_True;
+ }
+ case osl::FileBase::E_INVAL:
+ {
+ installError(CommandId,
+ TASKHANDLING_INVALID_NAME_MKDIR);
+ return sal_False;
+ }
+ case osl::FileBase::E_None:
+ {
+ rtl::OUString aPrtPath = getParentName( aUnqPath );
+ notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
+ return sal_True;
+ }
+ default:
+ return ensuredir(
+ CommandId,
+ aUnqPath,
+ TASKHANDLING_CREATEDIRECTORY_MKDIR );
+ }
+}
+
+
+/********************************************************************************/
+/* */
+/* mkfil-implementation */
+/* */
+/********************************************************************************/
+//
+// Creates new file with given URL.
+// The content of aInputStream becomes the content of the file
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::mkfil( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool Overwrite,
+ const uno::Reference< io::XInputStream >& aInputStream )
+ throw()
+{
+ // return value unimportant
+ sal_Bool bSuccess = write( CommandId,
+ aUnqPath,
+ Overwrite,
+ aInputStream );
+ if ( bSuccess )
+ {
+ rtl::OUString aPrtPath = getParentName( aUnqPath );
+ notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
+ }
+ return bSuccess;
+}
+
+
+/********************************************************************************/
+/* */
+/* write-implementation */
+/* */
+/********************************************************************************/
+//
+// writes to the file with given URL.
+// The content of aInputStream becomes the content of the file
+// Return:: success of operation
+//
+
+sal_Bool SAL_CALL
+shell::write( sal_Int32 CommandId,
+ const rtl::OUString& aUnqPath,
+ sal_Bool OverWrite,
+ const uno::Reference< io::XInputStream >& aInputStream )
+ throw()
+{
+ if( ! aInputStream.is() )
+ {
+ installError( CommandId,
+ TASKHANDLING_INPUTSTREAM_FOR_WRITE );
+ return sal_False;
+ }
+
+ // Create parent path, if necessary.
+ if ( ! ensuredir( CommandId,
+ getParentName( aUnqPath ),
+ TASKHANDLING_ENSUREDIR_FOR_WRITE ) )
+ return sal_False;
+
+ osl::FileBase::RC err;
+ osl::File aFile( aUnqPath );
+
+ if( OverWrite )
+ {
+ err = aFile.open( OpenFlag_Write | OpenFlag_Create );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ err = aFile.open( OpenFlag_Write );
+ }
+
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE,
+ err );
+ return sal_False;
+ }
+ }
+ else
+ {
+ err = aFile.open( OpenFlag_Read | OpenFlag_NoLock );
+ if( err == osl::FileBase::E_None ) // The file exists and shall not be overwritten
+ {
+ installError( CommandId,
+ TASKHANDLING_NOREPLACE_FOR_WRITE, // Now an exception
+ err );
+
+ aFile.close();
+ return sal_False;
+ }
+
+ // as a temporary solution the creation does not lock the file at all
+ // in future it should be possible to create the file without lock explicitly
+ err = aFile.open( OpenFlag_Write | OpenFlag_Create | OpenFlag_NoLock );
+
+ if( err != osl::FileBase::E_None )
+ {
+ aFile.close();
+ installError( CommandId,
+ TASKHANDLING_NO_OPEN_FILE_FOR_WRITE,
+ err );
+ return sal_False;
+ }
+ }
+
+ sal_Bool bSuccess = sal_True;
+
+ sal_uInt64 nTotalNumberOfBytes = 0;
+ sal_uInt64 nWrittenBytes;
+ sal_Int32 nReadBytes = 0, nRequestedBytes = 32768 /*32k*/;
+ uno::Sequence< sal_Int8 > seq( nRequestedBytes );
+
+ do
+ {
+ try
+ {
+ nReadBytes = aInputStream->readBytes( seq,
+ nRequestedBytes );
+ }
+ catch( const io::NotConnectedException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_NOTCONNECTED_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+ catch( const io::BufferSizeExceededException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+ catch( const io::IOException& )
+ {
+ installError( CommandId,
+ TASKHANDLING_IOEXCEPTION_FOR_WRITE );
+ bSuccess = sal_False;
+ break;
+ }
+
+ if( nReadBytes )
+ {
+ const sal_Int8* p = seq.getConstArray();
+
+ err = aFile.write( ((void*)(p)),
+ sal_uInt64( nReadBytes ),
+ nWrittenBytes );
+
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ break;
+ }
+ else if( nWrittenBytes != sal_uInt64( nReadBytes ) )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_NO_SPACE );
+ bSuccess = sal_False;
+ break;
+ }
+
+ nTotalNumberOfBytes += nWrittenBytes;
+ }
+ } while( nReadBytes == nRequestedBytes );
+
+ err = aFile.setSize( nTotalNumberOfBytes );
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILESIZE_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ }
+
+ err = aFile.close();
+ if( err != osl::FileBase::E_None )
+ {
+ installError( CommandId,
+ TASKHANDLING_FILEIOERROR_FOR_WRITE,
+ err );
+ bSuccess = sal_False;
+ }
+
+ return bSuccess;
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* insertDefaultProperties-Implementation */
+/* */
+/*********************************************************************************/
+
+
+void SAL_CALL shell::insertDefaultProperties( const rtl::OUString& aUnqPath )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentMap::iterator it =
+ m_aContent.insert( ContentMap::value_type( aUnqPath,UnqPathData() ) ).first;
+
+ load( it,false );
+
+ MyProperty ContentTProperty( ContentType );
+
+ PropertySet& properties = *(it->second.properties);
+ sal_Bool ContentNotDefau = properties.find( ContentTProperty ) != properties.end();
+
+ shell::PropertySet::iterator it1 = m_aDefaultProperties.begin();
+ while( it1 != m_aDefaultProperties.end() )
+ {
+ if( ContentNotDefau && it1->getPropertyName() == ContentType )
+ {
+ // No insertion
+ }
+ else
+ properties.insert( *it1 );
+ ++it1;
+ }
+}
+
+
+
+
+/******************************************************************************/
+/* */
+/* mapping of file urls */
+/* to uncpath and vice versa */
+/* */
+/******************************************************************************/
+
+
+sal_Bool SAL_CALL shell::getUnqFromUrl( const rtl::OUString& Url,rtl::OUString& Unq )
+{
+ if( 0 == Url.compareToAscii( "file:///" ) ||
+ 0 == Url.compareToAscii( "file://localhost/" ) ||
+ 0 == Url.compareToAscii( "file://127.0.0.1/" ) )
+ {
+ Unq = rtl::OUString::createFromAscii( "file:///" );
+ return false;
+ }
+
+ sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Url,Unq );
+
+ Unq = Url;
+
+ sal_Int32 l = Unq.getLength()-1;
+ if( ! err && Unq.getStr()[ l ] == '/' &&
+ Unq.indexOf( '/', RTL_CONSTASCII_LENGTH("//") ) < l )
+ Unq = Unq.copy(0, Unq.getLength() - 1);
+
+ return err;
+}
+
+
+
+sal_Bool SAL_CALL shell::getUrlFromUnq( const rtl::OUString& Unq,rtl::OUString& Url )
+{
+ sal_Bool err = osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( Unq,Url );
+
+ Url = Unq;
+
+ return err;
+}
+
+
+
+// Helper function for public copy
+
+osl::FileBase::RC SAL_CALL
+shell::copy_recursive( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Int32 TypeToCopy,
+ sal_Bool testExistBeforeCopy )
+ throw()
+{
+ osl::FileBase::RC err = osl::FileBase::E_None;
+
+ if( TypeToCopy == -1 ) // Document
+ {
+ err = osl_File_copy( srcUnqPath,dstUnqPath,testExistBeforeCopy );
+ }
+ else if( TypeToCopy == +1 ) // Folder
+ {
+ osl::Directory aDir( srcUnqPath );
+ aDir.open();
+
+ err = osl::Directory::create( dstUnqPath );
+ osl::FileBase::RC next = err;
+ if( err == osl::FileBase::E_None )
+ {
+ sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type;
+
+ osl::DirectoryItem aDirItem;
+
+ while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
+ {
+ sal_Bool IsDoc = false;
+ osl::FileStatus aFileStatus( n_Mask );
+ aDirItem.getFileStatus( aFileStatus );
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ // Getting the information for the next recursive copy
+ sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
+
+ rtl::OUString newSrcUnqPath;
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ newSrcUnqPath = aFileStatus.getFileURL();
+
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString tit;
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ tit = aFileStatus.getFileName();
+ if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
+ newDstUnqPath += rtl::OUString::createFromAscii( "/" );
+ newDstUnqPath += tit;
+
+ if ( newSrcUnqPath != dstUnqPath )
+ err = copy_recursive( newSrcUnqPath,newDstUnqPath,newTypeToCopy,false );
+ }
+
+ if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
+ err = next;
+ }
+ aDir.close();
+ }
+
+ return err;
+}
+
+
+
+// Helper function for mkfil,mkdir and write
+// Creates whole path
+// returns success of the operation
+
+
+sal_Bool SAL_CALL shell::ensuredir( sal_Int32 CommandId,
+ const rtl::OUString& rUnqPath,
+ sal_Int32 errorCode )
+ throw()
+{
+ rtl::OUString aPath;
+
+ if ( rUnqPath.getLength() < 1 )
+ return sal_False;
+
+ if ( rUnqPath[ rUnqPath.getLength() - 1 ] == sal_Unicode( '/' ) )
+ aPath = rUnqPath.copy( 0, rUnqPath.getLength() - 1 );
+ else
+ aPath = rUnqPath;
+
+
+ // HACK: create directory on a mount point with nobrowse option
+ // returns ENOSYS in any case !!
+ osl::Directory aDirectory( aPath );
+ osl::FileBase::RC nError = aDirectory.open();
+ aDirectory.close();
+
+ if( nError == osl::File::E_None )
+ return sal_True;
+
+ nError = osl::Directory::create( aPath );
+
+ if( nError == osl::File::E_None )
+ notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
+
+ sal_Bool bSuccess = ( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+
+ if( ! bSuccess )
+ {
+ rtl::OUString aParentDir = getParentName( aPath );
+
+ if ( aParentDir != aPath )
+ { // Create first the parent directory
+ bSuccess = ensuredir( CommandId,
+ getParentName( aPath ),
+ errorCode );
+
+ // After parent directory structure exists try it one's more
+
+ if ( bSuccess )
+ { // Parent directory exists, retry creation of directory
+ nError = osl::Directory::create( aPath );
+
+ if( nError == osl::File::E_None )
+ notifyInsert( getContentEventListeners( getParentName( aPath ) ),aPath );
+
+ bSuccess =( nError == osl::File::E_None || nError == osl::FileBase::E_EXIST );
+ }
+ }
+ }
+
+ if( ! bSuccess )
+ installError( CommandId,
+ errorCode,
+ nError );
+
+ return bSuccess;
+}
+
+
+
+
+//
+// Given a sequence of properties seq, this method determines the mask
+// used to instantiate a osl::FileStatus, so that a call to
+// osl::DirectoryItem::getFileStatus fills the required fields.
+//
+
+
+void SAL_CALL
+shell::getMaskFromProperties(
+ sal_Int32& n_Mask,
+ const uno::Sequence< beans::Property >& seq )
+{
+ n_Mask = 0;
+ for(sal_Int32 j = 0; j < seq.getLength(); ++j) {
+ if(seq[j].Name == Title)
+ n_Mask |= FileStatusMask_FileName;
+ else if(seq[j].Name == CasePreservingURL)
+ n_Mask |= FileStatusMask_FileURL;
+ else if(seq[j].Name == IsDocument ||
+ seq[j].Name == IsFolder ||
+ seq[j].Name == IsVolume ||
+ seq[j].Name == IsRemoveable ||
+ seq[j].Name == IsRemote ||
+ seq[j].Name == IsCompactDisc ||
+ seq[j].Name == IsFloppy ||
+ seq[j].Name == ContentType)
+ n_Mask |= (FileStatusMask_Type | FileStatusMask_LinkTargetURL);
+ else if(seq[j].Name == Size)
+ n_Mask |= (FileStatusMask_FileSize |
+ FileStatusMask_Type |
+ FileStatusMask_LinkTargetURL);
+ else if(seq[j].Name == IsHidden ||
+ seq[j].Name == IsReadOnly)
+ n_Mask |= FileStatusMask_Attributes;
+ else if(seq[j].Name == DateModified)
+ n_Mask |= FileStatusMask_ModifyTime;
+// n_Mask = FileStatusMask_FileURL;
+// n_Mask |= FileStatusMask_LinkTargetURL;
+// n_Mask |= FileStatusMask_FileName;
+// n_Mask |= FileStatusMask_Type;
+// n_Mask |= FileStatusMask_ModifyTime;
+// n_Mask |= FileStatusMask_FileSize;
+// n_Mask |= FileStatusMask_Attributes;
+ }
+}
+
+
+
+/*********************************************************************************/
+/* */
+/* load-Implementation */
+/* */
+/*********************************************************************************/
+//
+// Load the properties from configuration, if create == true create them.
+// The Properties are stored under the url belonging to it->first.
+//
+
+void SAL_CALL
+shell::load( const ContentMap::iterator& it, sal_Bool create )
+{
+ if( ! it->second.properties )
+ it->second.properties = new PropertySet;
+
+ if( ( ! it->second.xS.is() ||
+ ! it->second.xC.is() ||
+ ! it->second.xA.is() )
+ && m_xFileRegistry.is() )
+ {
+
+ uno::Reference< ucb::XPersistentPropertySet > xS = m_xFileRegistry->openPropertySet( it->first,create );
+ if( xS.is() )
+ {
+ uno::Reference< beans::XPropertyContainer > xC( xS,uno::UNO_QUERY );
+ uno::Reference< beans::XPropertyAccess > xA( xS,uno::UNO_QUERY );
+
+ it->second.xS = xS;
+ it->second.xC = xC;
+ it->second.xA = xA;
+
+ // Now put in all values in the storage in the local hash;
+
+ PropertySet& properties = *(it->second.properties);
+ uno::Sequence< beans::Property > seq = xS->getPropertySetInfo()->getProperties();
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( false,
+ seq[i].Name,
+ seq[i].Handle,
+ seq[i].Type,
+ xS->getPropertyValue( seq[i].Name ),
+ beans::PropertyState_DIRECT_VALUE,
+ seq[i].Attributes );
+ if( properties.find( readProp ) == properties.end() )
+ properties.insert( readProp );
+ }
+ }
+ else if( create )
+ {
+ // Catastrophic error
+ }
+ }
+}
+
+
+
+
+/*********************************************************************************/
+/* */
+/* commit-Implementation */
+/* */
+/*********************************************************************************/
+// Commit inserts the determined properties in the filestatus object into
+// the internal map, so that is possible to determine on a subsequent
+// setting of file properties which properties have changed without filestat
+
+
+void SAL_CALL
+shell::commit( const shell::ContentMap::iterator& it,
+ const osl::FileStatus& aFileStatus )
+{
+ uno::Any aAny;
+ uno::Any emptyAny;
+ shell::PropertySet::iterator it1;
+
+ if( it->second.properties == 0 )
+ {
+ rtl::OUString aPath = it->first;
+ insertDefaultProperties( aPath );
+ }
+
+ PropertySet& properties = *( it->second.properties );
+
+ it1 = properties.find( MyProperty( Title ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ {
+ aAny <<= aFileStatus.getFileName();
+ it1->setValue( aAny );
+ }
+ }
+
+ it1 = properties.find( MyProperty( CasePreservingURL ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ {
+ aAny <<= aFileStatus.getFileURL();
+ it1->setValue( aAny );
+ }
+ }
+
+
+ sal_Bool isDirectory,isFile,isVolume,isRemoveable,isRemote,isFloppy,isCompactDisc;
+
+ sal_Int64 dirSize = 0;
+
+ if( aFileStatus.isValid( FileStatusMask_FileSize ) )
+ dirSize = aFileStatus.getFileSize();
+
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ {
+ if( osl::FileStatus::Link == aFileStatus.getFileType() &&
+ aFileStatus.isValid( FileStatusMask_LinkTargetURL ) )
+ {
+ osl::DirectoryItem aDirItem;
+ osl::FileStatus aFileStatus2( FileStatusMask_Type );
+ if( osl::FileBase::E_None == osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(),aDirItem ) &&
+ osl::FileBase::E_None == aDirItem.getFileStatus( aFileStatus2 ) &&
+ aFileStatus2.isValid( FileStatusMask_Type ) )
+ {
+ isVolume = osl::FileStatus::Volume == aFileStatus2.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus2.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus2.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus2.getFileType();
+
+ if( aFileStatus2.isValid( FileStatusMask_FileSize ) )
+ dirSize = aFileStatus2.getFileSize();
+ }
+ else
+ {
+ // extremly ugly, but otherwise default construction
+ // of aDirItem and aFileStatus2
+ // before the preciding if
+ isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus.getFileType();
+ }
+ }
+ else
+ {
+ isVolume = osl::FileStatus::Volume == aFileStatus.getFileType();
+ isDirectory =
+ osl::FileStatus::Volume == aFileStatus.getFileType() ||
+ osl::FileStatus::Directory == aFileStatus.getFileType();
+ isFile =
+ osl::FileStatus::Regular == aFileStatus.getFileType();
+ }
+
+ it1 = properties.find( MyProperty( IsVolume ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isVolume ) );
+
+ it1 = properties.find( MyProperty( IsFolder ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isDirectory ) );
+
+ it1 = properties.find( MyProperty( IsDocument ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isFile ) );
+
+ osl::VolumeInfo aVolumeInfo( VolumeInfoMask_Attributes );
+ if( isVolume &&
+ osl::FileBase::E_None == osl::Directory::getVolumeInfo( it->first,aVolumeInfo ) &&
+ aVolumeInfo.isValid( VolumeInfoMask_Attributes ) )
+ {
+ // Retrieve the flags;
+ isRemote = aVolumeInfo.getRemoteFlag();
+ isRemoveable = aVolumeInfo.getRemoveableFlag();
+ isCompactDisc = aVolumeInfo.getCompactDiscFlag();
+ isFloppy = aVolumeInfo.getFloppyDiskFlag();
+
+ it1 = properties.find( MyProperty( IsRemote ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isRemote ) );
+
+ it1 = properties.find( MyProperty( IsRemoveable ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isRemoveable ) );
+
+ it1 = properties.find( MyProperty( IsCompactDisc ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isCompactDisc ) );
+
+ it1 = properties.find( MyProperty( IsFloppy ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( isFloppy ) );
+ }
+ else
+ {
+ sal_Bool dummy = false;
+ aAny <<= dummy;
+ it1 = properties.find( MyProperty( IsRemote ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsRemoveable ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsCompactDisc ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+
+ it1 = properties.find( MyProperty( IsFloppy ) );
+ if( it1 != properties.end() )
+ it1->setValue( aAny );
+ }
+ }
+ else
+ {
+ isDirectory = sal_False;
+ }
+
+ it1 = properties.find( MyProperty( Size ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny( dirSize ) );
+
+ it1 = properties.find( MyProperty( IsReadOnly ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_Attributes ) )
+ {
+ sal_uInt64 Attr = aFileStatus.getAttributes();
+ sal_Bool readonly = ( Attr & Attribute_ReadOnly ) != 0;
+ it1->setValue( uno::makeAny( readonly ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( IsHidden ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_Attributes ) )
+ {
+ sal_uInt64 Attr = aFileStatus.getAttributes();
+ sal_Bool ishidden = ( Attr & Attribute_Hidden ) != 0;
+ it1->setValue( uno::makeAny( ishidden ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( DateModified ) );
+ if( it1 != properties.end() )
+ {
+ if( aFileStatus.isValid( FileStatusMask_ModifyTime ) )
+ {
+ TimeValue temp = aFileStatus.getModifyTime();
+
+ // Convert system time to local time (for EA)
+ TimeValue myLocalTime;
+ osl_getLocalTimeFromSystemTime( &temp, &myLocalTime );
+
+ oslDateTime myDateTime;
+ osl_getDateTimeFromTimeValue( &myLocalTime, &myDateTime );
+ util::DateTime aDateTime;
+
+ aDateTime.HundredthSeconds = (unsigned short)(myDateTime.NanoSeconds / 10000000);
+ aDateTime.Seconds = myDateTime.Seconds;
+ aDateTime.Minutes = myDateTime.Minutes;
+ aDateTime.Hours = myDateTime.Hours;
+ aDateTime.Day = myDateTime.Day;
+ aDateTime.Month = myDateTime.Month;
+ aDateTime.Year = myDateTime.Year;
+ it1->setValue( uno::makeAny( aDateTime ) );
+ }
+ }
+
+ it1 = properties.find( MyProperty( CreatableContentsInfo ) );
+ if( it1 != properties.end() )
+ it1->setValue( uno::makeAny(
+ isDirectory || !aFileStatus.isValid( FileStatusMask_Type )
+ ? queryCreatableContentsInfo()
+ : uno::Sequence< ucb::ContentInfo >() ) );
+}
+
+
+// Special optimized method for getting the properties of a
+// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
+
+
+uno::Reference< sdbc::XRow > SAL_CALL
+shell::getv(
+ Notifier* pNotifier,
+ const uno::Sequence< beans::Property >& properties,
+ osl::DirectoryItem& aDirItem,
+ rtl::OUString& aUnqPath,
+ sal_Bool& aIsRegular )
+{
+ uno::Sequence< uno::Any > seq( properties.getLength() );
+
+ sal_Int32 n_Mask;
+ getMaskFromProperties( n_Mask,properties );
+
+ // Always retrieve the type and the target URL because item might be a link
+ osl::FileStatus aFileStatus( n_Mask |
+ FileStatusMask_FileURL |
+ FileStatusMask_Type |
+ FileStatusMask_LinkTargetURL );
+ aDirItem.getFileStatus( aFileStatus );
+ aUnqPath = aFileStatus.getFileURL();
+
+ // If the directory item type is a link retrieve the type of the target
+
+ if ( aFileStatus.getFileType() == osl::FileStatus::Link )
+ {
+ // Assume failure
+ aIsRegular = false;
+ osl::FileBase::RC result = osl::FileBase::E_INVAL;
+ osl::DirectoryItem aTargetItem;
+ osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
+ if ( aTargetItem.is() )
+ {
+ osl::FileStatus aTargetStatus( FileStatusMask_Type );
+
+ if ( osl::FileBase::E_None ==
+ ( result = aTargetItem.getFileStatus( aTargetStatus ) ) )
+ aIsRegular =
+ aTargetStatus.getFileType() == osl::FileStatus::Regular;
+ }
+ }
+ else
+ aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ registerNotifier( aUnqPath,pNotifier );
+ insertDefaultProperties( aUnqPath );
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ shell::ContentMap::iterator it = m_aContent.find( aUnqPath );
+ commit( it,aFileStatus );
+
+ shell::PropertySet::iterator it1;
+ PropertySet& propset = *(it->second.properties);
+
+ for( sal_Int32 i = 0; i < seq.getLength(); ++i )
+ {
+ MyProperty readProp( properties[i].Name );
+ it1 = propset.find( readProp );
+ if( it1 == propset.end() )
+ seq[i] = uno::Any();
+ else
+ seq[i] = it1->getValue();
+ }
+ }
+ deregisterNotifier( aUnqPath,pNotifier );
+
+ XRow_impl* p = new XRow_impl( this,seq );
+ return uno::Reference< sdbc::XRow >( p );
+}
+
+
+
+
+
+
+// EventListener
+
+
+std::list< ContentEventNotifier* >* SAL_CALL
+shell::getContentEventListeners( const rtl::OUString& aName )
+{
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cCEL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+
+std::list< ContentEventNotifier* >* SAL_CALL
+shell::getContentDeletedEventListeners( const rtl::OUString& aName )
+{
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cDEL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL
+shell::notifyInsert( std::list< ContentEventNotifier* >* listeners,const rtl::OUString& aChildName )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyChildInserted( aChildName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyContentDeleted( std::list< ContentEventNotifier* >* listeners )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyDeleted();
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyContentRemoved( std::list< ContentEventNotifier* >* listeners,
+ const rtl::OUString& aChildName )
+{
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyRemoved( aChildName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+
+std::list< PropertySetInfoChangeNotifier* >* SAL_CALL
+shell::getPropertySetListeners( const rtl::OUString& aName )
+{
+ std::list< PropertySetInfoChangeNotifier* >* p = new std::list< PropertySetInfoChangeNotifier* >;
+ std::list< PropertySetInfoChangeNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ PropertySetInfoChangeNotifier* notifier = pointer->cPSL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL
+shell::notifyPropertyAdded( std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName )
+{
+ std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyAdded( aPropertyName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+void SAL_CALL
+shell::notifyPropertyRemoved( std::list< PropertySetInfoChangeNotifier* >* listeners,
+ const rtl::OUString& aPropertyName )
+{
+ std::list< PropertySetInfoChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyRemoved( aPropertyName );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+std::vector< std::list< ContentEventNotifier* >* >* SAL_CALL
+shell::getContentExchangedEventListeners( const rtl::OUString aOldPrefix,
+ const rtl::OUString aNewPrefix,
+ sal_Bool withChilds )
+{
+
+ std::vector< std::list< ContentEventNotifier* >* >* aVectorOnHeap =
+ new std::vector< std::list< ContentEventNotifier* >* >;
+ std::vector< std::list< ContentEventNotifier* >* >& aVector = *aVectorOnHeap;
+
+ sal_Int32 count;
+ rtl::OUString aOldName;
+ rtl::OUString aNewName;
+ std::vector< rtl::OUString > oldChildList;
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( ! withChilds )
+ {
+ aOldName = aOldPrefix;
+ aNewName = aNewPrefix;
+ count = 1;
+ }
+ else
+ {
+ ContentMap::iterator itnames = m_aContent.begin();
+ while( itnames != m_aContent.end() )
+ {
+ if( isChild( aOldPrefix,itnames->first ) )
+ {
+ oldChildList.push_back( itnames->first );
+ }
+ ++itnames;
+ }
+ count = oldChildList.size();
+ }
+
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ std::list< ContentEventNotifier* >* p = new std::list< ContentEventNotifier* >;
+ std::list< ContentEventNotifier* >& listeners = *p;
+
+ if( withChilds )
+ {
+ aOldName = oldChildList[j];
+ aNewName = newName( aNewPrefix,aOldPrefix,aOldName );
+ }
+
+ shell::ContentMap::iterator itold = m_aContent.find( aOldName );
+ if( itold != m_aContent.end() )
+ {
+ shell::ContentMap::iterator itnew = m_aContent.insert(
+ ContentMap::value_type( aNewName,UnqPathData() ) ).first;
+
+ // copy Ownership also
+ delete itnew->second.properties;
+ itnew->second.properties = itold->second.properties;
+ itold->second.properties = 0;
+
+ // copy existing list
+ std::list< Notifier* >* copyList = itnew->second.notifier;
+ itnew->second.notifier = itold->second.notifier;
+ itold->second.notifier = 0;
+
+ m_aContent.erase( itold );
+
+ if( itnew != m_aContent.end() && itnew->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( itnew->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ ContentEventNotifier* notifier = pointer->cEXC( aNewName );
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+
+ // Merge with preexisting notifiers
+ // However, these may be in status BaseContent::Deleted
+ if( copyList != 0 )
+ {
+ std::list< Notifier* >::iterator copyIt = copyList->begin();
+ while( copyIt != copyList->end() )
+ {
+ itnew->second.notifier->push_back( *copyIt );
+ ++copyIt;
+ }
+ }
+ delete copyList;
+ }
+ aVector.push_back( p );
+ }
+ }
+
+ return aVectorOnHeap;
+}
+
+
+
+void SAL_CALL
+shell::notifyContentExchanged( std::vector< std::list< ContentEventNotifier* >* >* listeners_vec )
+{
+ std::list< ContentEventNotifier* >* listeners;
+ for( sal_uInt32 i = 0; i < listeners_vec->size(); ++i )
+ {
+ listeners = (*listeners_vec)[i];
+ std::list< ContentEventNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyExchanged();
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+ }
+ delete listeners_vec;
+}
+
+
+
+std::list< PropertyChangeNotifier* >* SAL_CALL
+shell::getPropertyChangeNotifier( const rtl::OUString& aName )
+{
+ std::list< PropertyChangeNotifier* >* p = new std::list< PropertyChangeNotifier* >;
+ std::list< PropertyChangeNotifier* >& listeners = *p;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ shell::ContentMap::iterator it = m_aContent.find( aName );
+ if( it != m_aContent.end() && it->second.notifier )
+ {
+ std::list<Notifier*>& listOfNotifiers = *( it->second.notifier );
+ std::list<Notifier*>::iterator it1 = listOfNotifiers.begin();
+ while( it1 != listOfNotifiers.end() )
+ {
+ Notifier* pointer = *it1;
+ PropertyChangeNotifier* notifier = pointer->cPCL();
+ if( notifier )
+ listeners.push_back( notifier );
+ ++it1;
+ }
+ }
+ }
+ return p;
+}
+
+
+void SAL_CALL shell::notifyPropertyChanges( std::list< PropertyChangeNotifier* >* listeners,
+ const uno::Sequence< beans::PropertyChangeEvent >& seqChanged )
+{
+ std::list< PropertyChangeNotifier* >::iterator it = listeners->begin();
+ while( it != listeners->end() )
+ {
+ (*it)->notifyPropertyChanged( seqChanged );
+ delete (*it);
+ ++it;
+ }
+ delete listeners;
+}
+
+
+
+
+/********************************************************************************/
+/* remove persistent propertyset */
+/********************************************************************************/
+
+void SAL_CALL
+shell::erasePersistentSet( const rtl::OUString& aUnqPath,
+ sal_Bool withChilds )
+{
+ if( ! m_xFileRegistry.is() )
+ {
+ OSL_ASSERT( m_xFileRegistry.is() );
+ return;
+ }
+
+ uno::Sequence< rtl::OUString > seqNames;
+
+ if( withChilds )
+ {
+ uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
+ seqNames = xName->getElementNames();
+ }
+
+ sal_Int32 count = withChilds ? seqNames.getLength() : 1;
+
+ rtl::OUString
+ old_Name = aUnqPath;
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ if( withChilds && ! ( isChild( old_Name,seqNames[j] ) ) )
+ continue;
+
+ if( withChilds )
+ {
+ old_Name = seqNames[j];
+ }
+
+ {
+ // Release possible references
+ osl::MutexGuard aGuard( m_aMutex );
+ ContentMap::iterator it = m_aContent.find( old_Name );
+ if( it != m_aContent.end() )
+ {
+ it->second.xS = 0;
+ it->second.xC = 0;
+ it->second.xA = 0;
+
+ delete it->second.properties;
+ it->second.properties = 0;
+ }
+ }
+
+ if( m_xFileRegistry.is() )
+ m_xFileRegistry->removePropertySet( old_Name );
+ }
+}
+
+
+
+
+/********************************************************************************/
+/* copy persistent propertyset */
+/* from srcUnqPath to dstUnqPath */
+/********************************************************************************/
+
+
+void SAL_CALL
+shell::copyPersistentSet( const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Bool withChilds )
+{
+ if( ! m_xFileRegistry.is() )
+ {
+ OSL_ASSERT( m_xFileRegistry.is() );
+ return;
+ }
+
+ uno::Sequence< rtl::OUString > seqNames;
+
+ if( withChilds )
+ {
+ uno::Reference< container::XNameAccess > xName( m_xFileRegistry,uno::UNO_QUERY );
+ seqNames = xName->getElementNames();
+ }
+
+ sal_Int32 count = withChilds ? seqNames.getLength() : 1;
+
+ rtl::OUString
+ old_Name = srcUnqPath,
+ new_Name = dstUnqPath;
+
+ for( sal_Int32 j = 0; j < count; ++j )
+ {
+ if( withChilds && ! ( isChild( srcUnqPath,seqNames[j] ) ) )
+ continue;
+
+ if( withChilds )
+ {
+ old_Name = seqNames[j];
+ new_Name = newName( dstUnqPath,srcUnqPath,old_Name );
+ }
+
+ uno::Reference< XPersistentPropertySet > x_src;
+
+ if( m_xFileRegistry.is() )
+ {
+ x_src = m_xFileRegistry->openPropertySet( old_Name,false );
+ m_xFileRegistry->removePropertySet( new_Name );
+ }
+
+ if( x_src.is() )
+ {
+ uno::Sequence< beans::Property > seqProperty =
+ x_src->getPropertySetInfo()->getProperties();
+
+ if( seqProperty.getLength() )
+ {
+ uno::Reference< XPersistentPropertySet >
+ x_dstS = m_xFileRegistry->openPropertySet( new_Name,true );
+ uno::Reference< beans::XPropertyContainer >
+ x_dstC( x_dstS,uno::UNO_QUERY );
+
+ for( sal_Int32 i = 0; i < seqProperty.getLength(); ++i )
+ {
+ x_dstC->addProperty( seqProperty[i].Name,
+ seqProperty[i].Attributes,
+ x_src->getPropertyValue( seqProperty[i].Name ) );
+ }
+ }
+ }
+ } // end for( sal_Int...
+}
+
+uno::Sequence< ucb::ContentInfo > shell::queryCreatableContentsInfo()
+{
+ uno::Sequence< ucb::ContentInfo > seq(2);
+
+ // file
+ seq[0].Type = FileContentType;
+ seq[0].Attributes = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+
+ uno::Sequence< beans::Property > props( 1 );
+ props[0] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< rtl::OUString* >( 0 ) ),
+ beans::PropertyAttribute::MAYBEVOID
+ | beans::PropertyAttribute::BOUND );
+ seq[0].Properties = props;
+
+ // folder
+ seq[1].Type = FolderContentType;
+ seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
+ seq[1].Properties = props;
+ return seq;
+}
+
+/*******************************************************************************/
+/* */
+/* some misceancellous static functions */
+/* */
+/*******************************************************************************/
+
+void SAL_CALL
+shell::getScheme( rtl::OUString& Scheme )
+{
+ Scheme = rtl::OUString::createFromAscii( "file" );
+}
+
+rtl::OUString SAL_CALL
+shell::getImplementationName_static( void )
+{
+ return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileProvider" );
+}
+
+
+uno::Sequence< rtl::OUString > SAL_CALL
+shell::getSupportedServiceNames_static( void )
+{
+ rtl::OUString Supported = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ) ;
+ com::sun::star::uno::Sequence< rtl::OUString > Seq( &Supported,1 );
+ return Seq;
+}