diff options
Diffstat (limited to 'ucb/source/ucp/file')
36 files changed, 13531 insertions, 0 deletions
diff --git a/ucb/source/ucp/file/bc.cxx b/ucb/source/ucp/file/bc.cxx new file mode 100644 index 000000000000..b78e5d6e4890 --- /dev/null +++ b/ucb/source/ucp/file/bc.cxx @@ -0,0 +1,1409 @@ +/************************************************************************* + * + * 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" +#include <rtl/uri.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/file.hxx> + +#include "osl/diagnose.h" +#include <com/sun/star/ucb/OpenMode.hpp> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/ucb/XProgressHandler.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/io/XActiveDataStreamer.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/beans/PropertySetInfoChange.hpp> +#include <com/sun/star/ucb/ContentAction.hpp> +#include <com/sun/star/ucb/NameClash.hpp> +#include "filglob.hxx" +#include "filid.hxx" +#include "filrow.hxx" +#include "bc.hxx" +#include "prov.hxx" +#ifndef _FILERROR_HXX_ +#include "filerror.hxx" +#endif +#include "filinsreq.hxx" + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; + +// PropertyListeners + + +typedef cppu::OMultiTypeInterfaceContainerHelperVar< rtl::OUString,hashOUString,equalOUString > +PropertyListeners_impl; + +class fileaccess::PropertyListeners + : public PropertyListeners_impl +{ +public: + PropertyListeners( ::osl::Mutex& aMutex ) + : PropertyListeners_impl( aMutex ) + { + } +}; + + +/****************************************************************************************/ +/* */ +/* BaseContent */ +/* */ +/****************************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +// Private Constructor for just inserted Contents + +BaseContent::BaseContent( shell* pMyShell, + const rtl::OUString& parentName, + sal_Bool bFolder ) + : m_pMyShell( pMyShell ), + m_xContentIdentifier( 0 ), + m_aUncPath( parentName ), + m_bFolder( bFolder ), + m_nState( JustInserted ), + m_pDisposeEventListeners( 0 ), + m_pContentEventListeners( 0 ), + m_pPropertySetInfoChangeListeners( 0 ), + m_pPropertyListener( 0 ) +{ + m_pMyShell->m_pProvider->acquire(); + // No registering, since we have no name +} + + +//////////////////////////////////////////////////////////////////////////////// +// Constructor for full featured Contents + +BaseContent::BaseContent( shell* pMyShell, + const Reference< XContentIdentifier >& xContentIdentifier, + const rtl::OUString& aUncPath ) + : m_pMyShell( pMyShell ), + m_xContentIdentifier( xContentIdentifier ), + m_aUncPath( aUncPath ), + m_bFolder( false ), + m_nState( FullFeatured ), + m_pDisposeEventListeners( 0 ), + m_pContentEventListeners( 0 ), + m_pPropertySetInfoChangeListeners( 0 ), + m_pPropertyListener( 0 ) +{ + m_pMyShell->m_pProvider->acquire(); + m_pMyShell->registerNotifier( m_aUncPath,this ); + m_pMyShell->insertDefaultProperties( m_aUncPath ); +} + + +BaseContent::~BaseContent( ) +{ + if( ( m_nState & FullFeatured ) || ( m_nState & Deleted ) ) + { + m_pMyShell->deregisterNotifier( m_aUncPath,this ); + } + m_pMyShell->m_pProvider->release(); + + delete m_pDisposeEventListeners; + delete m_pContentEventListeners; + delete m_pPropertyListener; + delete m_pPropertySetInfoChangeListeners; +} + + +////////////////////////////////////////////////////////////////////////// +// XInterface +////////////////////////////////////////////////////////////////////////// + +void SAL_CALL +BaseContent::acquire( void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +BaseContent::release( void ) + throw() +{ + OWeakObject::release(); +} + + +Any SAL_CALL +BaseContent::queryInterface( const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XComponent*, this ), + SAL_STATIC_CAST( lang::XTypeProvider*, this ), + SAL_STATIC_CAST( lang::XServiceInfo*, this ), + SAL_STATIC_CAST( XCommandProcessor*, this ), + SAL_STATIC_CAST( container::XChild*, this ), + SAL_STATIC_CAST( beans::XPropertiesChangeNotifier*, this ), + SAL_STATIC_CAST( beans::XPropertyContainer*, this ), + SAL_STATIC_CAST( XContentCreator*,this ), + SAL_STATIC_CAST( beans::XPropertySetInfoChangeNotifier*, this ), + SAL_STATIC_CAST( XContent*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + + + +////////////////////////////////////////////////////////////////////////////////////////// +// XComponent +//////////////////////////////////////////////////////////////////////////////////////// + +void SAL_CALL +BaseContent::addEventListener( const Reference< lang::XEventListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pDisposeEventListeners ) + m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +BaseContent::removeEventListener( const Reference< lang::XEventListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); +} + + +void SAL_CALL +BaseContent::dispose() + throw( RuntimeException ) +{ + lang::EventObject aEvt; + cppu::OInterfaceContainerHelper* pDisposeEventListeners; + cppu::OInterfaceContainerHelper* pContentEventListeners; + cppu::OInterfaceContainerHelper* pPropertySetInfoChangeListeners; + PropertyListeners* pPropertyListener; + + { + osl::MutexGuard aGuard( m_aMutex ); + aEvt.Source = static_cast< XContent* >( this ); + + + pDisposeEventListeners = + m_pDisposeEventListeners, m_pDisposeEventListeners = 0; + + pContentEventListeners = + m_pContentEventListeners, m_pContentEventListeners = 0; + + pPropertySetInfoChangeListeners = + m_pPropertySetInfoChangeListeners, + m_pPropertySetInfoChangeListeners = 0; + + pPropertyListener = + m_pPropertyListener, m_pPropertyListener = 0; + } + + if ( pDisposeEventListeners && pDisposeEventListeners->getLength() ) + pDisposeEventListeners->disposeAndClear( aEvt ); + + if ( pContentEventListeners && pContentEventListeners->getLength() ) + pContentEventListeners->disposeAndClear( aEvt ); + + if( pPropertyListener ) + pPropertyListener->disposeAndClear( aEvt ); + + if( pPropertySetInfoChangeListeners ) + pPropertySetInfoChangeListeners->disposeAndClear( aEvt ); + + delete pDisposeEventListeners; + delete pContentEventListeners; + delete pPropertyListener; + delete pPropertySetInfoChangeListeners; +} + + + +////////////////////////////////////////////////////////////////////////////////////////// +// XServiceInfo +////////////////////////////////////////////////////////////////////////////////////////// + +rtl::OUString SAL_CALL +BaseContent::getImplementationName() + throw( RuntimeException) +{ + return rtl::OUString::createFromAscii( "com.sun.star.comp.ucb.FileContent" ); +} + + + +sal_Bool SAL_CALL +BaseContent::supportsService( const rtl::OUString& ServiceName ) + throw( RuntimeException) +{ + if( ServiceName.compareToAscii( "com.sun.star.ucb.FileContent" ) == 0 ) + return true; + else + return false; +} + + + +Sequence< rtl::OUString > SAL_CALL +BaseContent::getSupportedServiceNames() + throw( RuntimeException ) +{ + Sequence< rtl::OUString > ret( 1 ); + ret[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContent" ); + return ret; +} + + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + +XTYPEPROVIDER_IMPL_10( BaseContent, + lang::XComponent, + lang::XTypeProvider, + lang::XServiceInfo, + XCommandProcessor, + XContentCreator, + XContent, + container::XChild, + beans::XPropertiesChangeNotifier, + beans::XPropertyContainer, + beans::XPropertySetInfoChangeNotifier ) + + +////////////////////////////////////////////////////////////////////////////////////////// +// XCommandProcessor +////////////////////////////////////////////////////////////////////////////////////////// + +sal_Int32 SAL_CALL +BaseContent::createCommandIdentifier( void ) + throw( RuntimeException ) +{ + return m_pMyShell->getCommandId(); +} + + +void SAL_CALL +BaseContent::abort( sal_Int32 CommandId ) + throw( RuntimeException ) +{ + m_pMyShell->abort( CommandId ); +} + + +Any SAL_CALL +BaseContent::execute( const Command& aCommand, + sal_Int32 CommandId, + const Reference< XCommandEnvironment >& Environment ) + throw( Exception, + CommandAbortedException, + RuntimeException ) +{ + if( ! CommandId ) + // A Command with commandid zero cannot be aborted + CommandId = createCommandIdentifier(); + + m_pMyShell->startTask( CommandId, + Environment ); + + Any aAny; + + if( ! aCommand.Name.compareToAscii( "getPropertySetInfo" ) ) // No exceptions + { + aAny <<= getPropertySetInfo( CommandId ); + } + else if( ! aCommand.Name.compareToAscii( "getCommandInfo" ) ) // no exceptions + { + aAny <<= getCommandInfo(); + } + else if( ! aCommand.Name.compareToAscii( "setPropertyValues" ) ) + { + Sequence< beans::PropertyValue > sPropertyValues; + + if( ! ( aCommand.Argument >>= sPropertyValues ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT ); + else + aAny <<= setPropertyValues( CommandId,sPropertyValues ); // calls endTask by itself + } + else if( ! aCommand.Name.compareToAscii( "getPropertyValues" ) ) + { + Sequence< beans::Property > ListOfRequestedProperties; + + if( ! ( aCommand.Argument >>= ListOfRequestedProperties ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT ); + else + aAny <<= getPropertyValues( CommandId, + ListOfRequestedProperties ); + } + else if( ! aCommand.Name.compareToAscii( "open" ) ) + { + OpenCommandArgument2 aOpenArgument; + if( ! ( aCommand.Argument >>= aOpenArgument ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_OPEN_ARGUMENT ); + else + { + Reference< XDynamicResultSet > result = open( CommandId,aOpenArgument ); + if( result.is() ) + aAny <<= result; + } + } + else if( ! aCommand.Name.compareToAscii( "delete" ) ) + { + if( ! aCommand.Argument.has< sal_Bool >() ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_DELETE_ARGUMENT ); + else + deleteContent( CommandId ); + } + else if( ! aCommand.Name.compareToAscii( "transfer" ) ) + { + TransferInfo aTransferInfo; + if( ! ( aCommand.Argument >>= aTransferInfo ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_TRANSFER_ARGUMENT ); + else + transfer( CommandId, aTransferInfo ); + } + else if( ! aCommand.Name.compareToAscii( "insert" ) ) + { + InsertCommandArgument aInsertArgument; + if( ! ( aCommand.Argument >>= aInsertArgument ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_INSERT_ARGUMENT ); + else + insert( CommandId,aInsertArgument ); + } + else if( ! aCommand.Name.compareToAscii( "getCasePreservingURL" ) ) + { + Sequence< beans::Property > seq(1); + seq[0] = beans::Property( + rtl::OUString::createFromAscii("CasePreservingURL"), + -1, + getCppuType( static_cast< sal_Bool* >(0) ), + 0 ); + Reference< sdbc::XRow > xRow = getPropertyValues( CommandId,seq ); + rtl::OUString CasePreservingURL = xRow->getString(1); + if(!xRow->wasNull()) + aAny <<= CasePreservingURL; + } + else if( ! aCommand.Name.compareToAscii( "createNewContent" ) ) + { + ucb::ContentInfo aArg; + if ( !( aCommand.Argument >>= aArg ) ) + m_pMyShell->installError( CommandId, + TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT ); + else + aAny <<= createNewContent( aArg ); + } + else + m_pMyShell->installError( CommandId, + TASKHANDLER_UNSUPPORTED_COMMAND ); + + + // This is the only function allowed to throw an exception + endTask( CommandId ); + + return aAny; +} + + + +void SAL_CALL +BaseContent::addPropertiesChangeListener( + const Sequence< rtl::OUString >& PropertyNames, + const Reference< beans::XPropertiesChangeListener >& Listener ) + throw( RuntimeException ) +{ + if( ! Listener.is() ) + return; + + osl::MutexGuard aGuard( m_aMutex ); + + if( ! m_pPropertyListener ) + m_pPropertyListener = new PropertyListeners( m_aEventListenerMutex ); + + + if( PropertyNames.getLength() == 0 ) + m_pPropertyListener->addInterface( rtl::OUString(),Listener ); + else + { + Reference< beans::XPropertySetInfo > xProp = m_pMyShell->info_p( m_aUncPath ); + for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i ) + if( xProp->hasPropertyByName( PropertyNames[i] ) ) + m_pPropertyListener->addInterface( PropertyNames[i],Listener ); + } +} + + +void SAL_CALL +BaseContent::removePropertiesChangeListener( const Sequence< rtl::OUString >& PropertyNames, + const Reference< beans::XPropertiesChangeListener >& Listener ) + throw( RuntimeException ) +{ + if( ! Listener.is() ) + return; + + osl::MutexGuard aGuard( m_aMutex ); + + if( ! m_pPropertyListener ) + return; + + for( sal_Int32 i = 0; i < PropertyNames.getLength(); ++i ) + m_pPropertyListener->removeInterface( PropertyNames[i],Listener ); + + m_pPropertyListener->removeInterface( rtl::OUString(), Listener ); +} + + +///////////////////////////////////////////////////////////////////////////////////////// +// XContent +///////////////////////////////////////////////////////////////////////////////////////// + +Reference< ucb::XContentIdentifier > SAL_CALL +BaseContent::getIdentifier() + throw( RuntimeException ) +{ + return m_xContentIdentifier; +} + + +rtl::OUString SAL_CALL +BaseContent::getContentType() + throw( RuntimeException ) +{ + if( !( m_nState & Deleted ) ) + { + if( m_nState & JustInserted ) + { + if ( m_bFolder ) + return m_pMyShell->FolderContentType; + else + return m_pMyShell->FileContentType; + } + else + { + try + { + // Who am I ? + Sequence< beans::Property > seq(1); + seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"), + -1, + getCppuType( static_cast< sal_Bool* >(0) ), + 0 ); + Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq ); + sal_Bool IsDocument = xRow->getBoolean( 1 ); + + if ( !xRow->wasNull() ) + { + if ( IsDocument ) + return m_pMyShell->FileContentType; + else + return m_pMyShell->FolderContentType; + } + else + { + OSL_ENSURE( false, + "BaseContent::getContentType - Property value was null!" ); + } + } + catch ( sdbc::SQLException const & ) + { + OSL_ENSURE( false, + "BaseContent::getContentType - Caught SQLException!" ); + } + } + } + + return rtl::OUString(); +} + + + +void SAL_CALL +BaseContent::addContentEventListener( + const Reference< XContentEventListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pContentEventListeners ) + m_pContentEventListeners = + new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + + + m_pContentEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +BaseContent::removeContentEventListener( + const Reference< XContentEventListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pContentEventListeners ) + m_pContentEventListeners->removeInterface( Listener ); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// XPropertyContainer +//////////////////////////////////////////////////////////////////////////////// + + +void SAL_CALL +BaseContent::addProperty( + const rtl::OUString& Name, + sal_Int16 Attributes, + const Any& DefaultValue ) + throw( beans::PropertyExistException, + beans::IllegalTypeException, + lang::IllegalArgumentException, + RuntimeException) +{ + if( ( m_nState & JustInserted ) || ( m_nState & Deleted ) || Name == rtl::OUString() ) + { + throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); + } + + m_pMyShell->associate( m_aUncPath,Name,DefaultValue,Attributes ); +} + + +void SAL_CALL +BaseContent::removeProperty( + const rtl::OUString& Name ) + throw( beans::UnknownPropertyException, + beans::NotRemoveableException, + RuntimeException) +{ + + if( m_nState & Deleted ) + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + m_pMyShell->deassociate( m_aUncPath, Name ); +} + +//////////////////////////////////////////////////////////////////////////////// +// XContentCreator +//////////////////////////////////////////////////////////////////////////////// + +Sequence< ContentInfo > SAL_CALL +BaseContent::queryCreatableContentsInfo( + void ) + throw( RuntimeException ) +{ + return m_pMyShell->queryCreatableContentsInfo(); +} + + +Reference< XContent > SAL_CALL +BaseContent::createNewContent( + const ContentInfo& Info ) + throw( RuntimeException ) +{ + // Check type. + if ( !Info.Type.getLength() ) + return Reference< XContent >(); + + sal_Bool bFolder + = ( Info.Type.compareTo( m_pMyShell->FolderContentType ) == 0 ); + if ( !bFolder ) + { + if ( Info.Type.compareTo( m_pMyShell->FileContentType ) != 0 ) + { + // Neither folder nor file to create! + return Reference< XContent >(); + } + } + + // Who am I ? + sal_Bool IsDocument = false; + + try + { + Sequence< beans::Property > seq(1); + seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"), + -1, + getCppuType( static_cast< sal_Bool* >(0) ), + 0 ); + Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq ); + IsDocument = xRow->getBoolean( 1 ); + + if ( xRow->wasNull() ) + { + IsDocument = false; +// OSL_ENSURE( false, +// "BaseContent::createNewContent - Property value was null!" ); +// return Reference< XContent >(); + } + } + catch ( sdbc::SQLException const & ) + { + OSL_ENSURE( false, + "BaseContent::createNewContent - Caught SQLException!" ); + return Reference< XContent >(); + } + + rtl::OUString dstUncPath; + + if( IsDocument ) + { + // KSO: Why is a document a XContentCreator? This is quite unusual. + dstUncPath = getParentName( m_aUncPath ); + } + else + dstUncPath = m_aUncPath; + + BaseContent* p = new BaseContent( m_pMyShell, dstUncPath, bFolder ); + return Reference< XContent >( p ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// XPropertySetInfoChangeNotifier +//////////////////////////////////////////////////////////////////////////////// + + +void SAL_CALL +BaseContent::addPropertySetInfoChangeListener( + const Reference< beans::XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + if( ! m_pPropertySetInfoChangeListeners ) + m_pPropertySetInfoChangeListeners = new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + + m_pPropertySetInfoChangeListeners->addInterface( Listener ); +} + + +void SAL_CALL +BaseContent::removePropertySetInfoChangeListener( + const Reference< beans::XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if( m_pPropertySetInfoChangeListeners ) + m_pPropertySetInfoChangeListeners->removeInterface( Listener ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// XChild +//////////////////////////////////////////////////////////////////////////////// + +Reference< XInterface > SAL_CALL +BaseContent::getParent( + void ) + throw( RuntimeException ) +{ + rtl::OUString ParentUnq = getParentName( m_aUncPath ); + rtl::OUString ParentUrl; + + + sal_Bool err = m_pMyShell->getUrlFromUnq( ParentUnq, ParentUrl ); + if( err ) + return Reference< XInterface >( 0 ); + + FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ParentUnq ); + Reference< XContentIdentifier > Identifier( p ); + + try + { + Reference< XContent > content = m_pMyShell->m_pProvider->queryContent( Identifier ); + return Reference<XInterface>(content,UNO_QUERY); + } + catch( IllegalIdentifierException ) + { + return Reference< XInterface >(); + } +} + + +void SAL_CALL +BaseContent::setParent( + const Reference< XInterface >& ) + throw( lang::NoSupportException, + RuntimeException) +{ + throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// Private Methods +////////////////////////////////////////////////////////////////////////////////////////// + + +Reference< XCommandInfo > SAL_CALL +BaseContent::getCommandInfo() + throw( RuntimeException ) +{ + if( m_nState & Deleted ) + return Reference< XCommandInfo >(); + + return m_pMyShell->info_c(); +} + + +Reference< beans::XPropertySetInfo > SAL_CALL +BaseContent::getPropertySetInfo( + sal_Int32 ) + throw( RuntimeException ) +{ + if( m_nState & Deleted ) + return Reference< beans::XPropertySetInfo >(); + + return m_pMyShell->info_p( m_aUncPath ); +} + + + + +Reference< sdbc::XRow > SAL_CALL +BaseContent::getPropertyValues( + sal_Int32 nMyCommandIdentifier, + const Sequence< beans::Property >& PropertySet ) + throw( RuntimeException ) +{ + sal_Int32 nProps = PropertySet.getLength(); + if ( !nProps ) + return Reference< sdbc::XRow >(); + + if( m_nState & Deleted ) + { + Sequence< Any > aValues( nProps ); + return Reference< sdbc::XRow >( new XRow_impl( m_pMyShell, aValues ) ); + } + + if( m_nState & JustInserted ) + { + Sequence< Any > aValues( nProps ); + Any* pValues = aValues.getArray(); + + const beans::Property* pProps = PropertySet.getConstArray(); + + for ( sal_Int32 n = 0; n < nProps; ++n ) + { + const beans::Property& rProp = pProps[ n ]; + Any& rValue = pValues[ n ]; + + if( rProp.Name.compareToAscii( "ContentType" ) == 0 ) + { + rValue <<= m_bFolder ? m_pMyShell->FolderContentType + : m_pMyShell->FileContentType; + } + else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 ) + { + rValue <<= m_bFolder; + } + else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 ) + { + rValue <<= sal_Bool( !m_bFolder ); + } + } + + return Reference< sdbc::XRow >( + new XRow_impl( m_pMyShell, aValues ) ); + } + + return m_pMyShell->getv( nMyCommandIdentifier, + m_aUncPath, + PropertySet ); +} + + +Sequence< Any > SAL_CALL +BaseContent::setPropertyValues( + sal_Int32 nMyCommandIdentifier, + const Sequence< beans::PropertyValue >& Values ) + throw() +{ + if( m_nState & Deleted ) + { // To do + return Sequence< Any >( Values.getLength() ); + } + + const rtl::OUString Title = rtl::OUString::createFromAscii( "Title" ); + + // Special handling for files which have to be inserted + if( m_nState & JustInserted ) + { + for( sal_Int32 i = 0; i < Values.getLength(); ++i ) + { + if( Values[i].Name == Title ) + { + rtl::OUString NewTitle; + if( Values[i].Value >>= NewTitle ) + { + if ( m_nState & NameForInsertionSet ) + { + // User wants to set another Title before "insert". + // m_aUncPath contains previous own URI. + + sal_Int32 nLastSlash = m_aUncPath.lastIndexOf( '/' ); + bool bTrailingSlash = false; + if ( nLastSlash == m_aUncPath.getLength() - 1 ) + { + bTrailingSlash = true; + nLastSlash + = m_aUncPath.lastIndexOf( '/', nLastSlash ); + } + + OSL_ENSURE( nLastSlash != -1, + "BaseContent::setPropertyValues: " + "Invalid URL!" ); + + rtl::OUStringBuffer aBuf( + m_aUncPath.copy( 0, nLastSlash + 1 ) ); + + if ( NewTitle.getLength() > 0 ) + { + aBuf.append( NewTitle ); + if ( bTrailingSlash ) + aBuf.append( sal_Unicode( '/' ) ); + } + else + { + m_nState &= ~NameForInsertionSet; + } + + m_aUncPath = aBuf.makeStringAndClear(); + } + else + { + if ( NewTitle.getLength() > 0 ) + { + // Initial Title before "insert". + // m_aUncPath contains parent's URI. + + if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 ) + m_aUncPath += rtl::OUString::createFromAscii("/"); + + m_aUncPath += rtl::Uri::encode( NewTitle, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + m_nState |= NameForInsertionSet; + } + } + } + } + } + + return Sequence< Any >( Values.getLength() ); + } + else + { + Sequence< Any > ret = m_pMyShell->setv( m_aUncPath, // Does not handle Title + Values ); + + // Special handling Title: Setting Title is equivalent to a renaming of the underlying file + for( sal_Int32 i = 0; i < Values.getLength(); ++i ) + { + if( Values[i].Name != Title ) + continue; // handled by setv + + rtl::OUString NewTitle; + if( !( Values[i].Value >>= NewTitle ) ) + { + ret[i] <<= beans::IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + break; + } + else if( ! NewTitle.getLength() ) + { + ret[i] <<= lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); + break; + } + + + rtl::OUString aDstName = getParentName( m_aUncPath ); + if( aDstName.lastIndexOf( sal_Unicode('/') ) != aDstName.getLength() - 1 ) + aDstName += rtl::OUString::createFromAscii("/"); + + aDstName += rtl::Uri::encode( NewTitle, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + + m_pMyShell->move( nMyCommandIdentifier, // move notifies the childs also; + m_aUncPath, + aDstName, + NameClash::KEEP ); + + try + { + endTask( nMyCommandIdentifier ); + } + catch( const Exception& e ) + { + ret[i] <<= e; + } + + // NameChanges come back trough a ContentEvent + break; // only handling Title + } // end for + + return ret; + } +} + + + +Reference< XDynamicResultSet > SAL_CALL +BaseContent::open( + sal_Int32 nMyCommandIdentifier, + const OpenCommandArgument2& aCommandArgument ) + throw() +{ + Reference< XDynamicResultSet > retValue( 0 ); + + if( ( m_nState & Deleted ) ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND ); + } + else if( m_nState & JustInserted ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND ); + } + else + { + if( aCommandArgument.Mode == OpenMode::DOCUMENT || + aCommandArgument.Mode == OpenMode::DOCUMENT_SHARE_DENY_NONE ) + + { + Reference< io::XOutputStream > outputStream( aCommandArgument.Sink,UNO_QUERY ); + if( outputStream.is() ) + { + m_pMyShell->page( nMyCommandIdentifier, + m_aUncPath, + outputStream ); + } + + sal_Bool bLock = ( aCommandArgument.Mode != OpenMode::DOCUMENT_SHARE_DENY_NONE ); + + Reference< io::XActiveDataSink > activeDataSink( aCommandArgument.Sink,UNO_QUERY ); + if( activeDataSink.is() ) + { + activeDataSink->setInputStream( m_pMyShell->open( nMyCommandIdentifier, + m_aUncPath, + bLock ) ); + } + + Reference< io::XActiveDataStreamer > activeDataStreamer( aCommandArgument.Sink,UNO_QUERY ); + if( activeDataStreamer.is() ) + { + activeDataStreamer->setStream( m_pMyShell->open_rw( nMyCommandIdentifier, + m_aUncPath, + bLock ) ); + } + } + else if ( aCommandArgument.Mode == OpenMode::ALL || + aCommandArgument.Mode == OpenMode::FOLDERS || + aCommandArgument.Mode == OpenMode::DOCUMENTS ) + { + retValue = m_pMyShell->ls( nMyCommandIdentifier, + m_aUncPath, + aCommandArgument.Mode, + aCommandArgument.Properties, + aCommandArgument.SortingInfo ); + } +// else if( aCommandArgument.Mode == +// OpenMode::DOCUMENT_SHARE_DENY_NONE || +// aCommandArgument.Mode == +// OpenMode::DOCUMENT_SHARE_DENY_WRITE ) +// m_pMyShell->installError( nMyCommandIdentifier, +// TASKHANDLING_UNSUPPORTED_OPEN_MODE, +// aCommandArgument.Mode); + else + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_UNSUPPORTED_OPEN_MODE, + aCommandArgument.Mode); + } + + return retValue; +} + + + +void SAL_CALL +BaseContent::deleteContent( sal_Int32 nMyCommandIdentifier ) + throw() +{ + if( m_nState & Deleted ) + return; + + if( m_pMyShell->remove( nMyCommandIdentifier,m_aUncPath ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_nState |= Deleted; + } +} + + + +void SAL_CALL +BaseContent::transfer( sal_Int32 nMyCommandIdentifier, + const TransferInfo& aTransferInfo ) + throw() +{ + if( m_nState & Deleted ) + return; + + if( aTransferInfo.SourceURL.compareToAscii( "file:",5 ) != 0 ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_TRANSFER_INVALIDSCHEME ); + return; + } + + rtl::OUString srcUnc; + if( m_pMyShell->getUnqFromUrl( aTransferInfo.SourceURL,srcUnc ) ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_TRANSFER_INVALIDURL ); + return; + } + + rtl::OUString srcUncPath = srcUnc; + + // Determine the new title ! + rtl::OUString NewTitle; + if( aTransferInfo.NewTitle.getLength() ) + NewTitle = rtl::Uri::encode( aTransferInfo.NewTitle, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + else + NewTitle = srcUncPath.copy( 1 + srcUncPath.lastIndexOf( sal_Unicode('/') ) ); + + // Is destination a document or a folder ? + Sequence< beans::Property > seq(1); + seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"), + -1, + getCppuType( static_cast< sal_Bool* >(0) ), + 0 ); + Reference< sdbc::XRow > xRow = getPropertyValues( nMyCommandIdentifier,seq ); + sal_Bool IsDocument = xRow->getBoolean( 1 ); + if( xRow->wasNull() ) + { // Destination file type could not be determined + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_TRANSFER_DESTFILETYPE ); + return; + } + + rtl::OUString dstUncPath; + if( IsDocument ) + { // as sibling + sal_Int32 lastSlash = m_aUncPath.lastIndexOf( sal_Unicode('/') ); + dstUncPath = m_aUncPath.copy(0,lastSlash ); + } + else + // as child + dstUncPath = m_aUncPath; + + dstUncPath += ( rtl::OUString::createFromAscii( "/" ) + NewTitle ); + + sal_Int32 NameClash = aTransferInfo.NameClash; + + if( aTransferInfo.MoveData ) + m_pMyShell->move( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash ); + else + m_pMyShell->copy( nMyCommandIdentifier,srcUncPath,dstUncPath,NameClash ); +} + + + + +void SAL_CALL BaseContent::insert( sal_Int32 nMyCommandIdentifier, + const InsertCommandArgument& aInsertArgument ) + throw() +{ + if( m_nState & FullFeatured ) + { + m_pMyShell->write( nMyCommandIdentifier, + m_aUncPath, + aInsertArgument.ReplaceExisting, + aInsertArgument.Data ); + return; + } + + if( ! ( m_nState & JustInserted ) ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND ); + return; + } + + // Inserts the content, which has the flag m_bIsFresh + + if( ! m_nState & NameForInsertionSet ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_NONAMESET_INSERT_COMMAND ); + return; + } + + // Inserting a document or a file? + sal_Bool bDocument = false; + + Sequence< beans::Property > seq(1); + seq[0] = beans::Property( rtl::OUString::createFromAscii("IsDocument"), + -1, + getCppuType( static_cast< sal_Bool* >(0) ), + 0 ); + + Reference< sdbc::XRow > xRow = getPropertyValues( -1,seq ); + + bool contentTypeSet = true; // is set to false, if contentType not set + try + { + bDocument = xRow->getBoolean( 1 ); + if( xRow->wasNull() ) + contentTypeSet = false; + + } + catch ( sdbc::SQLException const & ) + { + OSL_ENSURE( false, + "BaseContent::insert - Caught SQLException!" ); + contentTypeSet = false; + } + + if( ! contentTypeSet ) + { + m_pMyShell->installError( nMyCommandIdentifier, + TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND ); + return; + } + + + sal_Bool success = false; + if( bDocument ) + success = m_pMyShell->mkfil( nMyCommandIdentifier, + m_aUncPath, + aInsertArgument.ReplaceExisting, + aInsertArgument.Data ); + else + { + while( ! success ) + { + success = m_pMyShell->mkdir( nMyCommandIdentifier, + m_aUncPath, + aInsertArgument.ReplaceExisting ); + if( success ) + break; + + XInteractionRequestImpl *aRequestImpl = + new XInteractionRequestImpl( + rtl::Uri::decode( + getTitle(m_aUncPath), + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8), + (cppu::OWeakObject*)this, + m_pMyShell,nMyCommandIdentifier); + uno::Reference< task::XInteractionRequest > aReq( aRequestImpl ); + + m_pMyShell->handleTask( nMyCommandIdentifier,aReq ); + if( aRequestImpl->aborted() || + !aRequestImpl->newName().getLength() ) + // means aborting + break; + + // determine new uncpath + m_pMyShell->clearError( nMyCommandIdentifier ); + m_aUncPath = getParentName( m_aUncPath ); + if( m_aUncPath.lastIndexOf( sal_Unicode('/') ) != m_aUncPath.getLength() - 1 ) + m_aUncPath += rtl::OUString::createFromAscii("/"); + + m_aUncPath += rtl::Uri::encode( aRequestImpl->newName(), + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + } + } + + if ( ! success ) + return; + + FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,m_aUncPath ); + m_xContentIdentifier = Reference< XContentIdentifier >( p ); + + m_pMyShell->registerNotifier( m_aUncPath,this ); + m_pMyShell->insertDefaultProperties( m_aUncPath ); + + osl::MutexGuard aGuard( m_aMutex ); + m_nState = FullFeatured; +} + + + +void SAL_CALL BaseContent::endTask( sal_Int32 CommandId ) +{ + // This is the only function allowed to throw an exception + m_pMyShell->endTask( CommandId,m_aUncPath,this ); +} + + + +ContentEventNotifier* +BaseContent::cDEL( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + m_nState |= Deleted; + + ContentEventNotifier* p; + if( m_pContentEventListeners ) + p = new ContentEventNotifier( m_pMyShell, + this, + m_xContentIdentifier, + m_pContentEventListeners->getElements() ); + else + p = 0; + + return p; +} + + +ContentEventNotifier* +BaseContent::cEXC( const rtl::OUString aNewName ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + Reference< XContentIdentifier > xOldRef = m_xContentIdentifier; + m_aUncPath = aNewName; + FileContentIdentifier* pp = new FileContentIdentifier( m_pMyShell,aNewName ); + m_xContentIdentifier = Reference< XContentIdentifier >( pp ); + + ContentEventNotifier* p = 0; + if( m_pContentEventListeners ) + p = new ContentEventNotifier( m_pMyShell, + this, + m_xContentIdentifier, + xOldRef, + m_pContentEventListeners->getElements() ); + + return p; +} + + +ContentEventNotifier* +BaseContent::cCEL( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + ContentEventNotifier* p = 0; + if( m_pContentEventListeners ) + p = new ContentEventNotifier( m_pMyShell, + this, + m_xContentIdentifier, + m_pContentEventListeners->getElements() ); + + return p; +} + +PropertySetInfoChangeNotifier* +BaseContent::cPSL( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + PropertySetInfoChangeNotifier* p = 0; + if( m_pPropertySetInfoChangeListeners ) + p = new PropertySetInfoChangeNotifier( m_pMyShell, + this, + m_xContentIdentifier, + m_pPropertySetInfoChangeListeners->getElements() ); + + return p; +} + + + +PropertyChangeNotifier* +BaseContent::cPCL( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + Sequence< rtl::OUString > seqNames; + + if( m_pPropertyListener ) + seqNames = m_pPropertyListener->getContainedTypes(); + + PropertyChangeNotifier* p = 0; + + sal_Int32 length = seqNames.getLength(); + + if( length ) + { + ListenerMap* listener = new ListenerMap(); + for( sal_Int32 i = 0; i < length; ++i ) + { + (*listener)[seqNames[i]] = m_pPropertyListener->getContainer( seqNames[i] )->getElements(); + } + + p = new PropertyChangeNotifier( m_pMyShell, + this, + m_xContentIdentifier, + listener ); + } + + return p; +} + + +rtl::OUString BaseContent::getKey( void ) +{ + return m_aUncPath; +} diff --git a/ucb/source/ucp/file/bc.hxx b/ucb/source/ucp/file/bc.hxx new file mode 100644 index 000000000000..2163758bfffc --- /dev/null +++ b/ucb/source/ucp/file/bc.hxx @@ -0,0 +1,353 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _BC_HXX_ +#define _BC_HXX_ + +#include "osl/mutex.hxx" +#include "rtl/ustring.hxx" +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#ifndef _COM_SUN_STAR_UCB_XRESULTSET_HPP_ +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/XPropertySetInfoChangeNotifier.hpp> +#include <com/sun/star/beans/XPropertySetInfoChangeListener.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/ucb/XContentCreator.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> +#ifndef _COM_SUN_STAR_UCB_SHELL_HXX_ +#include "shell.hxx" +#endif + + +namespace fileaccess { + + class PropertyListeners; + class shell; + class FileProvider; + + class BaseContent: + public cppu::OWeakObject, + public com::sun::star::lang::XComponent, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::ucb::XCommandProcessor, + public com::sun::star::beans::XPropertiesChangeNotifier, + public com::sun::star::beans::XPropertyContainer, + public com::sun::star::beans::XPropertySetInfoChangeNotifier, + public com::sun::star::ucb::XContentCreator, + public com::sun::star::container::XChild, + public com::sun::star::ucb::XContent, + public fileaccess::Notifier // implementation class + { + private: + + // A special creator for inserted contents; Creates an ugly object + BaseContent( shell* pMyShell, + const rtl::OUString& parentName, + sal_Bool bFolder ); + + public: + BaseContent( + shell* pMyShell, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xContentIdentifier, + const rtl::OUString& aUnqPath ); + + virtual ~BaseContent(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XComponent + virtual void SAL_CALL + dispose( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + // XServiceInfo + virtual rtl::OUString SAL_CALL + getImplementationName() + throw( com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + supportsService( const rtl::OUString& ServiceName ) + throw( com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw( com::sun::star::uno::RuntimeException ); + + + // XCommandProcessor + virtual sal_Int32 SAL_CALL + createCommandIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Any SAL_CALL + execute( + const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ) + throw( com::sun::star::uno::Exception, + com::sun::star::ucb::CommandAbortedException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + abort( + sal_Int32 CommandId ) + throw( com::sun::star::uno::RuntimeException ); + + + // XContent + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL + getIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL + getContentType( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addContentEventListener( + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeContentEventListener( + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + // XPropertiesChangeNotifier + + virtual void SAL_CALL + addPropertiesChangeListener( + const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames, + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertiesChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removePropertiesChangeListener( const com::sun::star::uno::Sequence< rtl::OUString >& PropertyNames, + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertiesChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + // XPropertyContainer + + virtual void SAL_CALL + addProperty( + const rtl::OUString& Name, + sal_Int16 Attributes, + const com::sun::star::uno::Any& DefaultValue ) + throw( com::sun::star::beans::PropertyExistException, + com::sun::star::beans::IllegalTypeException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + removeProperty( + const rtl::OUString& Name ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::NotRemoveableException, + com::sun::star::uno::RuntimeException ); + + // XPropertySetInfoChangeNotifier + + virtual void SAL_CALL + addPropertySetInfoChangeListener( + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySetInfoChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removePropertySetInfoChangeListener( + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySetInfoChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + + // XContentCreator + + virtual com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo > SAL_CALL + queryCreatableContentsInfo( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL + createNewContent( + const com::sun::star::ucb::ContentInfo& Info ) + throw( com::sun::star::uno::RuntimeException ); + + + // XChild + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + getParent( + void ) throw( com::sun::star::uno::RuntimeException ); + + // Not supported + virtual void SAL_CALL + setParent( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& Parent ) + throw( com::sun::star::lang::NoSupportException, + com::sun::star::uno::RuntimeException); + + + // Notifier + + ContentEventNotifier* cDEL( void ); + ContentEventNotifier* cEXC( const rtl::OUString aNewName ); + ContentEventNotifier* cCEL( void ); + PropertySetInfoChangeNotifier* cPSL( void ); + PropertyChangeNotifier* cPCL( void ); + rtl::OUString getKey( void ); + + private: + // Data members + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xContentIdentifier; + rtl::OUString m_aUncPath; + + enum state { NameForInsertionSet = 1, + JustInserted = 2, + Deleted = 4, + FullFeatured = 8, + Connected = 16 }; + sal_Bool m_bFolder; + sal_uInt16 m_nState; + + osl::Mutex m_aMutex; + + osl::Mutex m_aEventListenerMutex; + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + cppu::OInterfaceContainerHelper* m_pContentEventListeners; + cppu::OInterfaceContainerHelper* m_pPropertySetInfoChangeListeners; + PropertyListeners* m_pPropertyListener; + + + // Private Methods + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo > SAL_CALL + getCommandInfo() + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo( + sal_Int32 nMyCommandIdentifier ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL + getPropertyValues( + sal_Int32 nMyCommandIdentifier, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& PropertySet ) + throw( com::sun::star::uno::RuntimeException ); + + com::sun::star::uno::Sequence< com::sun::star::uno::Any > SAL_CALL + setPropertyValues( + sal_Int32 nMyCommandIdentifier, + const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& Values ) + throw( ); + + com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > SAL_CALL + open( + sal_Int32 nMyCommandIdentifier, + const com::sun::star::ucb::OpenCommandArgument2& aCommandArgument ) + throw(); + + void SAL_CALL + deleteContent( sal_Int32 nMyCommandIdentifier ) + throw(); + + + void SAL_CALL + transfer( sal_Int32 nMyCommandIdentifier, + const com::sun::star::ucb::TransferInfo& aTransferInfo ) + throw(); + + void SAL_CALL + insert( sal_Int32 nMyCommandIdentifier, + const com::sun::star::ucb::InsertCommandArgument& aInsertArgument ) + throw(); + + void SAL_CALL endTask( sal_Int32 CommandId ); + + friend class ContentEventNotifier; + }; + +} // end namespace fileaccess + +#endif + diff --git a/ucb/source/ucp/file/exports.map b/ucb/source/ucp/file/exports.map new file mode 100644 index 000000000000..a8bd267fc9e9 --- /dev/null +++ b/ucb/source/ucp/file/exports.map @@ -0,0 +1,8 @@ +FIL_1_0 { + global: + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + local: + *; +}; diff --git a/ucb/source/ucp/file/exports2.dxp b/ucb/source/ucp/file/exports2.dxp new file mode 100644 index 000000000000..6c42314f228b --- /dev/null +++ b/ucb/source/ucp/file/exports2.dxp @@ -0,0 +1,9 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory + +_ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE +_ZTIN3com3sun4star3ucb22InteractiveIOExceptionE +_ZTIN3com3sun4star4task28ClassifiedInteractionRequestE +_ZTIN3com3sun4star3ucb18NameClashExceptionE +_ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE diff --git a/ucb/source/ucp/file/filcmd.cxx b/ucb/source/ucp/file/filcmd.cxx new file mode 100644 index 000000000000..776482957c1e --- /dev/null +++ b/ucb/source/ucp/file/filcmd.cxx @@ -0,0 +1,141 @@ + /************************************************************************* + * + * 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" +#include "filcmd.hxx" +#include "shell.hxx" +#include "prov.hxx" + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + +XCommandInfo_impl::XCommandInfo_impl( shell* pMyShell ) + : m_pMyShell( pMyShell ), + m_xProvider( pMyShell->m_pProvider ) +{ +} + +XCommandInfo_impl::~XCommandInfo_impl() +{ +} + + + +void SAL_CALL +XCommandInfo_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XCommandInfo_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +uno::Any SAL_CALL +XCommandInfo_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( XCommandInfo*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +uno::Sequence< CommandInfo > SAL_CALL +XCommandInfo_impl::getCommands( + void ) + throw( uno::RuntimeException ) +{ + return m_pMyShell->m_sCommandInfo; +} + + +CommandInfo SAL_CALL +XCommandInfo_impl::getCommandInfoByName( + const rtl::OUString& aName ) + throw( UnsupportedCommandException, + uno::RuntimeException) +{ + for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); i++ ) + if( m_pMyShell->m_sCommandInfo[i].Name == aName ) + return m_pMyShell->m_sCommandInfo[i]; + + throw UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +CommandInfo SAL_CALL +XCommandInfo_impl::getCommandInfoByHandle( + sal_Int32 Handle ) + throw( UnsupportedCommandException, + uno::RuntimeException ) +{ + for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i ) + if( m_pMyShell->m_sCommandInfo[i].Handle == Handle ) + return m_pMyShell->m_sCommandInfo[i]; + + throw UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +sal_Bool SAL_CALL +XCommandInfo_impl::hasCommandByName( + const rtl::OUString& aName ) + throw( uno::RuntimeException ) +{ + for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i ) + if( m_pMyShell->m_sCommandInfo[i].Name == aName ) + return true; + + return false; +} + + +sal_Bool SAL_CALL +XCommandInfo_impl::hasCommandByHandle( + sal_Int32 Handle ) + throw( uno::RuntimeException ) +{ + for( sal_Int32 i = 0; i < m_pMyShell->m_sCommandInfo.getLength(); ++i ) + if( m_pMyShell->m_sCommandInfo[i].Handle == Handle ) + return true; + + return false; +} diff --git a/ucb/source/ucp/file/filcmd.hxx b/ucb/source/ucp/file/filcmd.hxx new file mode 100644 index 000000000000..6a6725bfcb17 --- /dev/null +++ b/ucb/source/ucp/file/filcmd.hxx @@ -0,0 +1,108 @@ + /************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILCMD_HXX_ +#define _FILCMD_HXX_ + +#include <rtl/ustring.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> + + +namespace fileaccess { + + + // forward + class shell; + + + class XCommandInfo_impl + : public cppu::OWeakObject, + public com::sun::star::ucb::XCommandInfo + { + public: + + XCommandInfo_impl( shell* pMyShell ); + + virtual ~XCommandInfo_impl(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XCommandInfo + + virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > SAL_CALL + getCommands( + void ) + throw( com::sun::star::uno::RuntimeException); + + virtual com::sun::star::ucb::CommandInfo SAL_CALL + getCommandInfoByName( + const rtl::OUString& Name ) + throw( com::sun::star::ucb::UnsupportedCommandException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::ucb::CommandInfo SAL_CALL + getCommandInfoByHandle( + sal_Int32 Handle ) + throw( com::sun::star::ucb::UnsupportedCommandException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasCommandByName( + const rtl::OUString& Name ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasCommandByHandle( + sal_Int32 Handle ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + }; + +} + +#endif diff --git a/ucb/source/ucp/file/filerror.hxx b/ucb/source/ucp/file/filerror.hxx new file mode 100644 index 000000000000..35b0d8ae5ce8 --- /dev/null +++ b/ucb/source/ucp/file/filerror.hxx @@ -0,0 +1,118 @@ + /************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILERROR_HXX_ + +namespace fileaccess { + +// Error codes used to deliver the resulting exceptions +#define LOWEST_FREE_ERROR 72 + +#define TASKHANDLER_NO_ERROR 0 +#define TASKHANDLER_UNSUPPORTED_COMMAND 1 +#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT 2 +#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT 3 +#define TASKHANDLING_WRONG_OPEN_ARGUMENT 4 +#define TASKHANDLING_WRONG_DELETE_ARGUMENT 5 +#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT 6 +#define TASKHANDLING_WRONG_INSERT_ARGUMENT 7 +#define TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT 8 +#define TASKHANDLING_UNSUPPORTED_OPEN_MODE 9 + +#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND 10 +#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND 11 + +#define TASKHANDLING_OPEN_FILE_FOR_PAGING 12 +#define TASKHANDLING_NOTCONNECTED_FOR_PAGING 13 +#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING 14 +#define TASKHANDLING_IOEXCEPTION_FOR_PAGING 15 +#define TASKHANDLING_READING_FILE_FOR_PAGING 16 + +#define TASKHANDLING_OPEN_FOR_INPUTSTREAM 17 +#define TASKHANDLING_OPEN_FOR_STREAM 18 +#define TASKHANDLING_OPEN_FOR_DIRECTORYLISTING 19 + +#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND 22 +#define TASKHANDLING_NONAMESET_INSERT_COMMAND 23 +#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND 24 + +#define TASKHANDLING_ANYOTHER_WRITE 25 // not used +#define TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE 26 +#define TASKHANDLING_NO_OPEN_FILE_FOR_WRITE 27 +#define TASKHANDLING_NOTCONNECTED_FOR_WRITE 28 +#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE 29 +#define TASKHANDLING_IOEXCEPTION_FOR_WRITE 30 +#define TASKHANDLING_FILEIOERROR_FOR_WRITE 31 +#define TASKHANDLING_FILEIOERROR_FOR_NO_SPACE 71 +#define TASKHANDLING_FILESIZE_FOR_WRITE 32 +#define TASKHANDLING_INPUTSTREAM_FOR_WRITE 33 +#define TASKHANDLING_NOREPLACE_FOR_WRITE 34 +#define TASKHANDLING_ENSUREDIR_FOR_WRITE 35 + +#define TASKHANDLING_FOLDER_EXISTS_MKDIR 69 +#define TASKHANDLING_INVALID_NAME_MKDIR 70 +#define TASKHANDLING_CREATEDIRECTORY_MKDIR 36 + +#define TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE 38 +#define TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE 39 +#define TASKHANDLING_OPENDIRECTORY_FOR_REMOVE 40 +#define TASKHANDLING_DELETEFILE_FOR_REMOVE 41 +#define TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE 42 +#define TASKHANDLING_FILETYPE_FOR_REMOVE 43 +#define TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE 44 +#define TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE 45 + +#define TASKHANDLING_TRANSFER_ACCESSINGROOT 46 +#define TASKHANDLING_TRANSFER_INVALIDSCHEME 47 +#define TASKHANDLING_TRANSFER_INVALIDURL 48 +#define TASKHANDLING_TRANSFER_DESTFILETYPE 50 +#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCE 51 +#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT 52 +#define TASKHANDLING_KEEPERROR_FOR_MOVE 53 +#define TASKHANDLING_NAMECLASH_FOR_MOVE 54 +#define TASKHANDLING_NAMECLASHMOVE_FOR_MOVE 55 +#define TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE 56 +#define TASKHANDLING_OVERWRITE_FOR_MOVE 57 +#define TASKHANDLING_RENAME_FOR_MOVE 58 +#define TASKHANDLING_RENAMEMOVE_FOR_MOVE 59 + +#define TASKHANDLING_TRANSFER_BY_COPY_SOURCE 60 +#define TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT 61 +#define TASKHANDLING_KEEPERROR_FOR_COPY 62 +#define TASKHANDLING_OVERWRITE_FOR_COPY 63 +#define TASKHANDLING_RENAME_FOR_COPY 64 +#define TASKHANDLING_RENAMEMOVE_FOR_COPY 65 +#define TASKHANDLING_NAMECLASH_FOR_COPY 66 +#define TASKHANDLING_NAMECLASHMOVE_FOR_COPY 67 +#define TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY 68 + +} + +#endif + + + + diff --git a/ucb/source/ucp/file/filglob.cxx b/ucb/source/ucp/file/filglob.cxx new file mode 100644 index 000000000000..e947c68da1ba --- /dev/null +++ b/ucb/source/ucp/file/filglob.cxx @@ -0,0 +1,954 @@ + /************************************************************************* + * + * 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" +#include <stdio.h> +#include "filglob.hxx" +#ifndef _FILERROR_HXX_ +#include "filerror.hxx" +#endif +#include "shell.hxx" +#include "bc.hxx" +#include <osl/file.hxx> +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <ucbhelper/cancelcommandexecution.hxx> +#include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <com/sun/star/ucb/UnsupportedCommandException.hpp> +#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/ucb/IOErrorCode.hpp> +#include <com/sun/star/ucb/MissingPropertiesException.hpp> +#include <com/sun/star/ucb/MissingInputStreamException.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> +#include <com/sun/star/ucb/UnsupportedNameClashException.hpp> +#include "com/sun/star/beans/PropertyState.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" +#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Sequence.hxx" +#include "osl/diagnose.h" +#include "rtl/ustrbuf.hxx" +#include <rtl/uri.hxx> +#include <rtl/ustring.hxx> +#include "sal/types.h" + +using namespace ucbhelper; +using namespace osl; +using namespace ::com::sun::star; +using namespace com::sun::star::task; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; + +namespace { + + Sequence< Any > generateErrorArguments( + rtl::OUString const & rPhysicalUrl) + { + rtl::OUString aResourceName; + rtl::OUString aResourceType; + sal_Bool bRemovable; + bool bResourceName = false; + bool bResourceType = false; + bool bRemoveProperty = false; + + if (osl::FileBase::getSystemPathFromFileURL( + rPhysicalUrl, + aResourceName) + == osl::FileBase::E_None) + bResourceName = true; + + // The resource types "folder" (i.e., directory) and + // "volume" seem to be + // the most interesting when producing meaningful error messages: + osl::DirectoryItem aItem; + if (osl::DirectoryItem::get(rPhysicalUrl, aItem) == + osl::FileBase::E_None) + { + osl::FileStatus aStatus( FileStatusMask_Type ); + if (aItem.getFileStatus(aStatus) == osl::FileBase::E_None) + switch (aStatus.getFileType()) + { + case osl::FileStatus::Directory: + aResourceType + = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("folder")); + bResourceType = true; + break; + + case osl::FileStatus::Volume: + { + aResourceType + = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("volume")); + bResourceType = true; + osl::VolumeInfo aVolumeInfo( + VolumeInfoMask_Attributes ); + if( osl::Directory::getVolumeInfo( + rPhysicalUrl,aVolumeInfo ) == + osl::FileBase::E_None ) + { + bRemovable = aVolumeInfo.getRemoveableFlag(); + bRemoveProperty = true; + } + } + break; + case osl::FileStatus::Regular: + case osl::FileStatus::Fifo: + case osl::FileStatus::Socket: + case osl::FileStatus::Link: + case osl::FileStatus::Special: + case osl::FileStatus::Unknown: + // do nothing for now + break; + } + } + + Sequence< Any > aArguments( 1 + + (bResourceName ? 1 : 0) + + (bResourceType ? 1 : 0) + + (bRemoveProperty ? 1 : 0) ); + sal_Int32 i = 0; + aArguments[i++] + <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + makeAny(rPhysicalUrl), + PropertyState_DIRECT_VALUE); + if (bResourceName) + aArguments[i++] + <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "ResourceName")), + -1, + makeAny(aResourceName), + PropertyState_DIRECT_VALUE); + if (bResourceType) + aArguments[i++] + <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "ResourceType")), + -1, + makeAny(aResourceType), + PropertyState_DIRECT_VALUE); + if (bRemoveProperty) + aArguments[i++] + <<= PropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Removable")), + -1, + makeAny(bRemovable), + PropertyState_DIRECT_VALUE); + + return aArguments; + } +} + + + +namespace fileaccess { + + + sal_Bool isChild( const rtl::OUString& srcUnqPath, + const rtl::OUString& dstUnqPath ) + { + static sal_Unicode slash = '/'; + // Simple lexical comparison + sal_Int32 srcL = srcUnqPath.getLength(); + sal_Int32 dstL = dstUnqPath.getLength(); + + return ( + ( srcUnqPath == dstUnqPath ) + || + ( ( dstL > srcL ) + && + ( srcUnqPath.compareTo( dstUnqPath, srcL ) == 0 ) + && + ( dstUnqPath[ srcL ] == slash ) ) + ); + } + + + rtl::OUString newName( + const rtl::OUString& aNewPrefix, + const rtl::OUString& aOldPrefix, + const rtl::OUString& old_Name ) + { + sal_Int32 srcL = aOldPrefix.getLength(); + + rtl::OUString new_Name = old_Name.copy( srcL ); + new_Name = ( aNewPrefix + new_Name ); + return new_Name; + } + + + rtl::OUString getTitle( const rtl::OUString& aPath ) + { + sal_Unicode slash = '/'; + sal_Int32 lastIndex = aPath.lastIndexOf( slash ); + return aPath.copy( lastIndex + 1 ); + } + + + rtl::OUString getParentName( const rtl::OUString& aFileName ) + { + sal_Int32 lastIndex = aFileName.lastIndexOf( sal_Unicode('/') ); + rtl::OUString aParent = aFileName.copy( 0,lastIndex ); + + if( aParent[ aParent.getLength()-1] == sal_Unicode(':') && aParent.getLength() == 6 ) + aParent += rtl::OUString::createFromAscii( "/" ); + + if( 0 == aParent.compareToAscii( "file://" ) ) + aParent = rtl::OUString::createFromAscii( "file:///" ); + + return aParent; + } + + + osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath, + const rtl::OUString& strDestPath, + sal_Bool test ) + { + if( test ) + { + osl::DirectoryItem aItem; + if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT ) + return osl::FileBase::E_EXIST; + } + + return osl::File::copy( strPath,strDestPath ); + } + + + osl::FileBase::RC osl_File_move( const rtl::OUString& strPath, + const rtl::OUString& strDestPath, + sal_Bool test ) + { + if( test ) + { + osl::DirectoryItem aItem; + if( osl::DirectoryItem::get( strDestPath,aItem ) != osl::FileBase:: E_NOENT ) + return osl::FileBase::E_EXIST; + } + + return osl::File::move( strPath,strDestPath ); + } + + void throw_handler( + sal_Int32 errorCode, + sal_Int32 minorCode, + const Reference< XCommandEnvironment >& xEnv, + const rtl::OUString& aUncPath, + BaseContent* pContent, + bool isHandled ) + { + Reference<XCommandProcessor> xComProc(pContent); + Any aAny; + IOErrorCode ioErrorCode; + + if( errorCode == TASKHANDLER_UNSUPPORTED_COMMAND ) + { + aAny <<= UnsupportedCommandException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + cancelCommandExecution( aAny,xEnv ); + } + else if( errorCode == TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT || + errorCode == TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT || + errorCode == TASKHANDLING_WRONG_OPEN_ARGUMENT || + errorCode == TASKHANDLING_WRONG_DELETE_ARGUMENT || + errorCode == TASKHANDLING_WRONG_TRANSFER_ARGUMENT || + errorCode == TASKHANDLING_WRONG_INSERT_ARGUMENT || + errorCode == TASKHANDLING_WRONG_CREATENEWCONTENT_ARGUMENT ) + { + IllegalArgumentException excep; + excep.ArgumentPosition = 0; + aAny <<= excep; + cancelCommandExecution( + aAny,xEnv); + } + else if( errorCode == TASKHANDLING_UNSUPPORTED_OPEN_MODE ) + { + UnsupportedOpenModeException excep; + excep.Mode = sal::static_int_cast< sal_Int16 >(minorCode); + aAny <<= excep; + cancelCommandExecution( aAny,xEnv ); + } + else if(errorCode == TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND || + errorCode == TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND || + errorCode == TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND ) + { + // What to do here? + } + else if( + // error in opening file + errorCode == TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE || + // error in opening file + errorCode == TASKHANDLING_NO_OPEN_FILE_FOR_WRITE || + // error in opening file + errorCode == TASKHANDLING_OPEN_FOR_STREAM || + // error in opening file + errorCode == TASKHANDLING_OPEN_FOR_INPUTSTREAM || + // error in opening file + errorCode == TASKHANDLING_OPEN_FILE_FOR_PAGING ) + { + switch( minorCode ) + { + case FileBase::E_NAMETOOLONG: + // pathname was too long + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + case FileBase::E_NXIO: + // No such device or address + case FileBase::E_NODEV: + // No such device + ioErrorCode = IOErrorCode_INVALID_DEVICE; + break; + case FileBase::E_NOENT: + // No such file or directory + ioErrorCode = IOErrorCode_NOT_EXISTING; + break; + case FileBase::E_ROFS: + // #i4735# handle ROFS transparently as ACCESS_DENIED + case FileBase::E_ACCES: + // permission denied<P> + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_ISDIR: + // Is a directory<p> + ioErrorCode = IOErrorCode_NO_FILE; + break; + case FileBase::E_NOTREADY: + ioErrorCode = IOErrorCode_DEVICE_NOT_READY; + break; + case FileBase::E_MFILE: + // too many open files used by the process + case FileBase::E_NFILE: + // too many open files in the system + ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; + break; + case FileBase::E_INVAL: + // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_NOMEM: + // not enough memory for allocating structures + ioErrorCode = IOErrorCode_OUT_OF_MEMORY; + break; + case FileBase::E_BUSY: + // Text file busy + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + case FileBase::E_AGAIN: + // Operation would block + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + case FileBase::E_NOLCK: // No record locks available + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + + case FileBase::E_FAULT: // Bad address + case FileBase::E_LOOP: // Too many symbolic links encountered + case FileBase::E_NOSPC: // No space left on device + case FileBase::E_INTR: // function call was interrupted + case FileBase::E_IO: // I/O error + case FileBase::E_MULTIHOP: // Multihop attempted + case FileBase::E_NOLINK: // Link has been severed + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "an error occured during file opening")), + xComProc); + } + else if( errorCode == TASKHANDLING_OPEN_FOR_DIRECTORYLISTING || + errorCode == TASKHANDLING_OPENDIRECTORY_FOR_REMOVE ) + { + switch( minorCode ) + { + case FileBase::E_INVAL: + // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_NOENT: + // the specified path doesn't exist + ioErrorCode = IOErrorCode_NOT_EXISTING; + break; + case FileBase::E_NOTDIR: + // the specified path is not an directory + ioErrorCode = IOErrorCode_NO_DIRECTORY; + break; + case FileBase::E_NOMEM: + // not enough memory for allocating structures + ioErrorCode = IOErrorCode_OUT_OF_MEMORY; + break; + case FileBase::E_ROFS: + // #i4735# handle ROFS transparently as ACCESS_DENIED + case FileBase::E_ACCES: // permission denied + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_NOTREADY: + ioErrorCode = IOErrorCode_DEVICE_NOT_READY; + break; + case FileBase::E_MFILE: + // too many open files used by the process + case FileBase::E_NFILE: + // too many open files in the system + ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; + break; + case FileBase::E_NAMETOOLONG: + // File name too long + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + case FileBase::E_LOOP: + // Too many symbolic links encountered<p> + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "an error occured during opening a directory")), + xComProc); + } + else if( errorCode == TASKHANDLING_NOTCONNECTED_FOR_WRITE || + errorCode == TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE || + errorCode == TASKHANDLING_IOEXCEPTION_FOR_WRITE || + errorCode == TASKHANDLING_NOTCONNECTED_FOR_PAGING || + errorCode == TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING || + errorCode == TASKHANDLING_IOEXCEPTION_FOR_PAGING ) + { + ioErrorCode = IOErrorCode_UNKNOWN; + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "an error occured writing or reading from a file")), + xComProc ); + } + else if( errorCode == TASKHANDLING_FILEIOERROR_FOR_NO_SPACE ) + { + ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE; + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "device full")), + xComProc); + } + else if( errorCode == TASKHANDLING_FILEIOERROR_FOR_WRITE || + errorCode == TASKHANDLING_READING_FILE_FOR_PAGING ) + { + switch( minorCode ) + { + case FileBase::E_INVAL: + // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_FBIG: + // File too large + ioErrorCode = IOErrorCode_CANT_WRITE; + break; + case FileBase::E_NOSPC: + // No space left on device + ioErrorCode = IOErrorCode_OUT_OF_DISK_SPACE; + break; + case FileBase::E_NXIO: + // No such device or address + ioErrorCode = IOErrorCode_INVALID_DEVICE; + break; + case FileBase::E_NOLINK: + // Link has been severed + case FileBase::E_ISDIR: + // Is a directory + ioErrorCode = IOErrorCode_NO_FILE; + break; + case FileBase::E_AGAIN: + // Operation would block + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + case FileBase::E_TIMEDOUT: + ioErrorCode = IOErrorCode_DEVICE_NOT_READY; + break; + case FileBase::E_NOLCK: // No record locks available + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + case FileBase::E_IO: // I/O error + case FileBase::E_BADF: // Bad file + case FileBase::E_FAULT: // Bad address + case FileBase::E_INTR: // function call was interrupted + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "an error occured during opening a file")), + xComProc); + } + else if( errorCode == TASKHANDLING_NONAMESET_INSERT_COMMAND || + errorCode == TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND ) + { + Sequence< ::rtl::OUString > aSeq( 1 ); + aSeq[0] = + ( errorCode == TASKHANDLING_NONAMESET_INSERT_COMMAND ) ? + rtl::OUString::createFromAscii( "Title" ) : + rtl::OUString::createFromAscii( "ContentType" ); + + aAny <<= MissingPropertiesException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "a property is missing necessary" + "to create a content")), + xComProc, + aSeq); + cancelCommandExecution(aAny,xEnv); + } + else if( errorCode == TASKHANDLING_FILESIZE_FOR_WRITE ) + { + switch( minorCode ) + { + case FileBase::E_INVAL: + // the format of the parameters was not valid + case FileBase::E_OVERFLOW: + // The resulting file offset would be a value which cannot + // be represented correctly for regular files + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "there were problems with the filesize")), + xComProc); + } + else if(errorCode == TASKHANDLING_INPUTSTREAM_FOR_WRITE) + { + Reference<XInterface> xContext(xComProc,UNO_QUERY); + aAny <<= + MissingInputStreamException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "the inputstream is missing necessary" + "to create a content")), + xContext); + cancelCommandExecution(aAny,xEnv); + } + else if( errorCode == TASKHANDLING_NOREPLACE_FOR_WRITE ) + // Overwrite = false and file exists + { + NameClashException excep; + excep.Name = getTitle(aUncPath); + excep.Classification = InteractionClassification_ERROR; + Reference<XInterface> xContext(xComProc,UNO_QUERY); + excep.Context = xContext; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "file exists and overwrite forbidden")); + aAny <<= excep; + cancelCommandExecution( aAny,xEnv ); + } + else if( errorCode == TASKHANDLING_INVALID_NAME_MKDIR ) + { + InteractiveAugmentedIOException excep; + excep.Code = IOErrorCode_INVALID_CHARACTER; + PropertyValue prop; + prop.Name = rtl::OUString::createFromAscii("ResourceName"); + prop.Handle = -1; + rtl::OUString m_aClashingName( + rtl::Uri::decode( + getTitle(aUncPath), + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8)); + prop.Value <<= m_aClashingName; + Sequence<Any> seq(1); + seq[0] <<= prop; + excep.Arguments = seq; + excep.Classification = InteractionClassification_ERROR; + Reference<XInterface> xContext(xComProc,UNO_QUERY); + excep.Context = xContext; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "the name contained invalid characters")); + if(isHandled) + throw excep; + else { + aAny <<= excep; + cancelCommandExecution( aAny,xEnv ); + } +// ioErrorCode = IOErrorCode_INVALID_CHARACTER; +// cancelCommandExecution( +// ioErrorCode, +// generateErrorArguments(aUncPath), +// xEnv, +// rtl::OUString( +// RTL_CONSTASCII_USTRINGPARAM( +// "the name contained invalid characters")), +// xComProc ); + } + else if( errorCode == TASKHANDLING_FOLDER_EXISTS_MKDIR ) + { + NameClashException excep; + excep.Name = getTitle(aUncPath); + excep.Classification = InteractionClassification_ERROR; + Reference<XInterface> xContext(xComProc,UNO_QUERY); + excep.Context = xContext; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "folder exists and overwrite forbidden")); + if(isHandled) + throw excep; + else { + aAny <<= excep; + cancelCommandExecution( aAny,xEnv ); + } +// ioErrorCode = IOErrorCode_ALREADY_EXISTING; +// cancelCommandExecution( +// ioErrorCode, +// generateErrorArguments(aUncPath), +// xEnv, +// rtl::OUString( +// RTL_CONSTASCII_USTRINGPARAM( +// "the folder exists")), +// xComProc ); + } + else if( errorCode == TASKHANDLING_ENSUREDIR_FOR_WRITE || + errorCode == TASKHANDLING_CREATEDIRECTORY_MKDIR ) + { + switch( minorCode ) + { + case FileBase::E_ACCES: + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_ROFS: + ioErrorCode = IOErrorCode_WRITE_PROTECTED; + break; + case FileBase::E_NAMETOOLONG: + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + default: + ioErrorCode = IOErrorCode_NOT_EXISTING_PATH; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(getParentName(aUncPath)), + //TODO! ok to supply physical URL to getParentName()? + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "a folder could not be created")), + xComProc ); + } + else if( errorCode == TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE || + errorCode == TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE || + errorCode == TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE ) + { + switch( minorCode ) + { + case FileBase::E_INVAL: // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_NOMEM: // not enough memory for allocating structures + ioErrorCode = IOErrorCode_OUT_OF_MEMORY; + break; + case FileBase::E_ROFS: // #i4735# handle ROFS transparently as ACCESS_DENIED + case FileBase::E_ACCES: // permission denied + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_MFILE: // too many open files used by the process + case FileBase::E_NFILE: // too many open files in the system + ioErrorCode = IOErrorCode_OUT_OF_FILE_HANDLES; + break; + case FileBase::E_NOLINK: // Link has been severed + case FileBase::E_NOENT: // No such file or directory + ioErrorCode = IOErrorCode_NOT_EXISTING; + break; + case FileBase::E_NAMETOOLONG: // File name too long + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + case FileBase::E_NOTDIR: // A component of the path prefix of path is not a directory + ioErrorCode = IOErrorCode_NOT_EXISTING_PATH; + break; + case FileBase::E_LOOP: // Too many symbolic links encountered + case FileBase::E_IO: // I/O error + case FileBase::E_MULTIHOP: // Multihop attempted + case FileBase::E_FAULT: // Bad address + case FileBase::E_INTR: // function call was interrupted + case FileBase::E_NOSYS: // Function not implemented + case FileBase::E_NOSPC: // No space left on device + case FileBase::E_NXIO: // No such device or address + case FileBase::E_OVERFLOW: // Value too large for defined data type + case FileBase::E_BADF: // Invalid oslDirectoryItem parameter + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "a file status object could not be filled")), + xComProc ); + } + else if( errorCode == TASKHANDLING_DELETEFILE_FOR_REMOVE || + errorCode == TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE ) + { + switch( minorCode ) + { + case FileBase::E_INVAL: // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_NOMEM: // not enough memory for allocating structures + ioErrorCode = IOErrorCode_OUT_OF_MEMORY; + break; + case FileBase::E_ACCES: // Permission denied + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_PERM: // Operation not permitted + ioErrorCode = IOErrorCode_NOT_SUPPORTED; + break; + case FileBase::E_NAMETOOLONG: // File name too long + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + case FileBase::E_NOLINK: // Link has been severed + case FileBase::E_NOENT: // No such file or directory + ioErrorCode = IOErrorCode_NOT_EXISTING; + break; + case FileBase::E_ISDIR: // Is a directory + case FileBase::E_ROFS: // Read-only file system + ioErrorCode = IOErrorCode_NOT_SUPPORTED; + break; + case FileBase::E_BUSY: // Device or resource busy + ioErrorCode = IOErrorCode_LOCKING_VIOLATION; + break; + case FileBase::E_FAULT: // Bad address + case FileBase::E_LOOP: // Too many symbolic links encountered + case FileBase::E_IO: // I/O error + case FileBase::E_INTR: // function call was interrupted + case FileBase::E_MULTIHOP: // Multihop attempted + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "a file or directory could not be deleted")), + xComProc ); + } + else if( errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCE || + errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT || + errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCE || + errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT || + errorCode == TASKHANDLING_TRANSFER_DESTFILETYPE || + errorCode == TASKHANDLING_FILETYPE_FOR_REMOVE || + errorCode == TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE || + errorCode == TASKHANDLING_TRANSFER_INVALIDURL ) + { + rtl::OUString aMsg; + switch( minorCode ) + { + case FileBase::E_NOENT: // No such file or directory + if ( errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCE || + errorCode == TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT || + errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCE || + errorCode == TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT ) + { + ioErrorCode = IOErrorCode_NOT_EXISTING; + aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "source file/folder does not exist")); + break; + } + else + { + ioErrorCode = IOErrorCode_GENERAL; + aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "a general error during transfer command")); + break; + } + default: + ioErrorCode = IOErrorCode_GENERAL; + aMsg = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "a general error during transfer command")); + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + aMsg, + xComProc ); + } + else if( errorCode == TASKHANDLING_TRANSFER_ACCESSINGROOT ) + { + ioErrorCode = IOErrorCode_WRITE_PROTECTED; + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "accessing the root during transfer")), + xComProc ); + } + else if( errorCode == TASKHANDLING_TRANSFER_INVALIDSCHEME ) + { + Reference<XInterface> xContext(xComProc,UNO_QUERY); + + aAny <<= + InteractiveBadTransferURLException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "bad tranfer url")), + xContext); + cancelCommandExecution( aAny,xEnv ); + } + else if( errorCode == TASKHANDLING_OVERWRITE_FOR_MOVE || + errorCode == TASKHANDLING_OVERWRITE_FOR_COPY || + errorCode == TASKHANDLING_NAMECLASHMOVE_FOR_MOVE || + errorCode == TASKHANDLING_NAMECLASHMOVE_FOR_COPY || + errorCode == TASKHANDLING_KEEPERROR_FOR_MOVE || + errorCode == TASKHANDLING_KEEPERROR_FOR_COPY || + errorCode == TASKHANDLING_RENAME_FOR_MOVE || + errorCode == TASKHANDLING_RENAME_FOR_COPY || + errorCode == TASKHANDLING_RENAMEMOVE_FOR_MOVE || + errorCode == TASKHANDLING_RENAMEMOVE_FOR_COPY ) + { + rtl::OUString aMsg(RTL_CONSTASCII_USTRINGPARAM( + "general error during transfer")); + + switch( minorCode ) + { + case FileBase::E_EXIST: + ioErrorCode = IOErrorCode_ALREADY_EXISTING; + break; + case FileBase::E_INVAL: // the format of the parameters was not valid + ioErrorCode = IOErrorCode_INVALID_PARAMETER; + break; + case FileBase::E_NOMEM: // not enough memory for allocating structures + ioErrorCode = IOErrorCode_OUT_OF_MEMORY; + break; + case FileBase::E_ACCES: // Permission denied + ioErrorCode = IOErrorCode_ACCESS_DENIED; + break; + case FileBase::E_PERM: // Operation not permitted + ioErrorCode = IOErrorCode_NOT_SUPPORTED; + break; + case FileBase::E_NAMETOOLONG: // File name too long + ioErrorCode = IOErrorCode_NAME_TOO_LONG; + break; + case FileBase::E_NOENT: // No such file or directory + ioErrorCode = IOErrorCode_NOT_EXISTING; + aMsg = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "file/folder does not exist")); + break; + case FileBase::E_ROFS: // Read-only file system<p> + ioErrorCode = IOErrorCode_NOT_EXISTING; + break; + default: + ioErrorCode = IOErrorCode_GENERAL; + break; + } + cancelCommandExecution( + ioErrorCode, + generateErrorArguments(aUncPath), + xEnv, + aMsg, + xComProc ); + } + else if( errorCode == TASKHANDLING_NAMECLASH_FOR_COPY || + errorCode == TASKHANDLING_NAMECLASH_FOR_MOVE ) + { + NameClashException excep; + excep.Name = getTitle(aUncPath); + excep.Classification = InteractionClassification_ERROR; + Reference<XInterface> xContext(xComProc,UNO_QUERY); + excep.Context = xContext; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "name clash during copy or move")); + aAny <<= excep; + + cancelCommandExecution(aAny,xEnv); + } + else if( errorCode == TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE || + errorCode == TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY ) + { + Reference<XInterface> xContext( + xComProc,UNO_QUERY); + UnsupportedNameClashException excep; + excep.NameClash = minorCode; + excep.Context = xContext; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "name clash value not supported during copy or move")); + + aAny <<= excep; + cancelCommandExecution(aAny,xEnv); + } + else + { + // case TASKHANDLER_NO_ERROR: + return; + } + } + + +} // end namespace fileaccess diff --git a/ucb/source/ucp/file/filglob.hxx b/ucb/source/ucp/file/filglob.hxx new file mode 100644 index 000000000000..015128e6588b --- /dev/null +++ b/ucb/source/ucp/file/filglob.hxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILGLOB_HXX_ +#define _FILGLOB_HXX_ + +#include <rtl/ustring.hxx> +#include <osl/file.hxx> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> + + +namespace fileaccess { + + class BaseContent; + + struct equalOUString + { + bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const + { + return !!( rKey1 == rKey2 ); + } + }; + + + struct hashOUString + { + size_t operator()( const rtl::OUString& rName ) const + { + return rName.hashCode(); + } + }; + + + /******************************************************************************/ + /* */ + /* Helper functions */ + /* */ + /******************************************************************************/ + + + // Returns true if dstUnqPath is a child from srcUnqPath or both are equal + + extern sal_Bool isChild( const rtl::OUString& srcUnqPath, + const rtl::OUString& dstUnqPath ); + + + // Changes the prefix in name + extern rtl::OUString newName( const rtl::OUString& aNewPrefix, + const rtl::OUString& aOldPrefix, + const rtl::OUString& old_Name ); + + // returns the last part of the given url as title + extern rtl::OUString getTitle( const rtl::OUString& aPath ); + + // returns the url without last part as parentname + // In case aFileName is root ( file:/// ) root is returned + + extern rtl::OUString getParentName( const rtl::OUString& aFileName ); + + /** + * special copy: + * On test = true, the implementation determines whether the + * destination exists and returns the appropriate errorcode E_EXIST. + * osl::File::copy copies unchecked. + */ + + extern osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath, + const rtl::OUString& strDestPath, + sal_Bool test = false ); + + /** + * special move: + * On test = true, the implementation determines whether the + * destination exists and returns the appropriate errorcode E_EXIST. + * osl::File::move moves unchecked + */ + + extern osl::FileBase::RC osl_File_move( const rtl::OUString& strPath, + const rtl::OUString& strDestPath, + sal_Bool test = false ); + + // This function implements the global exception handler of the file_ucp; + // It never returns; + + extern void throw_handler( sal_Int32 errorCode, + sal_Int32 minorCode, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& xEnv, + const rtl::OUString& aUncPath, + BaseContent* pContent, + bool isHandled = false); + // the physical URL of the object + +} // end namespace fileaccess + +#endif diff --git a/ucb/source/ucp/file/filid.cxx b/ucb/source/ucp/file/filid.cxx new file mode 100644 index 000000000000..8ccd8980fb9b --- /dev/null +++ b/ucb/source/ucp/file/filid.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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" +#include "filid.hxx" +#include "shell.hxx" + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + +FileContentIdentifier::FileContentIdentifier( + shell* pMyShell, + const rtl::OUString& aUnqPath, + sal_Bool IsNormalized ) + : m_pMyShell( pMyShell ), + m_bNormalized( IsNormalized ) +{ + if( IsNormalized ) + { + m_pMyShell->getUrlFromUnq( aUnqPath,m_aContentId ); + m_aNormalizedId = aUnqPath; + m_pMyShell->getScheme( m_aProviderScheme ); + } + else + { + m_pMyShell->getUnqFromUrl( aUnqPath,m_aNormalizedId ); + m_aContentId = aUnqPath; + m_pMyShell->getScheme( m_aProviderScheme ); + } +} + +FileContentIdentifier::~FileContentIdentifier() +{ +} + + +void SAL_CALL +FileContentIdentifier::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +FileContentIdentifier::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +uno::Any SAL_CALL +FileContentIdentifier::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*, this), + SAL_STATIC_CAST( XContentIdentifier*, this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +uno::Sequence< sal_Int8 > SAL_CALL +FileContentIdentifier::getImplementationId() + throw( uno::RuntimeException ) +{ + static cppu::OImplementationId* pId = NULL; + if ( !pId ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if ( !pId ) + { + static cppu::OImplementationId id( sal_False ); + pId = &id; + } + } + return (*pId).getImplementationId(); +} + + +uno::Sequence< uno::Type > SAL_CALL +FileContentIdentifier::getTypes( + void ) + throw( uno::RuntimeException ) +{ + static cppu::OTypeCollection* pCollection = NULL; + if ( !pCollection ) { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if ( !pCollection ) + { + static cppu::OTypeCollection collection( + getCppuType( static_cast< uno::Reference< lang::XTypeProvider >* >( 0 ) ), + getCppuType( static_cast< uno::Reference< XContentIdentifier >* >( 0 ) ) ); + pCollection = &collection; + } + } + return (*pCollection).getTypes(); +} + + +rtl::OUString +SAL_CALL +FileContentIdentifier::getContentIdentifier( + void ) + throw( uno::RuntimeException ) +{ + return m_aContentId; +} + + +rtl::OUString SAL_CALL +FileContentIdentifier::getContentProviderScheme( + void ) + throw( uno::RuntimeException ) +{ + return m_aProviderScheme; +} diff --git a/ucb/source/ucp/file/filid.hxx b/ucb/source/ucp/file/filid.hxx new file mode 100644 index 000000000000..36c774353120 --- /dev/null +++ b/ucb/source/ucp/file/filid.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILID_HXX_ +#define _FILID_HXX_ + +#include <rtl/ustring.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> + +namespace fileaccess { + + class shell; + + class FileContentIdentifier : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::ucb::XContentIdentifier + { + + // This implementation has to be reworked + public: + FileContentIdentifier( shell* pMyShell, + const rtl::OUString& aUnqPath, + sal_Bool IsNormalized = true ); + + virtual ~FileContentIdentifier(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XTypeProvider + virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL + getTypes( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getImplementationId( + void ) + throw( com::sun::star::uno::RuntimeException ); + + // XContentIdentifier + virtual rtl::OUString SAL_CALL + getContentIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL + getContentProviderScheme( + void ) + throw( com::sun::star::uno::RuntimeException ); + + private: + shell* m_pMyShell; + rtl::OUString m_aContentId; // The URL string + rtl::OUString m_aNormalizedId; // The somehow normalized string + rtl::OUString m_aProviderScheme; + sal_Bool m_bNormalized; + }; + +} // end namespace fileaccess + + +#endif diff --git a/ucb/source/ucp/file/filinl.hxx b/ucb/source/ucp/file/filinl.hxx new file mode 100644 index 000000000000..d28af751403b --- /dev/null +++ b/ucb/source/ucp/file/filinl.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILINL_HXX_ +#define _FILINL_HXX_ + +inline const sal_Bool& SAL_CALL shell::MyProperty::IsNative() const +{ + return isNative; +} +inline const sal_Int32& SAL_CALL shell::MyProperty::getHandle() const +{ + return Handle; +} +inline const com::sun::star::uno::Type& SAL_CALL shell::MyProperty::getType() const +{ + return Typ; +} +inline const com::sun::star::uno::Any& SAL_CALL shell::MyProperty::getValue() const +{ + return Value; +} +inline const com::sun::star::beans::PropertyState& SAL_CALL shell::MyProperty::getState() const +{ + return State; +} +inline const sal_Int16& SAL_CALL shell::MyProperty::getAttributes() const +{ + return Attributes; +} +inline void SAL_CALL shell::MyProperty::setHandle( const sal_Int32& __Handle ) const +{ + (( MyProperty* )this )->Handle = __Handle; +} +inline void SAL_CALL shell::MyProperty::setType( const com::sun::star::uno::Type& __Typ ) const +{ + (( MyProperty* )this )->Typ = __Typ; +} +inline void SAL_CALL shell::MyProperty::setValue( const com::sun::star::uno::Any& __Value ) const +{ + (( MyProperty* )this )->Value = __Value; +} +inline void SAL_CALL shell::MyProperty::setState( const com::sun::star::beans::PropertyState& __State ) const +{ + (( MyProperty* )this )->State = __State; +} +inline void SAL_CALL shell::MyProperty::setAttributes( const sal_Int16& __Attributes ) const +{ + (( MyProperty* )this )->Attributes = __Attributes; +} + + +#endif diff --git a/ucb/source/ucp/file/filinpstr.cxx b/ucb/source/ucp/file/filinpstr.cxx new file mode 100644 index 000000000000..a66a0daf5def --- /dev/null +++ b/ucb/source/ucp/file/filinpstr.cxx @@ -0,0 +1,262 @@ + /************************************************************************* + * + * 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" +#include "filinpstr.hxx" +#ifndef _FILERROR_HXX_ +#include "filerror.hxx" +#endif +#include "shell.hxx" +#include "prov.hxx" + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +XInputStream_impl::XInputStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock ) + : m_pMyShell( pMyShell ), + m_xProvider( pMyShell->m_pProvider ), + m_bLock( bLock ), + m_aFile( aUncPath ), + m_nErrorCode( TASKHANDLER_NO_ERROR ), + m_nMinorErrorCode( TASKHANDLER_NO_ERROR ) +{ + sal_uInt32 nFlags = OpenFlag_Read; + if ( !bLock ) + nFlags |= OpenFlag_NoLock; + + osl::FileBase::RC err = m_aFile.open( nFlags ); + if( err != osl::FileBase::E_None ) + { + m_nIsOpen = false; + m_aFile.close(); + + m_nErrorCode = TASKHANDLING_OPEN_FOR_INPUTSTREAM; + m_nMinorErrorCode = err; + } + else + m_nIsOpen = true; +} + + +XInputStream_impl::~XInputStream_impl() +{ + try + { + closeInput(); + } + catch (io::IOException const &) + { + OSL_ENSURE(false, "unexpected situation"); + } + catch (uno::RuntimeException const &) + { + OSL_ENSURE(false, "unexpected situation"); + } +} + + +sal_Int32 SAL_CALL XInputStream_impl::CtorSuccess() +{ + return m_nErrorCode; +}; + + + +sal_Int32 SAL_CALL XInputStream_impl::getMinorError() +{ + return m_nMinorErrorCode; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + + +XTYPEPROVIDER_IMPL_3( XInputStream_impl, + lang::XTypeProvider, + io::XSeekable, + io::XInputStream ) + + + +uno::Any SAL_CALL +XInputStream_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( io::XInputStream*,this ), + SAL_STATIC_CAST( lang::XTypeProvider*,this ), + SAL_STATIC_CAST( io::XSeekable*,this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL +XInputStream_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XInputStream_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL +XInputStream_impl::readBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + if( ! m_nIsOpen ) throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + aData.realloc(nBytesToRead); + //TODO! translate memory exhaustion (if it were detectable...) into + // io::BufferSizeExceededException + + sal_uInt64 nrc(0); + if(m_aFile.read( aData.getArray(),sal_uInt64(nBytesToRead),nrc ) + != osl::FileBase::E_None) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + // Shrink aData in case we read less than nBytesToRead (XInputStream + // documentation does not tell whether this is required, and I do not know + // if any code relies on this, so be conservative---SB): + if (sal::static_int_cast<sal_Int32>(nrc) != nBytesToRead) + aData.realloc(sal_Int32(nrc)); + return ( sal_Int32 ) nrc; +} + +sal_Int32 SAL_CALL +XInputStream_impl::readSomeBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + +void SAL_CALL +XInputStream_impl::skipBytes( + sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) ); +} + + +sal_Int32 SAL_CALL +XInputStream_impl::available( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException) +{ + return 0; +} + + +void SAL_CALL +XInputStream_impl::closeInput( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + if( m_nIsOpen ) + { + osl::FileBase::RC err = m_aFile.close(); + if( err != osl::FileBase::E_None ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + m_nIsOpen = false; + } +} + + +void SAL_CALL +XInputStream_impl::seek( + sal_Int64 location ) + throw( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + if( location < 0 ) + throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); + if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +sal_Int64 SAL_CALL +XInputStream_impl::getPosition( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uPos; + if( osl::FileBase::E_None != m_aFile.getPos( uPos ) ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + return sal_Int64( uPos ); +} + +sal_Int64 SAL_CALL +XInputStream_impl::getLength( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uEndPos; + if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + else + return sal_Int64( uEndPos ); +} diff --git a/ucb/source/ucp/file/filinpstr.hxx b/ucb/source/ucp/file/filinpstr.hxx new file mode 100644 index 000000000000..cb0668c10c82 --- /dev/null +++ b/ucb/source/ucp/file/filinpstr.hxx @@ -0,0 +1,164 @@ + /************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILINPSTR_HXX_ +#define _FILINPSTR_HXX_ + +#include <rtl/ustring.hxx> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> + +#include "filrec.hxx" + +namespace fileaccess { + + // forward declaration + + class shell; + + + class XInputStream_impl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable + { + public: + + XInputStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock ); + + virtual ~XInputStream_impl(); + + /** + * Returns an error code as given by filerror.hxx + */ + + sal_Int32 SAL_CALL CtorSuccess(); + sal_Int32 SAL_CALL getMinorError(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + virtual sal_Int32 SAL_CALL + readBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + readSomeBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + skipBytes( + sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL + available( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + closeInput( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + seek( + sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getPosition( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getLength( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + private: + + shell* m_pMyShell; + com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Bool m_nIsOpen; + + sal_Bool m_bLock; + + ReconnectingFile m_aFile; + + sal_Int32 m_nErrorCode; + sal_Int32 m_nMinorErrorCode; + }; + + +} // end namespace XInputStream_impl + +#endif diff --git a/ucb/source/ucp/file/filinsreq.cxx b/ucb/source/ucp/file/filinsreq.cxx new file mode 100644 index 000000000000..586c9a6f3c85 --- /dev/null +++ b/ucb/source/ucp/file/filinsreq.cxx @@ -0,0 +1,224 @@ + /************************************************************************* + * + * 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" +#include "filinsreq.hxx" +#include "shell.hxx" +#include "filglob.hxx" +#include <com/sun/star/ucb/IOErrorCode.hpp> +#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + + + +using namespace cppu; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::task; +using namespace com::sun::star::ucb; +using namespace com::sun::star::beans; +using namespace fileaccess; + + + +void SAL_CALL +XInteractionSupplyNameImpl::acquire( void ) + throw() +{ + OWeakObject::acquire(); +} + + + +void SAL_CALL +XInteractionSupplyNameImpl::release( void ) + throw() +{ + OWeakObject::release(); +} + + + +Any SAL_CALL +XInteractionSupplyNameImpl::queryInterface( const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*, this ), + SAL_STATIC_CAST( XInteractionSupplyName*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + +XTYPEPROVIDER_IMPL_2( XInteractionSupplyNameImpl, + XTypeProvider, + XInteractionSupplyName ) + + + +void SAL_CALL +XInteractionAbortImpl::acquire( void ) + throw() +{ + OWeakObject::acquire(); +} + + + +void SAL_CALL +XInteractionAbortImpl::release( void ) + throw() +{ + OWeakObject::release(); +} + + + +Any SAL_CALL +XInteractionAbortImpl::queryInterface( const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*, this ), + SAL_STATIC_CAST( XInteractionAbort*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + +XTYPEPROVIDER_IMPL_2( XInteractionAbortImpl, + XTypeProvider, + XInteractionAbort ) + + + +XInteractionRequestImpl::XInteractionRequestImpl( + const rtl::OUString& aClashingName, + const Reference<XInterface>& xOrigin, + shell *pShell,sal_Int32 CommandId) + : p1( new XInteractionSupplyNameImpl ), + p2( new XInteractionAbortImpl ), + m_nErrorCode(0), + m_nMinorError(0), + m_aSeq( 2 ), + m_aClashingName(aClashingName), + m_xOrigin(xOrigin) +{ + if( pShell ) + pShell->retrieveError(CommandId,m_nErrorCode,m_nMinorError); + m_aSeq[0] = Reference<XInteractionContinuation>(p1); + m_aSeq[1] = Reference<XInteractionContinuation>(p2); +} + + +void SAL_CALL +XInteractionRequestImpl::acquire( void ) + throw() +{ + OWeakObject::acquire(); +} + + + +void SAL_CALL +XInteractionRequestImpl::release( void ) + throw() +{ + OWeakObject::release(); +} + + + +Any SAL_CALL +XInteractionRequestImpl::queryInterface( const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = + cppu::queryInterface( + rType, + SAL_STATIC_CAST( lang::XTypeProvider*, this ), + SAL_STATIC_CAST( XInteractionRequest*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + +XTYPEPROVIDER_IMPL_2( XInteractionRequestImpl, + XTypeProvider, + XInteractionRequest ) + + +Any SAL_CALL +XInteractionRequestImpl::getRequest() + throw(RuntimeException) +{ + Any aAny; + if(m_nErrorCode == TASKHANDLING_FOLDER_EXISTS_MKDIR) + { + NameClashException excep; + excep.Name = m_aClashingName; + excep.Classification = InteractionClassification_ERROR; + excep.Context = m_xOrigin; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "folder exists and overwritte forbidden")); + aAny <<= excep; + } + else if(m_nErrorCode == TASKHANDLING_INVALID_NAME_MKDIR) + { + InteractiveAugmentedIOException excep; + excep.Code = IOErrorCode_INVALID_CHARACTER; + PropertyValue prop; + prop.Name = rtl::OUString::createFromAscii("ResourceName"); + prop.Handle = -1; + prop.Value <<= m_aClashingName; + Sequence<Any> seq(1); + seq[0] <<= prop; + excep.Arguments = seq; + excep.Classification = InteractionClassification_ERROR; + excep.Context = m_xOrigin; + excep.Message = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "the name contained invalid characters")); + aAny <<= excep; + + } + return aAny; +} diff --git a/ucb/source/ucp/file/filinsreq.hxx b/ucb/source/ucp/file/filinsreq.hxx new file mode 100644 index 000000000000..bb78bd4c2973 --- /dev/null +++ b/ucb/source/ucp/file/filinsreq.hxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + + +#ifndef _FILINSREQ_HXX_ +#define _FILINSREQ_HXX_ + +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/ucb/XInteractionSupplyName.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> + + +namespace fileaccess { + + + class shell; + + + class XInteractionSupplyNameImpl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::ucb::XInteractionSupplyName + { + public: + + XInteractionSupplyNameImpl() + : m_bSelected(false) + { + } + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + virtual void SAL_CALL select() + throw (::com::sun::star::uno::RuntimeException) + { + m_bSelected = true; + } + + void SAL_CALL setName(const ::rtl::OUString& Name) + throw(::com::sun::star::uno::RuntimeException) + { + m_aNewName = Name; + } + + rtl::OUString getName() const + { + return m_aNewName; + } + + bool isSelected() const + { + return m_bSelected; + } + + private: + + bool m_bSelected; + rtl::OUString m_aNewName; + }; + + + + class XInteractionAbortImpl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::task::XInteractionAbort + { + public: + + XInteractionAbortImpl() + : m_bSelected(false) + { + } + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + virtual void SAL_CALL select() + throw (::com::sun::star::uno::RuntimeException) + { + m_bSelected = true; + } + + + bool isSelected() const + { + return m_bSelected; + } + + private: + + bool m_bSelected; + }; + + + + class XInteractionRequestImpl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::task::XInteractionRequest + { + public: + + XInteractionRequestImpl( + const rtl::OUString& aClashingName, + const com::sun::star::uno::Reference< + com::sun::star::uno::XInterface>& xOrigin, + shell* pShell, + sal_Int32 CommandId); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + ::com::sun::star::uno::Any SAL_CALL getRequest( ) + throw (::com::sun::star::uno::RuntimeException); + + com::sun::star::uno::Sequence< + com::sun::star::uno::Reference< + com::sun::star::task::XInteractionContinuation > > SAL_CALL + getContinuations( ) + throw (::com::sun::star::uno::RuntimeException) + { + return m_aSeq; + } + + bool aborted() const + { + return p2->isSelected(); + } + + rtl::OUString newName() const + { + if( p1->isSelected() ) + return p1->getName(); + else + return rtl::OUString(); + } + + private: + + XInteractionSupplyNameImpl* p1; + XInteractionAbortImpl* p2; + sal_Int32 m_nErrorCode,m_nMinorError; + + com::sun::star::uno::Sequence< + com::sun::star::uno::Reference< + com::sun::star::task::XInteractionContinuation > > m_aSeq; + + rtl::OUString m_aClashingName; + com::sun::star::uno::Reference< + com::sun::star::uno::XInterface> m_xOrigin; + }; + +} + + +#endif diff --git a/ucb/source/ucp/file/filnot.cxx b/ucb/source/ucp/file/filnot.cxx new file mode 100644 index 000000000000..0d2d5b4cb9b1 --- /dev/null +++ b/ucb/source/ucp/file/filnot.cxx @@ -0,0 +1,269 @@ +/************************************************************************* + * + * 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" +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/ContentAction.hpp> +#include <com/sun/star/beans/PropertySetInfoChange.hpp> +#include "filnot.hxx" +#include "filid.hxx" +#include "bc.hxx" +#include "prov.hxx" + + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + +ContentEventNotifier::ContentEventNotifier( shell* pMyShell, + const uno::Reference< XContent >& xCreatorContent, + const uno::Reference< XContentIdentifier >& xCreatorId, + const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners ) + : m_pMyShell( pMyShell ), + m_xCreatorContent( xCreatorContent ), + m_xCreatorId( xCreatorId ), + m_sListeners( sListeners ) +{ +} + + +ContentEventNotifier::ContentEventNotifier( shell* pMyShell, + const uno::Reference< XContent >& xCreatorContent, + const uno::Reference< XContentIdentifier >& xCreatorId, + const uno::Reference< XContentIdentifier >& xOldId, + const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners ) + : m_pMyShell( pMyShell ), + m_xCreatorContent( xCreatorContent ), + m_xCreatorId( xCreatorId ), + m_xOldId( xOldId ), + m_sListeners( sListeners ) +{ +} + + + +void ContentEventNotifier::notifyChildInserted( const rtl::OUString& aChildName ) +{ + FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,aChildName ); + uno::Reference< XContentIdentifier > xChildId( p ); + + uno::Reference< XContent > xChildContent = m_pMyShell->m_pProvider->queryContent( xChildId ); + + ContentEvent aEvt( m_xCreatorContent, + ContentAction::INSERTED, + xChildContent, + m_xCreatorId ); + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->contentEvent( aEvt ); + } +} + +void ContentEventNotifier::notifyDeleted( void ) +{ + + ContentEvent aEvt( m_xCreatorContent, + ContentAction::DELETED, + m_xCreatorContent, + m_xCreatorId ); + + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->contentEvent( aEvt ); + } +} + + + +void ContentEventNotifier::notifyRemoved( const rtl::OUString& aChildName ) +{ + FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,aChildName ); + uno::Reference< XContentIdentifier > xChildId( p ); + + BaseContent* pp = new BaseContent( m_pMyShell,xChildId,aChildName ); + { + osl::MutexGuard aGuard( pp->m_aMutex ); + pp->m_nState |= BaseContent::Deleted; + } + + uno::Reference< XContent > xDeletedContent( pp ); + + + ContentEvent aEvt( m_xCreatorContent, + ContentAction::REMOVED, + xDeletedContent, + m_xCreatorId ); + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->contentEvent( aEvt ); + } +} + +void ContentEventNotifier::notifyExchanged() +{ + ContentEvent aEvt( m_xCreatorContent, + ContentAction::EXCHANGED, + m_xCreatorContent, + m_xOldId ); + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< XContentEventListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->contentEvent( aEvt ); + } +} + +/*********************************************************************************/ +/* */ +/* PropertySetInfoChangeNotifier */ +/* */ +/*********************************************************************************/ + + +PropertySetInfoChangeNotifier::PropertySetInfoChangeNotifier( + shell* pMyShell, + const uno::Reference< XContent >& xCreatorContent, + const uno::Reference< XContentIdentifier >& xCreatorId, + const uno::Sequence< uno::Reference< uno::XInterface > >& sListeners ) + : m_pMyShell( pMyShell ), + m_xCreatorContent( xCreatorContent ), + m_xCreatorId( xCreatorId ), + m_sListeners( sListeners ) +{ + +} + + +void SAL_CALL +PropertySetInfoChangeNotifier::notifyPropertyAdded( const rtl::OUString & aPropertyName ) +{ + beans::PropertySetInfoChangeEvent aEvt( m_xCreatorContent, + aPropertyName, + -1, + beans::PropertySetInfoChange::PROPERTY_INSERTED ); + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< beans::XPropertySetInfoChangeListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->propertySetInfoChange( aEvt ); + } +} + + +void SAL_CALL +PropertySetInfoChangeNotifier::notifyPropertyRemoved( const rtl::OUString & aPropertyName ) +{ + beans::PropertySetInfoChangeEvent aEvt( m_xCreatorContent, + aPropertyName, + -1, + beans::PropertySetInfoChange::PROPERTY_REMOVED ); + + for( sal_Int32 i = 0; i < m_sListeners.getLength(); ++i ) + { + uno::Reference< beans::XPropertySetInfoChangeListener > ref( m_sListeners[i],uno::UNO_QUERY ); + if( ref.is() ) + ref->propertySetInfoChange( aEvt ); + } +} + + +/*********************************************************************************/ +/* */ +/* PropertySetInfoChangeNotifier */ +/* */ +/*********************************************************************************/ + + +PropertyChangeNotifier::PropertyChangeNotifier( + shell* pMyShell, + const com::sun::star::uno::Reference< XContent >& xCreatorContent, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId, + ListenerMap* pListeners ) + : m_pMyShell( pMyShell ), + m_xCreatorContent( xCreatorContent ), + m_xCreatorId( xCreatorId ), + m_pListeners( pListeners ) +{ +} + + +PropertyChangeNotifier::~PropertyChangeNotifier() +{ + delete m_pListeners; +} + + +void PropertyChangeNotifier::notifyPropertyChanged( + uno::Sequence< beans::PropertyChangeEvent > Changes ) +{ + sal_Int32 j; + + for( j = 0; j < Changes.getLength(); ++j ) + Changes[j].Source = m_xCreatorContent; + + // notify listeners for all Events + + uno::Sequence< uno::Reference< uno::XInterface > > seqList = (*m_pListeners)[ rtl::OUString() ]; + for( j = 0; j < seqList.getLength(); ++j ) + { + uno::Reference< beans::XPropertiesChangeListener > aListener( seqList[j],uno::UNO_QUERY ); + if( aListener.is() ) + { + aListener->propertiesChange( Changes ); + } + } + + uno::Sequence< beans::PropertyChangeEvent > seq(1); + for( j = 0; j < Changes.getLength(); ++j ) + { + seq[0] = Changes[j]; + seqList = (*m_pListeners)[ seq[0].PropertyName ]; + + for( sal_Int32 i = 0; i < seqList.getLength(); ++i ) + { + uno::Reference< beans::XPropertiesChangeListener > aListener( seqList[j],uno::UNO_QUERY ); + if( aListener.is() ) + { + aListener->propertiesChange( seq ); + } + } + } +} diff --git a/ucb/source/ucp/file/filnot.hxx b/ucb/source/ucp/file/filnot.hxx new file mode 100644 index 000000000000..24f982372328 --- /dev/null +++ b/ucb/source/ucp/file/filnot.hxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILNOT_HXX_ +#define _FILNOT_HXX_ + +#include <hash_map> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include "filglob.hxx" + + +namespace fileaccess { + + class shell; + class BaseContent; + + class ContentEventNotifier + { + private: + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xOldId; + com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > > m_sListeners; + public: + + ContentEventNotifier( + shell* pMyShell, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId, + const com::sun::star::uno::Sequence< + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners ); + + ContentEventNotifier( + shell* pMyShell, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xOldId, + const com::sun::star::uno::Sequence< + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners ); + + void notifyChildInserted( const rtl::OUString& aChildName ); + void notifyDeleted( void ); + void notifyRemoved( const rtl::OUString& aChildName ); + void notifyExchanged( ); + }; + + + class PropertySetInfoChangeNotifier + { + private: + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId; + com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > > m_sListeners; + public: + PropertySetInfoChangeNotifier( + shell* pMyShell, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId, + const com::sun::star::uno::Sequence< + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >& sListeners ); + + void SAL_CALL notifyPropertyAdded( const rtl::OUString & aPropertyName ); + void SAL_CALL notifyPropertyRemoved( const rtl::OUString & aPropertyName ); + }; + + + typedef std::hash_map< rtl::OUString, + com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::uno::XInterface > >, + hashOUString, + equalOUString > ListenerMap; + + class PropertyChangeNotifier + { + private: + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContent > m_xCreatorContent; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > m_xCreatorId; + ListenerMap* m_pListeners; + public: + PropertyChangeNotifier( + shell* pMyShell, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContent >& xCreatorContent, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& xCreatorId, + ListenerMap* pListeners ); + + ~PropertyChangeNotifier(); + + void notifyPropertyChanged( + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyChangeEvent > seqChanged ); + }; + + + class Notifier + { + public: + // Side effect of this function is the change of the name + virtual ContentEventNotifier* cEXC( const rtl::OUString aNewName ) = 0; + // Side effect is the change of the state of the object to "deleted". + virtual ContentEventNotifier* cDEL( void ) = 0; + virtual ContentEventNotifier* cCEL( void ) = 0; + virtual PropertySetInfoChangeNotifier* cPSL( void ) = 0; + virtual PropertyChangeNotifier* cPCL( void ) = 0; + virtual rtl::OUString getKey( void ) = 0; + }; + + +} // end namespace fileaccess + +#endif diff --git a/ucb/source/ucp/file/filprp.cxx b/ucb/source/ucp/file/filprp.cxx new file mode 100644 index 000000000000..86c494cbd710 --- /dev/null +++ b/ucb/source/ucp/file/filprp.cxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * 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" +#include "shell.hxx" +#include "prov.hxx" +#include "filprp.hxx" + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; + + +#include "filinl.hxx" + + +XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath ) + : m_pMyShell( pMyShell ), + m_xProvider( pMyShell->m_pProvider ), + m_count( 0 ), + m_seq( 0 ) +{ + m_pMyShell->m_pProvider->acquire(); + + shell::ContentMap::iterator it = m_pMyShell->m_aContent.find( aUnqPath ); + + shell::PropertySet& properties = *(it->second.properties); + shell::PropertySet::iterator it1 = properties.begin(); + + m_seq.realloc( properties.size() ); + + while( it1 != properties.end() ) + { + m_seq[ m_count++ ] = beans::Property( it1->getPropertyName(), + it1->getHandle(), + it1->getType(), + it1->getAttributes() ); + ++it1; + } +} + + +XPropertySetInfo_impl::XPropertySetInfo_impl( shell* pMyShell,const Sequence< beans::Property >& seq ) + : m_pMyShell( pMyShell ), + m_count( seq.getLength() ), + m_seq( seq ) +{ + m_pMyShell->m_pProvider->acquire(); +} + + +XPropertySetInfo_impl::~XPropertySetInfo_impl() +{ + m_pMyShell->m_pProvider->release(); +} + + +void SAL_CALL +XPropertySetInfo_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XPropertySetInfo_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +XTYPEPROVIDER_IMPL_2( XPropertySetInfo_impl, + lang::XTypeProvider, + beans::XPropertySetInfo ) + + +Any SAL_CALL +XPropertySetInfo_impl::queryInterface( + const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*,this), + SAL_STATIC_CAST( beans::XPropertySetInfo*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +beans::Property SAL_CALL +XPropertySetInfo_impl::getPropertyByName( + const rtl::OUString& aName ) + throw( beans::UnknownPropertyException, + RuntimeException) +{ + for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) + if( m_seq[i].Name == aName ) return m_seq[i]; + + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + + +Sequence< beans::Property > SAL_CALL +XPropertySetInfo_impl::getProperties( + void ) + throw( RuntimeException ) +{ + return m_seq; +} + + +sal_Bool SAL_CALL +XPropertySetInfo_impl::hasPropertyByName( + const rtl::OUString& aName ) + throw( RuntimeException ) +{ + for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) + if( m_seq[i].Name == aName ) return true; + return false; +} diff --git a/ucb/source/ucp/file/filprp.hxx b/ucb/source/ucp/file/filprp.hxx new file mode 100644 index 000000000000..24d1bf324339 --- /dev/null +++ b/ucb/source/ucp/file/filprp.hxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILPRP_HXX_ +#define _FILPRP_HXX_ + +#include <ucbhelper/macros.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> + + +namespace fileaccess { + + class shell; + + class XPropertySetInfo_impl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::beans::XPropertySetInfo + { + public: + XPropertySetInfo_impl( shell* pMyShell,const rtl::OUString& aUnqPath ); + XPropertySetInfo_impl( shell* pMyShell,const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq ); + + virtual ~XPropertySetInfo_impl(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property > SAL_CALL + getProperties( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::beans::Property SAL_CALL + getPropertyByName( + const rtl::OUString& aName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + hasPropertyByName( const rtl::OUString& Name ) + throw( com::sun::star::uno::RuntimeException ); + + private: + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Int32 m_count; + com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_seq; + }; +} + +#endif + diff --git a/ucb/source/ucp/file/filrec.cxx b/ucb/source/ucp/file/filrec.cxx new file mode 100644 index 000000000000..c0e9b02ddb70 --- /dev/null +++ b/ucb/source/ucp/file/filrec.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * 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" + +#include "filrec.hxx" + +namespace fileaccess { + +void ReconnectingFile::disconnect() +{ + m_aFile.close(); + m_bDisconnect = sal_True; +} + +sal_Bool ReconnectingFile::reconnect() +{ + sal_Bool bResult = sal_False; + if ( m_bFlagsSet ) + { + disconnect(); + if ( m_aFile.open( m_nFlags ) == ::osl::FileBase::E_None + || m_aFile.open( OpenFlag_Read ) == ::osl::FileBase::E_None ) + { + m_bDisconnect = sal_False; + bResult = sal_True; + } + } + + return bResult; +} + +::osl::FileBase::RC ReconnectingFile::open( sal_uInt32 uFlags ) +{ + ::osl::FileBase::RC nResult = m_aFile.open( uFlags ); + if ( nResult == ::osl::FileBase::E_None ) + { + if ( uFlags & OpenFlag_Create ) + m_nFlags = (uFlags & ( ~OpenFlag_Create )) | OpenFlag_Write; + else + m_nFlags = uFlags; + + m_bFlagsSet = sal_True; + } + + return nResult; +} + +::osl::FileBase::RC ReconnectingFile::close() +{ + m_nFlags = 0; + m_bFlagsSet = sal_False; + m_bDisconnect = sal_False; + + return m_aFile.close(); +} + +::osl::FileBase::RC ReconnectingFile::setPos( sal_uInt32 uHow, sal_Int64 uPos ) +{ + ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK; + + if ( uHow == Pos_Absolut && uPos > 0 ) + { + if ( m_bDisconnect ) + { + if ( reconnect() ) + nRes = m_aFile.setPos( uHow, uPos ); + } + else + { + // E_INVAL error code means in this case that + // the file handler is invalid + nRes = m_aFile.setPos( uHow, uPos ); + if ( ( nRes == ::osl::FileBase::E_NETWORK + || nRes == ::osl::FileBase::E_INVAL ) + && reconnect() ) + nRes = m_aFile.setPos( uHow, uPos ); + } + } + else + { + if ( !m_bDisconnect ) + nRes = m_aFile.setPos( uHow, uPos ); + } + + return nRes; +} + +::osl::FileBase::RC ReconnectingFile::getPos( sal_uInt64& uPos ) +{ + if ( m_bDisconnect ) + return ::osl::FileBase::E_NETWORK; + + return m_aFile.getPos( uPos ); +} + +::osl::FileBase::RC ReconnectingFile::setSize( sal_uInt64 uSize ) +{ + ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK; + + if ( uSize == 0 ) + { + if ( m_bDisconnect ) + { + if ( reconnect() ) + nRes = m_aFile.setSize( uSize ); + } + else + { + // E_INVAL error code means in this case that + // the file handler is invalid + nRes = m_aFile.setSize( uSize ); + if ( ( nRes == ::osl::FileBase::E_NETWORK + || nRes == ::osl::FileBase::E_INVAL ) + && reconnect() ) + nRes = m_aFile.setSize( uSize ); + } + } + else + { + if ( !m_bDisconnect ) + nRes = m_aFile.setSize( uSize ); + } + + return nRes; +} + +::osl::FileBase::RC ReconnectingFile::getSize( sal_uInt64 &rSize ) +{ + ::osl::FileBase::RC nRes = ::osl::FileBase::E_NETWORK; + + if ( !m_bDisconnect ) + nRes = m_aFile.getSize( rSize ); + + // E_INVAL error code means in this case that + // the file handler is invalid + if ( ( nRes == ::osl::FileBase::E_NETWORK + || nRes == ::osl::FileBase::E_INVAL ) + && reconnect() ) + { + nRes = m_aFile.getSize( rSize ); + + // the repairing should be disconnected, since the position might be wrong + // but the result should be retrieved + disconnect(); + } + + return nRes; +} + +::osl::FileBase::RC ReconnectingFile::read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead ) +{ + if ( m_bDisconnect ) + return ::osl::FileBase::E_NETWORK; + + return m_aFile.read( pBuffer, uBytesRequested, rBytesRead ); +} + +::osl::FileBase::RC ReconnectingFile::write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten) +{ + if ( m_bDisconnect ) + return ::osl::FileBase::E_NETWORK; + + return m_aFile.write( pBuffer, uBytesToWrite, rBytesWritten ); +} + +::osl::FileBase::RC ReconnectingFile::sync() const +{ + if ( m_bDisconnect ) + return ::osl::FileBase::E_NETWORK; + + return m_aFile.sync(); +} + +} // namespace fileaccess + diff --git a/ucb/source/ucp/file/filrec.hxx b/ucb/source/ucp/file/filrec.hxx new file mode 100644 index 000000000000..90168da2c9a5 --- /dev/null +++ b/ucb/source/ucp/file/filrec.hxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _FILREC_HXX_ +#define _FILREC_HXX_ + +#include <osl/file.hxx> + +namespace fileaccess { + +class ReconnectingFile +{ + ::osl::File m_aFile; + + sal_uInt32 m_nFlags; + sal_Bool m_bFlagsSet; + + sal_Bool m_bDisconnect; + + ReconnectingFile( ReconnectingFile& ); + + ReconnectingFile& operator=( ReconnectingFile& ); + +public: + + ReconnectingFile( const ::rtl::OUString& aFileURL ) + : m_aFile( aFileURL ) + , m_nFlags( 0 ) + , m_bFlagsSet( sal_False ) + , m_bDisconnect( sal_False ) + {} + + ~ReconnectingFile() + { + close(); + } + + void disconnect(); + sal_Bool reconnect(); + + ::osl::FileBase::RC open( sal_uInt32 uFlags ); + + ::osl::FileBase::RC close(); + + ::osl::FileBase::RC setPos( sal_uInt32 uHow, sal_Int64 uPos ); + + ::osl::FileBase::RC getPos( sal_uInt64& uPos ); + + ::osl::FileBase::RC setSize( sal_uInt64 uSize ); + + ::osl::FileBase::RC getSize( sal_uInt64 &rSize ); + + ::osl::FileBase::RC read( void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64& rBytesRead ); + + ::osl::FileBase::RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten); + + ::osl::FileBase::RC sync() const; +}; + +} // namespace fileaccess +#endif // _FILREC_HXX_ + diff --git a/ucb/source/ucp/file/filrow.cxx b/ucb/source/ucp/file/filrow.cxx new file mode 100644 index 000000000000..5b135358cf31 --- /dev/null +++ b/ucb/source/ucp/file/filrow.cxx @@ -0,0 +1,429 @@ +/************************************************************************* + * + * 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" +#include "filrow.hxx" +#include "shell.hxx" +#include "prov.hxx" + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +//using namespace com::sun::star::ucb; + + +// Funktion for TypeConverting + + +template< class _type_ > +sal_Bool convert( shell* pShell, + uno::Reference< script::XTypeConverter >& xConverter, + uno::Any& rValue, + _type_& aReturn ) +{ + // Try first without converting + sal_Bool no_success = ! ( rValue >>= aReturn ); + + if ( no_success ) + { + if( ! xConverter.is() ) + { + xConverter = uno::Reference< script::XTypeConverter >( + pShell->m_xMultiServiceFactory->createInstance( + rtl::OUString::createFromAscii( "com.sun.star.script.Converter" ) ),uno::UNO_QUERY ); + +/* DBG_ASSERT( m_xTypeConverter.is(), + "PropertyValueSet::getTypeConverter() - " + "Service 'com.sun.star.script.Converter' n/a!" );*/ + } + + try + { + if( rValue.hasValue() ) + { + uno::Any aConvertedValue + = xConverter->convertTo( rValue,getCppuType( static_cast< const _type_* >(0) ) ); + no_success = ! ( aConvertedValue >>= aReturn ); + } + else + no_success = sal_True; + } + catch ( lang::IllegalArgumentException ) + { + no_success = sal_True; + } + catch ( script::CannotConvertException ) + { + no_success = sal_True; + } + } + return no_success; +} + + +XRow_impl::XRow_impl( shell* pMyShell,const uno::Sequence< uno::Any >& seq ) + : m_aValueMap( seq ), + m_pMyShell( pMyShell ), + m_xProvider( pMyShell->m_pProvider ), + m_xTypeConverter( 0 ) +{ +} + +XRow_impl::~XRow_impl() +{ +} + + +void SAL_CALL +XRow_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + +void SAL_CALL +XRow_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +uno::Any SAL_CALL +XRow_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*,this), + SAL_STATIC_CAST( sdbc::XRow*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +XTYPEPROVIDER_IMPL_2( XRow_impl, + lang::XTypeProvider, + sdbc::XRow ) + + +sal_Bool SAL_CALL +XRow_impl::wasNull( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + return m_nWasNull; +} + + +rtl::OUString SAL_CALL +XRow_impl::getString( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + rtl::OUString Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<rtl::OUString>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +sal_Bool SAL_CALL +XRow_impl::getBoolean( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + sal_Bool Value( false ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<sal_Bool>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + + +sal_Int8 SAL_CALL +XRow_impl::getByte( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + sal_Int8 Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<sal_Int8>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +sal_Int16 SAL_CALL +XRow_impl::getShort( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + sal_Int16 Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<sal_Int16>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + + +sal_Int32 SAL_CALL +XRow_impl::getInt( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + sal_Int32 Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<sal_Int32>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +sal_Int64 SAL_CALL +XRow_impl::getLong( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + sal_Int64 Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<sal_Int64>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +float SAL_CALL +XRow_impl::getFloat( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + float Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<float>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +double SAL_CALL +XRow_impl::getDouble( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + double Value( 0 ); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<double>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +uno::Sequence< sal_Int8 > SAL_CALL +XRow_impl::getBytes( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Sequence< sal_Int8 > Value(0); + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Sequence< sal_Int8 > >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +util::Date SAL_CALL +XRow_impl::getDate( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + util::Date Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<util::Date>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +util::Time SAL_CALL +XRow_impl::getTime( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + util::Time Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<util::Time>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +util::DateTime SAL_CALL +XRow_impl::getTimestamp( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + util::DateTime Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<util::DateTime>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + + +uno::Reference< io::XInputStream > SAL_CALL +XRow_impl::getBinaryStream( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< io::XInputStream > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Reference< io::XInputStream > >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + + +uno::Reference< io::XInputStream > SAL_CALL +XRow_impl::getCharacterStream( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< io::XInputStream > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert< uno::Reference< io::XInputStream> >( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + + +uno::Any SAL_CALL +XRow_impl::getObject( + sal_Int32 columnIndex, + const uno::Reference< container::XNameAccess >& ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Any Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Any>( m_pMyShell,m_xTypeConverter,m_aValueMap[ --columnIndex ],Value ); + return Value; +} + +uno::Reference< sdbc::XRef > SAL_CALL +XRow_impl::getRef( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< sdbc::XRef > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Reference< sdbc::XRef> >( m_pMyShell, + m_xTypeConverter, + m_aValueMap[ --columnIndex ], + Value ); + return Value; +} + +uno::Reference< sdbc::XBlob > SAL_CALL +XRow_impl::getBlob( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< sdbc::XBlob > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Reference< sdbc::XBlob> >( m_pMyShell, + m_xTypeConverter, + m_aValueMap[ --columnIndex ], + Value ); + return Value; +} + +uno::Reference< sdbc::XClob > SAL_CALL +XRow_impl::getClob( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< sdbc::XClob > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Reference< sdbc::XClob> >( m_pMyShell, + m_xTypeConverter, + m_aValueMap[ --columnIndex ], + Value ); + return Value; +} + + +uno::Reference< sdbc::XArray > SAL_CALL +XRow_impl::getArray( + sal_Int32 columnIndex ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( columnIndex < 1 || columnIndex > m_aValueMap.getLength() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + uno::Reference< sdbc::XArray > Value; + osl::MutexGuard aGuard( m_aMutex ); + m_nWasNull = ::convert<uno::Reference< sdbc::XArray> >( m_pMyShell, + m_xTypeConverter, + m_aValueMap[ --columnIndex ], + Value ); + return Value; +} diff --git a/ucb/source/ucp/file/filrow.hxx b/ucb/source/ucp/file/filrow.hxx new file mode 100644 index 000000000000..bc8954da3510 --- /dev/null +++ b/ucb/source/ucp/file/filrow.hxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILROW_HXX_ +#define _FILROW_HXX_ + +#include <ucbhelper/macros.hxx> + +#include "osl/mutex.hxx" +#include <cppuhelper/weak.hxx> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> + +namespace fileaccess { + + class shell; + + class XRow_impl: + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::sdbc::XRow + { + public: + XRow_impl( shell* pShell,const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& __m_aValueMap ); + ~XRow_impl(); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + virtual sal_Bool SAL_CALL + wasNull( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL + getString( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + getBoolean( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int8 SAL_CALL + getByte( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int16 SAL_CALL + getShort( + sal_Int32 columnIndex ) + throw( + com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL + getInt( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getLong( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ); + + virtual float SAL_CALL + getFloat( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual double SAL_CALL + getDouble( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getBytes( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::util::Date SAL_CALL + getDate( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::util::Time SAL_CALL + getTime( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::util::DateTime SAL_CALL + getTimestamp( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getBinaryStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getCharacterStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Any SAL_CALL + getObject( + sal_Int32 columnIndex, + const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL + getRef( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL + getBlob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL + getClob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL + getArray( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + private: + osl::Mutex m_aMutex; + com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_aValueMap; + sal_Bool m_nWasNull; + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter > m_xTypeConverter; + }; + +} // end namespace fileaccess + +#endif diff --git a/ucb/source/ucp/file/filrset.cxx b/ucb/source/ucp/file/filrset.cxx new file mode 100644 index 000000000000..5dcdd8445556 --- /dev/null +++ b/ucb/source/ucp/file/filrset.cxx @@ -0,0 +1,936 @@ +/************************************************************************* + * + * 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" +#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp> +#include "filid.hxx" +#include "shell.hxx" +#include "filprp.hxx" +#include "filrset.hxx" +#include <com/sun/star/ucb/OpenMode.hpp> +#include "prov.hxx" +#include <com/sun/star/uno/Reference.h> + +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/ucb/ListActionType.hpp> +#include <com/sun/star/ucb/XSourceInitialization.hpp> +#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp> +#include <ucbhelper/resultsetmetadata.hxx> + +using namespace fileaccess; +using namespace com::sun::star; + +XResultSet_impl::XResultSet_impl( + shell* pMyShell, + const rtl::OUString& aUnqPath, + sal_Int32 OpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort ) + : m_pMyShell( pMyShell ), + m_xProvider( pMyShell->m_pProvider ), + m_nRow( -1 ), + m_nOpenMode( OpenMode ), + m_bRowCountFinal( false ), + m_aBaseDirectory( aUnqPath ), + m_aFolder( aUnqPath ), + m_sProperty( seq ), + m_sSortingInfo( seqSort ), + m_pDisposeEventListeners( 0 ), + m_pRowCountListeners( 0 ), + m_pIsFinalListeners( 0 ), + m_bStatic( false ), + m_nErrorCode( TASKHANDLER_NO_ERROR ), + m_nMinorErrorCode( TASKHANDLER_NO_ERROR ) +{ + osl::FileBase::RC err = m_aFolder.open(); + if( err != osl::FileBase::E_None ) + { + m_nIsOpen = false; + m_aFolder.close(); + + m_nErrorCode = TASKHANDLING_OPEN_FOR_DIRECTORYLISTING; + m_nMinorErrorCode = err; + } + else + m_nIsOpen = true; + + m_pMyShell->registerNotifier( m_aBaseDirectory,this ); +} + + +XResultSet_impl::~XResultSet_impl() +{ + m_pMyShell->deregisterNotifier( m_aBaseDirectory,this ); + + if( m_nIsOpen ) + m_aFolder.close(); + + delete m_pDisposeEventListeners; + delete m_pRowCountListeners; + delete m_pIsFinalListeners; +} + + + +sal_Int32 SAL_CALL XResultSet_impl::CtorSuccess() +{ + return m_nErrorCode; +} + + + +sal_Int32 SAL_CALL XResultSet_impl::getMinorError() +{ + return m_nMinorErrorCode; +} + + +void SAL_CALL +XResultSet_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XResultSet_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +uno::Any SAL_CALL +XResultSet_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( + rType, + SAL_STATIC_CAST( lang::XComponent*, this), + SAL_STATIC_CAST( lang::XTypeProvider*, this), + SAL_STATIC_CAST( lang::XEventListener*, this), + SAL_STATIC_CAST( sdbc::XRow*, this), + SAL_STATIC_CAST( sdbc::XResultSet*, this), + SAL_STATIC_CAST( sdbc::XCloseable*, this), + SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this), + SAL_STATIC_CAST( beans::XPropertySet*, this ), + SAL_STATIC_CAST( ucb::XContentAccess*, this), + SAL_STATIC_CAST( ucb::XDynamicResultSet*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL +XResultSet_impl::disposing( const lang::EventObject& ) + throw( uno::RuntimeException ) +{ + // To do, but what +} + + +XTYPEPROVIDER_IMPL_10( XResultSet_impl, + lang::XTypeProvider, + lang::XTypeProvider, + lang::XEventListener, + sdbc::XRow, + sdbc::XResultSet, + XDynamicResultSet, + sdbc::XCloseable, + sdbc::XResultSetMetaDataSupplier, + beans::XPropertySet, + ucb::XContentAccess ) + + +void SAL_CALL +XResultSet_impl::addEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pDisposeEventListeners ) + m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +XResultSet_impl::removeEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); +} + + + +void SAL_CALL +XResultSet_impl::dispose() + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + lang::EventObject aEvt; + aEvt.Source = static_cast< lang::XComponent * >( this ); + + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + { + m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + if( m_pRowCountListeners && m_pRowCountListeners->getLength() ) + { + m_pRowCountListeners->disposeAndClear( aEvt ); + } + if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() ) + { + m_pIsFinalListeners->disposeAndClear( aEvt ); + } +} + + + +void XResultSet_impl::rowCountChanged() +{ + sal_Int32 aOldValue,aNewValue; + uno::Sequence< uno::Reference< uno::XInterface > > seq; + { + osl::MutexGuard aGuard( m_aMutex ); + if( m_pRowCountListeners ) + seq = m_pRowCountListeners->getElements(); + aNewValue = m_aItems.size(); + aOldValue = aNewValue-1; + } + beans::PropertyChangeEvent aEv; + aEv.PropertyName = rtl::OUString::createFromAscii( "RowCount" ); + aEv.Further = false; + aEv.PropertyHandle = -1; + aEv.OldValue <<= aOldValue; + aEv.NewValue <<= aNewValue; + for( sal_Int32 i = 0; i < seq.getLength(); ++i ) + { + uno::Reference< beans::XPropertyChangeListener > listener( + seq[i], uno::UNO_QUERY ); + if( listener.is() ) + listener->propertyChange( aEv ); + } +} + + +void XResultSet_impl::isFinalChanged() +{ + uno::Sequence< uno::Reference< XInterface > > seq; + { + osl::MutexGuard aGuard( m_aMutex ); + if( m_pIsFinalListeners ) + seq = m_pIsFinalListeners->getElements(); + m_bRowCountFinal = true; + } + beans::PropertyChangeEvent aEv; + aEv.PropertyName = rtl::OUString::createFromAscii( "IsRowCountFinal" ); + aEv.Further = false; + aEv.PropertyHandle = -1; + sal_Bool fval = false; + sal_Bool tval = true; + aEv.OldValue <<= fval; + aEv.NewValue <<= tval; + for( sal_Int32 i = 0; i < seq.getLength(); ++i ) + { + uno::Reference< beans::XPropertyChangeListener > listener( + seq[i], uno::UNO_QUERY ); + if( listener.is() ) + listener->propertyChange( aEv ); + } +} + + +sal_Bool SAL_CALL +XResultSet_impl::OneMore( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + if( ! m_nIsOpen ) + return false; + + osl::FileBase::RC err; + sal_Bool IsRegular; + rtl::OUString aUnqPath; + osl::DirectoryItem m_aDirIte; + uno::Reference< sdbc::XRow > aRow; + + while( true ) + { + err = m_aFolder.getNextItem( m_aDirIte ); + + if( err == osl::FileBase::E_NOENT || err == osl::FileBase::E_INVAL ) + { + m_aFolder.close(); + isFinalChanged(); + return ( m_nIsOpen = false ); + } + else if( err == osl::FileBase::E_None ) + { + aRow = m_pMyShell->getv( + this, m_sProperty, m_aDirIte, aUnqPath, IsRegular ); + + if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && IsRegular ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_aItems.push_back( aRow ); + m_aIdents.push_back( + uno::Reference< ucb::XContentIdentifier >() ); + m_aUnqPath.push_back( aUnqPath ); + rowCountChanged(); + return true; + + } + else if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && ! IsRegular ) + { + continue; + } + else if( m_nOpenMode == ucb::OpenMode::FOLDERS && ! IsRegular ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_aItems.push_back( aRow ); + m_aIdents.push_back( + uno::Reference< ucb::XContentIdentifier >() ); + m_aUnqPath.push_back( aUnqPath ); + rowCountChanged(); + return true; + } + else if( m_nOpenMode == ucb::OpenMode::FOLDERS && IsRegular ) + { + continue; + } + else + { + osl::MutexGuard aGuard( m_aMutex ); + m_aItems.push_back( aRow ); + m_aIdents.push_back( + uno::Reference< ucb::XContentIdentifier >() ); + m_aUnqPath.push_back( aUnqPath ); + rowCountChanged(); + return true; + } + } + else // error fetching anything + { + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + } + } +} + + + + + +sal_Bool SAL_CALL +XResultSet_impl::next( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + sal_Bool test; + if( ++m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) test = true; + else + test = OneMore(); + return test; +} + + +sal_Bool SAL_CALL +XResultSet_impl::isBeforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == -1; +} + + +sal_Bool SAL_CALL +XResultSet_impl::isAfterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()); // Cannot happen, if m_aFolder.isOpen() +} + + +sal_Bool SAL_CALL +XResultSet_impl::isFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == 0; +} + + +sal_Bool SAL_CALL +XResultSet_impl::isLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( m_nRow == sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1 ) + return ! OneMore(); + else + return false; +} + + +void SAL_CALL +XResultSet_impl::beforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; +} + + +void SAL_CALL +XResultSet_impl::afterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()); + while( OneMore() ) + ++m_nRow; +} + + +sal_Bool SAL_CALL +XResultSet_impl::first( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; + return next(); +} + + +sal_Bool SAL_CALL +XResultSet_impl::last( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1; + while( OneMore() ) + ++m_nRow; + return true; +} + + +sal_Int32 SAL_CALL +XResultSet_impl::getRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + // Test, whether behind last row + if( -1 == m_nRow || m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return 0; + else + return m_nRow+1; +} + + + +sal_Bool SAL_CALL XResultSet_impl::absolute( sal_Int32 row ) + throw( sdbc::SQLException, uno::RuntimeException) +{ + if( row >= 0 ) + { + m_nRow = row - 1; + if( row >= sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + while( row-- && OneMore() ) + ; + } + else + { + last(); + m_nRow += ( row + 1 ); + if( m_nRow < -1 ) + m_nRow = -1; + } + + return 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()); +} + + + + +sal_Bool SAL_CALL +XResultSet_impl::relative( + sal_Int32 row ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( isAfterLast() || isBeforeFirst() ) + throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() ); + if( row > 0 ) + while( row-- ) next(); + else if( row < 0 ) + while( row++ && m_nRow > - 1 ) previous(); + + return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()); +} + + + +sal_Bool SAL_CALL +XResultSet_impl::previous( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( m_nRow > sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()); // Correct Handling of afterLast + if( 0 <= m_nRow ) -- m_nRow; + + return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()); +} + + +void SAL_CALL +XResultSet_impl::refreshRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + // get the row from the filesystem + return; +} + + +sal_Bool SAL_CALL +XResultSet_impl::rowUpdated( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +XResultSet_impl::rowInserted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +XResultSet_impl::rowDeleted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + + +uno::Reference< uno::XInterface > SAL_CALL +XResultSet_impl::getStatement( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return uno::Reference< uno::XInterface >(); +} + + +// XCloseable + +void SAL_CALL +XResultSet_impl::close( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( m_nIsOpen ) + { + m_aFolder.close(); + isFinalChanged(); + osl::MutexGuard aGuard( m_aMutex ); + m_nIsOpen = false; + } +} + + + +rtl::OUString SAL_CALL +XResultSet_impl::queryContentIdentifierString( + void ) + throw( uno::RuntimeException ) +{ + uno::Reference< ucb::XContentIdentifier > xContentId + = queryContentIdentifier(); + + if( xContentId.is() ) + return xContentId->getContentIdentifier(); + else + return rtl::OUString(); +} + + +uno::Reference< ucb::XContentIdentifier > SAL_CALL +XResultSet_impl::queryContentIdentifier( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + { + if( ! m_aIdents[m_nRow].is() ) + { + FileContentIdentifier* p + = new FileContentIdentifier( m_pMyShell, + m_aUnqPath[ m_nRow ] ); + m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >(p); + } + return m_aIdents[m_nRow]; + } + return uno::Reference< ucb::XContentIdentifier >(); +} + + +uno::Reference< ucb::XContent > SAL_CALL +XResultSet_impl::queryContent( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_pMyShell->m_pProvider->queryContent( queryContentIdentifier() ); + else + return uno::Reference< ucb::XContent >(); +} + + +// XDynamicResultSet + + +// virtual +uno::Reference< sdbc::XResultSet > SAL_CALL +XResultSet_impl::getStaticResultSet() + throw( ucb::ListenerAlreadySetException, + uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_xListener.is() ) + throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + return uno::Reference< sdbc::XResultSet >( this ); +} + +//========================================================================= +// virtual +void SAL_CALL +XResultSet_impl::setListener( + const uno::Reference< ucb::XDynamicResultSetListener >& Listener ) + throw( ucb::ListenerAlreadySetException, + uno::RuntimeException ) +{ + osl::ClearableMutexGuard aGuard( m_aMutex ); + + if ( m_xListener.is() ) + throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + m_xListener = Listener; + + ////////////////////////////////////////////////////////////////////// + // Create "welcome event" and send it to listener. + ////////////////////////////////////////////////////////////////////// + + // Note: We only have the implementation for a static result set at the + // moment (src590). The dynamic result sets passed to the listener + // are a fake. This implementation will never call "notify" at the + // listener to propagate any changes!!! + + uno::Any aInfo; + aInfo <<= ucb::WelcomeDynamicResultSetStruct( this, /* "old" */ + this /* "new" */ ); + + uno::Sequence< ucb::ListAction > aActions( 1 ); + aActions.getArray()[ 0 ] = ucb::ListAction( 0, // Position; not used + 0, // Count; not used + ucb::ListActionType::WELCOME, + aInfo ); + aGuard.clear(); + + Listener->notify( + ucb::ListEvent( + static_cast< cppu::OWeakObject * >( this ), aActions ) ); +} + +//========================================================================= +// virtual +void SAL_CALL +XResultSet_impl::connectToCache( + const uno::Reference< ucb::XDynamicResultSet > & xCache ) + throw( ucb::ListenerAlreadySetException, + ucb::AlreadyInitializedException, + ucb::ServiceNotFoundException, + uno::RuntimeException ) +{ + uno::Reference< lang::XMultiServiceFactory > mxSMgr + = m_pMyShell->m_xMultiServiceFactory; + + if( m_xListener.is() ) + throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + if( m_bStatic ) + throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + uno::Reference< ucb::XSourceInitialization > xTarget( + xCache, uno::UNO_QUERY ); + if( xTarget.is() && mxSMgr.is() ) + { + uno::Reference< ucb::XCachedDynamicResultSetStubFactory > xStubFactory; + try + { + xStubFactory + = uno::Reference< ucb::XCachedDynamicResultSetStubFactory >( + mxSMgr->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ), + uno::UNO_QUERY ); + } + catch ( uno::Exception const & ) + { + } + + if( xStubFactory.is() ) + { + xStubFactory->connectToCache( + this, xCache,m_sSortingInfo, NULL ); + return; + } + } + throw ucb::ServiceNotFoundException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + +//========================================================================= +// virtual +sal_Int16 SAL_CALL +XResultSet_impl::getCapabilities() + throw( uno::RuntimeException ) +{ + // Never set ucb::ContentResultSetCapability::SORTED + // - Underlying content cannot provide sorted data... + return 0; +} + +// XResultSetMetaDataSupplier +uno::Reference< sdbc::XResultSetMetaData > SAL_CALL +XResultSet_impl::getMetaData( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + for ( sal_Int32 n = 0; n < m_sProperty.getLength(); ++n ) + { + if ( m_sProperty.getConstArray()[ n ].Name.compareToAscii( "Title" ) + == 0 ) + { + // @@@ #82177# - Determine correct value! + sal_Bool bCaseSensitiveChildren = sal_False; + + std::vector< ::ucbhelper::ResultSetColumnData > + aColumnData( m_sProperty.getLength() ); + aColumnData[ n ].isCaseSensitive = bCaseSensitiveChildren; + + ::ucbhelper::ResultSetMetaData* p = + new ::ucbhelper::ResultSetMetaData( + m_pMyShell->m_xMultiServiceFactory, + m_sProperty, + aColumnData ); + return uno::Reference< sdbc::XResultSetMetaData >( p ); + } + } + + ::ucbhelper::ResultSetMetaData* p = + new ::ucbhelper::ResultSetMetaData( + m_pMyShell->m_xMultiServiceFactory, m_sProperty ); + return uno::Reference< sdbc::XResultSetMetaData >( p ); +} + + + +// XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL +XResultSet_impl::getPropertySetInfo() + throw( uno::RuntimeException) +{ + + uno::Sequence< beans::Property > seq(2); + seq[0].Name = rtl::OUString::createFromAscii( "RowCount" ); + seq[0].Handle = -1; + seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) ); + seq[0].Attributes = beans::PropertyAttribute::READONLY; + + seq[0].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" ); + seq[0].Handle = -1; + seq[0].Type = getCppuType( static_cast< sal_Bool* >(0) ); + seq[0].Attributes = beans::PropertyAttribute::READONLY; + + XPropertySetInfo_impl* p = new XPropertySetInfo_impl( m_pMyShell, + seq ); + return uno::Reference< beans::XPropertySetInfo > ( p ); +} + + + +void SAL_CALL XResultSet_impl::setPropertyValue( + const rtl::OUString& aPropertyName, const uno::Any& ) + throw( beans::UnknownPropertyException, + beans::PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) || + aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + return; + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +uno::Any SAL_CALL XResultSet_impl::getPropertyValue( + const rtl::OUString& PropertyName ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + uno::Any aAny; + aAny <<= m_bRowCountFinal; + return aAny; + } + else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + uno::Any aAny; + sal_Int32 count = sal::static_int_cast<sal_Int32>(m_aItems.size()); + aAny <<= count; + return aAny; + } + else + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +void SAL_CALL XResultSet_impl::addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& xListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pIsFinalListeners ) + m_pIsFinalListeners = + new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + + m_pIsFinalListeners->addInterface( xListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pRowCountListeners ) + m_pRowCountListeners = + new cppu::OInterfaceContainerHelper( m_aEventListenerMutex ); + m_pRowCountListeners->addInterface( xListener ); + } + else + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +void SAL_CALL XResultSet_impl::removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) && + m_pIsFinalListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_pIsFinalListeners->removeInterface( aListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) && + m_pRowCountListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + + m_pRowCountListeners->removeInterface( aListener ); + } + else + throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + +void SAL_CALL XResultSet_impl::addVetoableChangeListener( + const rtl::OUString&, + const uno::Reference< beans::XVetoableChangeListener >& ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ +} + + +void SAL_CALL XResultSet_impl::removeVetoableChangeListener( + const rtl::OUString&, + const uno::Reference< beans::XVetoableChangeListener >& ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ +} diff --git a/ucb/source/ucp/file/filrset.hxx b/ucb/source/ucp/file/filrset.hxx new file mode 100644 index 000000000000..977eddec8ccd --- /dev/null +++ b/ucb/source/ucp/file/filrset.hxx @@ -0,0 +1,683 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILRSET_HXX_ +#define _FILRSET_HXX_ + +#ifndef __SGI_STL_VECTOR +#include <vector> +#endif +#include <ucbhelper/macros.hxx> +#include <osl/file.hxx> + +#include "osl/mutex.hxx" +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/sdbc/XCloseable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#ifndef _COM_SUN_STAR_UCB_XDYNAMICRESULTSET_HPP__ +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#endif +#include <com/sun/star/ucb/XDynamicResultSetListener.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/beans/Property.hpp> +#include "filrow.hxx" +#include "filnot.hxx" + + + +namespace fileaccess { + + class Notifier; + + class XResultSet_impl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XEventListener, + public com::sun::star::sdbc::XRow, + public com::sun::star::sdbc::XResultSet, + public com::sun::star::ucb::XDynamicResultSet, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XResultSetMetaDataSupplier, + public com::sun::star::beans::XPropertySet, + public com::sun::star::ucb::XContentAccess, + public Notifier + { + public: + + XResultSet_impl( shell* pMyShell, + const rtl::OUString& aUnqPath, + sal_Int32 OpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort ); + + virtual ~XResultSet_impl(); + + virtual ContentEventNotifier* cDEL( void ) + { + return 0; + } + + virtual ContentEventNotifier* cEXC( const rtl::OUString ) + { + return 0; + } + + virtual ContentEventNotifier* cCEL( void ) + { + return 0; + } + + virtual PropertySetInfoChangeNotifier* cPSL( void ) + { + return 0; + } + + virtual PropertyChangeNotifier* cPCL( void ) + { + return 0; + } + + virtual rtl::OUString getKey( void ) + { + return m_aBaseDirectory; + } + + sal_Int32 SAL_CALL CtorSuccess(); + sal_Int32 SAL_CALL getMinorError(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + // XEventListener + virtual void SAL_CALL + disposing( + const com::sun::star::lang::EventObject& Source ) + throw( com::sun::star::uno::RuntimeException ); + + // XComponent + virtual void SAL_CALL + dispose( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ); + + + // XRow + virtual sal_Bool SAL_CALL + wasNull( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + m_nWasNull = m_aItems[m_nRow]->wasNull(); + else + m_nWasNull = true; + return m_nWasNull; + } + + virtual rtl::OUString SAL_CALL + getString( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getString( columnIndex ); + else + return rtl::OUString(); + } + + virtual sal_Bool SAL_CALL + getBoolean( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getBoolean( columnIndex ); + else + return false; + } + + virtual sal_Int8 SAL_CALL + getByte( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getByte( columnIndex ); + else + return sal_Int8( 0 ); + } + + virtual sal_Int16 SAL_CALL + getShort( + sal_Int32 columnIndex ) + throw( + com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getShort( columnIndex ); + else + return sal_Int16( 0 ); + } + + virtual sal_Int32 SAL_CALL + getInt( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getInt( columnIndex ); + else + return sal_Int32( 0 ); + } + + virtual sal_Int64 SAL_CALL + getLong( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getLong( columnIndex ); + else + return sal_Int64( 0 ); + } + + virtual float SAL_CALL + getFloat( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getFloat( columnIndex ); + else + return float( 0 ); + } + + virtual double SAL_CALL + getDouble( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getDouble( columnIndex ); + else + return double( 0 ); + } + + virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getBytes( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getBytes( columnIndex ); + else + return com::sun::star::uno::Sequence< sal_Int8 >(); + } + + virtual com::sun::star::util::Date SAL_CALL + getDate( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getDate( columnIndex ); + else + return com::sun::star::util::Date(); + } + + virtual com::sun::star::util::Time SAL_CALL + getTime( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getTime( columnIndex ); + else + return com::sun::star::util::Time(); + } + + virtual com::sun::star::util::DateTime SAL_CALL + getTimestamp( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getTimestamp( columnIndex ); + else + return com::sun::star::util::DateTime(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getBinaryStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getBinaryStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getCharacterStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getCharacterStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Any SAL_CALL + getObject( + sal_Int32 columnIndex, + const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getObject( columnIndex,typeMap ); + else + return com::sun::star::uno::Any(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL + getRef( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getRef( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XRef >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL + getBlob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getBlob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL + getClob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getClob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XClob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL + getArray( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) + return m_aItems[m_nRow]->getArray( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XArray >(); + } + + + // XResultSet + + virtual sal_Bool SAL_CALL + next( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isBeforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isAfterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + beforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + afterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + first( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + last( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + getRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + absolute( + sal_Int32 row ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + relative( + sal_Int32 rows ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + previous( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + refreshRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowUpdated( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowInserted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowDeleted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + getStatement( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + // XDynamicResultSet + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSet > SAL_CALL + getStaticResultSet( + void ) + throw( com::sun::star::ucb::ListenerAlreadySetException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + setListener( + const com::sun::star::uno::Reference< + com::sun::star::ucb::XDynamicResultSetListener >& Listener ) + throw( com::sun::star::ucb::ListenerAlreadySetException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + connectToCache( const com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > & xCache ) + throw( com::sun::star::ucb::ListenerAlreadySetException, + com::sun::star::ucb::AlreadyInitializedException, + com::sun::star::ucb::ServiceNotFoundException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int16 SAL_CALL + getCapabilities() + throw( com::sun::star::uno::RuntimeException ); + + + // XCloseable + + virtual void SAL_CALL + close( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + // XContentAccess + + virtual rtl::OUString SAL_CALL + queryContentIdentifierString( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL + queryContentIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL + queryContent( + void ) + throw( com::sun::star::uno::RuntimeException ); + + // XResultSetMetaDataSupplier + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > SAL_CALL + getMetaData( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + // XPropertySet + virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setPropertyValue( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Any& aValue ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Any SAL_CALL + getPropertyValue( + const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + private: + + // Members + // const uno::Reference< lang::XMultiServiceFactory > m_xMSF; + // const uno::Reference< ucb::XContentProvider > m_xProvider; + + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Bool m_nIsOpen; + sal_Int32 m_nRow; + sal_Bool m_nWasNull; + sal_Int32 m_nOpenMode; + sal_Bool m_bRowCountFinal; + + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > > IdentSet; + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > > ItemSet; + typedef std::vector< rtl::OUString > UnqPathSet; + + IdentSet m_aIdents; + ItemSet m_aItems; + UnqPathSet m_aUnqPath; + const rtl::OUString m_aBaseDirectory; + + osl::Directory m_aFolder; + com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_sProperty; + com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > m_sSortingInfo; + + osl::Mutex m_aMutex; + osl::Mutex m_aEventListenerMutex; + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + + cppu::OInterfaceContainerHelper* m_pRowCountListeners; + cppu::OInterfaceContainerHelper* m_pIsFinalListeners; + + com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSetListener > m_xListener; + sal_Bool m_bStatic; + + sal_Int32 m_nErrorCode; + sal_Int32 m_nMinorErrorCode; + + // Methods + sal_Bool SAL_CALL OneMore( void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ); + + void rowCountChanged(); + void isFinalChanged(); + }; + + +} // end namespace fileaccess + + +#endif diff --git a/ucb/source/ucp/file/filstr.cxx b/ucb/source/ucp/file/filstr.cxx new file mode 100644 index 000000000000..2e45e22b790b --- /dev/null +++ b/ucb/source/ucp/file/filstr.cxx @@ -0,0 +1,404 @@ + /************************************************************************* + * + * 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" +#include "com/sun/star/io/IOException.hpp" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "osl/diagnose.h" +#include "filstr.hxx" +#include "shell.hxx" +#include "prov.hxx" + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +/******************************************************************************/ +/* */ +/* XStream_impl implementation */ +/* */ +/******************************************************************************/ + + +uno::Any SAL_CALL +XStream_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XTypeProvider*,this ), + SAL_STATIC_CAST( io::XStream*,this ), + SAL_STATIC_CAST( io::XInputStream*,this ), + SAL_STATIC_CAST( io::XOutputStream*,this ), + SAL_STATIC_CAST( io::XSeekable*,this ), + SAL_STATIC_CAST( io::XTruncate*,this ), + SAL_STATIC_CAST( io::XAsyncOutputMonitor*,this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL +XStream_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XStream_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// XTypeProvider +////////////////////////////////////////////////////////////////////////////////////////// + + +XTYPEPROVIDER_IMPL_7( XStream_impl, + lang::XTypeProvider, + io::XStream, + io::XSeekable, + io::XInputStream, + io::XOutputStream, + io::XTruncate, + io::XAsyncOutputMonitor ) + + + +XStream_impl::XStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock ) + : m_bInputStreamCalled( false ), + m_bOutputStreamCalled( false ), + m_pMyShell( pMyShell ), + m_xProvider( m_pMyShell->m_pProvider ), + m_bLock( bLock ), + m_aFile( aUncPath ), + m_nErrorCode( TASKHANDLER_NO_ERROR ), + m_nMinorErrorCode( TASKHANDLER_NO_ERROR ) +{ + sal_uInt32 nFlags = ( OpenFlag_Read | OpenFlag_Write ); + if ( !bLock ) + nFlags |= OpenFlag_NoLock; + + osl::FileBase::RC err = m_aFile.open( nFlags ); + if( err != osl::FileBase::E_None ) + { + m_nIsOpen = false; + m_aFile.close(); + + m_nErrorCode = TASKHANDLING_OPEN_FOR_STREAM; + m_nMinorErrorCode = err; + } + else + m_nIsOpen = true; +} + + +XStream_impl::~XStream_impl() +{ + try + { + closeStream(); + } + catch (io::IOException const &) + { + OSL_ENSURE(false, "unexpected situation"); + } + catch (uno::RuntimeException const &) + { + OSL_ENSURE(false, "unexpected situation"); + } +} + + +sal_Int32 SAL_CALL XStream_impl::CtorSuccess() +{ + return m_nErrorCode; +} + + + +sal_Int32 SAL_CALL XStream_impl::getMinorError() +{ + return m_nMinorErrorCode; +} + + + +uno::Reference< io::XInputStream > SAL_CALL +XStream_impl::getInputStream( ) + throw( uno::RuntimeException) +{ + { + osl::MutexGuard aGuard( m_aMutex ); + m_bInputStreamCalled = true; + } + return uno::Reference< io::XInputStream >( this ); +} + + +uno::Reference< io::XOutputStream > SAL_CALL +XStream_impl::getOutputStream( ) + throw( uno::RuntimeException ) +{ + { + osl::MutexGuard aGuard( m_aMutex ); + m_bOutputStreamCalled = true; + } + return uno::Reference< io::XOutputStream >( this ); +} + + +void SAL_CALL XStream_impl::truncate(void) + throw( io::IOException, uno::RuntimeException ) +{ + if (osl::FileBase::E_None != m_aFile.setSize(0)) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + if (osl::FileBase::E_None != m_aFile.setPos(Pos_Absolut,sal_uInt64(0))) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + + +//=========================================================================== +// XStream_impl private non interface methods +//=========================================================================== + +sal_Int32 SAL_CALL +XStream_impl::readBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + if( ! m_nIsOpen ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + sal_Int8 * buffer; + try + { + buffer = new sal_Int8[nBytesToRead]; + } + catch( std::bad_alloc ) + { + if( m_nIsOpen ) m_aFile.close(); + throw io::BufferSizeExceededException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + } + + sal_uInt64 nrc(0); + if(m_aFile.read( (void* )buffer,sal_uInt64(nBytesToRead),nrc ) + != osl::FileBase::E_None) + { + delete[] buffer; + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + } + aData = uno::Sequence< sal_Int8 > ( buffer, (sal_uInt32)nrc ); + delete[] buffer; + return ( sal_Int32 ) nrc; +} + + +sal_Int32 SAL_CALL +XStream_impl::readSomeBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + +void SAL_CALL +XStream_impl::skipBytes( + sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) ); +} + + +sal_Int32 SAL_CALL +XStream_impl::available( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException) +{ + return 0; +} + + +void SAL_CALL +XStream_impl::writeBytes( const uno::Sequence< sal_Int8 >& aData ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + sal_uInt32 length = aData.getLength(); + if(length) + { + sal_uInt64 nWrittenBytes(0); + const sal_Int8* p = aData.getConstArray(); + if(osl::FileBase::E_None != m_aFile.write(((void*)(p)),sal_uInt64(length),nWrittenBytes) || + nWrittenBytes != length ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + } +} + + +void SAL_CALL +XStream_impl::closeStream( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + if( m_nIsOpen ) + { + osl::FileBase::RC err = m_aFile.close(); + + if( err != osl::FileBase::E_None ) { + io::IOException ex; + ex.Message = rtl::OUString::createFromAscii( + "could not close file"); + throw ex; + } + + m_nIsOpen = false; + } +} + +void SAL_CALL +XStream_impl::closeInput( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + m_bInputStreamCalled = false; + + if( ! m_bOutputStreamCalled ) + closeStream(); +} + + +void SAL_CALL +XStream_impl::closeOutput( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + m_bOutputStreamCalled = false; + + if( ! m_bInputStreamCalled ) + closeStream(); +} + + +void SAL_CALL +XStream_impl::seek( + sal_Int64 location ) + throw( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + if( location < 0 ) + throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); + if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +sal_Int64 SAL_CALL +XStream_impl::getPosition( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uPos; + if( osl::FileBase::E_None != m_aFile.getPos( uPos ) ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + return sal_Int64( uPos ); +} + +sal_Int64 SAL_CALL +XStream_impl::getLength( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uEndPos; + if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None ) + throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + else + return sal_Int64( uEndPos ); +} + +void SAL_CALL +XStream_impl::flush() + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{} + +void XStream_impl::waitForCompletion() + throw (io::IOException, uno::RuntimeException) +{ + // At least on UNIX, to reliably learn about any errors encountered by + // asynchronous NFS write operations, without closing the file directly + // afterwards, there appears to be no cheaper way than to call fsync: + if (m_nIsOpen && m_aFile.sync() != osl::FileBase::E_None) { + throw io::IOException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "could not synchronize file to disc")), + static_cast< OWeakObject * >(this)); + } +} diff --git a/ucb/source/ucp/file/filstr.hxx b/ucb/source/ucp/file/filstr.hxx new file mode 100644 index 000000000000..b5ffae2a5ea2 --- /dev/null +++ b/ucb/source/ucp/file/filstr.hxx @@ -0,0 +1,246 @@ + /************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILSTR_HXX_ +#define _FILSTR_HXX_ + +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XStream.hpp> +#include "com/sun/star/io/XAsyncOutputMonitor.hpp" +#include <com/sun/star/ucb/XContentProvider.hpp> + +#include "filrec.hxx" + +namespace fileaccess { + + // forward: + class shell; + class XInputStreamForStream; + class XOutputStreamForStream; + + class XStream_impl + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::io::XStream, + public com::sun::star::io::XSeekable, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XOutputStream, + public com::sun::star::io::XTruncate, + public com::sun::star::io::XAsyncOutputMonitor + { + friend class XInputStreamForStream; + friend class XOutputStreamForStream; + + public: + + XStream_impl( shell* pMyShell,const rtl::OUString& aUncPath, sal_Bool bLock ); + + /** + * Returns an error code as given by filerror.hxx + */ + + sal_Int32 SAL_CALL CtorSuccess(); + sal_Int32 SAL_CALL getMinorError(); + + virtual ~XStream_impl(); + + + // OWeakObject + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + // XStream + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getInputStream( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > SAL_CALL + getOutputStream( ) + throw( com::sun::star::uno::RuntimeException ); + + + // XTruncate + + virtual void SAL_CALL truncate( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + + // XInputStream + + sal_Int32 SAL_CALL + readBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + sal_Int32 SAL_CALL + readSomeBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + + void SAL_CALL + skipBytes( + sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + sal_Int32 SAL_CALL + available( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + void SAL_CALL + closeInput( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + // XSeekable + + void SAL_CALL + seek( + sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + sal_Int64 SAL_CALL + getPosition( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + sal_Int64 SAL_CALL + getLength( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + + // XOutputStream + + void SAL_CALL + writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + + + void SAL_CALL + flush() + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + + void SAL_CALL + closeOutput( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL waitForCompletion() + throw ( + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + private: + + osl::Mutex m_aMutex; + bool m_bInputStreamCalled,m_bOutputStreamCalled; + + shell* m_pMyShell; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Bool m_nIsOpen; + + sal_Bool m_bLock; + + ReconnectingFile m_aFile; + + sal_Int32 m_nErrorCode; + sal_Int32 m_nMinorErrorCode; + + // Implementation methods + + void SAL_CALL + closeStream( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + }; + +} // end namespace XStream_impl + +#endif diff --git a/ucb/source/ucp/file/filtask.cxx b/ucb/source/ucp/file/filtask.cxx new file mode 100644 index 000000000000..a1350bb4cfaf --- /dev/null +++ b/ucb/source/ucp/file/filtask.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * 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" +#include "filtask.hxx" +#include "filglob.hxx" + +/******************************************************************************/ +/* */ +/* TaskHandling */ +/* */ +/******************************************************************************/ + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; + + + +TaskManager::TaskManager() + : m_nCommandId( 0 ) +{ +} + + + +TaskManager::~TaskManager() +{ +} + + + +void SAL_CALL +TaskManager::startTask( + sal_Int32 CommandId, + const uno::Reference< XCommandEnvironment >& xCommandEnv ) + throw( DuplicateCommandIdentifierException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it != m_aTaskMap.end() ) + { + throw DuplicateCommandIdentifierException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), + uno::Reference< uno::XInterface >() ); + } + m_aTaskMap[ CommandId ] = TaskHandling( xCommandEnv ); +} + + + +void SAL_CALL +TaskManager::endTask( sal_Int32 CommandId, + const rtl::OUString& aUncPath, + BaseContent* pContent) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it == m_aTaskMap.end() ) + return; + + sal_Int32 ErrorCode = it->second.getInstalledError(); + sal_Int32 MinorCode = it->second.getMinorErrorCode(); + bool isHandled = it->second.isHandled(); + + Reference< XCommandEnvironment > xComEnv + = it->second.getCommandEnvironment(); + + m_aTaskMap.erase( it ); + + if( ErrorCode != TASKHANDLER_NO_ERROR ) + throw_handler( + ErrorCode, + MinorCode, + xComEnv, + aUncPath, + pContent, + isHandled); +} + + + +void SAL_CALL +TaskManager::abort( sal_Int32 CommandId ) +{ + if( CommandId ) + { + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it == m_aTaskMap.end() ) + return; + else + it->second.abort(); + } +} + + +void SAL_CALL TaskManager::clearError( sal_Int32 CommandId ) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it != m_aTaskMap.end() ) + it->second.clearError(); +} + + +void SAL_CALL TaskManager::retrieveError( sal_Int32 CommandId, + sal_Int32 &ErrorCode, + sal_Int32 &minorCode) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it != m_aTaskMap.end() ) + { + ErrorCode = it->second.getInstalledError(); + minorCode = it->second. getMinorErrorCode(); + } +} + + + +void SAL_CALL TaskManager::installError( sal_Int32 CommandId, + sal_Int32 ErrorCode, + sal_Int32 MinorCode ) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + if( it != m_aTaskMap.end() ) + it->second.installError( ErrorCode,MinorCode ); +} + + + +sal_Int32 SAL_CALL +TaskManager::getCommandId( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return ++m_nCommandId; +} + + + +void SAL_CALL TaskManager::handleTask( + sal_Int32 CommandId, + const uno::Reference< task::XInteractionRequest >& request ) +{ + osl::MutexGuard aGuard( m_aMutex ); + TaskMap::iterator it = m_aTaskMap.find( CommandId ); + uno::Reference< task::XInteractionHandler > xInt; + if( it != m_aTaskMap.end() ) + { + xInt = it->second.getInteractionHandler(); + if( xInt.is() ) + xInt->handle( request ); + it->second.setHandled(); + } +} diff --git a/ucb/source/ucp/file/filtask.hxx b/ucb/source/ucp/file/filtask.hxx new file mode 100644 index 000000000000..6ce4f35b4240 --- /dev/null +++ b/ucb/source/ucp/file/filtask.hxx @@ -0,0 +1,225 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef _FILTASK_HXX_ +#define _FILTASK_HXX_ +#endif + +#include <hash_map> +#include <rtl/ustring.hxx> + +#include "osl/mutex.hxx" +#include <com/sun/star/ucb/DuplicateCommandIdentifierException.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XProgressHandler.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include "filerror.hxx" + + +namespace fileaccess +{ + class BaseContent; + + /* + * This implementation is inherited by class fileaccess::shell. + * The relevant methods in this class all have as first argument the CommandId, + * so if necessary, every method has access to its relevant XInteractionHandler and + * XProgressHandler. + */ + + + class TaskManager + { + protected: + + class TaskHandling + { + private: + + bool m_bAbort,m_bHandled; + sal_Int32 m_nErrorCode,m_nMinorCode; + com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInteractionHandler; + com::sun::star::uno::Reference< com::sun::star::ucb::XProgressHandler > m_xProgressHandler; + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xCommandEnvironment; + + + public: + + TaskHandling( + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xCommandEnv + = com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >( 0 ) ) + : m_bAbort( false ), + m_bHandled( false ), + m_nErrorCode( TASKHANDLER_NO_ERROR ), + m_nMinorCode( TASKHANDLER_NO_ERROR ), + m_xInteractionHandler( 0 ), + m_xProgressHandler( 0 ), + m_xCommandEnvironment( xCommandEnv ) + { + } + + void SAL_CALL abort() + { + m_bAbort = true; + } + + void setHandled() + { + m_bHandled = true; + } + + bool isHandled() + { + return true; + } + + void clearError() + { + m_nErrorCode = TASKHANDLER_NO_ERROR; + m_nMinorCode = TASKHANDLER_NO_ERROR; + } + + void SAL_CALL installError( sal_Int32 nErrorCode, + sal_Int32 nMinorCode = TASKHANDLER_NO_ERROR ) + { + m_nErrorCode = nErrorCode; + m_nMinorCode = nMinorCode; + } + + sal_Int32 SAL_CALL getInstalledError() + { + return m_nErrorCode; + } + + sal_Int32 SAL_CALL getMinorErrorCode() + { + return m_nMinorCode; + } + + com::sun::star::uno::Reference< com::sun::star::ucb::XProgressHandler > SAL_CALL + getProgressHandler() + { + if( ! m_xProgressHandler.is() && m_xCommandEnvironment.is() ) + m_xProgressHandler = m_xCommandEnvironment->getProgressHandler(); + + return m_xProgressHandler; + } + + com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > SAL_CALL + getInteractionHandler() + { + if( ! m_xInteractionHandler.is() && m_xCommandEnvironment.is() ) + m_xInteractionHandler = m_xCommandEnvironment->getInteractionHandler(); + + return m_xInteractionHandler; + } + + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > SAL_CALL + getCommandEnvironment() + { + return m_xCommandEnvironment; + } + + }; // end class TaskHandling + + + typedef std::hash_map< sal_Int32,TaskHandling,std::hash< sal_Int32 > > TaskMap; + + + private: + + osl::Mutex m_aMutex; + sal_Int32 m_nCommandId; + TaskMap m_aTaskMap; + + + public: + + TaskManager(); + virtual ~TaskManager(); + + void SAL_CALL startTask( + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xCommandEnv ) + throw( com::sun::star::ucb::DuplicateCommandIdentifierException ); + + sal_Int32 SAL_CALL getCommandId( void ); + void SAL_CALL abort( sal_Int32 CommandId ); + + + /** + * The error code may be one of the error codes defined in + * filerror.hxx. + * The minor code refines the information given in ErrorCode. + */ + + void SAL_CALL clearError(); + + void SAL_CALL installError( sal_Int32 CommandId, + sal_Int32 ErrorCode, + sal_Int32 minorCode = TASKHANDLER_NO_ERROR ); + + +// void SAL_CALL installError( sal_Int32 CommandId, +// sal_Int32 ErrorCode, +// rtl::OUString message ); + +// void SAL_CALL installError( sal_Int32 CommandId, +// sal_Int32 ErrorCode, +// rtl::OUString message ); + + void SAL_CALL retrieveError( sal_Int32 CommandId, + sal_Int32 &ErrorCode, + sal_Int32 &minorCode); + + /** + * Deinstalls the task and evaluates a possibly set error code. + * "endTask" throws in case an error code is set the corresponding exception. + */ + + void SAL_CALL endTask( sal_Int32 CommandId, + // the physical URL of the object + const rtl::OUString& aUnqPath, + BaseContent* pContent); + + + /** + * Handles an interactionrequest + */ + + void SAL_CALL handleTask( sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& request ); + + /** + * Clears any error which are set on the commandid + */ + + void SAL_CALL clearError( sal_Int32 ); + + }; + +} // end namespace TaskHandling diff --git a/ucb/source/ucp/file/makefile.mk b/ucb/source/ucp/file/makefile.mk new file mode 100644 index 000000000000..b11fdd8081dc --- /dev/null +++ b/ucb/source/ucp/file/makefile.mk @@ -0,0 +1,80 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=ucb +TARGET=ucpfile +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# Version +UCPFILE_MAJOR=1 + +.INCLUDE: settings.mk +.IF "$(L10N_framework)"=="" + +SLOFILES=\ + $(SLO)$/prov.obj \ + $(SLO)$/bc.obj \ + $(SLO)$/shell.obj \ + $(SLO)$/filtask.obj \ + $(SLO)$/filrow.obj \ + $(SLO)$/filrset.obj \ + $(SLO)$/filid.obj \ + $(SLO)$/filnot.obj \ + $(SLO)$/filprp.obj \ + $(SLO)$/filinpstr.obj \ + $(SLO)$/filstr.obj \ + $(SLO)$/filcmd.obj \ + $(SLO)$/filglob.obj \ + $(SLO)$/filinsreq.obj \ + $(SLO)$/filrec.obj + +LIB1TARGET=$(SLB)$/_$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +SHL1TARGET=$(TARGET)$(UCPFILE_MAJOR) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1LIBS=$(LIB1TARGET) +SHL1IMPLIB=i$(TARGET) +SHL1STDLIBS=\ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) \ + $(UCBHELPERLIB) + +SHL1VERSIONMAP=exports.map + +.IF "$(GUI)" == "OS2" +DEF1EXPORTFILE=exports2.dxp +.ENDIF + +DEF1NAME=$(SHL1TARGET) +.ENDIF # L10N_framework + +.INCLUDE: target.mk + diff --git a/ucb/source/ucp/file/prov.cxx b/ucb/source/ucp/file/prov.cxx new file mode 100644 index 000000000000..a456d2acbd32 --- /dev/null +++ b/ucb/source/ucp/file/prov.cxx @@ -0,0 +1,738 @@ +/************************************************************************* + * + * 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" +#include <osl/security.hxx> +#include <osl/file.hxx> +#include <osl/socket.h> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/registry/XRegistryKey.hpp> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/ucb/FileSystemNotation.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include "filglob.hxx" +#include "filid.hxx" +#include "shell.hxx" +#include "bc.hxx" +#include "prov.hxx" + + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::ucb; +using namespace com::sun::star::container; + +//========================================================================= +static sal_Bool writeInfo( void * pRegistryKey, + const rtl::OUString & rImplementationName, + Sequence< rtl::OUString > const & rServiceNames ) +{ + rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) ); + aKeyName += rImplementationName; + aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" ); + + Reference< registry::XRegistryKey > xKey; + try + { + xKey = static_cast< registry::XRegistryKey * >( + pRegistryKey )->createKey( aKeyName ); + } + catch ( registry::InvalidRegistryException const & ) + { + } + + if ( !xKey.is() ) + return sal_False; + + sal_Bool bSuccess = sal_True; + + for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n ) + { + try + { + xKey->createKey( rServiceNames[ n ] ); + } + catch ( registry::InvalidRegistryException const & ) + { + bSuccess = sal_False; + break; + } + } + return bSuccess; +} + +//========================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//========================================================================= +extern "C" sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey ) +{ + return pRegistryKey && + + ////////////////////////////////////////////////////////////////////// + // File Content Provider. + ////////////////////////////////////////////////////////////////////// + + writeInfo( pRegistryKey, + fileaccess::shell::getImplementationName_static(), + fileaccess::shell::getSupportedServiceNames_static() ); +} + +//========================================================================= +extern "C" void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * ) +{ + void * pRet = 0; + + Reference< XMultiServiceFactory > xSMgr( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) ); + Reference< XSingleServiceFactory > xFactory; + + ////////////////////////////////////////////////////////////////////// + // File Content Provider. + ////////////////////////////////////////////////////////////////////// + + if ( fileaccess::shell::getImplementationName_static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = FileProvider::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +/****************************************************************************/ +/* */ +/* */ +/* FileProvider */ +/* */ +/* */ +/****************************************************************************/ + + + +FileProvider::FileProvider( const Reference< XMultiServiceFactory >& xMultiServiceFactory ) + : m_xMultiServiceFactory( xMultiServiceFactory ), + m_pMyShell( 0 ) +{ +} + + +FileProvider::~FileProvider() +{ + if( m_pMyShell ) + delete m_pMyShell; +} + + +////////////////////////////////////////////////////////////////////////// +// XInterface +////////////////////////////////////////////////////////////////////////// + +void SAL_CALL +FileProvider::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +FileProvider::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +Any SAL_CALL +FileProvider::queryInterface( + const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( + rType, + SAL_STATIC_CAST( XContentProvider*, this ), + SAL_STATIC_CAST( XInitialization*, this ), + SAL_STATIC_CAST( XContentIdentifierFactory*, this ), + SAL_STATIC_CAST( XServiceInfo*, this ), + SAL_STATIC_CAST( XTypeProvider*, this ), + SAL_STATIC_CAST( XFileIdentifierConverter*,this ), + SAL_STATIC_CAST( XPropertySet*, this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + +/////////////////////////////////////////////////////////////////////////////// +// XInitialization + +void SAL_CALL FileProvider::init() +{ + if( ! m_pMyShell ) + m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); +} + + +void SAL_CALL +FileProvider::initialize( + const Sequence< Any >& aArguments ) + throw (Exception, RuntimeException) +{ + if( ! m_pMyShell ) { + rtl::OUString config; + if( aArguments.getLength() > 0 && + (aArguments[0] >>= config) && + config.compareToAscii("NoConfig") == 0 ) + m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_False ); + else + m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// XTypeProvider methods. + + +XTYPEPROVIDER_IMPL_7( FileProvider, + XTypeProvider, + XServiceInfo, + XInitialization, + XContentIdentifierFactory, + XPropertySet, + XFileIdentifierConverter, + XContentProvider ) + + +//////////////////////////////////////////////////////////////////////////////// +// XServiceInfo methods. + +rtl::OUString SAL_CALL +FileProvider::getImplementationName() + throw( RuntimeException ) +{ + return fileaccess::shell::getImplementationName_static(); +} + + +sal_Bool SAL_CALL +FileProvider::supportsService( + const rtl::OUString& ServiceName ) + throw( RuntimeException ) +{ + return ServiceName == rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ); +} + + +Sequence< rtl::OUString > SAL_CALL +FileProvider::getSupportedServiceNames( + void ) + throw( RuntimeException ) +{ + return fileaccess::shell::getSupportedServiceNames_static(); +} + + + +Reference< XSingleServiceFactory > SAL_CALL +FileProvider::createServiceFactory( + const Reference< XMultiServiceFactory >& rxServiceMgr ) +{ + /** + * Create a single service factory.<BR> + * Note: The function pointer ComponentInstantiation points to a function throws Exception. + * + * @param rServiceManager the service manager used by the implementation. + * @param rImplementationName the implementation name. An empty string is possible. + * @param ComponentInstantiation the function pointer to create an object. + * @param rServiceNames the service supported by the implementation. + * @return a factory that support the interfaces XServiceProvider, XServiceInfo + * XSingleServiceFactory and XComponent. + * + * @see createOneInstanceFactory + */ + /* + * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory + * ( + * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager, + * const ::rtl::OUString & rImplementationName, + * ComponentInstantiation pCreateFunction, + + * const ::com::sun::star::Sequence< ::rtl::OUString > & rServiceNames + * ); + */ + + return Reference< XSingleServiceFactory > ( cppu::createSingleFactory( + rxServiceMgr, + fileaccess::shell::getImplementationName_static(), + FileProvider::CreateInstance, + fileaccess::shell::getSupportedServiceNames_static() ) ); +} + +Reference< XInterface > SAL_CALL +FileProvider::CreateInstance( + const Reference< XMultiServiceFactory >& xMultiServiceFactory ) +{ + XServiceInfo* xP = (XServiceInfo*) new FileProvider( xMultiServiceFactory ); + return Reference< XInterface >::query( xP ); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// XContent +//////////////////////////////////////////////////////////////////////////////// + + +Reference< XContent > SAL_CALL +FileProvider::queryContent( + const Reference< XContentIdentifier >& xIdentifier ) + throw( IllegalIdentifierException, + RuntimeException) +{ + init(); + rtl::OUString aUnc; + sal_Bool err = m_pMyShell->getUnqFromUrl( xIdentifier->getContentIdentifier(), + aUnc ); + + if( err ) + throw IllegalIdentifierException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + return Reference< XContent >( new BaseContent( m_pMyShell,xIdentifier,aUnc ) ); +} + + + +sal_Int32 SAL_CALL +FileProvider::compareContentIds( + const Reference< XContentIdentifier >& Id1, + const Reference< XContentIdentifier >& Id2 ) + throw( RuntimeException ) +{ + init(); + rtl::OUString aUrl1 = Id1->getContentIdentifier(); + rtl::OUString aUrl2 = Id2->getContentIdentifier(); + + sal_Int32 iComp = aUrl1.compareTo( aUrl2 ); + + if ( 0 != iComp ) + { + rtl::OUString aPath1, aPath2; + + m_pMyShell->getUnqFromUrl( aUrl1, aPath1 ); + m_pMyShell->getUnqFromUrl( aUrl2, aPath2 ); + + osl::FileBase::RC error; + osl::DirectoryItem aItem1, aItem2; + + error = osl::DirectoryItem::get( aPath1, aItem1 ); + if ( error == osl::FileBase::E_None ) + error = osl::DirectoryItem::get( aPath2, aItem2 ); + + if ( error != osl::FileBase::E_None ) + return iComp; + + osl::FileStatus aStatus1( FileStatusMask_FileURL ); + osl::FileStatus aStatus2( FileStatusMask_FileURL ); + error = aItem1.getFileStatus( aStatus1 ); + if ( error == osl::FileBase::E_None ) + error = aItem2.getFileStatus( aStatus2 ); + + if ( error == osl::FileBase::E_None ) + { + iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() ); + +// Quick hack for Windows to threat all file systems as case insensitive +#ifdef WNT + if ( 0 != iComp ) + { + error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 ); + if ( error == osl::FileBase::E_None ) + error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 ); + + if ( error == osl::FileBase::E_None ) + iComp = rtl_ustr_compareIgnoreAsciiCase( aPath1.getStr(), aPath2.getStr() ); + } +#endif + } + } + + return iComp; +} + + + +Reference< XContentIdentifier > SAL_CALL +FileProvider::createContentIdentifier( + const rtl::OUString& ContentId ) + throw( RuntimeException ) +{ + init(); + FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ContentId,false ); + return Reference< XContentIdentifier >( p ); +} + + + +//XPropertySetInfoImpl + +class XPropertySetInfoImpl2 + : public cppu::OWeakObject, + public XPropertySetInfo +{ +public: + XPropertySetInfoImpl2(); + ~XPropertySetInfoImpl2(); + + // XInterface + virtual Any SAL_CALL + queryInterface( + const Type& aType ) + throw( RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + virtual Sequence< Property > SAL_CALL + getProperties( + void ) + throw( RuntimeException ); + + virtual Property SAL_CALL + getPropertyByName( + const rtl::OUString& aName ) + throw( UnknownPropertyException, + RuntimeException); + + virtual sal_Bool SAL_CALL + hasPropertyByName( const rtl::OUString& Name ) + throw( RuntimeException ); + + +private: + Sequence< Property > m_seq; +}; + + +XPropertySetInfoImpl2::XPropertySetInfoImpl2() + : m_seq( 3 ) +{ + m_seq[0] = Property( rtl::OUString::createFromAscii( "HostName" ), + -1, + getCppuType( static_cast< rtl::OUString* >( 0 ) ), + PropertyAttribute::READONLY ); + + m_seq[1] = Property( rtl::OUString::createFromAscii( "HomeDirectory" ), + -1, + getCppuType( static_cast< rtl::OUString* >( 0 ) ), + PropertyAttribute::READONLY ); + + m_seq[2] = Property( rtl::OUString::createFromAscii( "FileSystemNotation" ), + -1, + getCppuType( static_cast< sal_Int32* >( 0 ) ), + PropertyAttribute::READONLY ); +} + + +XPropertySetInfoImpl2::~XPropertySetInfoImpl2() +{ + // nothing +} + + +void SAL_CALL +XPropertySetInfoImpl2::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XPropertySetInfoImpl2::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +Any SAL_CALL +XPropertySetInfoImpl2::queryInterface( + const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( XPropertySetInfo*,this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +Property SAL_CALL +XPropertySetInfoImpl2::getPropertyByName( + const rtl::OUString& aName ) + throw( UnknownPropertyException, + RuntimeException) +{ + for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) + if( m_seq[i].Name == aName ) + return m_seq[i]; + + throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + + +Sequence< Property > SAL_CALL +XPropertySetInfoImpl2::getProperties( + void ) + throw( RuntimeException ) +{ + return m_seq; +} + + +sal_Bool SAL_CALL +XPropertySetInfoImpl2::hasPropertyByName( + const rtl::OUString& aName ) + throw( RuntimeException ) +{ + for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) + if( m_seq[i].Name == aName ) + return true; + return false; +} + + + + + +void SAL_CALL FileProvider::initProperties( void ) +{ + osl::MutexGuard aGuard( m_aMutex ); + if( ! m_xPropertySetInfo.is() ) + { + osl_getLocalHostname( &m_HostName.pData ); + +#if defined ( UNX ) + m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION; +#elif defined( WNT ) || defined( OS2 ) + m_FileSystemNotation = FileSystemNotation::DOS_NOTATION; +#else + m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION; +#endif + osl::Security aSecurity; + aSecurity.getHomeDir( m_HomeDirectory ); + + // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0; + // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1; + // static const sal_Int32 DOS_NOTATION = (sal_Int32)2; + // static const sal_Int32 MAC_NOTATION = (sal_Int32)3; + + XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2(); + m_xPropertySetInfo = Reference< XPropertySetInfo >( p ); + } +} + + +// XPropertySet + +Reference< XPropertySetInfo > SAL_CALL +FileProvider::getPropertySetInfo( ) + throw( RuntimeException ) +{ + initProperties(); + return m_xPropertySetInfo; +} + + +void SAL_CALL +FileProvider::setPropertyValue( const rtl::OUString& aPropertyName, + const Any& ) + throw( UnknownPropertyException, + PropertyVetoException, + IllegalArgumentException, + WrappedTargetException, + RuntimeException ) +{ + if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 || + aPropertyName.compareToAscii( "HomeDirectory" ) == 0 || + aPropertyName.compareToAscii( "HostName" ) == 0 ) + return; + else + throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + + +Any SAL_CALL +FileProvider::getPropertyValue( + const rtl::OUString& aPropertyName ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ + initProperties(); + if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 ) + { + Any aAny; + aAny <<= m_FileSystemNotation; + return aAny; + } + else if( aPropertyName.compareToAscii( "HomeDirectory" ) == 0 ) + { + Any aAny; + aAny <<= m_HomeDirectory; + return aAny; + } + else if( aPropertyName.compareToAscii( "HostName" ) == 0 ) + { + Any aAny; + aAny <<= m_HostName; + return aAny; + } + else + throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); +} + + +void SAL_CALL +FileProvider::addPropertyChangeListener( + const rtl::OUString&, + const Reference< XPropertyChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException) +{ + return; +} + + +void SAL_CALL +FileProvider::removePropertyChangeListener( + const rtl::OUString&, + const Reference< XPropertyChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ + return; +} + +void SAL_CALL +FileProvider::addVetoableChangeListener( + const rtl::OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ + return; +} + + +void SAL_CALL +FileProvider::removeVetoableChangeListener( + const rtl::OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException) +{ + return; +} + + + +// XFileIdentifierConverter + +sal_Int32 SAL_CALL +FileProvider::getFileProviderLocality( const rtl::OUString& BaseURL ) + throw( RuntimeException ) +{ + // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise + // return -1 (missmatch). What is missing is a fast comparison to ASCII, + // ignoring case: + return BaseURL.getLength() >= 5 + && (BaseURL[0] == 'F' || BaseURL[0] == 'f') + && (BaseURL[1] == 'I' || BaseURL[1] == 'i') + && (BaseURL[2] == 'L' || BaseURL[2] == 'l') + && (BaseURL[3] == 'E' || BaseURL[3] == 'e') + && BaseURL[4] == ':' ? + 10 : -1; +} + +rtl::OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const rtl::OUString&, + const rtl::OUString& SystemPath ) + throw( RuntimeException ) +{ + rtl::OUString aNormalizedPath; + if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None ) + return rtl::OUString(); + + return aNormalizedPath; +} + +rtl::OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const rtl::OUString& URL ) + throw( RuntimeException ) +{ + rtl::OUString aSystemPath; + if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None ) + return rtl::OUString(); + + return aSystemPath; +} + diff --git a/ucb/source/ucp/file/prov.hxx b/ucb/source/ucp/file/prov.hxx new file mode 100644 index 000000000000..52f0ba35f3cb --- /dev/null +++ b/ucb/source/ucp/file/prov.hxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _PROV_HXX_ +#define _PROV_HXX_ + +#include <cppuhelper/weak.hxx> + +#include "osl/mutex.hxx" +#include <ucbhelper/macros.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifierFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/ucb/XFileIdentifierConverter.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> + +// FileProvider + + + +namespace fileaccess { + + // Forward declaration + + class BaseContent; + class shell; + + class FileProvider: + public cppu::OWeakObject, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::lang::XInitialization, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::ucb::XContentProvider, + public com::sun::star::ucb::XContentIdentifierFactory, + public com::sun::star::beans::XPropertySet, + public com::sun::star::ucb::XFileIdentifierConverter + { + friend class BaseContent; + public: + + FileProvider( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF ); + ~FileProvider(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XServiceInfo + virtual rtl::OUString SAL_CALL + getImplementationName( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( + const rtl::OUString& ServiceName ) + throw(com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames( + void ) + throw( com::sun::star::uno::RuntimeException ); + + + static com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > SAL_CALL + createServiceFactory( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxServiceMgr ); + + static com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + CreateInstance( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMultiServiceFactory ); + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + // XInitialization + virtual void SAL_CALL + initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + + // XContentProvider + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL + queryContent( + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Identifier ) + throw( com::sun::star::ucb::IllegalIdentifierException, + com::sun::star::uno::RuntimeException ); + + // XContentIdentifierFactory + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL + createContentIdentifier( + const rtl::OUString& ContentId ) + throw( com::sun::star::uno::RuntimeException ); + + + virtual sal_Int32 SAL_CALL + compareContentIds( + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Id1, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >& Id2 ) + throw( com::sun::star::uno::RuntimeException ); + + // XProperySet + + virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + setPropertyValue( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Any& aValue ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Any SAL_CALL + getPropertyValue( + const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + + // XFileIdentifierConverter + + virtual sal_Int32 SAL_CALL + getFileProviderLocality( const rtl::OUString& BaseURL ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getFileURLFromSystemPath( const rtl::OUString& BaseURL, + const rtl::OUString& SystemPath ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getSystemPathFromFileURL( const rtl::OUString& URL ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + // methods + void SAL_CALL init(); + + // Members + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMultiServiceFactory; + + void SAL_CALL initProperties( void ); + osl::Mutex m_aMutex; + rtl::OUString m_HostName; + rtl::OUString m_HomeDirectory; + sal_Int32 m_FileSystemNotation; + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > m_xPropertySetInfo; + + shell* m_pMyShell; + }; + +} // end namespace fileaccess + +#endif + 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; +} diff --git a/ucb/source/ucp/file/shell.hxx b/ucb/source/ucp/file/shell.hxx new file mode 100644 index 000000000000..14e332959a26 --- /dev/null +++ b/ucb/source/ucp/file/shell.hxx @@ -0,0 +1,607 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + + +#ifndef _SHELL_HXX_ +#define _SHELL_HXX_ + + +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <vector> +#include <hash_map> +#include <hash_set> +#include <list> +#include <osl/file.hxx> + +#include "osl/mutex.hxx" +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp> +#include <com/sun/star/ucb/TransferInfo.hpp> +#include <com/sun/star/ucb/ContentInfo.hpp> +#include "filtask.hxx" +#include "filnot.hxx" + +namespace fileaccess { + + class FileProvider; + class XPropertySetInfo_impl; + class XCommandInfo_impl; + class XResultSet_impl; + class BaseContent; + class shell; + + class shell + : public virtual TaskManager + { + friend class XPropertySetInfo_impl; + friend class XResultSet_impl; + friend class XCommandInfo_impl; + public: + // Type definitions + + typedef rtl::OUString UniquePath; + typedef equalOUString eUniquePath; + typedef hashOUString hUniquePath; + + class MyProperty + { + private: + rtl::OUString PropertyName; + sal_Int32 Handle; + sal_Bool isNative; + com::sun::star::uno::Type Typ; // Duplicates information in Value + com::sun::star::uno::Any Value; + com::sun::star::beans::PropertyState State; + sal_Int16 Attributes; + public: + MyProperty(); + MyProperty( const rtl::OUString& __PropertyName ); + 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 ); + + ~MyProperty(); + inline const sal_Bool& SAL_CALL IsNative() const; + inline const rtl::OUString& SAL_CALL getPropertyName() const { return PropertyName; } + inline const sal_Int32& SAL_CALL getHandle() const; + inline const com::sun::star::uno::Type& SAL_CALL getType() const; + inline const com::sun::star::uno::Any& SAL_CALL getValue() const; + inline const com::sun::star::beans::PropertyState& SAL_CALL getState() const; + inline const sal_Int16& SAL_CALL getAttributes() const; + + // The set* functions are declared const, because the key of "this" stays intact + inline void SAL_CALL setHandle( const sal_Int32& __Handle ) const; + inline void SAL_CALL setType( const com::sun::star::uno::Type& __Type ) const; + inline void SAL_CALL setValue( const com::sun::star::uno::Any& __Value ) const; + inline void SAL_CALL setState( const com::sun::star::beans::PropertyState& __State ) const; + inline void SAL_CALL setAttributes( const sal_Int16& __Attributes ) const; + }; + + struct eMyProperty + { + bool operator()( const MyProperty& rKey1, const MyProperty& rKey2 ) const + { + return !!( rKey1.getPropertyName() == rKey2.getPropertyName() ); + } + }; + + struct hMyProperty + { + size_t operator()( const MyProperty& rName ) const + { + return rName.getPropertyName().hashCode(); + } + }; + + typedef std::hash_set< MyProperty,hMyProperty,eMyProperty > PropertySet; + typedef std::list< Notifier* > NotifierList; + + + class UnqPathData + { + public: + UnqPathData(); + ~UnqPathData(); + UnqPathData( const UnqPathData& ); + UnqPathData& operator=( UnqPathData& ); + + PropertySet* properties; + NotifierList* notifier; + + // Three views on the PersistentPropertySet + com::sun::star::uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xS; + com::sun::star::uno::Reference< com::sun::star::beans::XPropertyContainer > xC; + com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xA; + }; + + typedef std::hash_map< UniquePath,UnqPathData,hUniquePath,eUniquePath > ContentMap; + + public: + + // MethodenDefinitionen + shell( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMultiServiceFactory, + FileProvider* pProvider,sal_Bool bWithConfig ); + + virtual ~shell(); + + + + /** + * This two methods register and deregister a change listener for the content belonging + * to URL aUnqPath + */ + + void SAL_CALL registerNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier ); + + void SAL_CALL deregisterNotifier( const rtl::OUString& aUnqPath,Notifier* pNotifier ); + + + + /** + * 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 associate( const rtl::OUString& UnqPath, + const rtl::OUString& PropertyName, + const com::sun::star::uno::Any& DefaultValue, + const sal_Int16 Attributes ) + throw( com::sun::star::beans::PropertyExistException, + com::sun::star::beans::IllegalTypeException, + com::sun::star::uno::RuntimeException); + + + void SAL_CALL deassociate( const rtl::OUString& UnqPath, + const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::NotRemoveableException, + com::sun::star::uno::RuntimeException); + + + + // + // Every method having a command id is not allowed to throw anything, + // but instead must install every error code in the task handler + // + + + /** + * Given an xOutputStream, this method writes the content of the file belonging to + * URL aUnqPath into the XOutputStream + */ + + void SAL_CALL page( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream ) + throw(); + + + /** + * Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file. + */ + + com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + open( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + sal_Bool bLock ) + throw(); + + + /** + * Given a file URL aUnqPath, this methods returns a XStream which can be used + * to read and write from/to the file. + */ + + com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL + open_rw( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + sal_Bool bLock ) + throw(); + + + /** + * This method returns the result set containing the the children of the directory belonging + * to file URL aUnqPath + */ + + com::sun::star::uno::Reference< com::sun::star::ucb::XDynamicResultSet > SAL_CALL + ls( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + const sal_Int32 OpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& sProperty, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > & sSortingInfo ) + throw(); + + + /** + * Info methods + */ + + // Info for commands + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo > SAL_CALL + info_c() + throw(); + + // Info for the properties + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + info_p( const rtl::OUString& aUnqPath ) + throw(); + + + /** + * Sets the values of the properties belonging to fileURL aUnqPath + */ + + com::sun::star::uno::Sequence< com::sun::star::uno::Any > SAL_CALL + setv( const rtl::OUString& aUnqPath, + const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& values ) + throw(); + + + /** + * Reads the values of the properties belonging to fileURL aUnqPath; + * Returns an XRow object containing the values in the requested order. + */ + + com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL + getv( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& properties ) + throw(); + + + /********************************************************************************/ + /* transfer-commands */ + /********************************************************************************/ + + /** + * Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath( files and directories ) + */ + + void SAL_CALL + move( sal_Int32 CommandId, + const rtl::OUString srcUnqPath, // Full file(folder)-path + const rtl::OUString dstUnqPath, // Path to the destination-directory + const sal_Int32 NameClash ) + throw(); + + /** + * Copies the content belonging to fileURL srcUnqPath to fileURL dstUnqPath ( files and directories ) + */ + + void SAL_CALL + copy( sal_Int32 CommandId, // See "move" + const rtl::OUString srcUnqPath, + const rtl::OUString dstUnqPath, + sal_Int32 NameClash ) + throw(); + +#define RemoveFolder 1 +#define RemoveFile -1 +#define RemoveUnknown 0 + + /** + * Deletes the content belonging to fileURL aUnqPath( recursively in case of directory ) + */ + + sal_Bool SAL_CALL + remove( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + sal_Int32 TypeToMove = RemoveUnknown, + sal_Bool MustExist = sal_True ) + throw(); + +#undef RemoveUnknown +#undef RemoveFile +#undef RemoveFolder + + + /********************************************************************************/ + /* write and create - commandos */ + /********************************************************************************/ + + /** + * Creates new directory with given URL, recursively if necessary + * Return:: success of operation + */ + + sal_Bool SAL_CALL + mkdir( sal_Int32 CommandId, + const rtl::OUString& aDirectoryName, + sal_Bool OverWrite ) + throw(); + + + /** + * Creates new file with given URL. + * The content of aInputStream becomes the content of the file + * Return:: success of operation + */ + + sal_Bool SAL_CALL + mkfil( sal_Int32 CommandId, + const rtl::OUString& aFileName, + sal_Bool OverWrite, + const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& aInputStream ) + throw(); + + + /** + * 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 + write( sal_Int32 CommandId, + const rtl::OUString& aUnqPath, + sal_Bool OverWrite, + const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& aInputStream ) + throw(); + + + + void SAL_CALL insertDefaultProperties( const rtl::OUString& aUnqPath ); + + com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo > + queryCreatableContentsInfo(); + + + /******************************************************************************/ + /* */ + /* mapping of file urls */ + /* to uncpath and vice versa */ + /* */ + /******************************************************************************/ + + sal_Bool SAL_CALL getUnqFromUrl( const rtl::OUString& Url, rtl::OUString& Unq ); + + sal_Bool SAL_CALL getUrlFromUnq( const rtl::OUString& Unq, rtl::OUString& Url ); + + + sal_Bool m_bWithConfig; + FileProvider* m_pProvider; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMultiServiceFactory; + com::sun::star::uno::Reference< com::sun::star::ucb::XPropertySetRegistry > m_xFileRegistry; + + private: + + /********************************************************************************/ + /* get eventListeners */ + /********************************************************************************/ + + std::list< ContentEventNotifier* >* SAL_CALL + getContentEventListeners( const rtl::OUString& aName ); + + std::list< ContentEventNotifier* >* SAL_CALL + getContentDeletedEventListeners( const rtl::OUString& aName ); + + std::vector< std::list< ContentEventNotifier* >* >* SAL_CALL + getContentExchangedEventListeners( const rtl::OUString aOldPrefix, + const rtl::OUString aNewPrefix, + sal_Bool withChilds ); + + std::list< PropertyChangeNotifier* >* SAL_CALL + getPropertyChangeNotifier( const rtl::OUString& aName ); + + std::list< PropertySetInfoChangeNotifier* >* SAL_CALL + getPropertySetListeners( const rtl::OUString& aName ); + + + /********************************************************************************/ + /* notify eventListeners */ + /********************************************************************************/ + + void SAL_CALL notifyPropertyChanges( + std::list< PropertyChangeNotifier* >* listeners, + const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyChangeEvent >& seqChanged ); + + void SAL_CALL notifyContentExchanged( + std::vector< std::list< ContentEventNotifier* >* >* listeners_vec ); + + void SAL_CALL notifyInsert( + std::list< ContentEventNotifier* >* listeners,const rtl::OUString& aChildName ); + + void SAL_CALL notifyContentDeleted( + std::list< ContentEventNotifier* >* listeners ); + + void SAL_CALL notifyContentRemoved( + std::list< ContentEventNotifier* >* listeners, + const rtl::OUString& aChildName ); + + void SAL_CALL notifyPropertyAdded( + std::list< PropertySetInfoChangeNotifier* >* listeners, + const rtl::OUString& aPropertyName ); + + void SAL_CALL notifyPropertyRemoved( + std::list< PropertySetInfoChangeNotifier* >* listeners, + const rtl::OUString& aPropertyName ); + + + /********************************************************************************/ + /* remove persistent propertyset */ + /********************************************************************************/ + + void SAL_CALL erasePersistentSet( const rtl::OUString& aUnqPath, + sal_Bool withChilds = false ); + + /********************************************************************************/ + /* copy persistent propertyset */ + /* from srcUnqPath to dstUnqPath */ + /********************************************************************************/ + + void SAL_CALL copyPersistentSet( const rtl::OUString& srcUnqPath, + const rtl::OUString& dstUnqPath, + sal_Bool withChilds = false ); + + + // Special optimized method for getting the properties of a directoryitem, which + // is returned by osl::DirectoryItem::getNextItem() + + com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > SAL_CALL + getv( Notifier* pNotifier, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& properties, + osl::DirectoryItem& DirItem, + rtl::OUString& aUnqPath, + sal_Bool& bIsRegular ); + + + /** + * Load the properties from configuration, if create == true create them. + * The Properties are stored under the url belonging to it->first. + */ + + void SAL_CALL load( const shell::ContentMap::iterator& it, + sal_Bool create ); + + /** + * 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 + commit( + const shell::ContentMap::iterator& it, + const osl::FileStatus& aFileStatus ); + + /** + * 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 + getMaskFromProperties( + sal_Int32& n_Mask, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq ); + + + void SAL_CALL + setFileProperties( + const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& values, + sal_Int32 numberOfValues ) + throw(); + + + // Helper function for public copy + + osl::FileBase::RC SAL_CALL + copy_recursive( + const rtl::OUString& srcUnqPath, + const rtl::OUString& dstUnqPath, + sal_Int32 TypeToCopy, + sal_Bool testExistence ) + throw(); + + + // Helper function for mkfil,mkdir and write + // Creates whole path + // returns success of the operation + // The calle determines the errorCode, which should be used to install + // any error + + sal_Bool SAL_CALL + ensuredir( sal_Int32 CommandId, + const rtl::OUString& aDirectoryName, + sal_Int32 errorCode ) + throw(); + + // General + osl::Mutex m_aMutex; + ContentMap m_aContent; + + // Default properties + + const rtl::OUString Title; + const rtl::OUString CasePreservingURL; + const rtl::OUString IsDocument; + const rtl::OUString IsFolder; + const rtl::OUString DateModified; + const rtl::OUString Size; + const rtl::OUString IsVolume; + const rtl::OUString IsRemoveable; + const rtl::OUString IsRemote; + const rtl::OUString IsCompactDisc; + const rtl::OUString IsFloppy; + const rtl::OUString IsHidden; + const rtl::OUString ContentType; + const rtl::OUString IsReadOnly; + const rtl::OUString CreatableContentsInfo; + + public: + + const rtl::OUString FolderContentType; + const rtl::OUString FileContentType; + + + private: + + PropertySet m_aDefaultProperties; + com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > m_sCommandInfo; + + public: + // Misceancellous: + // Methods for "writeComponentInfo" and "createComponentFactory" + + static void SAL_CALL getScheme( rtl::OUString& Scheme ); + + static rtl::OUString SAL_CALL getImplementationName_static( void ); + + static com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames_static( void ); + + }; // end class shell + +} // end namespace fileaccess + +#endif + diff --git a/ucb/source/ucp/file/ucpfile.xml b/ucb/source/ucp/file/ucpfile.xml new file mode 100644 index 000000000000..bd205639f476 --- /dev/null +++ b/ucb/source/ucp/file/ucpfile.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name> + ucpfile + </module-name> + + <component-description> + <author> + Andreas Bille + </author> + <name> + com.sun.star.comp.ucb.FileProvider + </name> + <description> + This component implements a Content Provider for the Universal + Content Broker. It provides access to file system contents. + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.FileContentProvider + </supported-service> + + <service-dependency> + com.sun.star.config.SpecialConfigManager + </service-dependency> + <service-dependency> + com.sun.star.configuration.ConfigurationAccess + </service-dependency> + <service-dependency> + com.sun.star.configuration.ConfigurationProvider + </service-dependency> + <service-dependency> + com.sun.star.script.Converter + </service-dependency> + <service-dependency> + com.sun.star.ucb.CachedDynamicResultSetStubFactory + </service-dependency> + <service-dependency> + com.sun.star.ucb.Store + </service-dependency> + </component-description> + + <project-build-dependency> sal </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> ucbhelper </project-build-dependency> + + <runtime-module-dependency> sal3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency> + <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency> + + <type> com.sun.star.beans.Property </type> + <type> com.sun.star.beans.PropertyAttribute </type> + <type> com.sun.star.beans.PropertySetInfoChange </type> + <type> com.sun.star.beans.PropertyState </type> + <type> com.sun.star.beans.PropertyValue </type> + <type> com.sun.star.beans.XPropertiesChangeNotifier </type> + <type> com.sun.star.beans.XPropertyAccess </type> + <type> com.sun.star.beans.XPropertyContainer </type> + <type> com.sun.star.beans.XPropertySetInfo </type> + <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type> + <type> com.sun.star.container.XChild </type> + <type> com.sun.star.container.XHierarchicalNameAccess </type> + <type> com.sun.star.frame.ConfigManager </type> + <type> com.sun.star.io.XActiveDataSink </type> + <type> com.sun.star.io.XActiveDataStreamer </type> + <type> com.sun.star.io.XSeekable </type> + <type> com.sun.star.io.XStream </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.script.XTypeConverter </type> + <type> com/sun/star/sdbc/ColumnValue </type> + <type> com.sun.star.sdbc.XCloseable </type> + <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type> + <type> com.sun.star.sdbc.XRow </type> + <type> com.sun.star.ucb.ContentAction </type> + <type> com.sun.star.ucb.ContentInfoAttribute </type> + <type> com.sun.star.ucb.FileSystemNotation </type> + <type> com.sun.star.ucb.InsertCommandArgument </type> + <type> com.sun.star.ucb.InteractiveBadTransferURLException </type> + <type> com.sun.star.ucb.ListAction </type> + <type> com.sun.star.ucb.NameClash </type> + <type> com.sun.star.ucb.NumberedSortingInfo </type> + <type> com.sun.star.ucb.OpenCommandArgument2 </type> + <type> com.sun.star.ucb.OpenMode </type> + <type> com.sun.star.ucb.TransferInfo </type> + <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type> + <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type> + <type> com.sun.star.ucb.XCommandInfo </type> + <type> com.sun.star.ucb.XCommandProcessor </type> + <type> com.sun.star.ucb.XContentAccess </type> + <type> com.sun.star.ucb.XContentCreator </type> + <type> com.sun.star.ucb.XContentIdentifier </type> + <type> com.sun.star.ucb.XContentIdentifierFactory </type> + <type> com.sun.star.ucb.XContentProvider </type> + <type> com.sun.star.ucb.XDynamicResultSet </type> + <type> com.sun.star.ucb.XFileIdentifierConverter </type> + <type> com.sun.star.ucb.XPropertySetRegistryFactory </type> + <type> com.sun.star.ucb.XSourceInitialization </type> + <type> com.sun.star.uno.XWeak </type> +</module-description> |