diff -r 000000000000 -r ccd0fd43f247 harvesterplugins/calendar/src/ccalendarplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/harvesterplugins/calendar/src/ccalendarplugin.cpp Mon Apr 19 14:40:05 2010 +0300 @@ -0,0 +1,538 @@ +/* +* 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 "ccalendarplugin.h" +#include "harvesterserverlogger.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include // CleanupResetAndDestroyPushL + +_LIT(KMimeTypeField, CPIX_MIMETYPE_FIELD); +_LIT(KMimeTypeCalendar, CALENDAR_MIMETYPE); + +_LIT(KExcerptDelimiter, " "); + +/** The delay between harvesting chunks. */ +const TInt KHarvestingDelay = 2000; + +_LIT(KCalendarTimeFormat,"%F%/0%Y%M%D%H%T"); // Locale independent YYYYMMDDHHSS + +// --------------------------------------------------------------------------- +// CMessagePlugin::NewL +// --------------------------------------------------------------------------- +// +CCalendarPlugin* CCalendarPlugin::NewL() + { + CCalendarPlugin* instance = CCalendarPlugin::NewLC(); + CleanupStack::Pop(instance); + return instance; + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::NewLC +// --------------------------------------------------------------------------- +// +CCalendarPlugin* CCalendarPlugin::NewLC() + { + CCalendarPlugin* instance = new (ELeave) CCalendarPlugin(); + CleanupStack::PushL(instance); + instance->ConstructL(); + return instance; + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::CCalendarPlugin +// --------------------------------------------------------------------------- +// +CCalendarPlugin::CCalendarPlugin() + { + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::~CCalendarPlugin +// --------------------------------------------------------------------------- +// +CCalendarPlugin::~CCalendarPlugin() + { + if (iAsynchronizer) + iAsynchronizer->CancelCallback(); + delete iAsynchronizer; + delete iIndexer; + + delete iEntryView; + delete iCalIterator; + if( iSession ) + { + iSession->StopChangeNotification(); + } + delete iSession; + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::ConstructL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::ConstructL() + { + iAsynchronizer = CDelayedCallback::NewL( CActive::EPriorityIdle ); + iSession = CCalSession::NewL(); + TRAPD ( err , iSession->OpenL( iSession->DefaultFileNameL() ) ); + if ( err == KErrNotFound) + { + iSession->CreateCalFileL( iSession->DefaultFileNameL() ); + iSession->OpenL( iSession->DefaultFileNameL() ); + } + iCalIterator = CCalIter::NewL( *iSession ); + iEntryView = CCalEntryView::NewL( *iSession, *this ); + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::StartPluginL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::StartPluginL() + { + // Define this base application class, use default location + User::LeaveIfError(iSearchSession.DefineVolume( _L(CALENDAR_QBASEAPPCLASS), KNullDesC )); + + // Open the database + iIndexer = CCPixIndexer::NewL(iSearchSession); + iIndexer->OpenDatabaseL( _L(CALENDAR_QBASEAPPCLASS) ); + + // Start harvester for this plugin + iObserver->AddHarvestingQueue(this, iIndexer->GetBaseAppClass()); + + // Start monitoring calendar events + TTime startTime( TDateTime( 1980, EJanuary, 0, 0, 0, 0, 0 ) ); + TTime endTime( startTime + TTimeIntervalYears( 40 ) ); + TCalTime startTimeCal; + TCalTime endTimeCal; + startTimeCal.SetTimeUtcL( startTime ); + endTimeCal.SetTimeUtcL( endTime ); + CCalChangeNotificationFilter* filter = CCalChangeNotificationFilter::NewL( MCalChangeCallBack2::EChangeEntryAll, ETrue, CalCommon::TCalTimeRange( startTimeCal, endTimeCal ) ); + iSession->StartChangeNotification( *this, *filter ); + delete filter; + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::StartHarvestingL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::StartHarvestingL(const TDesC& /*aQualifiedBaseAppClass*/) + { + iIndexer->ResetL(); + iStartHarvesting = ETrue; +#ifdef __PERFORMANCE_DATA + iStartTime.UniversalTime(); +#endif + if (iFirstEntry) + { + iAsynchronizer->Start( 0, this, KHarvestingDelay ); + } + } + +// ----------------------------------------------------------------------------- +// CCalendarPlugin::Progress +// ----------------------------------------------------------------------------- +// +void CCalendarPlugin::Progress( TInt /*aPercentageCompleted*/ ) + { + // No implementation needed + } + +// ----------------------------------------------------------------------------- +// CCalendarPlugin::Completed +// ----------------------------------------------------------------------------- +// +void CCalendarPlugin::Completed( TInt aError ) + { + // No error code and harvesting is needed star harvesting. + iFirstEntry = ETrue; + if (aError == KErrNone && iStartHarvesting) + { + // Calendar entry view constructed successfully, start harvesting + iAsynchronizer->Start( 0, this, KHarvestingDelay ); + } + } + +// ----------------------------------------------------------------------------- +// CCalendarPlugin::NotifyProgress +// ----------------------------------------------------------------------------- +// +TBool CCalendarPlugin::NotifyProgress() + { + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CContactsPlugin::DelayedCallbackL +// ----------------------------------------------------------------------------- +// +void CCalendarPlugin::DelayedCallbackL( TInt /*aCode*/ ) + { + // Harvest items on each call + TPtrC8 uid( KNullDesC8 ); + + if( iFirstEntry ) + { + uid.Set( iCalIterator->FirstL() ); + iFirstEntry = EFalse; + } + else + { + uid.Set( iCalIterator->NextL() ); + } + + if( uid != KNullDesC8 ) + { + RPointerArray entryArray; + CleanupResetAndDestroyPushL(entryArray); + iEntryView->FetchL( uid, entryArray ); + // Handle only the first (i.e. parent entry) + if( entryArray.Count() > 0 ) + { + CCalEntry* entry = (CCalEntry*)entryArray[ 0 ]; + CPIXLOGSTRING2("CCalendarPlugin::DelayedCallbackL(): Harvesting id=%d.", entry->LocalUidL()); + CreateEntryL( entry->LocalUidL(), ECPixAddAction ); + } + CleanupStack::PopAndDestroy(&entryArray); + + // Request next entry. + iAsynchronizer->Start( 0, this, KHarvestingDelay ); + } + else + { + // Harvesting was successfully completed + iFirstEntry = ETrue; // Make sure we can harvest next time as well... + Flush(*iIndexer); +#ifdef __PERFORMANCE_DATA + UpdatePerformaceDataL(); +#endif + iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), KErrNone); + } + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::DelayedError +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::DelayedError(TInt aError) + { + // Harvesting was completed + iFirstEntry = ETrue; // Make sure we can harvest next time as well... + Flush(*iIndexer); + iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), aError); + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::CalChangeNotification +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::CalChangeNotification( RArray< TCalChangeEntry >& aChangeItems ) + { + const TInt count(aChangeItems.Count()); + CPIXLOGSTRING2("CCalendarPlugin::CalChangeNotification(): changed item count =%d.", count); + for( TInt i = 0; i < count; ++i ) + { + TCalChangeEntry changedEntry = aChangeItems[ i ]; + TRAP_IGNORE(HandleChangedEntryL(changedEntry)); + } + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::HandleChangedEntryL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::HandleChangedEntryL(const TCalChangeEntry& changedEntry) + { + switch( changedEntry.iChangeType ) + { + case EChangeAdd: + { + CPIXLOGSTRING2("CCalendarPlugin::HandleChangedEntryL(): Monitored add id=%d.", changedEntry.iEntryId); +#ifdef __PERFORMANCE_DATA + iStartTime.UniversalTime(); + CreateEntryL( changedEntry.iEntryId, ECPixAddAction ); + UpdatePerformaceDataL(ECPixAddAction); +#else + CreateEntryL( changedEntry.iEntryId, ECPixAddAction ); +#endif + break; + } + + case EChangeDelete: + { + CPIXLOGSTRING2("CCalendarPlugin::HandleChangedEntryL(): Monitored delete id=%d.", changedEntry.iEntryId); +#ifdef __PERFORMANCE_DATA + iStartTime.UniversalTime(); + CreateEntryL( changedEntry.iEntryId, ECPixAddAction ); + UpdatePerformaceDataL(ECPixAddAction); +#else + CreateEntryL( changedEntry.iEntryId, ECPixRemoveAction ); +#endif + break; + } + + case EChangeModify: + { + CPIXLOGSTRING2("CCalendarPlugin::HandleChangedEntryL(): Monitored update id=%d.", changedEntry.iEntryId); +#ifdef __PERFORMANCE_DATA + iStartTime.UniversalTime(); + CreateEntryL( changedEntry.iEntryId, ECPixUpdateAction ); + UpdatePerformaceDataL(ECPixUpdateAction); +#else + CreateEntryL( changedEntry.iEntryId, ECPixUpdateAction ); +#endif + break; + } + + /* TCalChangeEntry documentation: + If iChangeType is EChangeUndefined or EChangeOverflowError, iEntryId and + iEntryType are undefined and should not be used by clients. + */ + case EChangeUndefined: + { + CPIXLOGSTRING("CCalendarPlugin::HandleChangedEntryL(): EChangeUndefined."); + // This event could be related to synchronization. + // Mark harvesting as cancelled. + // Remove it from the harvesting queue to cause it to enter + // EHarvesterStatusHibernate state. + // Now add it to the harvesting queue and force a reharvest. + + iFirstEntry = ETrue; // Make sure we can harvest next time as well... + Flush(*iIndexer); + iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), KErrCancel); + iObserver->RemoveHarvestingQueue(this, iIndexer->GetBaseAppClass()); + iObserver->AddHarvestingQueue(this, iIndexer->GetBaseAppClass(), ETrue); + break; + } + default: + // Ignore other events + break; + } + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::CreateEntryL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::CreateEntryL( const TCalLocalUid& aLocalUid, TCPixActionType aActionType ) + { + if (!iIndexer) + return; + + CPIXLOGSTRING2("CCalendarPlugin::CreateEntryL(): Uid = %d.", aLocalUid); + + // creating CSearchDocument object with unique ID for this application + TBuf<20> docid_str; + docid_str.AppendNum(aLocalUid); + + if (aActionType == ECPixAddAction || aActionType == ECPixUpdateAction) + { + CSearchDocument* index_item = CSearchDocument::NewLC(docid_str, _L(CALENDARAPPCLASS)); + + // Return the entry that has been fetched, this will be NULL if there are + // no entries with the cal unique id + CCalEntry* entry = iEntryView->FetchL(aLocalUid); + // TODO leave if entry is NULL + CleanupStack::PushL(entry); + // TODO Uncomment below portion of code when the latest Organiser code in MCL + if( CCalEntry::ENote == entry->EntryTypeL() ) + { + CleanupStack::PopAndDestroy(entry); + CleanupStack::PopAndDestroy(index_item); + CPIXLOGSTRING("CCalendarPlugin::CreateEntryL(): Donot harvest Note item."); + return; + } + + // Add fields + index_item->AddFieldL(KCalendarSummaryField, entry->SummaryL()); + index_item->AddFieldL(KCalendarDescriptionField, entry->DescriptionL()); + index_item->AddFieldL(KCalendarLocationField, entry->LocationL()); + + TBuf<30> dateString; + + TTime startTime = entry->StartTimeL().TimeUtcL(); + startTime.FormatL(dateString, KCalendarTimeFormat); + index_item->AddFieldL(KCalendarStartTimeField, dateString, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized); + + TTime endTime = entry->EndTimeL().TimeUtcL(); + endTime.FormatL(dateString, KCalendarTimeFormat); + index_item->AddFieldL(KCalendarEndTimeField, dateString, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized); + + index_item->AddFieldL(KMimeTypeField, KMimeTypeCalendar, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized); + + TInt excerptLength = 3 + entry->SummaryL().Length() + entry->DescriptionL().Length() + entry->LocationL().Length(); + HBufC* excerpt = HBufC::NewLC(excerptLength); + TPtr excerptDes = excerpt->Des(); + excerptDes.Copy(entry->SummaryL()); + excerptDes.Append(KExcerptDelimiter); + excerptDes.Append(entry->DescriptionL()); + excerptDes.Append(KExcerptDelimiter); + excerptDes.Append(entry->LocationL()); + + index_item->AddExcerptL(*excerpt); + CleanupStack::PopAndDestroy(excerpt); + CleanupStack::PopAndDestroy(entry); + + /* + RPointerArray& attendees = iEntry.AttendeesL(); + for( TInt i = 0; i < attendees.Count(); i++ ) + { + CCalAttendee* attendee = (CCalAttendee*)attendees[ i ]; + TInt err = KErrNone; + TRAP( err, AddContent( CIndexContent::NewL( attendee->CommonName(), ECalendarAttendee ) ) ); + } + attendees.ResetAndDestroy(); + */ + + // Send for indexing + if (aActionType == ECPixAddAction) + { + TRAPD(err, iIndexer->AddL(*index_item)); + if (err == KErrNone) + { + CPIXLOGSTRING("CCalendarPlugin::CreateEntryL(): Added."); + } + else + { + CPIXLOGSTRING2("CCalendarPlugin::CreateEntryL(): Error %d in adding.", err); + } + } + else if (aActionType == ECPixUpdateAction) + { + TRAPD(err, iIndexer->UpdateL(*index_item)); + if (err == KErrNone) + { + CPIXLOGSTRING("CCalendarPlugin::CreateEntryL(): Updated."); + } + else + { + CPIXLOGSTRING2("CCalendarPlugin::CreateEntryL(): Error %d in updating.", err); + } + } + CleanupStack::PopAndDestroy(index_item); + } + else if (aActionType == ECPixRemoveAction) + { + TRAPD(err, iIndexer->DeleteL(docid_str)); + if (err == KErrNone) + { + CPIXLOGSTRING("CCalendarPlugin::CreateEntryL(): Deleted."); + } + else + { + CPIXLOGSTRING2("CCalendarPlugin::CreateEntryL(): Error %d in deleting.", err); + } + } + + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::UpdatePerformaceDataL +// --------------------------------------------------------------------------- +// +#ifdef __PERFORMANCE_DATA +void CCalendarPlugin::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\\CalenderPerf.txt"), EFileWrite)) + User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\CalenderPerf.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 Calendar 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; + } + +// --------------------------------------------------------------------------- +// CCalendarPlugin::UpdatePerformaceDataL +// --------------------------------------------------------------------------- +// +void CCalendarPlugin::UpdatePerformaceDataL(TCPixActionType 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\\CalenderPerf.txt"), EFileWrite)) + User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\CalenderPerf.txt"), EFileWrite)); + + HBufC8 *heap = HBufC8::NewL(100); + TPtr8 ptr = heap->Des(); + + switch (action) { + case ECPixAddAction: ptr.Append( _L("add "));break; + case ECPixUpdateAction: ptr.Append( _L("upd "));break; + case ECPixRemoveAction: ptr.Append( _L("del "));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 +// End of file