Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/ucb/source/ucp/file/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 101 kB image not shown  

Quelle  filtask.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <config_features.h>

#include <sal/config.h>
#include <sal/log.hxx>

#if HAVE_FEATURE_MACOSX_SANDBOX
#include <sys/stat.h>
#endif

#include <com/sun/star/beans/IllegalTypeException.hpp>
#include <com/sun/star/beans/NotRemoveableException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/PropertyExistException.hpp>
#include <com/sun/star/io/BufferSizeExceededException.hpp>
#include <com/sun/star/io/NotConnectedException.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/lang/IllegalAccessException.hpp>
#include <com/sun/star/task/InteractionClassification.hpp>
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#include <com/sun/star/ucb/DuplicateCommandIdentifierException.hpp>
#include <com/sun/star/ucb/IOErrorCode.hpp>
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
#include <com/sun/star/ucb/NameClash.hpp>
#include <com/sun/star/ucb/OpenCommandArgument.hpp>
#include <com/sun/star/ucb/Store.hpp>
#include <com/sun/star/ucb/TransferInfo.hpp>
#include <comphelper/propertysequence.hxx>
#include <osl/diagnose.h>
#include <rtl/ref.hxx>
#include <rtl/uri.hxx>

#include "filtask.hxx"
#include "filcmd.hxx"
#include "filglob.hxx"
#include "filinpstr.hxx"
#include "filprp.hxx"
#include "filrset.hxx"
#include "filstr.hxx"
#include "prov.hxx"

/******************************************************************************/
/*                                                                            */
/*                              TaskHandling                                  */
/*                                                                            */
/******************************************************************************/


using namespace fileaccess;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::ucb;

#if OSL_DEBUG_LEVEL > 0
#define THROW_WHERE SAL_WHERE
#else
#define THROW_WHERE ""
#endif

TaskManager::UnqPathData::UnqPathData() = default;

TaskManager::UnqPathData::UnqPathData(TaskManager::UnqPathData&&) = default;


TaskManager::UnqPathData::~UnqPathData()
{
}

TaskManager::MyProperty::MyProperty( const OUString&                         thePropertyName )
    : PropertyName( thePropertyName )
    , Handle(-1)
    , isNative(false)
    , State(beans::PropertyState_AMBIGUOUS_VALUE)
    , Attributes(0)
{
    // empty
}

TaskManager::MyProperty::MyProperty( bool                               theisNative,
                               const OUString&                    thePropertyName,
                               sal_Int32                          theHandle,
                               const css::uno::Type&              theTyp,
                               const css::uno::Any&               theValue,
                               const css::beans::PropertyState&   theState,
                               sal_Int16                          theAttributes )
    : PropertyName( thePropertyName ),
      Handle( theHandle ),
      isNative( theisNative ),
      Typ( theTyp ),
      Value( theValue ),
      State( theState ),
      Attributes( theAttributes )
{
    // empty
}

#include "filinl.hxx"

        // Default properties

constexpr OUString Title( u"Title"_ustr );
constexpr OUString CasePreservingURL( u"CasePreservingURL"_ustr );
constexpr OUString IsDocument( u"IsDocument"_ustr );
constexpr OUString IsFolder( u"IsFolder"_ustr );
constexpr OUString DateModified( u"DateModified"_ustr );
constexpr OUString Size( u"Size"_ustr );
constexpr OUString IsVolume( u"IsVolume"_ustr );
constexpr OUString IsRemoveable( u"IsRemoveable"_ustr );
constexpr OUString IsRemote( u"IsRemote"_ustr );
constexpr OUString IsCompactDisc( u"IsCompactDisc"_ustr );
constexpr OUString IsFloppy( u"IsFloppy"_ustr );
constexpr OUString IsHidden( u"IsHidden"_ustr );
constexpr OUString ContentType( u"ContentType"_ustr );
constexpr OUString IsReadOnly( u"IsReadOnly"_ustr );
constexpr OUString CreatableContentsInfo( u"CreatableContentsInfo"_ustr );

