harvester/monitorplugins/fileplugin/src/FolderRenamer.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/harvester/monitorplugins/fileplugin/src/FolderRenamer.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,280 @@
+/*
+* 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:
+*
+*/
+
+#include <e32std.h>
+
+#include "FolderRenamer.h"
+#include "harvesterlog.h"
+#include "mdeharvestersession.h"
+#include "mdeharvestersession.h"
+#include "harvesterdata.h"
+#include "fileeventhandlerao.h"
+#include "harvestercommon.h"
+
+CRenameItem * CRenameItem::NewL(
+		const TDesC &aOldName, const TDesC &aNewName)
+	{	
+	CRenameItem *self = new (ELeave) CRenameItem();
+	CleanupStack::PushL(self);
+	self->ConstructL(aOldName,aNewName);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+CRenameItem::~CRenameItem()
+	{
+	delete iOldName;
+	delete iNewName;
+	iFileEvents.ResetAndDestroy();
+	}
+	
+
+void CRenameItem::ConstructL(const TDesC &aOldName, const TDesC &aNewName)
+	{
+	iOldName = HBufC::NewL( aOldName.Length() );
+	iNewName = HBufC::NewL( aNewName.Length() );
+
+	// convert paths to lower case
+	// Note: CopyLC doesn't push anything to cleanup stack
+	iOldName->Des().CopyLC( aOldName );
+	iNewName->Des().CopyLC( aNewName );
+	}
+
+CRenameItem::CRenameItem() : iOldName( NULL ), iNewName( NULL )
+	{
+	//No implementation required
+	}
+
+void CRenameItem::AddFileEvent(TMdsFSPStatus &aEvent)
+	{
+	TMdsFSPStatus* event = NULL;
+	event = new TMdsFSPStatus(aEvent);
+	if (event)
+		{
+		iFileEvents.Append(event);
+		}
+	}
+
+void CRenameItem::HandleFileEventsL(CFileEventHandlerAO &aCFileEventHandlerAO)
+	{
+	TInt count = iFileEvents.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		aCFileEventHandlerAO.HandleNotificationL(* (iFileEvents[i]));
+		}
+	iFileEvents.ResetAndDestroy();
+	}
+
+TPtrC CRenameItem::OldName()
+	{
+	return iOldName->Des();
+	}
+
+
+TPtrC CRenameItem::NewName()
+	{
+	return iNewName->Des();
+	}
+
+
+CFolderRenamer * CFolderRenamer::NewL(CFileEventHandlerAO &aCFileEventHandlerAO)
+	{	
+	CFolderRenamer *self = new (ELeave) CFolderRenamer(aCFileEventHandlerAO);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+CFolderRenamer::CFolderRenamer(CFileEventHandlerAO &aCFileEventHandlerAO) : 
+	CActive(KHarvesterPriorityMonitorPlugin),
+	iState(ERenameStateIdle),
+	iCFileEventHandlerAO(aCFileEventHandlerAO),
+	iIsRunning( EFalse )
+	{
+	}
+
+CFolderRenamer::~CFolderRenamer()
+	{
+	Cancel();
+	}
+
+void CFolderRenamer::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	}
+	
+void CFolderRenamer::DoCancel()
+	{	
+	}
+	
+
+void CFolderRenamer::RunL()
+	{
+	switch (iState)
+		{
+		case ERenameStateIdle:
+			{
+			if (iRenamedFolders.Count() == 0)
+				{
+				iIsRunning = EFalse;
+				return;
+				}
+			} //Flow to Renaming case -> no break
+			
+		case ERenameStateRenaming:
+			{
+			if (iRenamedFolders.Count())
+				{
+				iState = ERenameStateWaitingMdeRename;			
+				CRenameItem &currItem = *iRenamedFolders[0];				
+				CMdEHarvesterSession* session = iCFileEventHandlerAO.MdeHarvesterSession();
+				session->ChangePath( currItem.OldName(), currItem.NewName(), iStatus );
+				SetActive();
+				}
+			}
+			break;
+			
+		case ERenameStateWaitingMdeRename:
+			{
+			CRenameItem *currItem = iRenamedFolders[0];
+			iRenamedFolders.Remove(0);
+			TRAP_IGNORE(currItem->HandleFileEventsL(iCFileEventHandlerAO));
+			delete currItem;
+			SetNextRequest(ERenameStateIdle);
+			if (iRenamedFolders.Count() == 0)
+				{
+				iIsRunning = EFalse;
+				iRenamedFolders.Compress();
+				}
+			}
+			break;
+			
+		default:
+			{
+			WRITELOG("Unexpected state in FolderRenamer");
+			SetNextRequest(ERenameStateIdle);
+			}			
+			break;
+		}
+	}
+
+TInt CFolderRenamer::RunError( TInt aError )
+    {
+    WRITELOG("Unexpected error in FolderRenamer");
+    SetNextRequest(ERenameStateIdle);
+    return aError;
+    }
+
+void CFolderRenamer::RenameL(const TDesC &aOldName, const TDesC &aNewName)
+	{
+    //There comes multiple events for single rename, drop these 
+	TInt count = iRenamedFolders.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		if ( iRenamedFolders[i]->OldName().CompareF(aOldName) == 0 && 
+				iRenamedFolders[i]->NewName().CompareF(aNewName) == 0 )
+			{
+			return;
+			}
+		}
+	
+	CRenameItem *renameItem = CRenameItem::NewL(aOldName,aNewName);
+	iRenamedFolders.AppendL(renameItem);
+	iIsRunning = ETrue;
+	//First item --> Kickstart
+		
+	if (iState == ERenameStateIdle)
+		{
+		SetNextRequest(ERenameStateRenaming);
+		}
+	}
+
+
+void CFolderRenamer::SetNextRequest(TFolderRenameState aState)
+	{
+	iState = aState;	
+	if (!IsActive())
+		{
+		SetActive();				
+		TRequestStatus * status = &iStatus;
+		User::RequestComplete(status,KErrNone);	
+		}
+	}
+
+
+void CFolderRenamer::HandleFileEventL(TMdsFSPStatus &aEvent)
+	{
+	if (aEvent.iFileEventType == EMdsDirRenamed)
+		{
+		RenameL(aEvent.iFileName,aEvent.iNewFileName);
+		return;
+		}
+
+	//Check whether new folder name of the rename events matches to received path. If it matches
+    //queue events until folder is renamed, otherwise send notification to filemonitor immediatedly
+    //has to be started from last event!
+	if (iIsRunning)
+		{
+		const TInt count = iRenamedFolders.Count();	
+		for (TInt i = count-1; i >= 0; i--)
+			{
+			if (aEvent.iFileName.FindF(iRenamedFolders[i]->NewName()) != KErrNotFound)
+				{
+				iRenamedFolders[i]->AddFileEvent(aEvent);
+				return;
+				}
+			}		
+		}
+			
+	iCFileEventHandlerAO.HandleNotificationL(aEvent);
+	}
+
+void CFolderRenamer::HandleFileEventsL( CArrayFixSeg< TMdsFSPStatus >* aEvents )
+    {
+    const TInt count( aEvents->Count() );  // Can hold only delete events
+    
+    if( iIsRunning )
+        {
+        for( TInt i( 0 ); i < count; i++ )
+            {
+            //Check whether new folder name of the rename events matches to received path. If it matches
+            //queue events until folder is renamed, otherwise send notification to filemonitor immediatedly
+            //has to be started from last event!
+            const TInt count = iRenamedFolders.Count();   
+            for (TInt i = count-1; i >= 0; i--)
+                {
+                if ((*aEvents)[i].iFileName.FindF(iRenamedFolders[i]->NewName()) != KErrNotFound)
+                    {
+                    iRenamedFolders[i]->AddFileEvent((*aEvents)[i]);
+                    aEvents->Delete( i );
+                    break;
+                    } 
+                }
+            }
+        aEvents->Compress();
+        }
+    
+    if( aEvents->Count() )
+        {
+        iCFileEventHandlerAO.HandleMultideletionL(aEvents);
+        }
+    }
+	
+
+