remotestoragefw/remotefileengine/src/rsfwdeletestatemachine.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:07:59 +0200
changeset 0 3ad9d5175a89
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Delete a file or directory
*
*/


#include "rsfwdeletestatemachine.h"
#include "rsfwfileentry.h"
#include "rsfwfiletable.h"
#include "rsfwinterface.h"
#include "rsfwfileengine.h"
#include "mdebug.h"
#include "rsfwdirent.h"


// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::CRsfwDeleteStateMachine
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::CRsfwDeleteStateMachine(TUint aNodeType)
    : iNodeType(aNodeType)
    {
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::~CRsfwDeleteStateMachine
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::~CRsfwDeleteStateMachine()
    {
    iDirEnts.ResetAndDestroy();
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::CompleteRequestL
// ----------------------------------------------------------------------------
//
CRsfwRfeStateMachine::TState* CRsfwDeleteStateMachine::CompleteRequestL(TInt aError)
    {
    if (iKidPath)
        {
        delete iKidPath;
        iKidPath = NULL;
        }

    // If the return code was KErrInUse, the directory we were about to delete
    // was not empty, and we couldn't delete it. In this case it has anyway
    //been added to the cache (as a side effect),
    // so we don't want to delete the fep.
    if (aError != KErrInUse && iKidCreated)
        {
        delete iKidFep;
        iKidFep = NULL;
        }

    CompleteAndDestroyState()->SetErrorCode(aError);
    return CompleteAndDestroyState();
    }

// Check if exists


// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::TCheckIfCanBeDeleted
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::
TCheckIfCanBeDeleted::TCheckIfCanBeDeleted(CRsfwDeleteStateMachine* aParent)
    : iOperation(aParent)
    {
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::EnterL
// ----------------------------------------------------------------------------
//
void CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::EnterL()
    {
    // Kidname is in the same place in remove and rmdir structures,,,
    TRfeRemoveInArgs* inArgs =
        static_cast<TRfeRemoveInArgs*>(iOperation->iInArgs);
    TPtrC kidName(inArgs->iName);

    // the parent from which we are removing
    if (!iOperation->Node())
        {
        User::Leave(KErrNotFound);
        }

    DEBUGSTRING16(("removing entry '%S' from fid %d",
                   &kidName,
                   iOperation->Node()->Fid().iNodeId));

    // Do we know about the kid yet?
    iOperation->iKidFep = iOperation->Node()->FindKidByName(kidName);
    if (!iOperation->iKidFep)
        {
        // Create a temporary file entry for the target
        iOperation->iKidFep = CRsfwFileEntry::NewL(kidName, iOperation->Node());
        iOperation->iKidCreated = ETrue;
        }

    // Ensure the type matches with the operation (RmDir() or Delete())
    if ((iOperation->iKidFep->Type() != KNodeTypeUnknown) &&
        (iOperation->iKidFep->Type() != iOperation->iNodeType))
        {
        DEBUGSTRING(("object type does not match the parameter type!"));
        User::Leave(KErrArgument);
        }

    // if the type is unknown, set it from the operation parameter
    if (iOperation->iKidFep->Type() == KNodeTypeUnknown)
        {
        iOperation->iKidFep->SetType(iOperation->iNodeType);
        }

    // If it is a directory, check that it is empty
    if (!iOperation->FileEngine()->Disconnected() &&
        iOperation->iNodeType == KNodeTypeDir)
        {
        TInt zero = 0;
        iOperation->FileEngine()->
            FetchAndCacheL(*iOperation->iKidFep,
                           0,
                           &zero,
                           &iOperation->iDirEnts,
                           iOperation);
        }
    else
        {
        iOperation->HandleRemoteAccessResponse(0, KErrNone);
        }
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::CompleteL
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::TState*
CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::CompleteL()
    {
    if ((iOperation->iNodeType == KNodeTypeDir) &&
        ((iOperation->iDirEnts).Count() > 0))
        {
        // Attach the directory itself if it was unknown
        if (iOperation->iKidCreated)
            {
            iOperation->FileEngine()->iFileTable->AddL(iOperation->iKidFep);
            iOperation->Node()->AddKid(*iOperation->iKidFep);
            }
            
        // if the directory is not empty we cannot delete it
        // however, let's add its entries to the cache
        iOperation->FileEngine()->AddToCacheL(
            *iOperation->iKidFep,
            &iOperation->iDirEnts,
            iOperation->FileEngine(),
            0);

        return iOperation->CompleteRequestL(KErrInUse);
        }
    else
        {
        return new CRsfwDeleteStateMachine::TDeleteNodeState(iOperation);
        }
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::ErrorL
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::TState*
CRsfwDeleteStateMachine::TCheckIfCanBeDeleted::ErrorL(TInt aCode)
    {
    DEBUGSTRING(("kid didn't exist!"));
    return iOperation->CompleteRequestL(aCode);
    }

// Remove directory

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TDeleteNodeState::TDeleteNodeState
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::
TDeleteNodeState::TDeleteNodeState(CRsfwDeleteStateMachine* aParent)
    : iOperation(aParent)
    {
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TDeleteNodeState::EnterL
// ----------------------------------------------------------------------------
//
void CRsfwDeleteStateMachine::TDeleteNodeState::EnterL()
    {
    // Get the path for the actual remove
    iOperation->iKidPath =
        iOperation->FileEngine()->FullNameL(*iOperation->iKidFep);
    if (!iOperation->FileEngine()->Disconnected())
        {
        if (iOperation->iNodeType == KNodeTypeDir)
            {
            iOperation->
                FileEngine()->
                RemoteAccessL()->DeleteDirectoryL(*iOperation->iKidPath,
                                                  iOperation);
            }
        else // KNodeTypFile
            {
            iOperation->
                FileEngine()->
                RemoteAccessL()->DeleteFileL(*iOperation->iKidPath,
                                             iOperation);
            }
        }
    else
        {
        // Disconnected
        iOperation->HandleRemoteAccessResponse(0, KErrNone);
        }
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TDeleteNodeState::CompleteL
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::TState* CRsfwDeleteStateMachine::TDeleteNodeState::CompleteL()
    {
    if (!iOperation->FileEngine()->Disconnected())
        {
        // If the target was already known, remove and destroy it
        if (!iOperation->iKidCreated)
            {
            iOperation->FileEngine()->iFileTable->RemoveL(iOperation->iKidFep);
            delete iOperation->iKidFep;
            iOperation->iKidFep = NULL;
            }
        }

    iOperation->Node()->SetLocallyDirty();
    return iOperation->CompleteRequestL(KErrNone);
    }

// ----------------------------------------------------------------------------
// CRsfwDeleteStateMachine::TDeleteNodeState::ErrorL
// ----------------------------------------------------------------------------
//
CRsfwDeleteStateMachine::TState*
CRsfwDeleteStateMachine::TDeleteNodeState::ErrorL(TInt aCode)
    {
    return iOperation->CompleteRequestL(aCode);
    }