TaskManager::TaskManager( const uno::Reference< uno::XComponentContext >& rxContext,
              FileProvider* pProvider, bool bWithConfig )
    : m_nCommandId( 0 ),
      m_pProvider( pProvider ),
      m_xContext( rxContext ),
      // Commands
      m_sCommandInfo{
          { /* Name    */ u"getCommandInfo"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<void>::get() },

          { /* Name    */ u"getPropertySetInfo"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<void>::get() },

          { /* Name    */ u"getPropertyValues"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<uno::Sequence< beans::Property >>::get() },

          { /* Name    */ u"setPropertyValues"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() },

          { /* Name    */ u"open"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<OpenCommandArgument>::get() },

          { /* Name    */ u"transfer"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<TransferInfo>::get() },

          { /* Name    */ u"delete"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<sal_Bool>::get() },

          { /* Name    */ u"insert"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<InsertCommandArgument>::get() },

          { /* Name    */ u"createNewContent"_ustr,
            /* Handle  */ -1,
            /* ArgType */ cppu::UnoType<ucb::ContentInfo>::get() } }
{
    // Title
    m_aDefaultProperties.insert( MyProperty( true,
                                             Title,
                                             -1 ,
                                             cppu::UnoType<OUString>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND ) );

    // CasePreservingURL
    m_aDefaultProperties.insert(
        MyProperty( true,
                    CasePreservingURL,
                    -1 ,
                    cppu::UnoType<OUString>::get(),
                    uno::Any(),
                    beans::PropertyState_DEFAULT_VALUE,
                    beans::PropertyAttribute::MAYBEVOID
                    | beans::PropertyAttribute::BOUND
                    | beans::PropertyAttribute::READONLY ) );


    // IsFolder
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsFolder,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );


    // IsDocument
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsDocument,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    // Removable
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsVolume,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );


    // Removable
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsRemoveable,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    // Remote
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsRemote,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    // CompactDisc
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsCompactDisc,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    // Floppy
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsFloppy,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    // Hidden
    m_aDefaultProperties.insert(
        MyProperty(
            true,
            IsHidden,
            -1 ,
            cppu::UnoType<sal_Bool>::get(),
            uno::Any(),
            beans::PropertyState_DEFAULT_VALUE,
            beans::PropertyAttribute::MAYBEVOID
            | beans::PropertyAttribute::BOUND
#if defined(_WIN32)
        ));
#else
    | beans::PropertyAttribute::READONLY)); // under unix/linux only readable
#endif


    // ContentType
    m_aDefaultProperties.insert( MyProperty( false,
                                             ContentType,
                                             -1 ,
                                             cppu::UnoType<OUString>::get(),
                                             uno::Any(OUString()),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );


    // DateModified
    m_aDefaultProperties.insert( MyProperty( true,
                                             DateModified,
                                             -1 ,
                                             cppu::UnoType<util::DateTime>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND ) );

    // Size
    m_aDefaultProperties.insert( MyProperty( true,
                                             Size,
                                             -1,
                                             cppu::UnoType<sal_Int64>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND ) );

    // IsReadOnly
    m_aDefaultProperties.insert( MyProperty( true,
                                             IsReadOnly,
                                             -1 ,
                                             cppu::UnoType<sal_Bool>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND ) );


    // CreatableContentsInfo
    m_aDefaultProperties.insert( MyProperty( true,
                                             CreatableContentsInfo,
                                             -1 ,
                                             cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
                                             uno::Any(),
                                             beans::PropertyState_DEFAULT_VALUE,
                                             beans::PropertyAttribute::MAYBEVOID
                                             | beans::PropertyAttribute::BOUND
                                             | beans::PropertyAttribute::READONLY ) );

    if(bWithConfig)
    {
        uno::Reference< XPropertySetRegistryFactory > xRegFac = ucb::Store::create( m_xContext );
        // Open/create a registry
        m_xFileRegistry = xRegFac->createPropertySetRegistry( OUString() );
    }
}


TaskManager::~TaskManager()
{
}


void
TaskManager::startTask(
    sal_Int32 CommandId,
    const uno::Reference< XCommandEnvironment >& xCommandEnv )
{
    std::unique_lock aGuard( m_aMutex );
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
    if( it != m_aTaskMap.end() )
    {
        throw DuplicateCommandIdentifierException( OSL_LOG_PREFIX );
    }
    m_aTaskMap.emplace( CommandId, TaskHandling( xCommandEnv ));
}


