harvester/monitorplugins/messageplugin/src/messagescannerao.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:34:07 +0200
changeset 0 c53acadfccc6
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* 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 <msvstd.h>
#include <msvfind.h>
#include <msvapi.h>
#include <msvids.h>
#include "mdesession.h"
#include "mdeconstants.h"
#include "mdenamespacedef.h"
#include "messagescannerao.h"
#include "harvesterlog.h"
#include "messagemonitorplugin.h"
#include "clientkeywatcherkeys.h"

CMessageScannerAO* CMessageScannerAO::NewL( CMsvSession* aMsvSession, 
		CMdESession* aMdeSession,
		MMonitorPluginObserver* aMonitorPluginObserver )
	{
	CMessageScannerAO* self = new (ELeave) CMessageScannerAO( 
			aMsvSession, aMdeSession, aMonitorPluginObserver );
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}

CMessageScannerAO::CMessageScannerAO( CMsvSession* aMsvSession, 
		CMdESession* aMdeSession, 
		MMonitorPluginObserver* aMonitorPluginObserver ) :
		CActive( CActive::EPriorityStandard ),
		iFindOperation( NULL ), iObjectQuery( NULL )
	{
	CActiveScheduler::Add( this );
	iMsvSession = aMsvSession;
	iMdeSession = aMdeSession;
	iMonitorPluginObserver = aMonitorPluginObserver;
	iState = EScannerIdle;
	}

CMessageScannerAO::~CMessageScannerAO()
	{
	Cancel();
	Cleanup();
	}

void CMessageScannerAO::StartL()
	{
	WRITELOG("CMessageScannerAO::Start()");
	_LIT( KEmpty, "" );
	iFindOperation = CMsvFindOperation::FindInChildrenL( *iMsvSession, KEmpty, 
			KMsvRootIndexEntryId, KMsvMessagePartNone, iStatus );
	SetActive();
	iState = EScannerRunning;
	WRITELOG("CMessageScannerAO::Start() - ends");
	}
		
void CMessageScannerAO::ConstructL()
	{
	WRITELOG("CMessageScannerAO::ConstructL()");
	User::LeaveIfError( iProperty.Attach( KPSRestoreWatcherCategory,
			KPSRestoreWatcherClientsKey, EOwnerThread ) );
	
	TInt registeredClients = 0;
	iProperty.Get( registeredClients );
	TInt error = iProperty.Set( registeredClients + 1 );
	
	WRITELOG1("CMessageScannerAO::ConstructL() - error: %d", error);
	}

void CMessageScannerAO::RunL()
	{
	WRITELOG("CMessageScannerAO::RunL()");
	if ( iStatus.Int() != KErrNone )
		{
#ifdef _DEBUG
		WRITELOG1("CMessageScannerAO::RunL() . error %d", iStatus.Int());
#endif
		return;
		}
	
	switch ( iState )
		{
		case EScannerRunning:
			{
			QueryAllMessagesL();
			break;
			}
		case EScannerFinished:
			{
			Cleanup();
			break;
			}
		}
	}

void CMessageScannerAO::DoCancel()
	{
	iFindOperation->Cancel();
	iProperty.Cancel();
	}

#ifdef _DEBUG
TInt CMessageScannerAO::RunError( TInt aError )
#else
TInt CMessageScannerAO::RunError( TInt /*aError*/ )
#endif
	{
	WRITELOG1( "CMessageScannerAO::RunError - error: %d", aError );
	return KErrNone;
	}

void CMessageScannerAO::QueryAllMessagesL()
	{
	WRITELOG("CMessageScannerAO::QueryAllMessagesL()");
	CMdENamespaceDef& namespaceDef = iMdeSession->GetDefaultNamespaceDefL();
	CMdEObjectDef& messageDef = namespaceDef.GetObjectDefL( MdeConstants::Message::KMessageObject );
	
	iObjectQuery = iMdeSession->NewObjectQueryL( namespaceDef, messageDef, this );
	iObjectQuery->SetResultMode( EQueryResultModeItem );
	
	iObjectQuery->FindL();
	WRITELOG("CMessageScannerAO::QueryAllMessagesL() - ends");
	}

void CMessageScannerAO::HandleQueryNewResults( CMdEQuery& /*aQuery*/, TInt /*aFirstNewItemIndex*/,
		TInt /*aNewItemCount*/ )
	{
	}

void CMessageScannerAO::HandleQueryCompleted( CMdEQuery& aQuery, TInt /*aError*/ )
	{
	WRITELOG("CMessageScannerAO::HandleQueryCompleted()");
	RArray<TMessage> messages;
	TInt error = KErrNone;
	
	if ( aQuery.Count() > 0 )
		{
#ifdef _DEBUG
		WRITELOG1("CMessageScannerAO::HandleQueryCompleted() - aQuery count %d", aQuery.Count());
#endif
		TRAP( error, ProcessMessagesL( aQuery, messages ) );
		}

	if ( error == KErrNone )
		{
		TRAP_IGNORE( ScanMessagesL( messages ) );
		}
	
	messages.Close();
	Unregister();
	iState = EScannerFinished;
	
	SetActive();
	TRequestStatus* pStatus = &iStatus;
    User::RequestComplete( pStatus, KErrNone );
	}

