omads/omadsextensions/adapters/contactsgroup/src/changefinder.cpp
changeset 40 b63e67867dcd
equal deleted inserted replaced
39:9905f7d46607 40:b63e67867dcd
       
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Part of ContactsGroup Plug In Adapter
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "changefinder.h"
       
    20 #include "logger.h"
       
    21 
       
    22 const TUint KSnapshotFormatVersion ( 0xf0000001 ); // format version
       
    23 // -----------------------------------------------------------------------------
       
    24 // CChangeFinder::NewL
       
    25 // Static function to create CChangeFider object(s)
       
    26 // -----------------------------------------------------------------------------
       
    27 CChangeFinder* CChangeFinder::NewL( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey,
       
    28         TBool& aHasHistory, TInt aStreamUid )
       
    29     {
       
    30     CChangeFinder* self = new (ELeave) CChangeFinder( aSyncRelationship, aKey, aStreamUid );
       
    31     CleanupStack::PushL( self );
       
    32     self->ConstructL( aHasHistory );
       
    33     CleanupStack::Pop( self );
       
    34     return self;
       
    35     }
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CChangeFinder::CChangeFinder
       
    39 // Constructor for the class
       
    40 // -----------------------------------------------------------------------------
       
    41 CChangeFinder::CChangeFinder( MSmlSyncRelationship& aSyncRelationship,
       
    42         TKeyArrayFix aKey, TInt aStreamUid ) :
       
    43 iSyncRelationship( aSyncRelationship ),
       
    44 iKey( aKey ),
       
    45 iStreamUid( aStreamUid )
       
    46     {
       
    47     }
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // CChangeFinder::~CChangeFinder
       
    51 // Destructor for the class, closes the ChangeFinder and writes snapshot to stream
       
    52 // -----------------------------------------------------------------------------
       
    53 CChangeFinder::~CChangeFinder()
       
    54     {
       
    55     TRACE_FUNC_ENTRY;
       
    56     delete iOldSnapshot;
       
    57 	delete iCurrentSnapshot;
       
    58     TRACE_FUNC_EXIT;
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CChangeFinder::ConstructL
       
    63 // 2nd phase constructor for the class, reads snapshot from stream
       
    64 // -----------------------------------------------------------------------------
       
    65 void CChangeFinder::ConstructL( TBool& aHasHistory )
       
    66     {
       
    67     TRACE_FUNC_ENTRY;
       
    68     iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
    69 	iCurrentSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
    70     LOGGER_WRITE("CChangeFinder::ConstructL, CSnapshotArray:s created");
       
    71     TUid uid = {iStreamUid};
       
    72     
       
    73     aHasHistory = iSyncRelationship.IsStreamPresentL( uid );
       
    74     
       
    75     if ( aHasHistory )
       
    76         {
       
    77         LOGGER_WRITE("CChangeFinder::ConstructL, HasHistory");
       
    78         // Open stream for reading
       
    79         RReadStream readStream;
       
    80         iSyncRelationship.OpenReadStreamLC( readStream, uid );
       
    81         
       
    82         // Read used format version
       
    83         TUint formatVer = readStream.ReadUint32L();
       
    84         if ( formatVer != KSnapshotFormatVersion )
       
    85             {
       
    86             // Wrong version, do not try to import data
       
    87             LOGGER_WRITE("CChangeFinder::ConstructL, Wrong format version -> no history");
       
    88             aHasHistory = EFalse;
       
    89             CleanupStack::PopAndDestroy( &readStream );
       
    90             TRACE_FUNC_EXIT;
       
    91             return;
       
    92             }
       
    93         else
       
    94             {
       
    95             LOGGER_WRITE("CChangeFinder::ConstructL, format is OK");
       
    96             }
       
    97         
       
    98         // Read item count
       
    99         TInt count = readStream.ReadUint32L();
       
   100         
       
   101         // Read items
       
   102         for ( TInt i=0; i<count; i++ )
       
   103             {
       
   104             TSnapshotItem item;
       
   105             item.InternalizeL( readStream );
       
   106             iOldSnapshot->InsertIsqL( item, iKey );
       
   107             }
       
   108         iOldSnapshot->Compress();
       
   109         
       
   110         LOGGER_WRITE_1("iOldSnapshot done, iOldSnapshot->Count: %d", iOldSnapshot->Count() );
       
   111         CleanupStack::PopAndDestroy( &readStream ); // readStream
       
   112         }
       
   113     else
       
   114         {
       
   115         LOGGER_WRITE("CChangeFinder::ConstructL, no sync history.");
       
   116         }
       
   117         
       
   118     TRACE_FUNC_EXIT;
       
   119     }
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CChangeFinder::CloseL
       
   123 // Closes ChangeFinder object and writes snapshot to stream
       
   124 // -----------------------------------------------------------------------------
       
   125 void CChangeFinder::CloseL()
       
   126     {
       
   127     TRACE_FUNC_ENTRY;
       
   128      
       
   129     RWriteStream writeStream;
       
   130     
       
   131     TUid uid = {iStreamUid};
       
   132     
       
   133     // Open write stream
       
   134     iSyncRelationship.OpenWriteStreamLC( writeStream, uid );
       
   135     
       
   136     // Write used format version
       
   137     writeStream.WriteUint32L( KSnapshotFormatVersion );
       
   138     
       
   139     // Write item count
       
   140     TInt count = iOldSnapshot->Count();
       
   141     writeStream.WriteUint32L( count );
       
   142     
       
   143     // Write items
       
   144     for ( TInt i = 0; i < count; i++ )
       
   145         {
       
   146         const TSnapshotItem& item = iOldSnapshot->At( i );
       
   147         item.ExternalizeL( writeStream );
       
   148         }
       
   149     
       
   150     writeStream.CommitL();
       
   151     CleanupStack::PopAndDestroy( &writeStream ); // writeStream
       
   152     
       
   153     TRACE_FUNC_EXIT;
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CChangeFinder::ResetL
       
   158 // Resets synchronization history, all contetn is considered new after this call
       
   159 // -----------------------------------------------------------------------------
       
   160 void CChangeFinder::ResetL()
       
   161     {
       
   162     TRACE_FUNC_ENTRY;
       
   163     iOldSnapshot->Reset();
       
   164     
       
   165     // Write 'null' data to file, 
       
   166     // this removes change history from the file
       
   167     CloseL();
       
   168     
       
   169     TRACE_FUNC_EXIT;
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CChangeFinder::FindChangedItemsL
       
   174 // Compares snapshots, finds changed items
       
   175 // -----------------------------------------------------------------------------
       
   176 void CChangeFinder::FindChangedItemsL( CNSmlDataItemUidSet& aChangedUids )
       
   177     {   
       
   178     TRACE_FUNC_ENTRY;
       
   179     aChangedUids.Reset();
       
   180     
       
   181     TInt index;
       
   182     TInt count = iCurrentSnapshot->Count();
       
   183     LOGGER_WRITE_1( "CChangeFinder::FindChangedItemsL items on iCurrentSnapshot: %d", count );
       
   184     for ( TInt i=0; i < count; i++ )
       
   185         {
       
   186         const TSnapshotItem& currentItem = iCurrentSnapshot->At( i );
       
   187         
       
   188         // Find this entry from the old snapshot
       
   189         if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) == KErrNone)
       
   190             {
       
   191             // This is the old item
       
   192             TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   193             if ( currentItem.Hash().Compare( oldItem.Hash() ) != 0 )
       
   194                 {
       
   195                 // add to list
       
   196 				User::LeaveIfError( aChangedUids.AddItem( currentItem.ItemId() ) );
       
   197                 }
       
   198             }
       
   199         }
       
   200     
       
   201     TRACE_FUNC_EXIT;
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CChangeFinder::FindDeletedItemsL
       
   206 // Compares snapshots, finds deleted items
       
   207 // -----------------------------------------------------------------------------
       
   208 void CChangeFinder::FindDeletedItemsL( CNSmlDataItemUidSet& aDeletedUids )
       
   209     {
       
   210     TRACE_FUNC_ENTRY;
       
   211     aDeletedUids.Reset();
       
   212         
       
   213     TInt index;
       
   214     TInt count = iOldSnapshot->Count();
       
   215     for ( TInt i=0; i < count; i++ )
       
   216         {
       
   217         const TSnapshotItem& currentItem = iOldSnapshot->At( i );
       
   218         
       
   219         // If there's no current snapshot, this definately is deleted item
       
   220         if ( !iCurrentSnapshot )
       
   221             {
       
   222             User::LeaveIfError( aDeletedUids.AddItem( currentItem.ItemId() ) );
       
   223             LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() );
       
   224             }
       
   225         // It is also new if it doesn't exist int the current snapshot.
       
   226         else if ( iCurrentSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone )
       
   227             {
       
   228             User::LeaveIfError( aDeletedUids.AddItem( currentItem.ItemId() ) );
       
   229             LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() );
       
   230             }       
       
   231         }
       
   232         
       
   233     TRACE_FUNC_EXIT;
       
   234     }
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CChangeFinder::FindNewItemsL
       
   238 // Compares snapshots, finds new items
       
   239 // -----------------------------------------------------------------------------
       
   240 void CChangeFinder::FindNewItemsL( CNSmlDataItemUidSet& aNewUids )
       
   241     {
       
   242     TRACE_FUNC_ENTRY;
       
   243     aNewUids.Reset();
       
   244     
       
   245     TInt index;
       
   246     TInt count = iCurrentSnapshot->Count();
       
   247     LOGGER_WRITE_1( "iCurrentSnapshot->Count(): %d", count );
       
   248     LOGGER_WRITE_1( "iOldSnapshot->Count(): %d", iOldSnapshot->Count() );
       
   249     for ( TInt i=0; i < count; i++ )
       
   250         {
       
   251         const TSnapshotItem& currentItem = iCurrentSnapshot->At( i );
       
   252         
       
   253         // If there's no old snapshot, all items are new
       
   254         if ( !iOldSnapshot )
       
   255             {
       
   256             User::LeaveIfError( aNewUids.AddItem( currentItem.ItemId() ) );
       
   257             LOGGER_WRITE_1( "!iOldSnapshot, Item %d was new.", currentItem.ItemId() );
       
   258             }
       
   259         // It is also new if it doesn't exist int the old snapshot.
       
   260         else if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone )
       
   261             {
       
   262             User::LeaveIfError( aNewUids.AddItem( currentItem.ItemId() ) );
       
   263             LOGGER_WRITE_1( "Item %d was new.", currentItem.ItemId() );
       
   264             }       
       
   265         }
       
   266         
       
   267     TRACE_FUNC_EXIT;
       
   268     }
       
   269 
       
   270 // -----------------------------------------------------------------------------
       
   271 // CChangeFinder::ItemAddedL
       
   272 // Adds item to snapshot, this item is no longer considered new
       
   273 // -----------------------------------------------------------------------------
       
   274 void CChangeFinder::ItemAddedL( const TSnapshotItem& aItem )
       
   275     {
       
   276     TRACE_FUNC_ENTRY;
       
   277     LOGGER_WRITE_1( "Adding item %d.", aItem.ItemId() );
       
   278     
       
   279     iOldSnapshot->InsertIsqL( aItem, iKey );
       
   280     iOldSnapshot->Compress();
       
   281     
       
   282     TRACE_FUNC_EXIT;
       
   283     }
       
   284 
       
   285 // -----------------------------------------------------------------------------
       
   286 // CChangeFinder::ItemDeleted
       
   287 // Removes item from snapshot, this item is no longer considered deleted
       
   288 // -----------------------------------------------------------------------------
       
   289 void CChangeFinder::ItemDeleted( const TSnapshotItem& aItem )
       
   290     {
       
   291     TRACE_FUNC_ENTRY;
       
   292     LOGGER_WRITE_1( "deleting item %d.", aItem.ItemId() );
       
   293     
       
   294     // Delete item from the old snapshot
       
   295     TInt index;
       
   296     if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone )
       
   297         {
       
   298         iOldSnapshot->Delete( index );
       
   299         }
       
   300     else // Skip, there wasn't such entry
       
   301         {
       
   302         LOGGER_WRITE( "iOldSnapshot->FindIsq, item was not found." );
       
   303         }  
       
   304     
       
   305     TRACE_FUNC_EXIT;
       
   306     }
       
   307 
       
   308 // -----------------------------------------------------------------------------
       
   309 // CChangeFinder::ItemUpdatedL
       
   310 // Updates item to snapshot, this item is no longer considered changed
       
   311 // -----------------------------------------------------------------------------
       
   312 void CChangeFinder::ItemUpdatedL( const TSnapshotItem& aItem )
       
   313     {
       
   314     TRACE_FUNC_ENTRY;
       
   315     LOGGER_WRITE_1( "Updating item %d.", aItem.ItemId() );
       
   316     
       
   317     // Update item in the old snapshot
       
   318     TInt index;
       
   319     if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone )
       
   320         {
       
   321         iOldSnapshot->At( index ) = aItem;
       
   322         }
       
   323     else 
       
   324         {
       
   325         // There was no such item. Let's add it
       
   326         ItemAddedL( aItem );
       
   327         }
       
   328     TRACE_FUNC_EXIT;
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CChangeFinder::CommitChangesL
       
   333 // Commits current changes to snapshot
       
   334 // -----------------------------------------------------------------------------
       
   335 void CChangeFinder::CommitChangesL()
       
   336     {
       
   337     TRACE_FUNC_ENTRY;
       
   338      
       
   339     // Delete everything from the old snapshot
       
   340     iOldSnapshot->Reset();
       
   341     
       
   342     // Loop through all the items in current snapshot
       
   343     TInt count = iCurrentSnapshot->Count();
       
   344     
       
   345     // Copy everything from current to old snapshot
       
   346     for ( TInt i = 0; i < count; i++ )
       
   347         {
       
   348         // Commit it to the old array.
       
   349         iOldSnapshot->InsertIsqL( iCurrentSnapshot->At( i ), iKey );
       
   350         }
       
   351     TRACE_FUNC_EXIT;
       
   352     }
       
   353 
       
   354 // -----------------------------------------------------------------------------
       
   355 // CChangeFinder::CommitChangesL
       
   356 // Commits current changes to snapshot, affects only a specified group of items
       
   357 // -----------------------------------------------------------------------------
       
   358 void CChangeFinder::CommitChangesL( const MSmlDataItemUidSet& aUids )
       
   359     {
       
   360     TRACE_FUNC_ENTRY;
       
   361     
       
   362     // This function commits changes from current snapshot to old snapshot
       
   363     // But commits only the entries in the parameter array
       
   364     
       
   365     for ( TInt i = 0; i < aUids.ItemCount(); i++ )
       
   366 		{
       
   367 		TSmlDbItemUid itemId = aUids.ItemAt( i );
       
   368 		TSnapshotItem temp( itemId );
       
   369 		TInt indexOld( -1 );
       
   370 		TInt indexNew( -1 );
       
   371 		if ( !iOldSnapshot->FindIsq( temp, iKey, indexOld) )
       
   372 			{
       
   373 			if ( !iCurrentSnapshot->FindIsq(temp, iKey, indexNew) )
       
   374 				{
       
   375 				// Replace, moved or softdeleted
       
   376 				iOldSnapshot->At( indexOld ) = iCurrentSnapshot->At( indexNew );
       
   377 				}
       
   378 			else
       
   379 				{
       
   380 				// Delete
       
   381 				iOldSnapshot->Delete( indexOld );
       
   382 				}
       
   383 			}
       
   384 		else
       
   385 			{
       
   386 			// Add
       
   387 			if ( !iCurrentSnapshot->FindIsq( temp, iKey, indexNew ) )
       
   388 			    {
       
   389 			    iOldSnapshot->InsertIsqL( iCurrentSnapshot->At( indexNew ), iKey );
       
   390 			    }
       
   391 			}
       
   392 		}
       
   393     TRACE_FUNC_EXIT;
       
   394     }
       
   395 
       
   396 // -----------------------------------------------------------------------------
       
   397 // CChangeFinder::SetNewSnapshot
       
   398 // Sets new snapshot (to be compared against), ChangeFinder takes ownership
       
   399 // -----------------------------------------------------------------------------
       
   400 void CChangeFinder::SetNewSnapshot( CSnapshotArray* aNewSnapshot )
       
   401     {
       
   402     TRACE_FUNC;
       
   403     
       
   404     // Delete existing snapshot
       
   405     delete iCurrentSnapshot;
       
   406     
       
   407     // Set submitted snapshot as active
       
   408     iCurrentSnapshot = aNewSnapshot;
       
   409     TRACE_FUNC_EXIT;
       
   410     }