void
TaskManager::endTask( sal_Int32 CommandId,
                      const OUString& aUncPath,
                      BaseContent* pContent)
{
    std::unique_lock aGuard( m_aMutex );
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
    if( it == m_aTaskMap.end() )
        return;

    TaskHandlerErr 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 );

    aGuard.unlock();

    if( ErrorCode != TaskHandlerErr::NO_ERROR )
        throw_handler(
            ErrorCode,
            MinorCode,
            xComEnv,
            aUncPath,
            pContent,
            isHandled);
}


void TaskManager::clearError( sal_Int32 CommandId )
{
    std::unique_lock aGuard( m_aMutex );
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
    if( it != m_aTaskMap.end() )
        it->second.clearError();
}


void TaskManager::retrieveError( sal_Int32 CommandId,
                                          TaskHandlerErr &ErrorCode,
                                          sal_Int32 &minorCode)
{
    std::unique_lock aGuard( m_aMutex );
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
    if( it != m_aTaskMap.end() )
    {
        ErrorCode = it->second.getInstalledError();
        minorCode = it->second. getMinorErrorCode();
    }
}


void TaskManager::installError( sal_Int32 CommandId,
                                         TaskHandlerErr ErrorCode,
                                         sal_Int32 MinorCode )
{
    std::unique_lock aGuard( m_aMutex );
    TaskMap::iterator it = m_aTaskMap.find( CommandId );
    if( it != m_aTaskMap.end() )
        it->second.installError( ErrorCode,MinorCode );
}


sal_Int32
TaskManager::getCommandId()
{
    std::unique_lock aGuard( m_aMutex );
    return ++m_nCommandId;
}


void TaskManager::handleTask(
    sal_Int32 CommandId,
    const uno::Reference< task::XInteractionRequest >& request )
{
    std::unique_lock 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();
    }
}

/*********************************************************************************/
/*                                                                               */
/*                     de/registerNotifier-Implementation                        */
/*                                                                               */
/*********************************************************************************/


//  This two methods register and deregister a change listener for the content belonging
//  to URL aUnqPath


void
TaskManager::registerNotifier( const OUString& aUnqPath, Notifier* pNotifier )
{
    std::unique_lock aGuard( m_aMutex );

    ContentMap::iterator it =
        m_aContent.emplace( aUnqPath, UnqPathData() ).first;

    std::vector< Notifier* >& nlist = it->second.notifier;

    std::vector<Notifier*>::iterator it1 = std::find(nlist.begin(), nlist.end(), pNotifier);
    if( it1 != nlist.end() )               // Every "Notifier" only once
    {
        return;
    }
    nlist.push_back( pNotifier );
}


