harvesterplugins/messaging/email/src/cemailplugin.cpp
changeset 2 208a4ba3894c
child 3 6832643895f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/harvesterplugins/messaging/email/src/cemailplugin.cpp	Mon May 03 12:32:15 2010 +0300
@@ -0,0 +1,456 @@
+/*
+* Copyright (c) 2010 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 <e32base.h> 
+#include <ccpixindexer.h>
+#include <csearchdocument.h>
+#include <QtGlobal>
+#include "cemailplugin.h"
+#include "harvesterserverlogger.h"
+#include "qtemailfetcher.h"
+
+// maximum length that the fully qualified msg Plugin base app class descriptor can be
+// e.g. "@c:root msg email"
+const TInt KMsgPluginBaseAppClassMaxLen = 64;
+
+
+// local declarations and functions
+namespace {
+
+_LIT(KCPixSearchServerPrivateDirectory, "\\Private\\2001f6f7\\");
+_LIT(KPathIndexDbPath, CPIX_INDEVICE_INDEXDB);
+
+_LIT(KPathTrailer, "\\root\\msg\\email");
+_LIT(KMsgBaseAppClassGeneric, ":root msg email");
+_LIT(KAtSign, "@");
+_LIT(KColon, ":");
+
+/**
+* MapFileToDrive - gets the TDriveNumber associated with the aBaseAppClass.
+* @aBaseAppClass e.g. "@c:root file"
+* @aDrive returns the TDriveNumber for the aBaseAppClass
+* returns KErrNone on success or a standard error code
+*/
+TInt MapBaseAppClassToDrive(const TDesC& aBaseAppClass, TDriveNumber& aDrive)
+    {
+    if (KErrNone != aBaseAppClass.Left(1).Compare(KAtSign))
+        {
+        return KErrGeneral;
+        }
+
+    TPtrC drvChar = aBaseAppClass.Left(2).Right(1);
+    TChar d(drvChar[0]);
+    TInt drive;
+    const TInt ret = RFs::CharToDrive(d, drive);
+    if (!ret)
+        {
+        aDrive = TDriveNumber(drive);
+        }
+
+    return ret;
+    }
+
+}// anonymous namespace
+
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::NewL
+// ---------------------------------------------------------------------------
+//  
+CEmailPlugin* CEmailPlugin::NewL()
+{
+	  CEmailPlugin* instance = CEmailPlugin::NewLC();
+    CleanupStack::Pop(instance);
+    return instance;
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::NewLC
+// ---------------------------------------------------------------------------
+//  
+CEmailPlugin* CEmailPlugin::NewLC()
+{
+	  CEmailPlugin* instance = new (ELeave)CEmailPlugin();
+    CleanupStack::PushL(instance);
+    instance->ConstructL();
+    return instance;
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::CEmailPlugin
+// ---------------------------------------------------------------------------
+//  
+CEmailPlugin::CEmailPlugin()
+{
+	
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::~CEmailPlugin
+// ---------------------------------------------------------------------------
+//  
+CEmailPlugin::~CEmailPlugin()
+{
+    // remove notification paths before destroying iMonitor
+    for (TInt i=EDriveA; i<=EDriveZ; i++)
+        UnMount(TDriveNumber(i), EFalse);
+	  iFs.Close();
+	  delete iQEmailFetcher;  
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::ConstructL
+// ---------------------------------------------------------------------------
+//  
+void CEmailPlugin::ConstructL()
+{
+	TInt err = iFs.Connect();
+    CPIXLOGSTRING2("CEmailPlugin::ConstructL, iFs.Connect: %i", err);
+    User::LeaveIfError(err);
+    iCurrentDrive = EDriveC; //Default drive is C drive
+    for (TInt i=EDriveA; i<=EDriveZ; i++)
+        {
+        iIndexer[i] = NULL; //Initialize to NULL
+        }
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::StartPluginL
+// ---------------------------------------------------------------------------
+//  
+void CEmailPlugin::StartPluginL()
+	{
+	CPIXLOGSTRING2("currentDrive used is : %d", iCurrentDrive );
+	MountL(TDriveNumber(iCurrentDrive)); //Mount current drive
+	//create instance of QEmailFetcher
+	QT_TRYCATCH_LEAVING(iQEmailFetcher = QEmailFetcher::newInstance(*this));
+	// Define this base application class, use default location
+	}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::StartHarvestingL
+// ---------------------------------------------------------------------------
+//  
+void CEmailPlugin::StartHarvestingL(const TDesC& aQualifiedBaseAppClass)
+	{
+	CPIXLOGSTRING("START CEmailPlugin::StartHarvestingL");
+	// Map base app class to a drive number
+	TDriveNumber drive ( EDriveA );//Initialize to silence compiler warnings.
+	if (KErrNone != MapBaseAppClassToDrive(aQualifiedBaseAppClass, drive))
+	   User::Leave(KErrGeneral);
+
+    // Leave if no indexer for this drive
+	if (!iIndexer[drive])
+	   User::Leave(KErrGeneral);
+	
+	//Complete harvesting here only for time being
+	//HarvestingCompleted(KErrNone);
+    // Reset the database
+	iIndexer[drive]->ResetL();
+#ifdef __PERFORMANCE_DATA
+    iStartTime.UniversalTime();
+#endif
+	}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::HandleDocumentL
+// ---------------------------------------------------------------------------
+//
+void CEmailPlugin::HandleDocumentL(const CSearchDocument* aSearchDocument, 
+	                               TCPixActionType aActionType)
+  {
+  CPIXLOGSTRING("START CEmailPlugin::HandleDocumentL");
+  // Index an empty item if removal action
+  if (aActionType == ECPixRemoveAction)
+      {
+      if (GetIndexer())
+          {
+          TRAPD(err, GetIndexer()->DeleteL(aSearchDocument->Id()));
+          if (err == KErrNone)
+              {
+              CPIXLOGSTRING("CEmailPlugin::HandleDocumentL: Document deleted.");
+              }
+          else
+              {
+              CPIXLOGSTRING2("CEmailPlugin::HandleDocumentL: Error %d in deleting the document.", err);              
+              }
+          }
+      return;
+      }
+  //Add or update action do accordingly
+  if (GetIndexer())
+      {
+      if (aActionType == ECPixAddAction)
+          {
+          TRAPD(err, GetIndexer()->AddL(*aSearchDocument));
+          if (err == KErrNone)
+              {
+              CPIXLOGSTRING("CEmailPlugin::HandleDocumentL(): Added.");
+              }
+          else
+              {
+              CPIXLOGSTRING2("CEmailPlugin::HandleDocumentL(): Error %d in adding.", err);
+              }
+          }
+      else if (aActionType == ECPixUpdateAction)
+          {
+          TRAPD(err, GetIndexer()->UpdateL(*aSearchDocument));
+          if (err == KErrNone)
+              {
+              CPIXLOGSTRING("CEmailPlugin::HandleDocumentL(): Updated.");
+              }
+          else
+              {
+              CPIXLOGSTRING2("CEmailPlugin::HandleDocumentL(): Error %d in updating.", err);
+              }
+          }
+      }
+  else
+      {
+      CPIXLOGSTRING("END CEmailPlugin::HandleDocumentL(): No indexer present.");
+      }
+  }
+  
+// ---------------------------------------------------------------------------
+// CEmailPlugin::MountL
+// ---------------------------------------------------------------------------
+//
+void CEmailPlugin::MountL(TDriveNumber aMedia,TBool aForceReharvesting)
+    {
+    CPIXLOGSTRING("START CEmailPlugin::MountL");
+    // Check if already exists
+    if (iIndexer[aMedia])
+        return;
+    
+    // Form the baseappclass for this media
+    TBuf<KMsgPluginBaseAppClassMaxLen> baseAppClass;
+    FormBaseAppClass(aMedia, baseAppClass);
+
+    // Define this volume
+    HBufC* path = DatabasePathLC(aMedia);
+    User::LeaveIfError(iSearchSession.DefineVolume(baseAppClass, *path));
+    CleanupStack::PopAndDestroy(path);
+    
+    // construct and open the database
+    TRAPD(err,iIndexer[aMedia] = CCPixIndexer::NewL(iSearchSession));
+    CPIXLOGSTRING2("CCPixIndexer::NewL returned : %d", err );
+    TRAP(err,iIndexer[aMedia]->OpenDatabaseL(baseAppClass));
+
+    // Add to harvesting queue
+    iObserver->AddHarvestingQueue(this, baseAppClass,aForceReharvesting);  
+    CPIXLOGSTRING("END CEmailPlugin::MountL");
+    }
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::UnMount
+// ---------------------------------------------------------------------------
+//
+void CEmailPlugin::UnMount(TDriveNumber aMedia, TBool aUndefineAsWell)
+    {
+    CPIXLOGSTRING("START CEmailPlugin::UnMount");
+    // Check if already exists
+    if (!iIndexer[aMedia])
+        return;
+    
+    // Form the baseappclass for this media
+    TBuf<KMsgPluginBaseAppClassMaxLen> baseAppClass;
+    FormBaseAppClass(aMedia, baseAppClass);             
+        
+    // Remove from harvesting queue
+    iObserver->RemoveHarvestingQueue(this, baseAppClass);   
+    
+    // Delete the index object
+    if (iIndexer[aMedia])
+        {
+        delete iIndexer[aMedia];
+        iIndexer[aMedia] = NULL;
+        }
+    
+    // if the aActionType is EFFMmcDismount, then the
+    // parameter aFilename is the baseAppClass of the Index database
+    // to be dropped.
+    if (aUndefineAsWell)
+        iSearchSession.UnDefineVolume(baseAppClass);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::FormBaseAppClass
+// ---------------------------------------------------------------------------
+//  
+TInt CEmailPlugin::FormBaseAppClass(TDriveNumber aMedia, TDes& aBaseAppClass)
+    {
+    TChar chr;
+    const TInt ret = RFs::DriveToChar(aMedia, chr);
+    if (KErrNone == ret)
+        {
+        aBaseAppClass.Copy(KAtSign);
+        aBaseAppClass.Append(chr);
+        aBaseAppClass.LowerCase();
+        aBaseAppClass.Append(KMsgBaseAppClassGeneric);
+        }
+
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::DatabasePathLC
+// ---------------------------------------------------------------------------
+//
+HBufC* CEmailPlugin::DatabasePathLC(TDriveNumber aMedia)
+    {
+    CPIXLOGSTRING("START CEmailPlugin::DatabasePathLC");
+    // Allocate extra space for root path e.g. "C:\\Private\\2001f6f7\\"
+    const TInt KRootPathMaxLength = 30;
+    HBufC* indexDbPath = HBufC::NewLC(KRootPathMaxLength + KPathIndexDbPath().Length() + KPathTrailer().Length());
+    TPtr indexDbPathPtr = indexDbPath->Des();
+
+#if 1 // Data caging implementation
+    iFs.CreatePrivatePath(aMedia);
+
+    TChar chr;
+    RFs::DriveToChar(aMedia, chr);
+    indexDbPathPtr.Append(chr);
+    indexDbPathPtr.Append(KColon);
+
+    TFileName pathWithoutDrive;
+    iFs.PrivatePath(pathWithoutDrive);
+    indexDbPathPtr.Append(KCPixSearchServerPrivateDirectory);
+#else // here is the way to calculate the path if data caging is not being used.
+    TFileName rootPath;
+    PathInfo::GetRootPath(rootPath, aMedia);
+    indexDbPathPtr.Append(rootPath);
+#endif 
+
+    indexDbPathPtr.Append(KPathIndexDbPath);
+    indexDbPathPtr.Append(KPathTrailer);
+
+    return indexDbPath;
+    }
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::GetIndexer
+// ---------------------------------------------------------------------------
+//
+CCPixIndexer* CEmailPlugin::GetIndexer()
+    {
+    return iIndexer[iCurrentDrive];
+    }
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::HarvestingCompleted
+// ---------------------------------------------------------------------------
+//  
+void CEmailPlugin::HarvestingCompleted(TInt aError)
+{
+	// Notifies the indexing manager of completed harvesting, called by CMessageHarvester
+    Flush( *GetIndexer() );
+    TBuf<KMsgPluginBaseAppClassMaxLen> baseAppClass;
+    FormBaseAppClass(TDriveNumber(iCurrentDrive), baseAppClass);
+#ifdef __PERFORMANCE_DATA
+    TRAP_IGNORE( UpdatePerformaceDataL() );
+#endif
+    iObserver->HarvestingCompleted(this, baseAppClass, aError);
+}
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::UpdatePerformaceDataL
+// ---------------------------------------------------------------------------
+//
+#ifdef __PERFORMANCE_DATA
+void CEmailPlugin::UpdatePerformaceDataL()
+    {
+    TTime now;
+   
+    
+    iCompleteTime.UniversalTime();
+    TTimeIntervalMicroSeconds timeDiff = iCompleteTime.MicroSecondsFrom(iStartTime);
+    
+    RFs fileSession;
+    RFile perfFile;
+    User::LeaveIfError( fileSession.Connect () );
+    
+    
+    /* Open file if it exists, otherwise create it and write content in it */
+    
+        if(perfFile.Open(fileSession, _L("c:\\data\\MessagePerf.txt"), EFileWrite))
+                   User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\MessagePerf.txt"), EFileWrite));
+    
+    HBufC8 *heap = HBufC8::NewL(100);
+    TPtr8 ptr = heap->Des();
+    now.HomeTime();
+    TBuf<50> timeString;             
+                
+    _LIT(KOwnTimeFormat,"%:0%H%:1%T%:2%S");
+    now.FormatL(timeString,KOwnTimeFormat);
+    ptr.AppendNum(now.DateTime().Day());
+    ptr.Append(_L("/"));
+    ptr.AppendNum(now.DateTime().Month());
+    ptr.Append(_L("/"));
+    ptr.AppendNum(now.DateTime().Year());
+    ptr.Append(_L(":"));
+    ptr.Append(timeString);
+    ptr.Append( _L("Time taken for Harvesting Message is : "));
+    ptr.AppendNum(timeDiff.Int64()/1000) ;
+    ptr.Append(_L(" MilliSeonds \n"));
+    TInt myInt = 0;
+    perfFile.Seek(ESeekEnd,myInt);
+    perfFile.Write (ptr);
+    perfFile.Close ();
+    fileSession.Close ();
+    delete heap;
+    }
+
+// ---------------------------------------------------------------------------
+// CEmailPlugin::UpdatePerformaceDataL
+// ---------------------------------------------------------------------------
+//
+void CEmailPlugin::UpdatePerformaceDataL(TMsvSessionEvent action) {
+    
+        iCompleteTime.UniversalTime();
+        TTimeIntervalMicroSeconds timeDiff = iCompleteTime.MicroSecondsFrom(iStartTime);
+        
+        RFs fileSession;
+        RFile perfFile;
+        User::LeaveIfError( fileSession.Connect () );
+        
+        
+        /* Open file if it exists, otherwise create it and write content in it */
+        
+            if(perfFile.Open(fileSession, _L("c:\\data\\MessagePerf.txt"), EFileWrite))
+                       User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\MessagePerf.txt"), EFileWrite));
+        
+        HBufC8 *heap = HBufC8::NewL(100);
+        TPtr8 ptr = heap->Des();
+
+        switch (action) {
+            case EMsvEntriesDeleted: ptr.Append( _L("del "));break;
+            case EMsvEntriesChanged: ptr.Append( _L("upd "));break;
+            case EMsvEntriesMoved: ptr.Append( _L("mov "));break;
+        }
+        ptr.AppendNum(timeDiff.Int64()/1000) ;
+        ptr.Append(_L("\n"));
+        TInt myInt = 0;
+        perfFile.Seek(ESeekEnd,myInt);
+        perfFile.Write (ptr);
+        perfFile.Close ();
+        fileSession.Close ();
+        delete heap;
+    }
+
+#endif