--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omads/omadsextensions/adapters/agenda/src/nsmlagendadatastore.cpp Mon Nov 23 14:46:41 2009 +0200
@@ -0,0 +1,1770 @@
+/*
+* Copyright (c) 2005 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: DS agenda data store
+*
+*/
+
+
+
+// INCLUDES
+#include "nsmldebug.h"
+#include "nsmlagendadatastore.h"
+#include "nsmlagendadataprovider.h"
+#include "nsmlchangefinder.h"
+#include "NSmlDataModBase.h"
+#include "nsmlagendadefines.hrh"
+#include <ecom.h>
+#include <barsc.h>
+#include <bautils.h>
+#include <calsession.h>
+#include <caldataexchange.h>
+#include <calentryview.h>
+#include <caliterator.h>
+#include <calentry.h>
+#include <caldataformat.h>
+#include <caltime.h>
+#include <nsmldsimpluids.h>
+#include <sysutil.h>
+#include <SmlDataProvider.h>
+#include <SmlDataFormat.h>
+#include <SmlDataSyncDefs.h>
+#include <data_caging_path_literals.hrh>
+#include <NSmlAgendaDataStore_1_1_2.rsg>
+#include <NSmlAgendaDataStore_1_2.rsg>
+#include <e32property.h>
+#include <DataSyncInternalPSKeys.h>
+#include <CalenImporter.h>
+#include <CalenInterimUtils2.h>
+
+#ifndef __WINS__
+// This lowers the unnecessary compiler warning (armv5) to remark.
+// "Warning: #174-D: expression has no effect..." is caused by
+// DBG_ARGS8 macro in no-debug builds.
+#pragma diag_remark 174
+#endif
+// ============================= MEMBER FUNCTIONS ==============================
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CNSmlAgendaDataStore
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore::CNSmlAgendaDataStore() :
+ iKey( TKeyArrayFix( _FOFF( TNSmlSnapshotItem, ItemId() ), ECmpTInt ) ),
+ iPos( -1 ),
+ iHasHistory( EFalse ),
+ iModificationCount( KNSmlCompactAfterChanges ),
+ iState( ENSmlClosed ),
+ iSnapshotRegistered( EFalse ),
+ iDrive( -1 ),
+ iReplaceItemId( -1 ),
+ iRXEntryType( ENSmlNotSet ),
+ iTXEntryType( ENSmlNotSet )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): BEGIN");
+ _DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::ConstructL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::ConstructL: BEGIN");
+
+ iStringPool.OpenL();
+ User::LeaveIfError( iRfs.Connect() );
+
+ iDataMod = new ( ELeave ) CNSmlVCalMod();
+
+ iNewUids = new ( ELeave ) CNSmlDataItemUidSet();
+ iDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
+ iSoftDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
+ iMovedUids = new ( ELeave ) CNSmlDataItemUidSet();
+ iReplacedUids = new ( ELeave ) CNSmlDataItemUidSet();
+
+ iDefaultStoreName = HBufC::NewL( KNSmlDefaultStoreNameMaxSize );
+
+ iVersitTlsData = &CVersitTlsData::VersitTlsDataL();
+ // Create CalSession and CalEntryView instances
+ iVCalSession = CCalSession::NewL();
+
+ TPtr obptr = iDefaultStoreName->Des();
+ obptr = iVCalSession->DefaultFileNameL();
+
+ iOwnFormat = DoOwnStoreFormatL();
+ iDataMod->SetOwnStoreFormat( *iOwnFormat );
+
+ iInterimUtils = CCalenInterimUtils2::NewL();
+
+ _DBG_FILE("CNSmlAgendaDataStore::ConstructL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore* CNSmlAgendaDataStore::NewL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::NewL: BEGIN");
+
+ CNSmlAgendaDataStore* self = new ( ELeave ) CNSmlAgendaDataStore();
+ CleanupStack::PushL( self );
+
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+
+ _DBG_FILE("CNSmlAgendaDataStore::NewL: END");
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::~CNSmlAgendaDataStore
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CNSmlAgendaDataStore::~CNSmlAgendaDataStore()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): BEGIN");
+
+ // Enable notifications
+ TInt error( KErrNone );
+ if ( iVCalSession )
+ {
+ TRAP_IGNORE( iVCalSession->EnablePubSubNotificationsL() );
+ TRAP_IGNORE( iVCalSession->EnableChangeBroadcast() );
+ }
+
+ delete iOwnFormat;
+ iRfs.Close();
+ iStringPool.Close();
+
+ if ( iChangeFinder )
+ {
+ TRAP( error, iChangeFinder->CloseL() );
+ }
+ if (iVersitTlsData)
+ {
+ iVersitTlsData->VersitTlsDataClose();
+ }
+ delete iChangeFinder;
+ delete iNewUids;
+ delete iDeletedUids;
+ delete iSoftDeletedUids;
+ delete iMovedUids;
+ delete iReplacedUids;
+
+ delete iDefaultStoreName;
+ delete iOpenedStoreName;
+ delete iDataMod;
+ delete iItemData;
+
+ delete iAgendaProgressview;
+
+ delete iImporter;
+ delete iExporter;
+
+ delete iEntryView;
+ delete iVCalSession;
+ delete iInterimUtils;
+
+
+ // REComSession::FinalClose();
+
+ _DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOpenL
+// Open calendar database for access.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoOpenL( const TDesC& aStoreName,
+ MSmlSyncRelationship& aContext, TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlClosed )
+ {
+ User::RequestComplete( iCallerStatus, KErrInUse );
+ return;
+ }
+
+ if( RFs::CharToDrive( aStoreName[0], iDrive ) != KErrNone )
+ {
+ RFs::CharToDrive( KNSmlDriveC()[0], iDrive );
+ }
+
+ // Open database
+ TInt err( KErrNone );
+ if ( aStoreName == KNSmlAgendaStoreNameForDefaultDB )
+ {
+ TRAP( err, iVCalSession->OpenL( *iDefaultStoreName ) );
+ }
+ else
+ {
+ TRAP( err, iVCalSession->OpenL( aStoreName ) );
+ }
+ if ( err )
+ {
+ User::RequestComplete( iCallerStatus, err );
+ return;
+ }
+
+ // Disable notifications
+ TRAP_IGNORE( iVCalSession->DisablePubSubNotificationsL() );
+ TRAP_IGNORE( iVCalSession->DisableChangeBroadcast() );
+
+ if ( iOpenedStoreName )
+ {
+ delete iOpenedStoreName;
+ iOpenedStoreName = NULL;
+ }
+ iOpenedStoreName = aStoreName.AllocL();
+
+ // Initialize some member variables
+ // Create importer and exporter
+ iImporter = CCalenImporter::NewL( *iVCalSession );
+ iExporter = CCalenExporter::NewL( *iVCalSession );
+
+ // Progress view
+ iAgendaProgressview = CNSmlAgendaProgressview::NewL();
+
+ iEntryView = CCalEntryView::NewL( *iVCalSession, *iAgendaProgressview );
+ CActiveScheduler::Start();
+ TInt completedStatus = iAgendaProgressview->GetCompletedStatus();
+ if ( completedStatus != KErrNone )
+ {
+ User::RequestComplete( iCallerStatus, completedStatus );
+ return;
+ }
+
+ if ( iChangeFinder )
+ {
+ iChangeFinder->CloseL();
+ delete iChangeFinder;
+ iChangeFinder = NULL;
+ }
+ iChangeFinder = CNSmlChangeFinder::NewL( aContext, iKey, iHasHistory,
+ KNSmlAgendaAdapterImplUid );
+
+ // Get ID of database
+ iVCalSession->FileIdL( iOpenedStoreId );
+
+ if( !iSnapshotRegistered )
+ {
+ RegisterSnapshotL();
+ }
+
+ iState = ENSmlOpenAndWaiting;
+ User::RequestComplete( iCallerStatus, err );
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCancelRequest
+// Set internal module state to previous state.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCancelRequest()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iState = ENSmlClosed;
+ }
+ else
+ {
+ iState = ENSmlOpenAndWaiting;
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoStoreName
+// Returns previously opened database name.
+// -----------------------------------------------------------------------------
+//
+const TDesC& CNSmlAgendaDataStore::DoStoreName() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoStoreName: BEGIN");
+ _DBG_FILE("CNSmlAgendaDataStore::DoStoreName: END");
+ return *iOpenedStoreName;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoBeginTransactionL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoBeginTransactionL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: BEGIN");
+ User::Leave( KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitTransactionL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitTransactionL( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoRevertTransaction
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoRevertTransaction( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoBeginBatchL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoBeginBatchL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: BEGIN");
+ User::Leave( KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitBatchL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/,
+ TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCancelBatch
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCancelBatch()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: BEGIN");
+ // Nothing to do
+ _DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSetRemoteStoreFormatL
+// Set SyncML Remote Server data store format.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSetRemoteStoreFormatL(
+ const CSmlDataStoreFormat& aServerDataStoreFormat )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: BEGIN");
+
+ if ( iOwnFormat )
+ {
+ delete iOwnFormat;
+ iOwnFormat = NULL;
+ }
+
+ iOwnFormat = DoOwnStoreFormatL();
+ iDataMod->SetOwnStoreFormat( *iOwnFormat );
+
+ iDataMod->SetPartnerStoreFormat( ( CSmlDataStoreFormat& )
+ aServerDataStoreFormat );
+
+ // Check which calendar type (vCal/iCal) is used
+ // If server supports iCal then it is used
+ // Otherwise vCal is used
+ TInt returnValue( KErrNotSupported );
+
+#ifdef __NSML_USE_ICAL_FEATURE
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support iCal");
+ returnValue = iDataMod->SetUsedMimeType(
+ iOwnFormat->MimeFormat( 1 ).MimeType(),
+ iOwnFormat->MimeFormat( 1 ).MimeVersion() );
+
+#endif // __NSML_USE_ICAL_FEATURE
+
+ if ( returnValue == KErrNone )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets iCal");
+ iRXEntryType = ENSmlICal;
+ iTXEntryType = ENSmlICal;
+ }
+ else
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support vCal");
+ returnValue = iDataMod->SetUsedMimeType(
+ iOwnFormat->MimeFormat( 0 ).MimeType(),
+ iOwnFormat->MimeFormat( 0 ).MimeVersion() );
+ if ( returnValue == KErrNone )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets vCal");
+ iRXEntryType = ENSmlVCal;
+ iTXEntryType = ENSmlVCal;
+ }
+ }
+ if ( iRXEntryType == ENSmlNotSet || iTXEntryType == ENSmlNotSet )
+ {
+ // Leave if server does not support either vCal or iCal
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: MimeType Not supported");
+ User::Leave( KErrNotFound );
+ }
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize
+// Set SyncML Remote Server maximum object size.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize( TInt aServerMaxObjectSize )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: BEGIN");
+ iServerMaxObjectSize = aServerMaxObjectSize;
+ _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMaxObjectSize
+// Set SyncML Component maximum object size.
+// -----------------------------------------------------------------------------
+//
+TInt CNSmlAgendaDataStore::DoMaxObjectSize() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize: BEGIN");
+ _DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize - Default: END");
+ return KNSmlAgendaOwnMaxObjectSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOpenItemL
+// Open calendar item for reading.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoOpenItemL( TSmlDbItemUid aUid, TBool& aFieldChange,
+ TInt& aSize, TSmlDbItemUid& /*aParent*/, TDes8& aMimeType,
+ TDes8& aMimeVer, TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+
+ iReplaceItemId = aUid;
+
+ CCalEntry* entry = NULL;
+ TInt err( KErrNone );
+ TRAP( err, entry = iEntryView->FetchL( aUid ) );
+ CleanupStack::PushL( entry );
+
+ if ( err || !entry )
+ {
+ CleanupStack::PopAndDestroy( entry ); // entry
+ User::RequestComplete( iCallerStatus, KErrNotFound );
+ return;
+ }
+
+ if ( !iSnapshotRegistered )
+ {
+ RegisterSnapshotL();
+ }
+ delete iItemData;
+ iItemData = NULL;
+ iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+
+ RBufWriteStream writeStream( *iItemData );
+ writeStream.PushL();
+
+ // Export item from database
+ if ( iTXEntryType == ENSmlICal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - iCal DB");
+ iExporter->ExportICalL( *entry, writeStream );
+ aMimeType = iOwnFormat->MimeFormat( 1 ).MimeType().DesC();
+ aMimeVer = iOwnFormat->MimeFormat( 1 ).MimeVersion().DesC();
+ }
+ else if ( iTXEntryType == ENSmlVCal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - vCal DB");
+ iExporter->ExportVCalL( *entry, writeStream );
+ aMimeType = iOwnFormat->MimeFormat( 0 ).MimeType().DesC();
+ aMimeVer = iOwnFormat->MimeFormat( 0 ).MimeVersion().DesC();
+ }
+ else
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - DB Not Supported");
+ CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ return;
+ }
+
+ writeStream.CommitL();
+ iItemData->Compress();
+ iPos = 0;
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+ _S8( "Item from database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+
+ iDataMod->StripTxL( *iItemData );
+ CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+ _S8( "Item from database after strip:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ aFieldChange = EFalse;
+ aSize = iItemData->Size();
+
+ iState = ENSmlItemOpen;
+
+ if ( iServerMaxObjectSize == 0 || aSize <= iServerMaxObjectSize )
+ {
+ User::RequestComplete( iCallerStatus, KErrNone );
+ }
+ else
+ {
+ User::RequestComplete( iCallerStatus, KErrTooBig );
+ }
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCreateItemL
+// Prepare item data for writing to database. WriteItemL() writes item's data as
+// buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCreateItemL( TSmlDbItemUid& aUid, TInt aSize,
+ TSmlDbItemUid /*aParent*/, const TDesC8& aMimeType,
+ const TDesC8& /*aMimeVer*/, TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ iAddItemId = &aUid;
+
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrNotReady: END");
+ return;
+ }
+
+ if ( KNSmlAgendaOwnMaxObjectSize < aSize )
+ {
+ User::RequestComplete( iCallerStatus, KErrTooBig );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrTooBig: END");
+ return;
+ }
+
+ if( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
+ {
+ User::RequestComplete( iCallerStatus, KErrDiskFull );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrDiskFull: END");
+ return;
+ }
+
+ // Check if MIME type of new item is supported
+ TBool mimeFound( EFalse );
+ // vCal
+ if ( iOwnFormat->MimeFormat( 0 ).MimeType().DesC().Compare( aMimeType )
+ == 0 )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received vCal");
+ mimeFound = ETrue;
+ iRXEntryType = ENSmlVCal;
+ }
+
+#ifdef __NSML_USE_ICAL_FEATURE
+
+ // iCal
+ else if ( iOwnFormat->MimeFormat( 1 ).MimeType().DesC().Compare( aMimeType )
+ == 0 )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received iCal");
+ mimeFound = ETrue;
+ iRXEntryType = ENSmlICal;
+ }
+
+#endif // __NSML_USE_ICAL_FEATURE
+
+ // Else use original iRXEntryType
+ else
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: \
+ mime type not received");
+ iRXEntryType = iTXEntryType;
+ }
+
+ if ( !mimeFound )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL -KErrNotSupported: END");
+ return;
+ }
+
+ if( !iSnapshotRegistered )
+ {
+ RegisterSnapshotL();
+ }
+ delete iItemData;
+ iItemData = NULL;
+ iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+ iPos = 0;
+
+ iState = ENSmlItemCreating;
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoReplaceItemL
+// Prepare item data for writing and replacing item in database. WriteItemL()
+// writes item's data as buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoReplaceItemL( TSmlDbItemUid aUid, TInt aSize,
+ TSmlDbItemUid /*aParent*/, TBool aFieldChange,
+ TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotReady: END");
+ return;
+ }
+
+ if ( KNSmlAgendaOwnMaxObjectSize < aSize )
+ {
+ User::RequestComplete( iCallerStatus, KErrTooBig );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrTooBig: END");
+ return;
+ }
+
+ if ( aFieldChange )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL \
+ - KErrNotSupported: END");
+ return;
+ }
+ if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
+ {
+ User::RequestComplete( iCallerStatus, KErrDiskFull );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrDiskFull: END");
+ return;
+ }
+
+ iReplaceItemId = aUid;
+
+ CCalEntry* entry = NULL;
+ TInt err( KErrNone );
+ TRAP( err, entry = iEntryView->FetchL( aUid ) );
+ CleanupStack::PushL( entry );
+
+ if ( !entry || err == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy( entry ); // entry
+ User::RequestComplete( iCallerStatus, KErrNotFound );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotFound: END");
+ return;
+ }
+ else if ( err )
+ {
+ CleanupStack::PopAndDestroy( entry ); // entry
+ User::RequestComplete( iCallerStatus, err );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - Error: END");
+ return;
+ }
+
+ CleanupStack::PopAndDestroy( entry ); // entry
+
+ if ( !iSnapshotRegistered )
+ {
+ RegisterSnapshotL();
+ }
+
+ delete iItemData;
+ iItemData = NULL;
+ iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
+ iPos = 0;
+ iReplaceItemId = aUid;
+
+ iState = ENSmlItemUpdating;
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoReadItemL
+// Read item data to given buffer.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoReadItemL( TDes8& aBuffer )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: BEGIN");
+ if ( iState != ENSmlItemOpen || !iItemData )
+ {
+ iPos = -1;
+ User::Leave( KErrNotReady );
+ }
+
+ if ( iPos == -1 )
+ {
+ User::Leave( KErrEof );
+ }
+
+ if ( aBuffer.Size() < iItemData->Size() - iPos )
+ {
+ iItemData->Read( iPos, aBuffer );
+ iPos += aBuffer.Size();
+ }
+ else
+ {
+ iItemData->Read( iPos, aBuffer, iItemData->Size() - iPos );
+ iPos = -1;
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoWriteItemL
+// Write item data as buffered.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoWriteItemL( const TDesC8& aData )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: BEGIN");
+ if ( iState == ENSmlItemCreating || iState == ENSmlItemUpdating )
+ {
+ if ( iItemData )
+ {
+ if ( iPos == -1 )
+ {
+ User::Leave( KErrEof );
+ }
+ iItemData->InsertL( iPos, aData );
+ iPos += aData.Size();
+ return;
+ }
+ }
+ User::Leave( KErrNotReady );
+ _DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitItemL
+// Commit item data to database when adding or replacing item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitItemL( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+
+ if ( iState != ENSmlItemCreating && iState != ENSmlItemUpdating )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL - KErrNotReady: END");
+ return;
+ }
+
+ iItemData->Compress();
+ TInt error( KErrNone );
+
+ if ( iState == ENSmlItemCreating )
+ {
+ TRAP( error, DoCommitCreateItemL() );
+ }
+ else // ENSmlItemUpdating
+ {
+ TRAP( error, DoCommitReplaceItemL() );
+ }
+ iReplaceItemId = -1;
+ iPos = -1;
+ iState = ENSmlOpenAndWaiting;
+ iRXEntryType = iTXEntryType;
+ User::RequestComplete( iCallerStatus, error );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCloseItem
+// Return to previous state and clean item buffer.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCloseItem()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: BEGIN");
+ if ( iState == ENSmlItemOpen )
+ {
+ iPos = -1;
+ iState = ENSmlOpenAndWaiting;
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMoveItemL
+// Not supported.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoMoveItemL( TSmlDbItemUid /*aUid*/,
+ TSmlDbItemUid /*aNewParent*/, TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeleteItemL
+// Delete item from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoDeleteItemL( TSmlDbItemUid aUid,
+ TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+
+ CCalEntry* entry = NULL;
+ TInt err( KErrNone );
+ TRAP( err, entry = iEntryView->FetchL( aUid ) );
+ CleanupStack::PushL( entry );
+
+ if ( !entry || err == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy( entry ); // entry
+ User::RequestComplete( iCallerStatus, KErrNotFound );
+ return;
+ }
+ else if ( err )
+ {
+ CleanupStack::PopAndDestroy( entry ); // entry
+ User::RequestComplete( iCallerStatus, err );
+ return;
+ }
+
+ iEntryView->DeleteL( *entry );
+ CleanupStack::PopAndDestroy( entry ); // entry
+
+ if ( iChangeFinder )
+ {
+ TNSmlSnapshotItem item( aUid );
+ iChangeFinder->ItemDeleted( item );
+ }
+
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSoftDeleteItemL
+// Delete item from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoSoftDeleteItemL( TSmlDbItemUid /*aUid*/,
+ TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ User::RequestComplete( iCallerStatus, KErrNotSupported );
+ _DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeleteAllItemsL
+// Delete all items from database.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+
+ // Delete all items
+ // First searh every UIDs ...
+ TInt aNumSuccessfulDeleted( 0 );
+ RArray<TCalLocalUid> uidArray;
+ CleanupClosePushL( uidArray );
+ TCalTime zeroTime;
+ zeroTime.SetTimeUtcL( Time::NullTTime() );
+ iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
+
+
+ // ... and then delete them
+ iEntryView->DeleteL( uidArray, aNumSuccessfulDeleted );
+ CleanupStack::PopAndDestroy( &uidArray ); // uidArray
+
+ // Update changefinder
+ if ( iChangeFinder )
+ {
+ iChangeFinder->ResetL();
+ }
+ iSnapshotRegistered = EFalse;
+ RegisterSnapshotL();
+
+ User::RequestComplete( iCallerStatus, KErrNone );
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoHasSyncHistory
+// Return ETrue if syncronization history is available.
+// -----------------------------------------------------------------------------
+//
+TBool CNSmlAgendaDataStore::DoHasSyncHistory() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: BEGIN");
+ TBool ret = EFalse;
+ if ( iHasHistory )
+ {
+ if ( iOpenedStoreId != iChangeFinder->DataStoreUid() )
+ {
+ iChangeFinder->SetDataStoreUid( iOpenedStoreId );
+ }
+ else
+ {
+ ret = ETrue;
+ }
+ }
+ else
+ {
+ iChangeFinder->SetDataStoreUid( iOpenedStoreId );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: END");
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoAddedItems
+// Give uid list of added items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoAddedItems() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iNewUids->Reset();
+ TRAP_IGNORE( iChangeFinder->FindNewItemsL( *iNewUids ) );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: END");
+ return *iNewUids;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoDeletedItems
+// Give uid list of deleted items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoDeletedItems() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iDeletedUids->Reset();
+ TRAP_IGNORE( iChangeFinder->FindDeletedItemsL( *iDeletedUids ) );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: END");
+ return *iDeletedUids;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoSoftDeletedItems
+// Give uid list of deleted items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoSoftDeletedItems() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iSoftDeletedUids->Reset();
+ TRAP_IGNORE(
+ iChangeFinder->FindSoftDeletedItemsL( *iSoftDeletedUids ) );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: END");
+ return *iSoftDeletedUids;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoModifiedItems
+// Give uid list of modified items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoModifiedItems() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iReplacedUids->Reset();
+ TRAP_IGNORE( iChangeFinder->FindChangedItemsL( *iReplacedUids ) );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: END");
+ return *iReplacedUids;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoMovedItems
+// Give uid list of moved items since last syncronization.
+// -----------------------------------------------------------------------------
+//
+const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoMovedItems() const
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: BEGIN");
+ if ( iState == ENSmlOpenAndWaiting )
+ {
+ iMovedUids->Reset();
+ TRAP_IGNORE( iChangeFinder->FindMovedItemsL( *iMovedUids ) );
+ }
+ _DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: END");
+ return *iMovedUids;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoResetChangeInfoL
+// Reset change info that exist since last syncronization.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoResetChangeInfoL( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+ iChangeFinder->ResetL();
+ iSnapshotRegistered = EFalse;
+ if( !iSnapshotRegistered )
+ {
+ RegisterSnapshotL();
+ }
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitChangeInfoL
+// Commit change info that exist since last syncronization for given uid list.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus,
+ const MSmlDataItemUidSet& aItems )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+ iChangeFinder->CommitChangesL( aItems );
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitChangeInfoL
+// Commit change info that exist since last syncronization.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
+ iCallerStatus = &aStatus;
+ *iCallerStatus = KRequestPending;
+ if ( iState != ENSmlOpenAndWaiting )
+ {
+ User::RequestComplete( iCallerStatus, KErrNotReady );
+ return;
+ }
+ iChangeFinder->CommitChangesL();
+ User::RequestComplete( iCallerStatus, KErrNone );
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::RegisterSnapshotL
+// Register snapshot.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::RegisterSnapshotL()
+ {
+ _DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): begin");
+ CArrayFixSeg<TNSmlSnapshotItem>* snapshot =
+ new ( ELeave ) CArrayFixSeg<TNSmlSnapshotItem>( 64 );
+ CleanupStack::PushL( snapshot );
+
+ // First find all entries ...
+ RArray<TCalLocalUid> uidArray;
+ CleanupClosePushL( uidArray );
+ TCalTime zeroTime;
+ zeroTime.SetTimeUtcL( Time::NullTTime() );
+ iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
+
+ // ... and then create snapshot items
+ for ( TInt i = 0; i < uidArray.Count(); i++ )
+ {
+ TNSmlSnapshotItem newItem = CreateSnapshotItemL( uidArray[i] );
+ if ( newItem.ItemId() != 0 )
+ {
+ snapshot->InsertIsqL( newItem, iKey );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &uidArray );
+
+ iChangeFinder->SetNewSnapshot( snapshot );
+
+ // iChangeFinder takes ownership of items
+ CleanupStack::Pop( snapshot );
+ iSnapshotRegistered = ETrue;
+
+ _DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): end");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CreateSnapshotItemL
+// Creates new snapshot. Method gets data from database.
+// -----------------------------------------------------------------------------
+TNSmlSnapshotItem CNSmlAgendaDataStore::CreateSnapshotItemL(
+ const TCalLocalUid& aUid )
+ {
+ TNSmlSnapshotItem item( 0 );
+ CCalEntry* entry = iEntryView->FetchL( aUid );
+ CleanupStack::PushL( entry );
+
+ if( entry )
+ {
+ CCalEntry::TReplicationStatus replicationStatus =
+ entry->ReplicationStatusL();
+ if ( CanBeSynchronized( replicationStatus ) )
+ {
+ TUint intUid = entry->LocalUidL();
+ item.SetItemId( intUid );
+ item.SetLastChangedDate(
+ entry->LastModifiedDateL().TimeUtcL() );
+ item.SetSoftDelete( EFalse );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( entry ); // entry
+ return item;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoListAgendaFilesL
+// List possible calendar database file names.
+// -----------------------------------------------------------------------------
+//
+CDesCArray* CNSmlAgendaDataStore::DoListAgendaFilesLC() const
+ {
+ CDesCArray* array = iVCalSession->ListCalFilesL();
+ CleanupStack::PushL( array );
+ return array;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoGetDefaultFileNameL
+// Return default calendar database name.
+// -----------------------------------------------------------------------------
+//
+const TDesC& CNSmlAgendaDataStore::DoGetDefaultFileNameL() const
+ {
+ if ( !iDefaultStoreName )
+ {
+ User::Leave( KErrGeneral );
+ }
+ return *iDefaultStoreName;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::CanBeSynchronized
+// Return ETrue if entry can be synchronized.
+// -----------------------------------------------------------------------------
+//
+TBool CNSmlAgendaDataStore::CanBeSynchronized(
+ const CCalEntry::TReplicationStatus&
+ aReplicationStatus ) const
+ {
+ return ( aReplicationStatus != CCalEntry::ERestricted );
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoOwnStoreFormatL
+// Returns adapters supported store format which is read from Calendar Plug
+// In Adapter own resource file.
+// -----------------------------------------------------------------------------
+//
+CSmlDataStoreFormat* CNSmlAgendaDataStore::DoOwnStoreFormatL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): BEGIN");
+ TFileName fileName;
+ TParse parse;
+
+ // Check correct Data Sync protocol
+ TInt value( EDataSyncNotRunning );
+ TInt error = RProperty::Get( KPSUidDataSynchronizationInternalKeys,
+ KDataSyncStatus,
+ value );
+ if ( error == KErrNone &&
+ value == EDataSyncRunning )
+ {
+ parse.Set( KNSmlDSAgendaDataStoreRsc_1_1_2,
+ &KDC_RESOURCE_FILES_DIR, NULL );
+ }
+ else // error or protocol version 1.2
+ {
+ parse.Set( KNSmlDSAgendaDataStoreRsc_1_2,
+ &KDC_RESOURCE_FILES_DIR, NULL );
+ }
+
+ fileName = parse.FullName();
+ RResourceFile resourceFile;
+ BaflUtils::NearestLanguageFile( iRfs, fileName );
+
+ TRAPD( leavecode, resourceFile.OpenL( iRfs,fileName ) );
+ if ( leavecode != 0 )
+ {
+ CleanupStack::PopAndDestroy(); // parse
+ _DBG_FILE("CNSmlAgendaDataProvider::DoStoreFormatL(): END");
+ User::Leave( leavecode );
+ }
+ CleanupClosePushL( resourceFile );
+ HBufC8* profileRes = resourceFile.AllocReadLC( NSML_AGENDA_DATA_STORE );
+ TResourceReader reader;
+ reader.SetBuffer( profileRes );
+
+ CSmlDataStoreFormat* dsFormat = CSmlDataStoreFormat::NewLC( iStringPool,
+ reader );
+ CleanupStack::Pop();
+ CleanupStack::PopAndDestroy( 2 ); // resourceFile, profileRes
+ _DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): END");
+ return dsFormat;
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitCreateItemL
+// Commit item data to database when adding item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitCreateItemL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: BEGIN");
+ iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
+ CCalEntry::TReplicationStatus replicationStatus;
+
+ RBufReadStream readStream;
+ readStream.Open( *iItemData );
+ readStream.PushL();
+
+ RPointerArray<CCalEntry> rdArray;
+ CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
+ if ( iRXEntryType == ENSmlICal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportICalendarL");
+ iImporter->ImportICalendarL( readStream, rdArray );
+ }
+ else if ( iRXEntryType == ENSmlVCal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportVCalendarL");
+ iImporter->ImportVCalendarL( readStream, rdArray );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+ KErrNotSupported: END");
+ User::Leave( KErrNotSupported );
+ }
+
+ // If rdArray is empty or there is multiple items then return error
+ // Multiple items are not supported
+ if ( rdArray.Count() != 1 )
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+ Multiple items are not supported: END");
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt err( KErrNone );
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: before StoreL");
+ TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
+ DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
+ if ( err )
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
+ Error at storing item to database: END");
+ User::Leave( KErrGeneral );
+ }
+
+ *iAddItemId = rdArray[0]->LocalUidL();
+
+ CCalEntry* newEntry = iEntryView->FetchL( *iAddItemId );
+
+ if( newEntry )
+ {
+ CleanupStack::PushL( newEntry );
+
+ replicationStatus = newEntry->ReplicationStatusL();
+
+ if ( CanBeSynchronized( replicationStatus ) )
+ {
+ if ( iChangeFinder )
+ {
+ TNSmlSnapshotItem item( *iAddItemId );
+ item.SetLastChangedDate(
+ newEntry->LastModifiedDateL().TimeUtcL() );
+ item.SetSoftDelete( EFalse );
+ TRAPD( changeFinderError, iChangeFinder->ItemAddedL( item ) );
+ if ( changeFinderError == KErrAlreadyExists )
+ {
+ iChangeFinder->ItemUpdatedL( item );
+ }
+ else
+ {
+ User::LeaveIfError( changeFinderError );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy();// newEntry,
+ }
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::DoCommitReplaceItemL
+// Commit item data to database when replacing item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::DoCommitReplaceItemL()
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: BEGIN");
+ iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
+ CBufFlat* oldItem = CBufFlat::NewL( KNSmlItemDataExpandSize );
+ CleanupStack::PushL( oldItem );
+ RBufWriteStream writeStream( *oldItem );
+ writeStream.PushL();
+
+ CCalEntry* entry = NULL;
+ TInt error( KErrNone );
+ TRAP( error, entry = iEntryView->FetchL( iReplaceItemId ) );
+ if ( error || !entry )
+ {
+ CleanupStack::PopAndDestroy( 2 ); // writeStream, oldItem
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+ Error in fetching the item: END");
+ User::Leave( KErrGeneral );
+ }
+ CleanupStack::PushL( entry );
+
+ // Export item from database depending on transmitted item entry type
+ if ( iTXEntryType == ENSmlVCal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportVCalL");
+ iExporter->ExportVCalL( *entry, writeStream );
+ }
+#ifdef __NSML_USE_ICAL_FEATURE
+ else if ( iTXEntryType == ENSmlICal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportICalL");
+ iExporter->ExportICalL( *entry, writeStream );
+ }
+#endif // __NSML_USE_ICAL_FEATURE
+ else
+ {
+ CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+ KErrNotSupported: END");
+ User::Leave( KErrNotSupported );
+ }
+
+ writeStream.CommitL();
+ oldItem->Compress();
+
+ CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
+
+ // Get original UID, geoId and Recurrence-ID properties
+ HBufC8* uid = NULL;
+ HBufC8* recurrenceId = NULL;
+ HBufC8* xRecurrenceId = NULL;
+ HBufC8* geoId = NULL;
+ GetPropertiesFromDataL( oldItem, uid, KVersitTokenUID() );
+ GetPropertiesFromDataL( oldItem, recurrenceId, KNSmlVersitTokenRecurrenceID() );
+ GetPropertiesFromDataL( oldItem, xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );
+ GetPropertiesFromDataL( oldItem, geoId, KNSmlVersitTokenGeoID() );
+ CleanupStack::PushL( uid );
+ CleanupStack::PushL( recurrenceId );
+ CleanupStack::PushL( xRecurrenceId );
+ CleanupStack::PushL( geoId );
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ DBG_DUMP( ( void* )oldItem->Ptr( 0 ).Ptr(), oldItem->Size(),
+ _S8( "Old item from database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ if ( iDataMod->NeedsMerge() )
+ {
+ // Merge data
+ iDataMod->MergeRxL( *iItemData, *oldItem );
+ }
+
+ // Add original UID and Recurrence-ID to merged data
+ // This first removes UID and Recurrence-ID from merged data
+ // and then adds original ones
+ if ( uid )
+ {
+ SetPropertiesToDataL( uid, KVersitTokenUID() );
+ }
+ else
+ {
+ User::Leave( KErrNotSupported );
+ }
+ if ( recurrenceId )
+ {
+ SetPropertiesToDataL( recurrenceId, KNSmlVersitTokenRecurrenceID() );
+ }
+ if ( xRecurrenceId )
+ {
+ SetPropertiesToDataL( xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );
+ }
+ if ( geoId )
+ {
+ SetPropertiesToDataL( geoId, KNSmlVersitTokenGeoID() );
+ }
+
+#ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
+ _S8( "New item to database:" ) );
+
+#endif // __NSML_MORE_DEBUG_FOR_ITEMS__
+
+ CleanupStack::PopAndDestroy( 5 ); // xRecurrenceId, recurrenceId,
+ // uid, oldItem, geoId
+
+ // Replace item to database
+ RBufReadStream readStream;
+ readStream.Open( *iItemData );
+ readStream.PushL();
+
+ RPointerArray<CCalEntry> rdArray;
+ CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
+
+ // Import item to database depending on received item entry type
+ if ( iRXEntryType == ENSmlVCal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportVCalendarL");
+ iImporter->ImportVCalendarL( readStream, rdArray );
+ }
+#ifdef __NSML_USE_ICAL_FEATURE
+ else if ( iRXEntryType == ENSmlICal )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportICalendarL");
+ iImporter->ImportICalendarL( readStream, rdArray );
+ }
+#endif // __NSML_USE_ICAL_FEATURE
+ else
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+ KErrNotSupported: END");
+ User::Leave( KErrNotSupported );
+ }
+
+ // If rdArray is empty or there is multiple items then return error
+ // Multiple items are not supported
+ if ( rdArray.Count() != 1 )
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+ Multiple items are not supported: END");
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt err( KErrNone );
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: before StoreL");
+ TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
+ DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
+ if ( err )
+ {
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
+ Error at storing item to database: END");
+ User::Leave( KErrGeneral );
+ }
+
+ CCalEntry::TReplicationStatus replicationStatus;
+
+ CCalEntry* replacedEntry = iEntryView->FetchL( iReplaceItemId );
+ if( replacedEntry )
+ {
+ CleanupStack::PushL( replacedEntry );
+
+ replicationStatus = replacedEntry->ReplicationStatusL();
+
+ if ( CanBeSynchronized( replicationStatus ) )
+ {
+ if ( iChangeFinder )
+ {
+ TNSmlSnapshotItem item( iReplaceItemId );
+ item.SetLastChangedDate(
+ replacedEntry->LastModifiedDateL().TimeUtcL());
+ item.SetSoftDelete( EFalse );
+ iChangeFinder->ItemUpdatedL( item );
+ }
+ }
+ CleanupStack::PopAndDestroy(); // replacedEntry
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
+
+ _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: END");
+ }
+
+// -----------------------------------------------------------------------------
+// CNSmlAgendaDataStore::GetPropertiesFromDataL
+// Gets property from old item.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::GetPropertiesFromDataL( CBufFlat* aOldItem,
+ HBufC8*& aValue,
+ const TDesC8& aProperty )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): begin");
+
+ // Gemerate property that is searched (Linebreak + property + tokencolon)
+ HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+ aProperty.Length() );
+ TPtr8 startBufferPtr( startBuffer->Des() );
+ startBufferPtr.Append( KVersitTokenCRLF() );
+ startBufferPtr.Append( aProperty );
+
+ // Get start position of property value
+ TInt startPos = aOldItem->Ptr( 0 ).Find( startBufferPtr );
+
+ TInt endPos( KErrNotFound );
+ if ( startPos != KErrNotFound )
+ {
+ // startPos is before UID word
+ startPos = startPos + KVersitTokenCRLF().Length();
+
+ // End end position of property value
+ endPos = startPos +
+ aOldItem->Ptr( startPos ).Find( KVersitTokenCRLF() );
+
+ TPtrC8 tempPtr( aOldItem->Ptr( 0 ).Mid( endPos ) );
+
+ // If next char after linebreak is ' ' or '=' then it is only
+ // linebreak inside of value. This does not work with base64 coding!
+ while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
+ tempPtr[KVersitTokenCRLF().Length()] == '=' )
+ {
+ endPos = endPos + KVersitTokenCRLF().Length();
+ TInt tempPos = aOldItem->Ptr( endPos ).Find( KVersitTokenCRLF() );
+ endPos = endPos + tempPos;
+ tempPtr.Set( aOldItem->Ptr( 0 ).Mid( endPos ) );
+ }
+
+ // Then cut value to value parameter
+ delete aValue;
+ aValue = NULL;
+ TInt length = endPos - startPos;
+ aValue = HBufC8::NewLC( length );
+ TPtr8 valuePtr( aValue->Des() );
+ aOldItem->Read( startPos, valuePtr, length );
+ CleanupStack::Pop( aValue ); // aValue
+ }
+ CleanupStack::PopAndDestroy( startBuffer ); // startBuffer
+
+ _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): end");
+ }
+
+// -----------------------------------------------------------------------------
+// Adds property and it's value to new item.
+// This method also removes original property and it's value.
+// -----------------------------------------------------------------------------
+//
+void CNSmlAgendaDataStore::SetPropertiesToDataL( HBufC8*& aValue,
+ const TDesC8& aProperty )
+ {
+ _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): begin");
+
+ // Gemerate property that is searched (Linebreak + property + tokencolon)
+ HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+ aProperty.Length() );
+ TPtr8 startBufferPtr( startBuffer->Des() );
+ startBufferPtr.Append( KVersitTokenCRLF() );
+ startBufferPtr.Append( aProperty );
+
+ // Get start position of property value
+ TInt startPos = iItemData->Ptr( 0 ).Find( startBufferPtr );
+
+ TInt endPos( KErrNotFound );
+ if ( startPos != KErrNotFound )
+ {
+ // startPos is before UID word
+ startPos = startPos + KVersitTokenCRLF().Length();
+
+ // End end position of property value
+ endPos = startPos +
+ iItemData->Ptr( startPos ).Find( KVersitTokenCRLF() );
+
+ TPtrC8 tempPtr( iItemData->Ptr( 0 ).Mid( endPos ) );
+
+ // If next char after linebreak is ' ' or '=' then it is only
+ // linebreak inside of value. This does not work with base64 coding!
+ while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
+ tempPtr[KVersitTokenCRLF().Length()] == '=' )
+ {
+ endPos = endPos + KVersitTokenCRLF().Length();
+ TInt tempPos = iItemData->Ptr( endPos ).Find( KVersitTokenCRLF() );
+ endPos = endPos + tempPos;
+ tempPtr.Set( iItemData->Ptr( 0 ).Mid( endPos ) );
+ }
+
+ // Delete original property and value
+ iItemData->Delete( startPos, endPos - startPos );
+
+ }
+
+ // Add property and new value from parameter.
+ // First find end of VEVENT or VTODO
+
+ // Generate VEVENT END property
+ HBufC8* endVEvent = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+ KVersitTokenEND().Length() +
+ KVersitTokenColon().Length() +
+ KVersitVarTokenVEVENT().Length() );
+ TPtr8 endVEventPtr( endVEvent->Des() );
+ endVEventPtr.Append( KVersitTokenCRLF() );
+ endVEventPtr.Append( KVersitTokenEND() );
+ endVEventPtr.Append( KVersitTokenColon() );
+ endVEventPtr.Append( KVersitVarTokenVEVENT() );
+
+ // Generate VTODO END property
+ HBufC8* endVTodo = HBufC8::NewLC( KVersitTokenCRLF().Size() +
+ KVersitTokenEND().Length() +
+ KVersitTokenColon().Length() +
+ KVersitVarTokenVTODO().Length() );
+ TPtr8 endVTodoPtr( endVTodo->Des() );
+ endVTodoPtr.Append( KVersitTokenCRLF() );
+ endVTodoPtr.Append( KVersitTokenEND() );
+ endVTodoPtr.Append( KVersitTokenColon() );
+ endVTodoPtr.Append( KVersitVarTokenVTODO() );
+
+ // Find end of VEVENT or VTODO
+ endPos = iItemData->Ptr( 0 ).Find( endVEventPtr );
+ if ( endPos == KErrNotFound )
+ {
+ endPos = iItemData->Ptr( 0 ).Find( endVTodoPtr );
+ if ( endPos == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+
+ // Add property and value from parameter
+ iItemData->InsertL( endPos, KVersitTokenCRLF() );
+ iItemData->InsertL( endPos + KVersitTokenCRLF().Size(),
+ aValue->Des() );
+ iItemData->Compress();
+
+ CleanupStack::PopAndDestroy( 3 ); // endVTodo, endVEvent, startBuffer
+
+ _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): end");
+ }
+
+// End of File