void
TaskManager::deregisterNotifier( const OUString& aUnqPath,Notifier* pNotifier )
{
    std::unique_lock aGuard( m_aMutex );

    ContentMap::iterator it = m_aContent.find( aUnqPath );
    if( it == m_aContent.end() )
        return;

    std::erase(it->second.notifier, pNotifier);

    if( it->second.notifier.empty() )
        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 attributes are input


void
TaskManager::associate( const OUString& aUnqPath,
                  const OUString& PropertyName,
                  const uno::Any& DefaultValue,
                  const sal_Int16 Attributes )
{
    MyProperty newProperty( false,
                            PropertyName,
                            -1,
                            DefaultValue.getValueType(),
                            DefaultValue,
                            beans::PropertyState_DEFAULT_VALUE,
                            Attributes );

    auto it1 = m_aDefaultProperties.find( newProperty );
    if( it1 != m_aDefaultProperties.end() )
        throw beans::PropertyExistException( THROW_WHERE );

    {
        std::unique_lock aGuard( m_aMutex );

        ContentMap::iterator it = m_aContent.emplace( 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(THROW_WHERE );

        // Property does not exist
        properties.insert( newProperty );
        it->second.xC->addProperty( PropertyName,Attributes,DefaultValue );
    }
    notifyPropertyAdded( getPropertySetListeners( aUnqPath ), PropertyName );
}


void
TaskManager::deassociate( const OUString& aUnqPath,
            const OUString& PropertyName )
{
    MyProperty oldProperty( PropertyName );

    auto it1 = m_aDefaultProperties.find( oldProperty );
    if( it1 != m_aDefaultProperties.end() )
        throw beans::NotRemoveableException( THROW_WHERE );

    std::unique_lock aGuard( m_aMutex );

    ContentMap::iterator it = m_aContent.emplace( aUnqPath,UnqPathData() ).first;

    load( it, false );

    PropertySet& properties = it->second.properties;

    it1 = properties.find( oldProperty );
    if( it1 == properties.end() )
        throw beans::UnknownPropertyException( PropertyName );

    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 = nullptr;
            it->second.xC = nullptr;
            it->second.xA = nullptr;
            if(m_xFileRegistry.is())
                m_xFileRegistry->removePropertySet( aUnqPath );
        }
    }
    aGuard.unlock();
    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 TaskManager::page( sal_Int32 CommandId,
                           const OUString& aUnqPath,
                           const uno::Reference< io::XOutputStream >& xOutputStream )
{
    osl::File aFile( aUnqPath );
    osl::FileBase::RC err = aFile.open( osl_File_OpenFlag_Read );

    if( err != osl::FileBase::E_None )
    {
        aFile.close();
        installError( CommandId,
                      TaskHandlerErr::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( static_cast<void*>(BFF),bfz,nrc );
        if(  err == osl::FileBase::E_None )
        {
            // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
            uno::Sequence< sal_Int8 > seq( BFF, static_cast<sal_uInt32>(nrc) );
            try
            {
                xOutputStream->writeBytes( seq );
            }
            catch (const io::NotConnectedException&)
            {
                installError( CommandId,
                              TaskHandlerErr::NOTCONNECTED_FOR_PAGING );
                break;
            }
            catch (const io::BufferSizeExceededException&)
            {
                installError( CommandId,
                              TaskHandlerErr::BUFFERSIZEEXCEEDED_FOR_PAGING );
                break;
            }
            catch (const io::IOException&)
            {
                installError( CommandId,
                              TaskHandlerErr::IOEXCEPTION_FOR_PAGING );
                break;
            }
        }
        else
        {
            installError( CommandId,
                          TaskHandlerErr::READING_FILE_FOR_PAGING,
                          err );
            break;
        }
    } while( nrc == bfz );


    aFile.close();


    try
    {
        xOutputStream->closeOutput();
    }
    catch (const io::NotConnectedException&)
    {
    }
    catch (const io::BufferSizeExceededException&)
    {
    }
    catch (const io::IOException&)
    {
    }
}


/*********************************************************************************/
/*                                                                               */
/*                     open-Implementation                                       */
/*                                                                               */
/*********************************************************************************/

//  Given a file URL aUnqPath, this methods returns a XInputStream which reads from the open file.


uno::Reference< io::XInputStream >
TaskManager::open( sal_Int32 CommandId,
             const OUString& aUnqPath,
             bool bLock )
{
    rtl::Reference<XInputStream_impl> pInputStream(new XInputStream_impl( aUnqPath, bLock )); // from filinpstr.hxx

    TaskHandlerErr ErrorCode = pInputStream->CtorSuccess();

    if( ErrorCode != TaskHandlerErr::NO_ERROR )
    {
        installError( CommandId,
                      ErrorCode,
                      pInputStream->getMinorError() );

        pInputStream.clear();
    }

    return pInputStream;
}


/*********************************************************************************/
/*                                                                               */
/*                     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 >
TaskManager::open_rw( sal_Int32 CommandId,
                const OUString& aUnqPath,
                bool bLock )
{
    rtl::Reference<XStream_impl> pStream(new XStream_impl( aUnqPath, bLock ));  // from filstr.hxx

    TaskHandlerErr ErrorCode = pStream->CtorSuccess();

    if( ErrorCode != TaskHandlerErr::NO_ERROR )
    {
        installError( CommandId,
                      ErrorCode,
                      pStream->getMinorError() );

        pStream.clear();
    }
    return pStream;
}


/*********************************************************************************/
/*                                                                               */
/*                       ls-Implementation                                       */
/*                                                                               */
/*********************************************************************************/

//  This method returns the result set containing the children of the directory belonging
//  to file URL aUnqPath


uno::Reference< XDynamicResultSet >
TaskManager::ls( sal_Int32 CommandId,
           const OUString& aUnqPath,
           const sal_Int32 OpenMode,
           const uno::Sequence< beans::Property >& seq,
           const uno::Sequence< NumberedSortingInfo >& seqSort )
{
    rtl::Reference<XResultSet_impl> p(new XResultSet_impl( this,aUnqPath,OpenMode,seq,seqSort ));

    TaskHandlerErr ErrorCode = p->CtorSuccess();

    if( ErrorCode != TaskHandlerErr::NO_ERROR )
    {
        installError( CommandId,
                      ErrorCode,
                      p->getMinorError() );

        p.clear();
    }

    return p;
}


/*********************************************************************************/
/*                                                                               */
/*                          info_c implementation                                */
/*                                                                               */
/*********************************************************************************/
// Info for commands

uno::Reference< XCommandInfo >
TaskManager::info_c()
{
    return new XCommandInfo_impl( this );
}


/*********************************************************************************/
/*                                                                               */
/*                     info_p-Implementation                                     */
/*                                                                               */
/*********************************************************************************/
// Info for the properties

uno::Reference< beans::XPropertySetInfo >
TaskManager::info_p( const OUString& aUnqPath )
{
    std::unique_lock aGuard( m_aMutex );
    return new XPropertySetInfo_impl( this,aUnqPath );
}


/*********************************************************************************/
/*                                                                               */
/*                     setv-Implementation                                       */
/*                                                                               */
/*********************************************************************************/

//  Sets the values of the properties belonging to fileURL aUnqPath


uno::Sequence< uno::Any >
TaskManager::setv( const OUString& aUnqPath,
             const uno::Sequence< beans::PropertyValue >& values )
{
    std::unique_lock aGuard( m_aMutex );

    sal_Int32 propChanged = 0;
    uno::Sequence< uno::Any > ret( values.getLength() );
    auto retRange = asNonConstRange(ret);
    uno::Sequence< beans::PropertyChangeEvent > seqChanged( values.getLength() );
    auto seqChangedRange = asNonConstRange(seqChanged);

    TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
    PropertySet& properties = it->second.properties;
    TaskManager::PropertySet::const_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() )
        {
            retRange[i] <<= beans::UnknownPropertyException( THROW_WHERE );
            continue;
        }

        aAny = it1->getValue();
        if( aAny == values[i].Value )
            continue;  // nothing needs to be changed

        if( it1->getAttributes() & beans::PropertyAttribute::READONLY )
        {
            retRange[i] <<= lang::IllegalAccessException( THROW_WHERE );
            continue;
        }

        seqChangedRange[ propChanged   ].PropertyName = values[i].Name;
        seqChangedRange[ propChanged   ].PropertyHandle   = -1;
        seqChangedRange[ propChanged   ].Further   = false;
        seqChangedRange[ propChanged   ].OldValue = aAny;
        seqChangedRange[ 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
                retRange[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(osl_File_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(comphelper::InitAnyPropertySequence(
                        {
                            {"Uri", uno::Any(aUnqPath)}
                        }));
                        retRange[i] <<= InteractiveAugmentedIOException(
                            OUString(),
                            nullptr,
                            task::InteractionClassification_ERROR,
                            IOErrorCode_GENERAL,
                            names );
                    }
                }
                else
                    retRange[i] <<= beans::IllegalTypeException( THROW_WHERE );
            }
            else if(values[i].Name == IsReadOnly ||
                    values[i].Name == IsHidden)
            {
                bool value = 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(osl_FileStatus_Mask_Attributes);
                        err = aDirItem.getFileStatus(aFileStatus);
                        if(err == osl::FileBase::E_None &&
                           aFileStatus.isValid(osl_FileStatus_Mask_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 &= ~(osl_File_Attribute_OwnWrite |
                                             osl_File_Attribute_GrpWrite |
                                             osl_File_Attribute_OthWrite |
                                             osl_File_Attribute_ReadOnly);
                            if(value)
                                nAttributes |= osl_File_Attribute_ReadOnly;
                            else
                                nAttributes |= (
                                    osl_File_Attribute_OwnWrite |
                                    osl_File_Attribute_GrpWrite |
                                    osl_File_Attribute_OthWrite);
                        }
                        else if(values[i].Name == IsHidden)
                        {
                            nAttributes &= ~(osl_File_Attribute_Hidden);
                            if(value)
                                nAttributes |= osl_File_Attribute_Hidden;
                        }
                        err = osl::File::setAttributes(
                            aUnqPath,nAttributes);
                    }

                    if( err != osl::FileBase::E_None )
                    {
                        --propChanged; // unsuccessful setting
                        uno::Sequence<uno::Any> names(comphelper::InitAnyPropertySequence(
                        {
                            {"Uri", uno::Any(aUnqPath)}
                        }));
                        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;
                        }
                        retRange[i] <<= InteractiveAugmentedIOException(
                            OUString(),
                            nullptr,
                            task::InteractionClassification_ERROR,
                            ioError,
                            names );
                    }
                }
                else
                    retRange[i] <<= beans::IllegalTypeException( THROW_WHERE );
            }
        }
    }   // end for

    aGuard.unlock();
    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 >