void CMessageScannerAO::ProcessMessagesL( CMdEQuery& aQuery, RArray<TMessage>& aMessages )
	{
	_LIT( KPeriod, "." );

	CMdENamespaceDef& namespaceDef = iMdeSession->GetDefaultNamespaceDefL();
	CMdEObjectDef& messageDef = namespaceDef.GetObjectDefL( MdeConstants::Message::KMessageObject );
	CMdEPropertyDef& creationDateDef = messageDef.GetPropertyDefL( 
			MdeConstants::Object::KCreationDateProperty );

	TInt count = aQuery.Count();
	
	for (TInt i = 0; i < count; i++ )
		{
		CMdEObject& object = static_cast<CMdEObject&>( aQuery.ResultItem( i ) );
		TInt index = object.Uri().Find( KPeriod );
		if ( index != KErrNotFound )
			{
			TLex16 lex( object.Uri().Left( index ) );
			TMessage message;
			message.iMdeId = object.Id();

			CMdEProperty* creationDateProp = NULL;
			object.Property( creationDateDef, creationDateProp, 0 );
			message.iCreationDate = creationDateProp->TimeValueL();

			TInt error = lex.Val( message.iMsvId );
			if ( error == KErrNone )
				{
				aMessages.Append( message );
				}
			}
		}
	}

void CMessageScannerAO::ScanMessagesL( RArray<TMessage>& aMessages )
	{
	WRITELOG("CMessageScannerAO::ScanMessagesL()");
	const CMsvFindResultSelection& findResults = iFindOperation->GetFindResult();
	CMdENamespaceDef& defaultNamespace = iMdeSession->GetDefaultNamespaceDefL();
	TInt msvCount = findResults.Count();
	
	for ( TInt i = 0; i < msvCount; i++ )
		{
		WRITELOG1("CMessageScannerAO::ScanMessagesL() - MSV item %d", i);
		TBool idMatched = EFalse;
		for ( TInt j = 0; j < aMessages.Count(); j++ )
			{
			WRITELOG1("CMessageScannerAO::ScanMessagesL() - MDE item %d", j);
			if ( findResults[i].iId == aMessages[j].iMsvId )
				{
				WRITELOG("CMessageScannerAO::ScanMessagesL() - id matches");
				idMatched = ETrue;
				CMsvEntry* e = iMsvSession->GetEntryL( findResults[i].iId );
				if ( !e )
					{
					WRITELOG("CMessageScannerAO::ScanMessagesL() - message entry is NULL!?");
					continue;
					}
				
				CleanupStack::PushL( e );
				const TMsvEntry& entry = e->Entry();
				WRITELOG("CMessageScannerAO::ScanMessagesL() - comparing dates");
				if ( entry.iDate != aMessages[j].iCreationDate )
					{
					WRITELOG("CMessageScannerAO::ScanMessagesL() - creation dates don't match");
					// Harvest the message with EHarvesterEdit event type.
					HBufC* uri = CMessageMonitorPlugin::CreateUriL( entry.iMtm, entry.Id() );
					CleanupStack::PushL( uri );
					CHarvesterData* hd = CHarvesterData::NewL( uri );
					CleanupStack::Pop( uri );
					hd->SetEventType( EHarvesterEdit );
					hd->SetTakeSnapshot( EFalse );
					hd->SetBinary( EFalse );
					iMonitorPluginObserver->MonitorEvent( hd );
					}
				
				CleanupStack::PopAndDestroy( e );
				aMessages.Remove( j );
				j--;
				break;
				}
			}
		
		if ( !idMatched )
			{
			WRITELOG("CMessageScannerAO::ScanMessagesL() - harvesting new message");
			// Harvest the message as new message.
			CMsvEntry* e = iMsvSession->GetEntryL( findResults[i].iId );
			if ( !e )
				{
				WRITELOG("CMessageScannerAO::ScanMessagesL() - message entry is NULL!?");
				continue;
				}
			
			CleanupStack::PushL( e );
			const TMsvEntry& entry = e->Entry();
			HBufC* uri = CMessageMonitorPlugin::CreateUriL( entry.iMtm, entry.Id() );
			CleanupStack::PushL( uri );
			CHarvesterData* hd = CHarvesterData::NewL( uri );
			CleanupStack::Pop( uri );
			hd->SetEventType( EHarvesterAdd );
			hd->SetTakeSnapshot( EFalse );
			hd->SetBinary( EFalse );
			iMonitorPluginObserver->MonitorEvent( hd );
			
			CleanupStack::PopAndDestroy( e );
			}
		}
	
	// Remove extra messages in MdS db.
	if ( aMessages.Count() > 0 )
		{
		WRITELOG1("CMessageScannerAO::ScanMessagesL() - removing extra messages from mde (%d)", 
				aMessages.Count() );
		RArray<TItemId> extraMessages;
		CleanupClosePushL( extraMessages );
		
		for ( TInt i = 0; i < aMessages.Count(); i++ )
			{
			extraMessages.Append( aMessages[i].iMdeId );
			}
		
		RArray<TItemId> results;
		CleanupClosePushL( results );
		iMdeSession->RemoveObjectsL( extraMessages, results, &defaultNamespace );
		CleanupStack::PopAndDestroy( 2 ); // extramessages, results
		}
	}

void CMessageScannerAO::Unregister()
	{
	TInt registeredClients = 0;
	iProperty.Get( registeredClients );
	WRITELOG1("CMessageScannerAO::Unregister() - registered clients: %d", registeredClients);
	if ( registeredClients > 0 )
		{
		iProperty.Set( registeredClients - 1 );
		}
	}

void CMessageScannerAO::Cleanup()
	{
	iProperty.Close();
	delete iFindOperation;
	iFindOperation = NULL;
	delete iObjectQuery;
	iObjectQuery = NULL;
	}