diff -r e6e896426eac -r 2691f6aa1921 omads/omadsextensions/adapters/sms/src/ChangeFinder.cpp --- a/omads/omadsextensions/adapters/sms/src/ChangeFinder.cpp Tue Feb 02 00:02:49 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,697 +0,0 @@ -/* -* Copyright (c) 2005-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: Part of SyncML Data Synchronization Plug In Adapter -* -*/ - - -#include "ChangeFinder.h" -#include "Logger.h" - -const TUint KSnapshotFormatVersion ( 0xf0000001 ); // format version - -// ----------------------------------------------------------------------------- -// CChangeFinder::NewL -// Static function to create CChangeFider object(s) -// ----------------------------------------------------------------------------- -CChangeFinder* CChangeFinder::NewL( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey, - TBool& aHasHistory, TInt aStreamUid ) - { - CChangeFinder* self = new (ELeave) CChangeFinder( aSyncRelationship, aKey, aStreamUid ); - CleanupStack::PushL( self ); - self->ConstructL( aHasHistory ); - CleanupStack::Pop( self ); - return self; - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::CChangeFinder -// Constructor for the class -// ----------------------------------------------------------------------------- -CChangeFinder::CChangeFinder( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey, TInt aStreamUid ) : -iSyncRelationship( aSyncRelationship ), -iKey( aKey ), -iStreamUid( aStreamUid ), -iDataStoreUid( KErrNotFound ) - { - - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::~CChangeFinder -// Destructor for the class, closes the ChangeFinder and writes snapshot to stream -// ----------------------------------------------------------------------------- -CChangeFinder::~CChangeFinder() - { - LOGGER_ENTERFN( "CChangeFinder::~CChangeFinder" ); - TInt error; - TRAP( error, CloseL() ); - if ( error != KErrNone ) - { - LOGGER_WRITE( "CChangeFinder::~CChangeFinder, CloseL failed." ); - } - - delete iCurrentSnapshot; - delete iOldSnapshot; - - LOGGER_LEAVEFN( "CChangeFinder::~CChangeFinder" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ConstructL -// 2nd phase constructor for the class, reads snapshot from stream -// ----------------------------------------------------------------------------- -void CChangeFinder::ConstructL( TBool& aHasHistory ) - { - LOGGER_ENTERFN( "CChangeFinder::ConstructL" ); - - aHasHistory = EFalse; - RReadStream readStream; - - TUid streamId; - streamId.iUid = iStreamUid; - - aHasHistory = iSyncRelationship.IsStreamPresentL(streamId); - - if (aHasHistory) - { - iSyncRelationship.OpenReadStreamLC(readStream, streamId); - - // Read the index, first create snapshot array - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - - // Read used format version - TUint formatVer = readStream.ReadUint32L(); - if ( formatVer != KSnapshotFormatVersion ) - { - // Wrong version, do not try to import data - LOGGER_WRITE("CChangeFinder::ConstructL, Wrong format version -> no history"); - aHasHistory = EFalse; - CleanupStack::PopAndDestroy(); // readStream - LOGGER_LEAVEFN("CChangeFinder::ConstructL"); - return; - } - - // Read item count - TInt count = readStream.ReadUint32L(); - - // Read items - for ( TInt i=0; iInsertIsqL( item, iKey ); - } - - readStream.Close(); - readStream.Pop(); - } - else - { - LOGGER_WRITE("CChangeFinder::ConstructL, no sync history."); - } - - LOGGER_LEAVEFN("CChangeFinder::ConstructL"); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::CloseL -// Closes ChangeFinder object and writes snapshot to stream -// ----------------------------------------------------------------------------- -void CChangeFinder::CloseL() - { - LOGGER_ENTERFN( "CChangeFinder::CloseL" ); - - // Write to stream - RWriteStream writeStream; - - TUid streamId; - streamId.iUid = iStreamUid; - - // Open write stream - iSyncRelationship.OpenWriteStreamLC( writeStream, streamId ); - - // Write used format version - writeStream.WriteUint32L( KSnapshotFormatVersion ); - - // Write item count - TInt count(0); - if ( iOldSnapshot ) - { - count = iOldSnapshot->Count(); - } - writeStream.WriteUint32L(count); - - // Write items - for (TInt i=0; iAt( i ); - item.ExternalizeL( writeStream ); - } - - writeStream.CommitL(); - writeStream.Close(); - writeStream.Pop(); - - LOGGER_LEAVEFN( "CChangeFinder::CloseL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ResetL -// Resets synchronization history, all contetn is considered new after this call -// ----------------------------------------------------------------------------- -void CChangeFinder::ResetL() - { - LOGGER_ENTERFN( "CChangeFinder::ResetL" ); - // Delete old change information - if ( iOldSnapshot ) - { - LOGGER_WRITE("iOldSnapshot->Reset()"); - iOldSnapshot->Reset(); - } - - // Write 'null' data to file, - // this removes change history from the file - CloseL(); - - LOGGER_LEAVEFN( "CChangeFinder::ResetL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::FindChangedItemsL -// Compares snapshots, finds changed items -// ----------------------------------------------------------------------------- -void CChangeFinder::FindChangedItemsL( CNSmlDataItemUidSet& aChangedUids ) - { - LOGGER_ENTERFN( "CChangeFinder::FindChangedItemsL" ); - - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::FindChangedItemsL leaved, no current snapshot." ); - User::Leave( KErrNotFound ); - } - - if ( !iOldSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::FindChangedItemsL leaved, no old snapshot." ); - User::Leave( KErrNotFound ); - } - - TInt index; - TInt count = iCurrentSnapshot->Count(); - for ( TInt i=0; i < count; i++ ) - { - const TSnapshotItem& currentItem = iCurrentSnapshot->At( i ); - // Find this entry from the old snapshot - if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) == KErrNone) - { - // This is the old item - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - // Compare times to see whether this was changed or item was read - if ( ( oldItem.LastChangedDate() != currentItem.LastChangedDate() ) - || ( oldItem.Unread() && !currentItem.Unread() ) - || ( !oldItem.Unread() && currentItem.Unread() ) - || ( oldItem.FolderName().Compare( currentItem.FolderName() ) != 0 ) ) - { - aChangedUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was changed.", currentItem.ItemId() ); - } - } - } - - LOGGER_LEAVEFN( "CChangeFinder::FindChangedItemsL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::FindDeletedItemsL -// Compares snapshots, finds deleted items -// ----------------------------------------------------------------------------- -void CChangeFinder::FindDeletedItemsL( CNSmlDataItemUidSet& aDeletedUids ) - { - LOGGER_ENTERFN( "CChangeFinder::FindDeletedItemsL" ); - - if ( !iOldSnapshot ) - { - LOGGER_LEAVEFN( "CChangeFinder::FindDeletedItemsL leaved, no old snapshot." ); - User::Leave( KErrNotFound ); - } - - TInt index; - TInt count = iOldSnapshot->Count(); - for ( TInt i=0; i < count; i++ ) - { - const TSnapshotItem& currentItem = iOldSnapshot->At( i ); - - // If there's no current snapshot, this definately is deleted item - if ( !iCurrentSnapshot ) - { - aDeletedUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() ); - } - // It is also new if it doesn't exist int the current snapshot. - else if ( iCurrentSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone ) - { - aDeletedUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() ); - } - } - - LOGGER_LEAVEFN( "CChangeFinder::FindDeletedItemsL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::FindNewItemsL -// Compares snapshots, finds new items -// ----------------------------------------------------------------------------- -void CChangeFinder::FindNewItemsL( CNSmlDataItemUidSet& aNewUids ) - { - LOGGER_ENTERFN( "CChangeFinder::FindNewItemsL" ); - - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::FindNewItemsL leaved, no current snapshot." ); - User::Leave( KErrNotFound ); - } - - TInt index; - TInt count = iCurrentSnapshot->Count(); - for ( TInt i=0; i < count; i++ ) - { - const TSnapshotItem& currentItem = iCurrentSnapshot->At( i ); - - // If there's no old snapshot, all items are new - if ( !iOldSnapshot ) - { - aNewUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was new.", currentItem.ItemId() ); - } - // It is also new if it doesn't exist int the old snapshot. - else if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone ) - { - aNewUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was new.", currentItem.ItemId() ); - } - } - - LOGGER_LEAVEFN( "CChangeFinder::FindNewItemsL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::FindMovedItemsL -// Compares snapshots, finds moved items -// ----------------------------------------------------------------------------- -void CChangeFinder::FindMovedItemsL( CNSmlDataItemUidSet& aMovedUids ) - { - LOGGER_ENTERFN( "CChangeFinder::FindMovedItemsL" ); - - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::FindMovedItemsL leaved, no current snapshot." ); - User::Leave( KErrNotFound ); - } - - if ( !iOldSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::FindMovedItemsL leaved, no old snapshot." ); - User::Leave( KErrNotFound ); - } - - TInt index; - TInt count = iCurrentSnapshot->Count(); - for ( TInt i=0; i < count; i++ ) - { - const TSnapshotItem& currentItem = iCurrentSnapshot->At( i ); - - // Find this entry from the old snapshot - if(iOldSnapshot->FindIsq( currentItem, iKey, index ) == KErrNone) - { - // This is the old item - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - - // Report only moved items in which only parent id has been changed - if ( oldItem.ParentId() != currentItem.ParentId() - && oldItem.LastChangedDate() == currentItem.LastChangedDate() - && !(oldItem.Unread() && !currentItem.Unread() ) - && !(!oldItem.Unread() && currentItem.Unread() ) ) - { - aMovedUids.AddItem( currentItem.ItemId() ); - LOGGER_WRITE_1( "Item %d was moved.", currentItem.ItemId() ); - } - } - } - - LOGGER_LEAVEFN( "CChangeFinder::FindMovedItemsL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ItemAddedL -// Adds item to snapshot, this item is no longer considered new -// ----------------------------------------------------------------------------- -void CChangeFinder::ItemAddedL( const TSnapshotItem& aItem ) - { - LOGGER_ENTERFN( "CChangeFinder::ItemAddedL" ); - - // Add this to old snapshot, if there's no old snapshot it must be created - if ( !iOldSnapshot ) - { - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - } - - LOGGER_WRITE_1( "Adding item %d.", aItem.ItemId() ); - - TRAPD( error, iOldSnapshot->InsertIsqL( aItem, iKey ) ); - if ( error == KErrAlreadyExists ) - { - // It was already committed, no actions required - LOGGER_WRITE( "iOldSnapshot->InsertIsqL leaved with KErrAlreadyExists" ); - } - else if ( error != KErrNone ) - { - LOGGER_WRITE_1( "iOldSnapshot->InsertIsqL leaved with %d.", error ); - User::Leave( error ); - } - - LOGGER_LEAVEFN( "CChangeFinder::ItemAddedL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ItemDeletedL -// Removes item to snapshot, this item is no longer considered deleted -// ----------------------------------------------------------------------------- -void CChangeFinder::ItemDeletedL( const TSnapshotItem& aItem ) - { - LOGGER_ENTERFN( "CChangeFinder::ItemDeleted" ); - - LOGGER_WRITE_1( "deleting item %d.", aItem.ItemId() ); - - if ( !iOldSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::ItemDeleted leaved, no old snapshot." ); - User::Leave( KErrNotFound ); - } - - // Delete item from the old snapshot - TInt index; - if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone ) - { - iOldSnapshot->Delete( index ); - } - else // Skip, there wasn't such entry - { - LOGGER_WRITE( "iOldSnapshot->FindIsq, item was not found." ); - } - - LOGGER_LEAVEFN( "CChangeFinder::ItemDeleted" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ItemUpdatedL -// Updates item to snapshot, this item is no longer considered changed -// ----------------------------------------------------------------------------- -void CChangeFinder::ItemUpdatedL( const TSnapshotItem& aItem ) - { - LOGGER_ENTERFN( "CChangeFinder::ItemUpdatedL" ); - - LOGGER_WRITE_1( "Updating item %d.", aItem.ItemId() ); - - // There must be such entry in the snapshot after this - // If there isn't old snapshot, we'll create it and add the item - if ( !iOldSnapshot ) - { - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - ItemAddedL( aItem ); - } - else - { - // Update item in the old snapshot - TInt index; - if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone ) - { - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - oldItem = aItem; - } - else - { - // There was old snapshot but no such item. Let's add it - ItemAddedL( aItem ); - } - - } - - LOGGER_LEAVEFN( "CChangeFinder::ItemUpdatedL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::ItemMovedL -// Moves item within snapshot, this item is no longer considered moved -// ----------------------------------------------------------------------------- -void CChangeFinder::ItemMovedL( const TSnapshotItem& aItem ) - { - LOGGER_ENTERFN( "CChangeFinder::ItemMovedL" ); - - LOGGER_WRITE_1( "Moving item %d.", aItem.ItemId() ); - - // There must be such entry in the snapshot after this - // If there isn't old snapshot, we'll create it and add the item - if ( !iOldSnapshot ) - { - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - ItemAddedL( aItem ); - } - else - { - // Update item's parent in the old snapshot - TInt index; - if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone ) - { - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - oldItem.SetParentId( aItem.ParentId() ); - } - else - { - // There was old snapshot but no such item. Let's add it - ItemAddedL( aItem ); - } - } - - LOGGER_LEAVEFN("CChangeFinder::ItemMovedL"); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::CommitChangesL -// Commits current changes to snapshot -// ----------------------------------------------------------------------------- -void CChangeFinder::CommitChangesL() - { - LOGGER_ENTERFN( "CChangeFinder::CommitChangesL" ); - - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::CommitChangesL leaved, current snapshot missing." ); - User::Leave( KErrNotFound ); - } - - if ( !iOldSnapshot ) - { - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - } - - // Delete everything from the old snapshot - iOldSnapshot->Reset(); - - // Loop through all the items in current snapshot - TInt count = iCurrentSnapshot->Count(); - - // Copy everything from current to old snapshot - for ( TInt i=0; i < count; i++ ) - { - const TSnapshotItem& newItem = iCurrentSnapshot->At( i ); - - // Commit it to the old array. - TRAPD( error, iOldSnapshot->InsertIsqL( newItem, iKey ) ); - if ( error == KErrAlreadyExists ) - { - // It was already committed, this is an internal error of change finder - LOGGER_WRITE( "iOldSnapshot->InsertIsqL leaved with KErrAlreadyExists." ); - User::Leave( error ); - } - else if ( error != KErrNone ) - { - LOGGER_WRITE_1( "iOldSnapshot->InsertIsqL leaved with %d.", error ); - User::Leave( error ); - } - } - LOGGER_LEAVEFN( "CChangeFinder::CommitChangesL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::CommitChangesL -// Commits current changes to snapshot, affects only a specified group of items -// ----------------------------------------------------------------------------- -void CChangeFinder::CommitChangesL( const MSmlDataItemUidSet& aUids ) - { - LOGGER_ENTERFN( "CChangeFinder::CommitChangesL" ); - - // This function commits changes from current snapshot to old snapshot - // But commits only the entries in the parameter array - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::CommitChangesL leaved, current snapshot missing." ); - User::Leave( KErrNotFound ); - } - - if ( !iOldSnapshot ) - { - iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - } - - // Use only these uid values - TInt index; - TInt count = aUids.ItemCount(); - - for ( TInt i=0; i < count; i++ ) - { - TSmlDbItemUid uid = aUids.ItemAt( i ); - TSnapshotItem item( uid ); - // Let's see if this uid exists in the current snapshot - if ( iCurrentSnapshot->FindIsq( item, iKey, index ) == KErrNone ) - { - // This is the new item - const TSnapshotItem& newItem = iCurrentSnapshot->At( index ); - - // Let's see if we can find the old one - if ( iOldSnapshot->FindIsq( item, iKey, index ) == KErrNone ) - { - // This is the old item - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - - // Copy new item over the old one, this'll commit the change - oldItem = newItem; - } - else // This entry was not found. It means that it is new one - { - // Commit it to the old array. - ItemAddedL( newItem ); - } - } - else - { - // This item was deleted from the current snapshot. - TSnapshotItem toDelete( item ); - ItemDeletedL( toDelete ); - } - } - - LOGGER_LEAVEFN( "CChangeFinder::CommitChangesL" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::SetNewSnapshot -// Sets new snapshot (to be compared against), ChangeFinder takes ownership -// ----------------------------------------------------------------------------- -void CChangeFinder::SetNewSnapshot( CSnapshotArray* aNewSnapshot ) - { - LOGGER_ENTERFN( "CChangeFinder::SetNewSnapshot" ); - - // Delete existing snapshot - delete iCurrentSnapshot; - - // Set submitted snapshot as active - iCurrentSnapshot = aNewSnapshot; - LOGGER_LEAVEFN( "CChangeFinder::SetNewSnapshot" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::DataStoreUid -// returns stored data store id number -// ----------------------------------------------------------------------------- -TInt64 CChangeFinder::DataStoreUid() const - { - LOGGER_ENTERFN( "CChangeFinder::DataStoreUid" ); - LOGGER_LEAVEFN( "CChangeFinder::DataStoreUid" ); - return iDataStoreUid; - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::SetDataStoreUid -// Sets data store id number -// ----------------------------------------------------------------------------- -void CChangeFinder::SetDataStoreUid( TInt64 aUid ) - { - LOGGER_ENTERFN( "CChangeFinder::SetDataStoreUid" ); - iDataStoreUid = aUid; - LOGGER_LEAVEFN( "CChangeFinder::SetDataStoreUid" ); - } - -// ----------------------------------------------------------------------------- -// CChangeFinder::UpdatePartialL -// Returns ETrue if item can be updated partially (only status bits are changed) -// ----------------------------------------------------------------------------- -TBool CChangeFinder::UpdatePartialL( TSmlDbItemUid& aUid ) - { - LOGGER_ENTERFN( "CChangeFinder::UpdatePartialL" ); - - if ( !iCurrentSnapshot ) - { - LOGGER_WRITE( "CChangeFinder::UpdatePartialL leaved, current snapshot missing." ); - User::Leave( KErrNotFound ); - } - - if ( !iOldSnapshot ) - { - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return EFalse; - } - - TInt index; - TSnapshotItem item( aUid ); - // Find from current snapshot, if not found -> deleted - if ( iCurrentSnapshot->FindIsq( item, iKey, index ) != KErrNone ) - { - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return EFalse; - } - - // Current item - const TSnapshotItem& currentItem = iCurrentSnapshot->At( index ); - - // Old item, if not found -> added - if ( iOldSnapshot->FindIsq( item, iKey, index ) != KErrNone ) - { - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return EFalse; - } - else - { - // This is the old item - TSnapshotItem& oldItem = iOldSnapshot->At( index ); - - // Status bits must have been changed to allow partial update - if ( oldItem.Unread() == currentItem.Unread() ) - { - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return EFalse; - } - - // Date should be same, otherwise 'just' changed item - if ( oldItem.LastChangedDate() == currentItem.LastChangedDate() ) - { - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return ETrue; - } - - LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" ); - return EFalse; - } - }