TaskManager::getv( sal_Int32 CommandId,
             const OUString& aUnqPath,
             const uno::Sequence< beans::Property >& properties )
{
    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,
                     TaskHandlerErr::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,
                     TaskHandlerErr::OPEN_FILE_FOR_PAGING, // BEAWARE, REUSED
                     nError2);

    {
        std::unique_lock aGuard( m_aMutex );

        TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
        commit( aGuard, it, aFileStatus );

        PropertySet& propset = it->second.properties;

        std::transform(properties.begin(), properties.end(), seq.getArray(),
            [&propset](const beans::Property& rProp) -> uno::Any {
                MyProperty readProp( rProp.Name );
                auto it1 = propset.find( readProp );
                if( it1 == propset.end() )
                    return uno::Any();
                return it1->getValue();
            });
    }

    return new XRow_impl( this,seq );
}


/********************************************************************************/
/*                                                                              */
/*                         transfer-commandos                                   */
/*                                                                              */
/********************************************************************************/


/********************************************************************************/
/*                                                                              */
/*                         move-implementation                                  */
/*                                                                              */
/********************************************************************************/

//  Moves the content belonging to fileURL srcUnqPath to fileURL dstUnqPath.


void
TaskManager::move( sal_Int32 CommandId,
             const OUString& srcUnqPath,
             const OUString& dstUnqPathIn,
             const sal_Int32 NameClash )
{
    // --> #i88446# Method notifyContentExchanged( getContentExchangedEventListeners( srcUnqPath,dstUnqPath,!isDocument ) ); crashes if
    // srcUnqPath and dstUnqPathIn are equal
    if( srcUnqPath == dstUnqPathIn )
        return;

    osl::FileBase::RC nError;
    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,
                              TaskHandlerErr::KEEPERROR_FOR_MOVE,
                              nError );
                return;
            }
            break;
        }
    case NameClash::OVERWRITE:
        {
            // stat to determine whether we have a symlink
            OUString targetPath(dstUnqPath);

            osl::FileStatus aStatus(osl_FileStatus_Mask_Type|osl_FileStatus_Mask_LinkTargetURL);
            osl::DirectoryItem aItem;
            (void)osl::DirectoryItem::get(dstUnqPath,aItem);
            (void)aItem.getFileStatus(aStatus);

            if( aStatus.isValid(osl_FileStatus_Mask_Type)          &&
                aStatus.isValid(osl_FileStatus_Mask_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,
                              TaskHandlerErr::OVERWRITE_FOR_MOVE,
                              nError );
                return;
            }
            break;
        }
    case NameClash::RENAME:
        {
            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;

                    OUString aPostfix =  "_" + OUString::number( ++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,
                              TaskHandlerErr::RENAME_FOR_MOVE );
                return;
            }
            else if( nError != osl::FileBase::E_None )
            {
                installError( CommandId,
                              TaskHandlerErr::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,
                              TaskHandlerErr::NAMECLASH_FOR_MOVE );
                return;
            }
            else if( nError != osl::FileBase::E_None )
            {
                installError( CommandId,
                              TaskHandlerErr::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,
                              TaskHandlerErr::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,
                      TaskHandlerErr::TRANSFER_BY_MOVE_SOURCE,
                      nError );
        return;
    }
    osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
    nError = aItem.getFileStatus( aStatus );
    if( nError != osl::FileBase::E_None || ! aStatus.isValid( osl_FileStatus_Mask_Type ) )
    {
        installError( CommandId,
                      TaskHandlerErr::TRANSFER_BY_MOVE_SOURCESTAT,
                      nError );
        return;
    }
    bool isDocument = ( aStatus.getFileType() == osl::FileStatus::Regular );


    copyPersistentSet( srcUnqPath,dstUnqPath,!isDocument );

    OUString aDstParent = getParentName( dstUnqPath );
    OUString aSrcParent = getParentName( 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, OUString const & fileUrl,
    osl::DirectoryItem * item, osl::FileStatus::Type * type)
{
    assert(item != nullptr && type != nullptr);
    osl::FileBase::RC err = osl::DirectoryItem::get(fileUrl, *item);
    if (err != osl::FileBase::E_None) {
        task.installError(id, TaskHandlerErr::TRANSFER_BY_COPY_SOURCE, err);
        return false;
    }
    osl::FileStatus stat(osl_FileStatus_Mask_Type);
    err = item->getFileStatus(stat);
    if (err != osl::FileBase::E_None) {
        task.installError(id, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT, err);
        return false;
    }
    *type = stat.getFileType();
    return true;
}

}

