mtpdataproviders/mtpimagedp/src/cmtpimagedpmoveobject.cpp
changeset 0 d0791faffa3f
child 2 4843bb5893b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpdataproviders/mtpimagedp/src/cmtpimagedpmoveobject.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,305 @@
+// Copyright (c) 2009 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:
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <f32file.h>
+#include <bautils.h>
+#include <pathinfo.h> // PathInfo
+#include <sysutil.h>
+
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/mmtpstoragemgr.h>
+#include <mtp/cmtpobjectmetadata.h>
+#include <mtp/cmtptypearray.h>
+#include <mtp/cmtptypestring.h>
+
+#include "cmtpimagedpmoveobject.h"
+#include "mtpimagedppanic.h"
+#include "cmtpimagedpobjectpropertymgr.h"
+#include "mtpimagedputilits.h"
+#include "cmtpimagedpthumbnailcreator.h"
+#include "cmtpimagedp.h"
+
+__FLOG_STMT(_LIT8(KComponent,"MoveObject");)
+
+/**
+Verification data for the MoveObject request
+*/    
+const TMTPRequestElementInfo KMTPMoveObjectPolicy[] = 
+    {
+        {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeStorageId, EMTPElementAttrWrite, 0, 0, 0},
+        {TMTPTypeRequest::ERequestParameter3, EMTPElementTypeObjectHandle, EMTPElementAttrDir | EMTPElementAttrWrite, 1, 0, 0}
+    };
+
+/**
+Two-phase construction method
+@param aPlugin	The data provider plugin
+@param aFramework	The data provider framework
+@param aConnection	The connection from which the request comes
+@return a pointer to the created request processor object
+*/     
+MMTPRequestProcessor* CMTPImageDpMoveObject::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,CMTPImageDataProvider& aDataProvider)
+    {
+    CMTPImageDpMoveObject* self = new (ELeave) CMTPImageDpMoveObject(aFramework, aConnection,aDataProvider);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor
+*/	
+CMTPImageDpMoveObject::~CMTPImageDpMoveObject()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::~CMTPImageDpMoveObject")); 
+    delete iDest;
+    delete iFileMan;
+    delete iObjectInfo;
+    __FLOG(_L8("<< CMTPImageDpMoveObject::~CMTPImageDpMoveObject"));
+    __FLOG_CLOSE;
+    }
+
+/**
+Standard c++ constructor
+*/	
+CMTPImageDpMoveObject::CMTPImageDpMoveObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,CMTPImageDataProvider& aDataProvider) :
+    CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPMoveObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPMoveObjectPolicy),
+    iDataProvider(aDataProvider)
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);
+    }
+	
+/**
+ Second phase constructor
+*/
+void CMTPImageDpMoveObject::ConstructL()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::ConstructL")); 
+    iFileMan = CFileMan::NewL(iFramework.Fs());
+    iObjectInfo = CMTPObjectMetaData::NewL();
+    __FLOG(_L8("<< CMTPImageDpMoveObject::ConstructL")); 
+    }
+
+TMTPResponseCode CMTPImageDpMoveObject::CheckRequestL()
+    {
+    __FLOG(_L8(">> CMTPImageDpCopyObject::CheckRequestL"));
+    TMTPResponseCode responseCode = CMTPRequestProcessor::CheckRequestL();
+    if (EMTPRespCodeOK == responseCode)
+        {
+        TUint32 objectHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
+        // Check whether object handle is valid
+        responseCode = MTPImageDpUtilits::VerifyObjectHandleL(iFramework, objectHandle, *iObjectInfo);
+        }
+    else if(EMTPRespCodeInvalidObjectHandle == responseCode) //we only check the parent handle
+        {
+        responseCode = EMTPRespCodeInvalidParentObject;
+        }
+    
+    __FLOG_VA((_L8("CheckRequestL - Exit with responseCode = 0x%04X"), responseCode));
+    __FLOG(_L8("<< CMTPImageDpCopyObject::CheckRequestL"));
+    return responseCode;
+    }
+
+/**
+MoveObject request handler
+*/		
+void CMTPImageDpMoveObject::ServiceL()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::ServiceL"));
+    
+    TMTPResponseCode ret = MoveObjectL();
+    SendResponseL(ret);
+    
+    __FLOG(_L8("<< CMTPImageDpMoveObject::ServiceL")); 
+    }
+
+/**
+A helper function of MoveObjectL.
+@param aNewFileName the new file name after the object is moved.
+*/
+TMTPResponseCode CMTPImageDpMoveObject::MoveFileL(const TDesC& aOldFileName, const TDesC& aNewFileName)	
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::MoveFileL"));
+    
+    TMTPResponseCode responseCode = EMTPRespCodeOK;    
+    /**
+     * File system process the move operation has two different ways:
+     * 1. move object between the same storage.
+     *    under this situation, move operatoin will triggers the EFsRename event by file system.
+     *    then harvester of MdS will directly update the uri of mde object.      
+     *    
+     * 2. move object tetween the different storage.
+     *    uder this situation, move operation will triggers four events by file system:
+     *    a. EFsFileReplace event for old uri object.
+     *    b. EFsFileReplace event for new uri object.
+     *    c. EFsFileSetModified event for DateModified property of object.
+     *    d. EFsDelete event for old uri object.
+     *    
+     *    then harvester of MdS will generate four actions for the above events:
+     *    a. EMdsFileReplaced action for old uri object, this action is a null operation, because no object associates with old uri.
+     *    b. EMdsFileReplaced action for new uri object, this action will add a new mde object into database and 
+     *       put this action into queue of image plugin to wait for execution.
+     *    c. EmdsFileModified action for new object, this action will update the DateModified property of mde object and
+     *       put this action into queue of image plugin to wait for execution.
+     *    d. EmdsFileDeleted action for old object, this action will directly delete old mde object from database.
+     */
+    
+    /**
+     * image dp should update object properties in database to avoid race condition with MdS,
+     * if move faile, it should rollback.
+     */
+    
+    TUint oldStoradId = iObjectInfo->Uint(CMTPObjectMetaData::EStorageId);
+    TUint oldParentHandle = iObjectInfo->Uint(CMTPObjectMetaData::EParentHandle);    
+    iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName);
+    iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
+    iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
+    iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
+    __FLOG_VA((_L16("CMTPImageDpMoveObject::MoveFileL - Update object info:%S"), &aNewFileName));
+    
+    TInt ret = MoveImageFile(aOldFileName, *iDest);
+    if (ret != KErrNone)
+        {
+        //rollback
+        __FLOG_VA((_L16("CMTPImageDpMoveObject::MoveFileL - Rollback")));
+        iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aOldFileName);
+        iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, oldStoradId);
+        iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, oldParentHandle);
+        iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);       
+        responseCode = EMTPRespCodeGeneralError;        
+        }
+    __FLOG_VA((_L8("CMTPImageDpMoveObject::MoveFileL - MoveImageFile:%d"), ret));
+    
+    __FLOG(_L8("<< CMTPImageDpMoveObject::MoveFileL")); 	
+    return responseCode;
+    }
+/**
+move object operations
+@return A valid MTP response code.
+*/
+TMTPResponseCode CMTPImageDpMoveObject::MoveObjectL()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::MoveObjectL"));
+    TMTPResponseCode responseCode = EMTPRespCodeOK;
+    GetParametersL();
+    RBuf newObjectName;
+    newObjectName.CreateL(KMaxFileName);
+    newObjectName.CleanupClosePushL();
+    newObjectName = *iDest;
+    TFileName oldFileName = iObjectInfo->DesC(CMTPObjectMetaData::ESuid);
+    TParsePtrC fileNameParser(oldFileName);
+    if((newObjectName.Length() + fileNameParser.NameAndExt().Length()) <= newObjectName.MaxLength())
+        {
+        newObjectName.Append(fileNameParser.NameAndExt());
+        responseCode = CanMoveObjectL(oldFileName, newObjectName);
+        }
+    else
+        {
+        responseCode = EMTPRespCodeGeneralError;
+        }
+        
+    if(responseCode == EMTPRespCodeOK)
+        {
+        responseCode = MoveFileL(oldFileName, newObjectName);
+        }
+    CleanupStack::PopAndDestroy(); // newObjectName.
+    __FLOG(_L8("<< CMTPImageDpMoveObject::MoveObjectL")); 	
+    return responseCode;
+    }
+
+/**
+Retrieve the parameters of the request
+*/	
+void CMTPImageDpMoveObject::GetParametersL()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::GetParametersL"));
+    __ASSERT_DEBUG(iRequestChecker, Panic(EMTPImageDpRequestCheckNull));
+    
+    TUint32 objectHandle  = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
+    iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
+    iNewParentHandle  = Request().Uint32(TMTPTypeRequest::ERequestParameter3);
+    
+    if(iNewParentHandle == 0)
+        {
+        SetDefaultParentObjectL();
+        }
+    else	
+        {
+        CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iNewParentHandle);
+        __ASSERT_DEBUG(parentObjectInfo, Panic(EMTPImageDpObjectNull));
+        delete iDest;
+        iDest = NULL;
+        iDest = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL();
+        }
+    __FLOG(_L8("<< CMTPImageDpMoveObject::GetParametersL"));
+    }
+    
+/**
+Get a default parent object, ff the request does not specify a parent object, 
+*/
+void CMTPImageDpMoveObject::SetDefaultParentObjectL()
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::SetDefaultParentObjectL"));  
+    const CMTPStorageMetaData& storage = iFramework.StorageMgr().StorageL(iStorageId);
+    delete iDest;
+    iDest = NULL;
+    iDest = storage.DesC(CMTPStorageMetaData::EStorageSuid).AllocL();
+    iNewParentHandle = KMTPHandleNoParent;
+    __FLOG(_L8("<< CMTPImageDpMoveObject::SetDefaultParentObjectL"));  
+    }
+
+/**
+Check if we can move the file to the new location
+*/
+TMTPResponseCode CMTPImageDpMoveObject::CanMoveObjectL(const TDesC& aOldName, const TDesC& aNewName) const
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::CanMoveObjectL"));     
+    TMTPResponseCode result = EMTPRespCodeOK;
+
+    TEntry fileEntry;
+    User::LeaveIfError(iFramework.Fs().Entry(aOldName, fileEntry));
+    TDriveNumber drive(static_cast<TDriveNumber>(iFramework.StorageMgr().DriveNumber(iStorageId)));
+    User::LeaveIfError(drive);
+    TVolumeInfo volumeInfo;
+    User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive));
+    
+    if(volumeInfo.iFree < fileEntry.iSize)
+        {
+        result = EMTPRespCodeStoreFull;
+        }
+    else if (BaflUtils::FileExists(iFramework.Fs(), aNewName))			
+        {
+        result = EMTPRespCodeInvalidParentObject;
+        }
+    __FLOG_VA((_L8("CanMoveObjectL - Exit with response code 0x%04X"), result));
+    __FLOG(_L8("<< CMTPImageDpMoveObject::CanMoveObjectL"));     
+    return result;	
+    }
+
+TInt CMTPImageDpMoveObject::MoveImageFile(const TDesC& aOldImageName, const TDesC& aNewImageName)
+    {
+    __FLOG(_L8(">> CMTPImageDpMoveObject::MoveImageFile"));
+    __FLOG_VA((_L8("move image src: %S dest: %S"), &aOldImageName, &aNewImageName));        
+    __FLOG(_L8("<< CMTPImageDpMoveObject::MoveImageFile"));
+    return iFileMan->Move(aOldImageName, aNewImageName);
+    }
+
+// End of file