void
TaskManager::copy(
    sal_Int32 CommandId,
    const OUString& srcUnqPath,
    const OUString& dstUnqPathIn,
    sal_Int32 NameClash )
{
    osl::FileBase::RC nError;
    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;
    }
    OUString rslvdSrcUnqPath;
    if (type == osl::FileStatus::Link) {
        osl::FileStatus stat(osl_FileStatus_Mask_LinkTargetURL);
        nError = item.getFileStatus(stat);
        if (nError != osl::FileBase::E_None) {
            installError(
                CommandId, TaskHandlerErr::TRANSFER_BY_COPY_SOURCESTAT, nError);
            return;
        }
        rslvdSrcUnqPath = stat.getLinkTargetURL();
        if (!getType(*this, CommandId, srcUnqPath, &item, &type)) {
            return;
        }
    } else {
        rslvdSrcUnqPath = srcUnqPath;
    }

    bool isDocument
        = type != osl::FileStatus::Directory && type != osl::FileStatus::Volume;
    FileUrlType IsWhat = isDocument ? FileUrlType::File : FileUrlType::Folder;

    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,
                              TaskHandlerErr::KEEPERROR_FOR_COPY,
                              nError );
                return;
            }
            break;
        }
        case NameClash::OVERWRITE:
        {
            // remove (..., MustExist = sal_False).
            remove( CommandId, dstUnqPath, IsWhat, false );

            // copy.
            nError = copy_recursive( rslvdSrcUnqPath,dstUnqPath,IsWhat,false );
            if( nError != osl::FileBase::E_None )
            {
                installError( CommandId,
                              TaskHandlerErr::OVERWRITE_FOR_COPY,
                              nError );
                return;
            }
            break;
        }
        case NameClash::RENAME:
        {
            OUString newDstUnqPath = dstUnqPath;
            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;

                    OUString aPostfix =  "_" + OUString::number( ++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,
                              TaskHandlerErr::RENAME_FOR_COPY );
                return;
            }
            else if( nError != osl::FileBase::E_None )
            {
                installError( CommandId,
                              TaskHandlerErr::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,
                              TaskHandlerErr::NAMECLASH_FOR_COPY );
                return;
            }
            else if( nError != osl::FileBase::E_None )
            {
                installError( CommandId,
                              TaskHandlerErr::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,
                              TaskHandlerErr::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


bool
TaskManager::remove( sal_Int32 CommandId,
               const OUString& aUnqPath,
               FileUrlType IsWhat,
               bool  MustExist )
{
    sal_Int32 nMask = osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL;

    osl::DirectoryItem aItem;
    osl::FileStatus aStatus( nMask );
    osl::FileBase::RC nError;

    if( IsWhat == FileUrlType::Unknown ) // 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,
                              TaskHandlerErr::NOSUCHFILEORDIR_FOR_REMOVE,
                              nError );
            }
            return (!MustExist);
        }

        nError = aItem.getFileStatus( aStatus );
        if( nError != osl::FileBase::E_None || ! aStatus.isValid( nMask ) )
        {
            installError( CommandId,
                          TaskHandlerErr::VALIDFILESTATUS_FOR_REMOVE,
                          nError != osl::FileBase::E_None ? nError : 0 );
            return false;
        }

        if( aStatus.getFileType() == osl::FileStatus::Regular ||
            aStatus.getFileType() == osl::FileStatus::Link )
            IsWhat = FileUrlType::File;
        else if(  aStatus.getFileType() == osl::FileStatus::Directory ||
                  aStatus.getFileType() == osl::FileStatus::Volume )
            IsWhat = FileUrlType::Folder;
    }


    if( IsWhat == FileUrlType::File )
    {
        nError = osl::File::remove( aUnqPath );
        if( nError != osl::FileBase::E_None )
        {
            if (MustExist)
            {
                installError( CommandId,
                              TaskHandlerErr::DELETEFILE_FOR_REMOVE,
                              nError );
            }
            return (!MustExist);
        }
        else
        {
            notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
            erasePersistentSet( aUnqPath ); // Removes from XPersistentPropertySet
        }
    }
    else if( IsWhat == FileUrlType::Folder )
    {
        osl::Directory aDirectory( aUnqPath );

        nError = aDirectory.open();
        if( nError != osl::FileBase::E_None )
        {
            if (MustExist)
            {
                installError( CommandId,
                              TaskHandlerErr::OPENDIRECTORY_FOR_REMOVE,
                              nError );
            }
            return (!MustExist);
        }

        bool whileSuccess = true;
        FileUrlType recurse = FileUrlType::Unknown;
        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,
                              TaskHandlerErr::VALIDFILESTATUSWHILE_FOR_REMOVE,
                              nError != osl::FileBase::E_None ? nError : 0 );
                whileSuccess = false;
                break;
            }

            if( aStatus.getFileType() == osl::FileStatus::Regular ||
                aStatus.getFileType() == osl::FileStatus::Link )
                recurse = FileUrlType::File;
            else if( aStatus.getFileType() == osl::FileStatus::Directory ||
                     aStatus.getFileType() == osl::FileStatus::Volume )
                recurse = FileUrlType::Folder;

            name = aStatus.getFileURL();
            whileSuccess = remove( CommandId, name, recurse, MustExist );
            if( !whileSuccess )
                break;

            nError = aDirectory.getNextItem( aItem );
        }

        aDirectory.close();

        if( ! whileSuccess )
            return false;     // error code is installed

        if( nError != osl::FileBase::E_NOENT )
        {
            installError( CommandId,
                          TaskHandlerErr::DIRECTORYEXHAUSTED_FOR_REMOVE,
                          nError );
            return false;
        }

        nError = osl::Directory::remove( aUnqPath );
        if( nError != osl::FileBase::E_None )
        {
            if (MustExist)
            {
                installError( CommandId,
                              TaskHandlerErr::DELETEDIRECTORY_FOR_REMOVE,
                              nError );
            }
            return (!MustExist);
        }
        else
        {
            notifyContentDeleted( getContentDeletedEventListeners(aUnqPath) );
            erasePersistentSet( aUnqPath );
        }
    }
    else   // Don't know what to remove
    {
        installError( CommandId,
                      TaskHandlerErr::FILETYPE_FOR_REMOVE );
        return false;
    }

    return true;
}


/********************************************************************************/
/*                                                                              */
/*                         mkdir-implementation                                 */
/*                                                                              */
/********************************************************************************/

//  Creates new directory with given URL, recursively if necessary
//  Return:: success of operation


bool
TaskManager::mkdir( sal_Int32 CommandId,
              const OUString& rUnqPath,
              bool OverWrite )
{
    OUString aUnqPath;

    // remove trailing slash
    if ( rUnqPath.endsWith("/") )
        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,
                              TaskHandlerErr::FOLDER_EXISTS_MKDIR );
                return false;
            }
            else
                return true;
        }
        case osl::FileBase::E_INVAL:
        {
            installError(CommandId,
                         TaskHandlerErr::INVALID_NAME_MKDIR);
            return false;
        }
        case osl::FileBase::E_None:
        {
            OUString aPrtPath = getParentName( aUnqPath );
            notifyInsert( getContentEventListeners( aPrtPath ),aUnqPath );
            return true;
        }
        default:
            return ensuredir(
                CommandId,
                aUnqPath,
                TaskHandlerErr::CREATEDIRECTORY_MKDIR );
    }
}


/********************************************************************************/
/*                                                                              */
/*                         mkfil-implementation                                 */
/*                                                                              */
/********************************************************************************/

//  Creates new file with given URL.
//  The content of aInputStream becomes the content of the file
//  Return:: success of operation


bool
TaskManager::mkfil( sal_Int32 CommandId,
              const OUString& aUnqPath,
              bool Overwrite,
              const uno::Reference< io::XInputStream >& aInputStream )
{
    // return value unimportant
    bool bSuccess = write( CommandId,
                               aUnqPath,
                               Overwrite,
                               aInputStream );
    if ( bSuccess )
    {
        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


bool
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=90 H=98 G=94

¤ Dauer der Verarbeitung: 0.19 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.